changeset 0:a1985f14b030

Initial load
author chegar
date Fri, 11 May 2012 10:42:02 +0100
parents
children 8ff6e91a0455
files ASSEMBLY_EXCEPTION LICENSE README THIRD_PARTY_README dist/Makefile.in dist/RELEASE dist/api_flags dist/api_flags.c dist/buildpkg dist/bumprel dist/clib_port.in dist/config.guess dist/config.hin dist/config.sub dist/configure dist/configure.ac dist/errno.h dist/gen_inc.awk dist/gen_msg.awk dist/install.sh dist/ltmain.sh dist/pubdef.in dist/s_all dist/s_apiflags dist/s_config dist/s_docs dist/s_include dist/s_message dist/s_message_id dist/s_perm dist/s_readme dist/s_sig dist/s_tags dist/s_test dist/s_validate dist/s_windows dist/s_windows_dsp dist/srcfiles.in make/FILES_c.gmk make/Makefile make/libdb.def make/libdb.rc src/btree/bt_compare.c src/btree/bt_conv.c src/btree/bt_curadj.c src/btree/bt_cursor.c src/btree/bt_delete.c src/btree/bt_method.c src/btree/bt_open.c src/btree/bt_put.c src/btree/bt_reclaim.c src/btree/bt_recno.c src/btree/bt_rsearch.c src/btree/bt_search.c src/btree/bt_split.c src/btree/bt_stat.c src/btree/bt_verify.c src/clib/getopt.c src/clib/isalpha.c src/clib/snprintf.c src/clib/strsep.c src/common/clock.c src/common/crypto_stub.c src/common/db_byteorder.c src/common/db_err.c src/common/db_getlong.c src/common/db_idspace.c src/common/db_log2.c src/common/db_shash.c src/common/dbt.c src/common/mkpath.c src/common/os_method.c src/common/rds_stub.c src/common/util_cache.c src/common/util_log.c src/common/util_sig.c src/common/zerofill.c src/db/db.c src/db/db_am.c src/db/db_backup.c src/db/db_cam.c src/db/db_conv.c src/db/db_copy.c src/db/db_dup.c src/db/db_iface.c src/db/db_meta.c src/db/db_method.c src/db/db_open.c src/db/db_overflow.c src/db/db_ovfl_vrfy.c src/db/db_pr.c src/db/db_reclaim.c src/db/db_remove.c src/db/db_rename.c src/db/db_ret.c src/db/db_setid.c src/db/db_setlsn.c src/db/db_sort_multiple.c src/db/db_stati.c src/db/db_truncate.c src/db/db_vrfy.c src/db/db_vrfy_stub.c src/db/db_vrfyutil.c src/db/partition_stub.c src/dbinc/atomic.h src/dbinc/btree.h src/dbinc/clock.h src/dbinc/crypto.h src/dbinc/cxx_int.h src/dbinc/db.in src/dbinc/db_185.in src/dbinc/db_am.h src/dbinc/db_cxx.in src/dbinc/db_dispatch.h src/dbinc/db_int.in src/dbinc/db_join.h src/dbinc/db_page.h src/dbinc/db_swap.h src/dbinc/db_upgrade.h src/dbinc/db_verify.h src/dbinc/debug.h src/dbinc/fop.h src/dbinc/globals.h src/dbinc/hash.h src/dbinc/heap.h src/dbinc/hmac.h src/dbinc/lock.h src/dbinc/log.h src/dbinc/log_verify.h src/dbinc/mp.h src/dbinc/mutex.h src/dbinc/mutex_int.h src/dbinc/os.h src/dbinc/partition.h src/dbinc/perfmon.h src/dbinc/qam.h src/dbinc/queue.h src/dbinc/region.h src/dbinc/rep.h src/dbinc/repmgr.h src/dbinc/shqueue.h src/dbinc/tcl_db.h src/dbinc/txn.h src/dbinc/win_db.h src/dbinc/xa.h src/dbinc_auto/api_flags.in src/dbinc_auto/btree_auto.h src/dbinc_auto/btree_ext.h src/dbinc_auto/clib_ext.h src/dbinc_auto/common_ext.h src/dbinc_auto/crdel_auto.h src/dbinc_auto/crypto_ext.h src/dbinc_auto/db_auto.h src/dbinc_auto/db_ext.h src/dbinc_auto/dbreg_auto.h src/dbinc_auto/dbreg_ext.h src/dbinc_auto/env_ext.h src/dbinc_auto/ext_185_def.in src/dbinc_auto/ext_185_prot.in src/dbinc_auto/ext_def.in src/dbinc_auto/ext_prot.in src/dbinc_auto/fileops_auto.h src/dbinc_auto/fileops_ext.h src/dbinc_auto/hash_auto.h src/dbinc_auto/hash_ext.h src/dbinc_auto/heap_auto.h src/dbinc_auto/heap_ext.h src/dbinc_auto/hmac_ext.h src/dbinc_auto/int_def.in src/dbinc_auto/lock_ext.h src/dbinc_auto/log_ext.h src/dbinc_auto/mp_ext.h src/dbinc_auto/mutex_ext.h src/dbinc_auto/os_ext.h src/dbinc_auto/qam_auto.h src/dbinc_auto/qam_ext.h src/dbinc_auto/rep_automsg.h src/dbinc_auto/rep_ext.h src/dbinc_auto/repmgr_auto.h src/dbinc_auto/repmgr_automsg.h src/dbinc_auto/repmgr_ext.h src/dbinc_auto/sequence_ext.h src/dbinc_auto/tcl_ext.h src/dbinc_auto/txn_auto.h src/dbinc_auto/txn_ext.h src/dbinc_auto/xa_ext.h src/env/env_alloc.c src/env/env_config.c src/env/env_file.c src/env/env_globals.c src/env/env_method.c src/env/env_name.c src/env/env_open.c src/env/env_region.c src/env/env_sig.c src/env/env_stat.c src/fileops/fop_basic.c src/fileops/fop_util.c src/hash/hash_func.c src/hash/hash_stub.c src/heap/heap_stub.c src/lock/lock_stub.c src/log/log_verify_stub.c src/mp/mp_alloc.c src/mp/mp_bh.c src/mp/mp_fget.c src/mp/mp_fmethod.c src/mp/mp_fopen.c src/mp/mp_fput.c src/mp/mp_fset.c src/mp/mp_method.c src/mp/mp_region.c src/mp/mp_register.c src/mp/mp_resize.c src/mp/mp_stat.c src/mp/mp_sync.c src/mp/mp_trickle.c src/mutex/mut_alloc.c src/mutex/mut_method.c src/mutex/mut_pthread.c src/mutex/mut_region.c src/mutex/mut_stat.c src/mutex/mut_tas.c src/mutex/mut_win32.c src/os/os_abort.c src/os/os_abs.c src/os/os_addrinfo.c src/os/os_alloc.c src/os/os_clock.c src/os/os_config.c src/os/os_cpu.c src/os/os_ctime.c src/os/os_dir.c src/os/os_errno.c src/os/os_fid.c src/os/os_flock.c src/os/os_fsync.c src/os/os_getenv.c src/os/os_handle.c src/os/os_map.c src/os/os_mkdir.c src/os/os_open.c src/os/os_path.c src/os/os_pid.c src/os/os_rename.c src/os/os_root.c src/os/os_rpath.c src/os/os_rw.c src/os/os_seek.c src/os/os_stack.c src/os/os_stat.c src/os/os_tmpdir.c src/os/os_truncate.c src/os/os_uid.c src/os/os_unlink.c src/os/os_yield.c src/os_windows/ce_ctime.c src/os_windows/os_abs.c src/os_windows/os_clock.c src/os_windows/os_config.c src/os_windows/os_cpu.c src/os_windows/os_dir.c src/os_windows/os_errno.c src/os_windows/os_fid.c src/os_windows/os_flock.c src/os_windows/os_fsync.c src/os_windows/os_getenv.c src/os_windows/os_handle.c src/os_windows/os_map.c src/os_windows/os_mkdir.c src/os_windows/os_open.c src/os_windows/os_rename.c src/os_windows/os_rw.c src/os_windows/os_seek.c src/os_windows/os_stat.c src/os_windows/os_truncate.c src/os_windows/os_unlink.c src/os_windows/os_yield.c src/qam/qam_stub.c src/rep/rep_stub.c src/repmgr/repmgr_stub.c src/windows_incl/clib_port.h src/windows_incl/db.h src/windows_incl/db_config.h src/windows_incl/db_int.h util/db_dump.c util/db_load.c util/db_stat.c util/db_verify.c
diffstat 288 files changed, 168363 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ASSEMBLY_EXCEPTION	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,27 @@
+
+OPENJDK ASSEMBLY EXCEPTION
+
+The OpenJDK source code made available by Sun at openjdk.java.net and
+openjdk.dev.java.net ("OpenJDK Code") is distributed under the terms of the
+GNU General Public License <http://www.gnu.org/copyleft/gpl.html> version 2
+only ("GPL2"), with the following clarification and special exception.
+
+    Linking this OpenJDK Code statically or dynamically with other code
+    is making a combined work based on this library.  Thus, the terms
+    and conditions of GPL2 cover the whole combination.
+
+    As a special exception, Sun gives you permission to link this
+    OpenJDK Code with certain code licensed by Sun as indicated at
+    http://openjdk.java.net/legal/exception-modules-2007-05-08.html
+    ("Designated Exception Modules") to produce an executable,
+    regardless of the license terms of the Designated Exception Modules,
+    and to copy and distribute the resulting executable under GPL2,
+    provided that the Designated Exception Modules continue to be
+    governed by the licenses under which they were offered by Sun.
+
+As such, it allows licensees and sublicensees of Sun's GPL2 OpenJDK Code to
+build an executable that includes those portions of necessary code that Sun
+could not provide under GPL2 (or that Sun has provided under GPL2 with the
+Classpath exception).  If you modify or add to the OpenJDK code, that new
+GPL2 code may still be combined with Designated Exception Modules if the
+new code is made subject to this exception by its copyright holder.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LICENSE	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,347 @@
+The GNU General Public License (GPL)
+
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it.  By contrast, the GNU General Public License is intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users.  This General Public License applies to
+most of the Free Software Foundation's software and to any other program whose
+authors commit to using it.  (Some other Free Software Foundation software is
+covered by the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+When we speak of free software, we are referring to freedom, not price.  Our
+General Public Licenses are designed to make sure that you have the freedom to
+distribute copies of free software (and charge for this service if you wish),
+that you receive source code or can get it if you want it, that you can change
+the software or use pieces of it in new free programs; and that you know you
+can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny
+you these rights or to ask you to surrender the rights.  These restrictions
+translate to certain responsibilities for you if you distribute copies of the
+software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for
+a fee, you must give the recipients all the rights that you have.  You must
+make sure that they, too, receive or can get the source code.  And you must
+show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy, distribute
+and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software.  If the
+software is modified by someone else and passed on, we want its recipients to
+know that what they have is not the original, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents.  We
+wish to avoid the danger that redistributors of a free program will
+individually obtain patent licenses, in effect making the program proprietary.
+To prevent this, we have made it clear that any patent must be licensed for
+everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms of
+this General Public License.  The "Program", below, refers to any such program
+or work, and a "work based on the Program" means either the Program or any
+derivative work under copyright law: that is to say, a work containing the
+Program or a portion of it, either verbatim or with modifications and/or
+translated into another language.  (Hereinafter, translation is included
+without limitation in the term "modification".) Each licensee is addressed as
+"you".
+
+Activities other than copying, distribution and modification are not covered by
+this License; they are outside its scope.  The act of running the Program is
+not restricted, and the output from the Program is covered only if its contents
+constitute a work based on the Program (independent of having been made by
+running the Program).  Whether that is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code as
+you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and
+disclaimer of warranty; keep intact all the notices that refer to this License
+and to the absence of any warranty; and give any other recipients of the
+Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may
+at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it, thus
+forming a work based on the Program, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all of
+these conditions:
+
+    a) You must cause the modified files to carry prominent notices stating
+    that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in whole or
+    in part contains or is derived from the Program or any part thereof, to be
+    licensed as a whole at no charge to all third parties under the terms of
+    this License.
+
+    c) If the modified program normally reads commands interactively when run,
+    you must cause it, when started running for such interactive use in the
+    most ordinary way, to print or display an announcement including an
+    appropriate copyright notice and a notice that there is no warranty (or
+    else, saying that you provide a warranty) and that users may redistribute
+    the program under these conditions, and telling the user how to view a copy
+    of this License.  (Exception: if the Program itself is interactive but does
+    not normally print such an announcement, your work based on the Program is
+    not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If identifiable
+sections of that work are not derived from the Program, and can be reasonably
+considered independent and separate works in themselves, then this License, and
+its terms, do not apply to those sections when you distribute them as separate
+works.  But when you distribute the same sections as part of a whole which is a
+work based on the Program, the distribution of the whole must be on the terms
+of this License, whose permissions for other licensees extend to the entire
+whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise the
+right to control the distribution of derivative or collective works based on
+the Program.
+
+In addition, mere aggregation of another work not based on the Program with the
+Program (or with a work based on the Program) on a volume of a storage or
+distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may copy and distribute the Program (or a work based on it, under
+Section 2) in object code or executable form under the terms of Sections 1 and
+2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable source
+    code, which must be distributed under the terms of Sections 1 and 2 above
+    on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three years, to
+    give any third party, for a charge no more than your cost of physically
+    performing source distribution, a complete machine-readable copy of the
+    corresponding source code, to be distributed under the terms of Sections 1
+    and 2 above on a medium customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer to
+    distribute corresponding source code.  (This alternative is allowed only
+    for noncommercial distribution and only if you received the program in
+    object code or executable form with such an offer, in accord with
+    Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it.  For an executable work, complete source code means all
+the source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and installation
+of the executable.  However, as a special exception, the source code
+distributed need not include anything that is normally distributed (in either
+source or binary form) with the major components (compiler, kernel, and so on)
+of the operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the source
+code from the same place counts as distribution of the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as
+expressly provided under this License.  Any attempt otherwise to copy, modify,
+sublicense or distribute the Program is void, and will automatically terminate
+your rights under this License.  However, parties who have received copies, or
+rights, from you under this License will not have their licenses terminated so
+long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it.
+However, nothing else grants you permission to modify or distribute the Program
+or its derivative works.  These actions are prohibited by law if you do not
+accept this License.  Therefore, by modifying or distributing the Program (or
+any work based on the Program), you indicate your acceptance of this License to
+do so, and all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program),
+the recipient automatically receives a license from the original licensor to
+copy, distribute or modify the Program subject to these terms and conditions.
+You may not impose any further restrictions on the recipients' exercise of the
+rights granted herein.  You are not responsible for enforcing compliance by
+third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues), conditions
+are imposed on you (whether by court order, agreement or otherwise) that
+contradict the conditions of this License, they do not excuse you from the
+conditions of this License.  If you cannot distribute so as to satisfy
+simultaneously your obligations under this License and any other pertinent
+obligations, then as a consequence you may not distribute the Program at all.
+For example, if a patent license would not permit royalty-free redistribution
+of the Program by all those who receive copies directly or indirectly through
+you, then the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or
+other property right claims or to contest validity of any such claims; this
+section has the sole purpose of protecting the integrity of the free software
+distribution system, which is implemented by public license practices.  Many
+people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose that
+choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original
+copyright holder who places the Program under this License may add an explicit
+geographical distribution limitation excluding those countries, so that
+distribution is permitted only in or among countries not thus excluded.  In
+such case, this License incorporates the limitation as if written in the body
+of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of the
+General Public License from time to time.  Such new versions will be similar in
+spirit to the present version, but may differ in detail to address new problems
+or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any later
+version", you have the option of following the terms and conditions either of
+that version or of any later version published by the Free Software Foundation.
+If the Program does not specify a version number of this License, you may
+choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission.  For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this.
+Our decision will be guided by the two goals of preserving the free status of
+all derivatives of our free software and of promoting the sharing and reuse of
+software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
+PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND
+PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE,
+YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
+ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
+PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
+INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
+OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible
+use to the public, the best way to achieve this is to make it free software
+which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program.  It is safest to attach
+them to the start of each source file to most effectively convey the exclusion
+of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+    One line to give the program's name and a brief idea of what it does.
+
+    Copyright (C) <year> <name of author>
+
+    This program is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the Free
+    Software Foundation; either version 2 of the License, or (at your option)
+    any later version.
+
+    This program is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+    more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc., 59
+    Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this when it
+starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
+    with ABSOLUTELY NO WARRANTY; for details type 'show w'.  This is free
+    software, and you are welcome to redistribute it under certain conditions;
+    type 'show c' for details.
+
+The hypothetical commands 'show w' and 'show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may be
+called something other than 'show w' and 'show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.  Here
+is a sample; alter the names:
+
+    Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+    'Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+    signature of Ty Coon, 1 April 1989
+
+    Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General Public
+License instead of this License.
+
+
+"CLASSPATH" EXCEPTION TO THE GPL
+
+Certain source files distributed by Oracle America and/or its affiliates are
+subject to the following clarification and special exception to the GPL, but
+only where Oracle has expressly included in the particular source file's header
+the words "Oracle designates this particular file as subject to the "Classpath"
+exception as provided by Oracle in the LICENSE file that accompanied this code."
+
+    Linking this library statically or dynamically with other modules is making
+    a combined work based on this library.  Thus, the terms and conditions of
+    the GNU General Public License cover the whole combination.
+
+    As a special exception, the copyright holders of this library give you
+    permission to link this library with independent modules to produce an
+    executable, regardless of the license terms of these independent modules,
+    and to copy and distribute the resulting executable under terms of your
+    choice, provided that you also meet, for each linked independent module,
+    the terms and conditions of the license of that module.  An independent
+    module is a module which is not derived from or based on this library.  If
+    you modify this library, you may extend this exception to your version of
+    the library, but you are not obligated to do so.  If you do not wish to do
+    so, delete this exception statement from your version.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,16 @@
+Berkeley DB 11g Release 2, library version 11.2.5.4.0: (May  7, 2012)
+
+This file should be located at the top of the bdb Mercurial repository.
+
+See http://openjdk.java.net/ for more information about the OpenJDK.
+
+See ../README-builds.html for complete details on build machine requirements.
+
+Simple Build Instructions:
+
+    cd make && gnumake
+     
+The files that will be imported into the jdk build will be in the "import"
+directory.
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/THIRD_PARTY_README	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,3385 @@
+DO NOT TRANSLATE OR LOCALIZE.
+-----------------------------
+
+%% This notice is provided with respect to ASM Bytecode Manipulation 
+Framework v3.1, which is included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+Copyright (c) 2000-2005 INRIA, France Telecom
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holders nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+
+--- end of LICENSE ---
+
+--------------------------------------------------------------------------------
+
+%% This notice is provided with respect to CodeViewer 1.0, which is included 
+with JDK 7.
+
+--- begin of LICENSE ---
+
+Copyright 1999 by CoolServlets.com.
+
+Any errors or suggested improvements to this class can be reported as
+instructed on CoolServlets.com. We hope you enjoy this program... your
+comments will encourage further development!  This software is distributed
+under the terms of the BSD License.  Redistribution and use in source and
+binary forms, with or without modification, are permitted provided that the
+following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+Neither name of CoolServlets.com nor the names of its contributors may be
+used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY COOLSERVLETS.COM AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Cryptix AES 3.2.0, which is
+included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+Cryptix General License
+
+Copyright (c) 1995-2005 The Cryptix Foundation Limited.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  1. Redistributions of source code must retain the copyright notice,
+     this list of conditions and the following disclaimer.
+
+  2. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE CRYPTIX FOUNDATION LIMITED AND
+CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE CRYPTIX FOUNDATION LIMITED OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to CUP Parser Generator for 
+Java 0.10k, which is included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+Copyright 1996-1999 by Scott Hudson, Frank Flannery, C. Scott Ananian
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both the
+copyright notice and this permission notice and warranty disclaimer appear in
+supporting documentation, and that the names of the authors or their
+employers not be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+The authors and their employers disclaim all warranties with regard to
+this software, including all implied warranties of merchantability and fitness.
+In no event shall the authors or their employers be liable for any special,
+indirect or consequential damages or any damages whatsoever resulting from
+loss of use, data or profits, whether in an action of contract, negligence or
+other tortious action, arising out of or in connection with the use or
+performance of this software.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Document Object Model (DOM) Level 2
+& 3, which is included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+W3C SOFTWARE NOTICE AND LICENSE
+
+http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+This work (and included software, documentation such as READMEs, or other
+related items) is being provided by the copyright holders under the following
+license. By obtaining, using and/or copying this work, you (the licensee)
+agree that you have read, understood, and will comply with the following terms
+and conditions.
+
+Permission to copy, modify, and distribute this software and its
+documentation, with or without modification, for any purpose and without fee
+or royalty is hereby granted, provided that you include the following on ALL
+copies of the software and documentation or portions thereof, including
+modifications:
+
+   1.The full text of this NOTICE in a location viewable to users of the
+   redistributed or derivative work.
+
+   2.Any pre-existing intellectual property disclaimers, notices, or terms and
+   conditions. If none exist, the W3C Software Short Notice should be included
+   (hypertext is preferred, text is permitted) within the body of any
+   redistributed or derivative code.
+
+   3.Notice of any changes or modifications to the files, including the date
+   changes were made. (We recommend you provide URIs to the location from
+   which the code is derived.)
+
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS
+MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
+PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY
+THIRD PARTY PATENTS,COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL
+OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR
+DOCUMENTATION.  The name and trademarks of copyright holders may NOT be used
+in advertising or publicity pertaining to the software without specific,
+written prior permission. Title to copyright in this software and any
+associated documentation will at all times remain with copyright holders.
+
+____________________________________
+
+This formulation of W3C's notice and license became active on December 31
+2002. This version removes the copyright ownership notice such that this
+license can be used with materials other than those owned by the W3C, reflects
+that ERCIM is now a host of the W3C, includes references to this specific
+dated version of the license, and removes the ambiguous grant of "use".
+Otherwise, this version is the same as the previous version and is written so
+as to preserve the Free Software Foundation's assessment of GPL compatibility
+and OSI's certification under the Open Source Definition. Please see our
+Copyright FAQ for common questions about using materials from our site,
+including specific terms and conditions for packages like libwww, Amaya, and
+Jigsaw. Other questions about this notice can be directed to
+site-policy@w3.org.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Elliptic Curve Cryptography, which 
+is included with JRE 7, JDK 7, and OpenJDK 7.
+
+You are receiving a copy of the Elliptic Curve Cryptography library in source
+form with the JDK 7 source distribution and object code in the JRE 7 & JDK 7
+runtime.
+
+The terms of the Oracle license do NOT apply to the Elliptic Curve
+Cryptography library program; it is licensed under the following license,
+separately from the Oracle programs you receive. If you do not wish to install
+this program, you may delete the library named libsunec.so (on Solaris and
+Linux systems) or sunec.dll (on Windows systems) from the JRE bin directory
+reserved for native libraries.
+
+--- begin of LICENSE ---
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to FontConfig 2.5, which is 
+included with JRE 7, JDK 7, and OpenJDK 7 source distributions on
+Linux and Solaris.
+
+--- begin of LICENSE ---
+
+Copyright © 2001,2003 Keith Packard
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that the
+above copyright notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting documentation, and that
+the name of Keith Packard not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior permission.
+Keith Packard makes no representations about the suitability of this software
+for any purpose.  It is provided "as is" without express or implied warranty.
+
+KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL KEITH
+PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to IAIK PKCS#11 Wrapper, 
+which is included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+IAIK PKCS#11 Wrapper License
+
+Copyright (c) 2002 Graz University of Technology. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3. The end-user documentation included with the redistribution, if any, must
+   include the following acknowledgment:
+
+   "This product includes software developed by IAIK of Graz University of
+    Technology."
+
+   Alternately, this acknowledgment may appear in the software itself, if and
+   wherever such third-party acknowledgments normally appear.
+
+4. The names "Graz University of Technology" and "IAIK of Graz University of
+   Technology" must not be used to endorse or promote products derived from this
+   software without prior written permission.
+
+5. Products derived from this software may not be called "IAIK PKCS Wrapper",
+   nor may "IAIK" appear in their name, without prior written permission of
+   Graz University of Technology.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to ICU4C 4.0.1 and ICU4J 4.4, which 
+is included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+Copyright (c) 1995-2010 International Business Machines Corporation and others 
+
+All rights reserved. 
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, and/or sell copies of the
+Software, and to permit persons to whom the Software is furnished to do so,
+provided that the above copyright notice(s) and this permission notice appear
+in all copies of the Software and that both the above copyright notice(s) and
+this permission notice appear in supporting documentation.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
+NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE
+LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY
+DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization of the copyright holder.
+All trademarks and registered trademarks mentioned herein are the property of
+their respective owners.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to IJG JPEG 6b, which is 
+included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+This software is copyright (C) 1991-1998, Thomas G. Lane.
+All Rights Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to these
+conditions:
+(1) If any part of the source code for this software is distributed, then this
+README file must be included, with this copyright and no-warranty notice
+unaltered; and any additions, deletions, or changes to the original files
+must be clearly indicated in accompanying documentation.
+(2) If only executable code is distributed, then the accompanying
+documentation must state that "this software is based in part on the work of
+the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user accepts
+full responsibility for any undesirable consequences; the authors accept
+NO LIABILITY for damages of any kind.
+
+These conditions apply to any software derived from or based on the IJG code,
+not just to the unmodified library.  If you use our work, you ought to
+acknowledge us.
+
+Permission is NOT granted for the use of any IJG author's name or company name
+in advertising or publicity relating to this software or products derived from
+it.  This software may be referred to only as "the Independent JPEG Group's
+software".
+
+We specifically permit and encourage the use of this software as the basis of
+commercial products, provided that all warranty or liability claims are
+assumed by the product vendor.
+
+--- end of LICENSE ---
+
+--------------------------------------------------------------------------------
+
+%% This notice is provided with respect to JOpt-Simple v3.0,  which is 
+included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+ Copyright (c) 2004-2009 Paul R. Holser, Jr.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+--- end of LICENSE ---
+
+--------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Kerberos functionality, which 
+which is included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+ (C) Copyright IBM Corp. 1999 All Rights Reserved.
+ Copyright 1997 The Open Group Research Institute. All rights reserved.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Kerberos functionality from 
+FundsXpress, INC., which is included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+ Copyright (C) 1998 by the FundsXpress, INC.
+
+ All rights reserved.
+
+ Export of this software from the United States of America may require
+ a specific license from the United States Government.  It is the
+ responsibility of any person or organization contemplating export to
+ obtain such a license before exporting.
+
+ WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ distribute this software and its documentation for any purpose and
+ without fee is hereby granted, provided that the above copyright
+ notice appear in all copies and that both that copyright notice and
+ this permission notice appear in supporting documentation, and that
+ the name of FundsXpress. not be used in advertising or publicity pertaining
+ to distribution of the software without specific, written prior
+ permission.  FundsXpress makes no representations about the suitability of
+ this software for any purpose.  It is provided "as is" without express
+ or implied warranty.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Kronos OpenGL headers, which is 
+included with JDK 7 and OpenJDK 7 source distributions.
+
+--- begin of LICENSE ---
+
+ Copyright (c) 2007 The Khronos Group Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and/or associated documentation files (the "Materials"), to
+ deal in the Materials without restriction, including without limitation the
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Materials, and to permit persons to whom the Materials are
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Materials.
+
+ THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS IN THE
+ MATERIALS.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% Portions Copyright Eastman Kodak Company 1992
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to libpng 1.2.18, which is 
+included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+This copy of the libpng notices is provided for your convenience.  In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+libpng versions 1.2.6, August 15, 2004, through 1.2.18, May 15, 2007, are
+Copyright (c) 2004, 2006-2007 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.2.5
+with the following individual added to the list of Contributing Authors
+
+   Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+   Simon-Pierre Cadieux
+   Eric S. Raymond
+   Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+   There is no warranty against interference with your enjoyment of the
+   library or against infringement.  There is no warranty that our
+   efforts or the library will fulfill any of your particular purposes
+   or needs.  This library is provided with all faults, and the entire
+   risk of satisfactory quality, performance, accuracy, and effort is with
+   the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+   Tom Lane
+   Glenn Randers-Pehrson
+   Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+   John Bowler
+   Kevin Bracey
+   Sam Bushell
+   Magnus Holmgren
+   Greg Roelofs
+   Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+   Andreas Dilger
+   Dave Martindale
+   Guy Eric Schalnat
+   Paul Schmidt
+   Tim Wegner
+
+The PNG Reference Library is supplied "AS IS".  The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose.  The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and must not
+   be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any
+   source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products.  If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+   printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software.  OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+May 15, 2007
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to libungif 4.1.3, which is 
+included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+The GIFLIB distribution is Copyright (c) 1997  Eric S. Raymond
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Little CMS 2.0, which is 
+included with OpenJDK 7.
+
+--- begin of LICENSE ---
+
+Little CMS
+Copyright (c) 1998-2010 Marti Maria Saguer
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% Lucida is a registered trademark or trademark of Bigelow & Holmes in the
+U.S. and other countries.
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Mesa 3D Graphics Library v4.1,
+which is included with JRE 7, JDK 7, and OpenJDK 7 source distributions.
+
+--- begin of LICENSE ---
+
+ Mesa 3-D graphics library
+ Version:  4.1
+
+ Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to PC/SC Lite for Suse Linux v.1.1.1,
+which is included with JRE 7, JDK 7, and OpenJDK 7 on Linux and Solaris.
+
+--- begin of LICENSE ---
+
+Copyright (c) 1999-2004 David Corcoran <corcoran@linuxnet.com>
+Copyright (c) 1999-2004 Ludovic Rousseau <ludovic.rousseau (at) free.fr>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement:
+     This product includes software developed by: 
+      David Corcoran <corcoran@linuxnet.com>
+      http://www.linuxnet.com (MUSCLE)
+4. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+Changes to this license can be made only by the copyright author with 
+explicit written consent.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Relax NG Object/Parser v.20050510,
+which is included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+Copyright (c) Kohsuke Kawaguchi
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions: The above copyright
+notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to RelaxNGCC v1.12, which is 
+included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+Copyright (c) 2000-2003 Daisuke Okajima and Kohsuke Kawaguchi.  
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3. The end-user documentation included with the redistribution, if any, must
+   include the following acknowledgment:
+
+    "This product includes software developed by Daisuke Okajima
+    and Kohsuke Kawaguchi (http://relaxngcc.sf.net/)."
+
+Alternately, this acknowledgment may appear in the software itself, if and
+wherever such third-party acknowledgments normally appear.
+
+4. The names of the copyright holders must not be used to endorse or promote
+   products derived from this software without prior written permission. For
+   written permission, please contact the copyright holders.
+
+5. Products derived from this software may not be called "RELAXNGCC", nor may
+  "RELAXNGCC" appear in their name, without prior written permission of the
+  copyright holders.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE APACHE
+SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Mozilla Rhino v1.7R3, which 
+is included with JRE 7, JDK 7, and OpenJDK 7
+
+--- begin of LICENSE ---
+
+                          MOZILLA PUBLIC LICENSE
+                                Version 1.1
+
+                              ---------------
+
+1. Definitions.
+
+     1.0.1. "Commercial Use" means distribution or otherwise making the
+     Covered Code available to a third party.
+
+     1.1. "Contributor" means each entity that creates or contributes to
+     the creation of Modifications.
+
+     1.2. "Contributor Version" means the combination of the Original
+     Code, prior Modifications used by a Contributor, and the Modifications
+     made by that particular Contributor.
+
+     1.3. "Covered Code" means the Original Code or Modifications or the
+     combination of the Original Code and Modifications, in each case
+     including portions thereof.
+
+     1.4. "Electronic Distribution Mechanism" means a mechanism generally
+     accepted in the software development community for the electronic
+     transfer of data.
+
+     1.5. "Executable" means Covered Code in any form other than Source
+     Code.
+
+     1.6. "Initial Developer" means the individual or entity identified
+     as the Initial Developer in the Source Code notice required by Exhibit
+     A.
+
+     1.7. "Larger Work" means a work which combines Covered Code or
+     portions thereof with code not governed by the terms of this License.
+
+     1.8. "License" means this document.
+
+     1.8.1. "Licensable" means having the right to grant, to the maximum
+     extent possible, whether at the time of the initial grant or
+     subsequently acquired, any and all of the rights conveyed herein.
+
+     1.9. "Modifications" means any addition to or deletion from the
+     substance or structure of either the Original Code or any previous
+     Modifications. When Covered Code is released as a series of files, a
+     Modification is:
+          A. Any addition to or deletion from the contents of a file
+          containing Original Code or previous Modifications.
+
+          B. Any new file that contains any part of the Original Code or
+          previous Modifications.
+
+     1.10. "Original Code" means Source Code of computer software code
+     which is described in the Source Code notice required by Exhibit A as
+     Original Code, and which, at the time of its release under this
+     License is not already Covered Code governed by this License.
+
+     1.10.1. "Patent Claims" means any patent claim(s), now owned or
+     hereafter acquired, including without limitation,  method, process,
+     and apparatus claims, in any patent Licensable by grantor.
+
+     1.11. "Source Code" means the preferred form of the Covered Code for
+     making modifications to it, including all modules it contains, plus
+     any associated interface definition files, scripts used to control
+     compilation and installation of an Executable, or source code
+     differential comparisons against either the Original Code or another
+     well known, available Covered Code of the Contributor's choice. The
+     Source Code can be in a compressed or archival form, provided the
+     appropriate decompression or de-archiving software is widely available
+     for no charge.
+
+     1.12. "You" (or "Your")  means an individual or a legal entity
+     exercising rights under, and complying with all of the terms of, this
+     License or a future version of this License issued under Section 6.1.
+     For legal entities, "You" includes any entity which controls, is
+     controlled by, or is under common control with You. For purposes of
+     this definition, "control" means (a) the power, direct or indirect,
+     to cause the direction or management of such entity, whether by
+     contract or otherwise, or (b) ownership of more than fifty percent
+     (50%) of the outstanding shares or beneficial ownership of such
+     entity.
+
+2. Source Code License.
+
+     2.1. The Initial Developer Grant.
+     The Initial Developer hereby grants You a world-wide, royalty-free,
+     non-exclusive license, subject to third party intellectual property
+     claims:
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Initial Developer to use, reproduce,
+          modify, display, perform, sublicense and distribute the Original
+          Code (or portions thereof) with or without Modifications, and/or
+          as part of a Larger Work; and
+
+          (b) under Patents Claims infringed by the making, using or
+          selling of Original Code, to make, have made, use, practice,
+          sell, and offer for sale, and/or otherwise dispose of the
+          Original Code (or portions thereof).
+
+          (c) the licenses granted in this Section 2.1(a) and (b) are
+          effective on the date Initial Developer first distributes
+          Original Code under the terms of this License.
+
+          (d) Notwithstanding Section 2.1(b) above, no patent license is
+          granted: 1) for code that You delete from the Original Code; 2)
+          separate from the Original Code;  or 3) for infringements caused
+          by: i) the modification of the Original Code or ii) the
+          combination of the Original Code with other software or devices.
+
+     2.2. Contributor Grant.
+     Subject to third party intellectual property claims, each Contributor
+     hereby grants You a world-wide, royalty-free, non-exclusive license
+
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Contributor, to use, reproduce, modify,
+          display, perform, sublicense and distribute the Modifications
+          created by such Contributor (or portions thereof) either on an
+          unmodified basis, with other Modifications, as Covered Code
+          and/or as part of a Larger Work; and
+
+          (b) under Patent Claims infringed by the making, using, or
+          selling of  Modifications made by that Contributor either alone
+          and/or in combination with its Contributor Version (or portions
+          of such combination), to make, use, sell, offer for sale, have
+          made, and/or otherwise dispose of: 1) Modifications made by that
+          Contributor (or portions thereof); and 2) the combination of
+          Modifications made by that Contributor with its Contributor
+          Version (or portions of such combination).
+
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+          effective on the date Contributor first makes Commercial Use of
+          the Covered Code.
+
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is
+          granted: 1) for any code that Contributor has deleted from the
+          Contributor Version; 2)  separate from the Contributor Version;
+          3)  for infringements caused by: i) third party modifications of
+          Contributor Version or ii)  the combination of Modifications made
+          by that Contributor with other software  (except as part of the
+          Contributor Version) or other devices; or 4) under Patent Claims
+          infringed by Covered Code in the absence of Modifications made by
+          that Contributor.
+
+3. Distribution Obligations.
+
+     3.1. Application of License.
+     The Modifications which You create or to which You contribute are
+     governed by the terms of this License, including without limitation
+     Section 2.2. The Source Code version of Covered Code may be
+     distributed only under the terms of this License or a future version
+     of this License released under Section 6.1, and You must include a
+     copy of this License with every copy of the Source Code You
+     distribute. You may not offer or impose any terms on any Source Code
+     version that alters or restricts the applicable version of this
+     License or the recipients' rights hereunder. However, You may include
+     an additional document offering the additional rights described in
+     Section 3.5.
+
+     3.2. Availability of Source Code.
+     Any Modification which You create or to which You contribute must be
+     made available in Source Code form under the terms of this License
+     either on the same media as an Executable version or via an accepted
+     Electronic Distribution Mechanism to anyone to whom you made an
+     Executable version available; and if made available via Electronic
+     Distribution Mechanism, must remain available for at least twelve (12)
+     months after the date it initially became available, or at least six
+     (6) months after a subsequent version of that particular Modification
+     has been made available to such recipients. You are responsible for
+     ensuring that the Source Code version remains available even if the
+     Electronic Distribution Mechanism is maintained by a third party.
+
+     3.3. Description of Modifications.
+     You must cause all Covered Code to which You contribute to contain a
+     file documenting the changes You made to create that Covered Code and
+     the date of any change. You must include a prominent statement that
+     the Modification is derived, directly or indirectly, from Original
+     Code provided by the Initial Developer and including the name of the
+     Initial Developer in (a) the Source Code, and (b) in any notice in an
+     Executable version or related documentation in which You describe the
+     origin or ownership of the Covered Code.
+
+     3.4. Intellectual Property Matters
+          (a) Third Party Claims.
+          If Contributor has knowledge that a license under a third party's
+          intellectual property rights is required to exercise the rights
+          granted by such Contributor under Sections 2.1 or 2.2,
+          Contributor must include a text file with the Source Code
+          distribution titled "LEGAL" which describes the claim and the
+          party making the claim in sufficient detail that a recipient will
+          know whom to contact. If Contributor obtains such knowledge after
+          the Modification is made available as described in Section 3.2,
+          Contributor shall promptly modify the LEGAL file in all copies
+          Contributor makes available thereafter and shall take other steps
+          (such as notifying appropriate mailing lists or newsgroups)
+          reasonably calculated to inform those who received the Covered
+          Code that new knowledge has been obtained.
+
+          (b) Contributor APIs.
+          If Contributor's Modifications include an application programming
+          interface and Contributor has knowledge of patent licenses which
+          are reasonably necessary to implement that API, Contributor must
+          also include this information in the LEGAL file.
+
+               (c)    Representations.
+          Contributor represents that, except as disclosed pursuant to
+          Section 3.4(a) above, Contributor believes that Contributor's
+          Modifications are Contributor's original creation(s) and/or
+          Contributor has sufficient rights to grant the rights conveyed by
+          this License.
+
+     3.5. Required Notices.
+     You must duplicate the notice in Exhibit A in each file of the Source
+     Code.  If it is not possible to put such notice in a particular Source
+     Code file due to its structure, then You must include such notice in a
+     location (such as a relevant directory) where a user would be likely
+     to look for such a notice.  If You created one or more Modification(s)
+     You may add your name as a Contributor to the notice described in
+     Exhibit A.  You must also duplicate this License in any documentation
+     for the Source Code where You describe recipients' rights or ownership
+     rights relating to Covered Code.  You may choose to offer, and to
+     charge a fee for, warranty, support, indemnity or liability
+     obligations to one or more recipients of Covered Code. However, You
+     may do so only on Your own behalf, and not on behalf of the Initial
+     Developer or any Contributor. You must make it absolutely clear than
+     any such warranty, support, indemnity or liability obligation is
+     offered by You alone, and You hereby agree to indemnify the Initial
+     Developer and every Contributor for any liability incurred by the
+     Initial Developer or such Contributor as a result of warranty,
+     support, indemnity or liability terms You offer.
+
+     3.6. Distribution of Executable Versions.
+     You may distribute Covered Code in Executable form only if the
+     requirements of Section 3.1-3.5 have been met for that Covered Code,
+     and if You include a notice stating that the Source Code version of
+     the Covered Code is available under the terms of this License,
+     including a description of how and where You have fulfilled the
+     obligations of Section 3.2. The notice must be conspicuously included
+     in any notice in an Executable version, related documentation or
+     collateral in which You describe recipients' rights relating to the
+     Covered Code. You may distribute the Executable version of Covered
+     Code or ownership rights under a license of Your choice, which may
+     contain terms different from this License, provided that You are in
+     compliance with the terms of this License and that the license for the
+     Executable version does not attempt to limit or alter the recipient's
+     rights in the Source Code version from the rights set forth in this
+     License. If You distribute the Executable version under a different
+     license You must make it absolutely clear that any terms which differ
+     from this License are offered by You alone, not by the Initial
+     Developer or any Contributor. You hereby agree to indemnify the
+     Initial Developer and every Contributor for any liability incurred by
+     the Initial Developer or such Contributor as a result of any such
+     terms You offer.
+
+     3.7. Larger Works.
+     You may create a Larger Work by combining Covered Code with other code
+     not governed by the terms of this License and distribute the Larger
+     Work as a single product. In such a case, You must make sure the
+     requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+     If it is impossible for You to comply with any of the terms of this
+     License with respect to some or all of the Covered Code due to
+     statute, judicial order, or regulation then You must: (a) comply with
+     the terms of this License to the maximum extent possible; and (b)
+     describe the limitations and the code they affect. Such description
+     must be included in the LEGAL file described in Section 3.4 and must
+     be included with all distributions of the Source Code. Except to the
+     extent prohibited by statute or regulation, such description must be
+     sufficiently detailed for a recipient of ordinary skill to be able to
+     understand it.
+
+5. Application of this License.
+
+     This License applies to code to which the Initial Developer has
+     attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+     6.1. New Versions.
+     Netscape Communications Corporation ("Netscape") may publish revised
+     and/or new versions of the License from time to time. Each version
+     will be given a distinguishing version number.
+
+     6.2. Effect of New Versions.
+     Once Covered Code has been published under a particular version of the
+     License, You may always continue to use it under the terms of that
+     version. You may also choose to use such Covered Code under the terms
+     of any subsequent version of the License published by Netscape. No one
+     other than Netscape has the right to modify the terms applicable to
+     Covered Code created under this License.
+
+     6.3. Derivative Works.
+     If You create or use a modified version of this License (which you may
+     only do in order to apply it to code which is not already Covered Code
+     governed by this License), You must (a) rename Your license so that
+     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+     "MPL", "NPL" or any confusingly similar phrase do not appear in your
+     license (except to note that your license differs from this License)
+     and (b) otherwise make it clear that Your version of the license
+     contains terms which differ from the Mozilla Public License and
+     Netscape Public License. (Filling in the name of the Initial
+     Developer, Original Code or Contributor in the notice described in
+     Exhibit A shall not of themselves be deemed to be modifications of
+     this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+     8.1.  This License and the rights granted hereunder will terminate
+     automatically if You fail to comply with terms herein and fail to cure
+     such breach within 30 days of becoming aware of the breach. All
+     sublicenses to the Covered Code which are properly granted shall
+     survive any termination of this License. Provisions which, by their
+     nature, must remain in effect beyond the termination of this License
+     shall survive.
+
+     8.2.  If You initiate litigation by asserting a patent infringement
+     claim (excluding declatory judgment actions) against Initial Developer
+     or a Contributor (the Initial Developer or Contributor against whom
+     You file such action is referred to as "Participant")  alleging that:
+
+     (a)  such Participant's Contributor Version directly or indirectly
+     infringes any patent, then any and all rights granted by such
+     Participant to You under Sections 2.1 and/or 2.2 of this License
+     shall, upon 60 days notice from Participant terminate prospectively,
+     unless if within 60 days after receipt of notice You either: (i)
+     agree in writing to pay Participant a mutually agreeable reasonable
+     royalty for Your past and future use of Modifications made by such
+     Participant, or (ii) withdraw Your litigation claim with respect to
+     the Contributor Version against such Participant.  If within 60 days
+     of notice, a reasonable royalty and payment arrangement are not
+     mutually agreed upon in writing by the parties or the litigation claim
+     is not withdrawn, the rights granted by Participant to You under
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+     the 60 day notice period specified above.
+
+     (b)  any software, hardware, or device, other than such Participant's
+     Contributor Version, directly or indirectly infringes any patent, then
+     any rights granted to You by such Participant under Sections 2.1(b)
+     and 2.2(b) are revoked effective as of the date You first made, used,
+     sold, distributed, or had made, Modifications made by that
+     Participant.
+
+     8.3.  If You assert a patent infringement claim against Participant
+     alleging that such Participant's Contributor Version directly or
+     indirectly infringes any patent where such claim is resolved (such as
+     by license or settlement) prior to the initiation of patent
+     infringement litigation, then the reasonable value of the licenses
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken
+     into account in determining the amount or value of any payment or
+     license.
+
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
+     all end user license agreements (excluding distributors and resellers)
+     which have been validly granted by You or any distributor hereunder
+     prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+     The Covered Code is a "commercial item," as that term is defined in
+     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+     software" and "commercial computer software documentation," as such
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+     all U.S. Government End Users acquire Covered Code with only those
+     rights set forth herein.
+
+11. MISCELLANEOUS.
+
+     This License represents the complete agreement concerning subject
+     matter hereof. If any provision of this License is held to be
+     unenforceable, such provision shall be reformed only to the extent
+     necessary to make it enforceable. This License shall be governed by
+     California law provisions (except to the extent applicable law, if
+     any, provides otherwise), excluding its conflict-of-law provisions.
+     With respect to disputes in which at least one party is a citizen of,
+     or an entity chartered or registered to do business in the United
+     States of America, any litigation relating to this License shall be
+     subject to the jurisdiction of the Federal Courts of the Northern
+     District of California, with venue lying in Santa Clara County,
+     California, with the losing party responsible for costs, including
+     without limitation, court costs and reasonable attorneys' fees and
+     expenses. The application of the United Nations Convention on
+     Contracts for the International Sale of Goods is expressly excluded.
+     Any law or regulation which provides that the language of a contract
+     shall be construed against the drafter shall not apply to this
+     License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+     As between Initial Developer and the Contributors, each party is
+     responsible for claims and damages arising, directly or indirectly,
+     out of its utilization of rights under this License and You agree to
+     work with Initial Developer and Contributors to distribute such
+     responsibility on an equitable basis. Nothing herein is intended or
+     shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+     Initial Developer may designate portions of the Covered Code as
+     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
+     Developer permits you to utilize portions of the Covered Code under
+     Your choice of the NPL or the alternative licenses, if any, specified
+     by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A - Mozilla Public License.
+
+     ``The contents of this file are subject to the Mozilla Public License
+     Version 1.1 (the "License"); you may not use this file except in
+     compliance with the License. You may obtain a copy of the License at
+     http://www.mozilla.org/MPL/
+
+     Software distributed under the License is distributed on an "AS IS"
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+     License for the specific language governing rights and limitations
+     under the License.
+
+     The Original Code is ______________________________________.
+
+     The Initial Developer of the Original Code is ________________________.
+     Portions created by ______________________ are Copyright (C) ______
+     _______________________. All Rights Reserved.
+
+     Contributor(s): ______________________________________.
+
+     Alternatively, the contents of this file may be used under the terms
+     of the _____ license (the  "[___] License"), in which case the
+     provisions of [______] License are applicable instead of those
+     above.  If you wish to allow use of your version of this file only
+     under the terms of the [____] License and not to allow others to use
+     your version of this file under the MPL, indicate your decision by
+     deleting  the provisions above and replace  them with the notice and
+     other provisions required by the [___] License.  If you do not delete
+     the provisions above, a recipient may use your version of this file
+     under either the MPL or the [___] License."
+
+     [NOTE: The text of this Exhibit A may differ slightly from the text of
+     the notices in the Source Code files of the Original Code. You should
+     use the text of this Exhibit A rather than the text found in the
+     Original Code Source Code for Your Modifications.]
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to SAX 2.0.1, which is included 
+with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+ SAX is free!
+
+ In fact, it's not possible to own a license to SAX, since it's been placed in
+ the public domain.
+
+ No Warranty
+
+ Because SAX is released to the public domain, there is no warranty for the
+ design or for the software implementation, to the extent permitted by
+ applicable law. Except when otherwise stated in writing the copyright holders
+ and/or other parties provide SAX "as is" without warranty of any kind, either
+ expressed or implied, including, but not limited to, the implied warranties
+ of merchantability and fitness for a particular purpose. The entire risk as
+ to the quality and performance of SAX is with you. Should SAX prove
+ defective, you assume the cost of all necessary servicing, repair or
+ correction.
+
+ In no event unless required by applicable law or agreed to in writing will
+ any copyright holder, or any other party who may modify and/or redistribute
+ SAX, be liable to you for damages, including any general, special, incidental
+ or consequential damages arising out of the use or inability to use SAX
+ (including but not limited to loss of data or data being rendered inaccurate
+ or losses sustained by you or third parties or a failure of the SAX to
+ operate with any other programs), even if such holder or other party has been
+ advised of the possibility of such damages.
+
+ Copyright Disclaimers 
+
+ This page includes statements to that effect by David Megginson, who would
+ have been able to claim copyright for the original work.  SAX 1.0
+
+ Version 1.0 of the Simple API for XML (SAX), created collectively by the
+ membership of the XML-DEV mailing list, is hereby released into the public
+ domain.
+
+ No one owns SAX: you may use it freely in both commercial and non-commercial
+ applications, bundle it with your software distribution, include it on a
+ CD-ROM, list the source code in a book, mirror the documentation at your own
+ web site, or use it in any other way you see fit.
+
+ David Megginson, sax@megginson.com
+ 1998-05-11
+
+ SAX 2.0 
+
+ I hereby abandon any property rights to SAX 2.0 (the Simple API for XML), and
+ release all of the SAX 2.0 source code, compiled code, and documentation
+ contained in this distribution into the Public Domain. SAX comes with NO
+ WARRANTY or guarantee of fitness for any purpose.
+
+ David Megginson, david@megginson.com
+ 2000-05-05
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to SoftFloat version 2b, which is 
+included with JRE 7, JDK 7, and OpenJDK 7 on Linux/ARM.
+
+--- begin of LICENSE ---
+
+Use of any of this software is governed by the terms of the license below:
+
+SoftFloat was written by me, John R. Hauser. This work was made possible in 
+part by the International Computer Science Institute, located at Suite 600, 
+1947 Center Street, Berkeley, California 94704. Funding was partially 
+provided by the National Science Foundation under grant MIP-9311980. The 
+original version of this code was written as part of a project to build 
+a fixed-point vector processor in collaboration with the University of 
+California at Berkeley, overseen by Profs. Nelson Morgan and John Wawrzynek. 
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort 
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT 
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO 
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL 
+LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO 
+FURTHERMORE EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER 
+SCIENCE INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, 
+COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE 
+SOFTWARE. 
+
+Derivative works are acceptable, even for commercial purposes, provided 
+that the minimal documentation requirements stated in the source code are 
+satisfied. 
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% Portions licensed from Taligent, Inc.
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Thai Dictionary, which is 
+included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+Copyright (C) 1982 The Royal Institute, Thai Royal Government.
+
+Copyright (C) 1998 National Electronics and Computer Technology Center,
+National Science and Technology Development Agency,
+Ministry of Science Technology and Environment,
+Thai Royal Government.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Unicode 6.0.0, CLDR v1.4.1, & CLDR
+v1.9, which is included with JRE 7, JDK 7, and OpenJDK 7.
+
+--- begin of LICENSE ---
+
+Unicode Terms of Use
+
+For the general privacy policy governing access to this site, see the Unicode
+Privacy Policy. For trademark usage, see the Unicode® Consortium Name and
+Trademark Usage Policy.
+
+A. Unicode Copyright.
+   1. Copyright © 1991-2011 Unicode, Inc. All rights reserved.
+
+   2. Certain documents and files on this website contain a legend indicating
+      that "Modification is permitted." Any person is hereby authorized,
+      without fee, to modify such documents and files to create derivative
+      works conforming to the Unicode® Standard, subject to Terms and
+      Conditions herein.
+
+    3. Any person is hereby authorized, without fee, to view, use, reproduce,
+       and distribute all documents and files solely for informational
+       purposes in the creation of products supporting the Unicode Standard,
+       subject to the Terms and Conditions herein.
+
+    4. Further specifications of rights and restrictions pertaining to the use
+       of the particular set of data files known as the "Unicode Character
+       Database" can be found in Exhibit 1.
+
+    5. Each version of the Unicode Standard has further specifications of
+       rights and restrictions of use. For the book editions (Unicode 5.0 and
+       earlier), these are found on the back of the title page. The online
+       code charts carry specific restrictions. All other files, including
+       online documentation of the core specification for Unicode 6.0 and
+       later, are covered under these general Terms of Use.
+
+    6. No license is granted to "mirror" the Unicode website where a fee is
+       charged for access to the "mirror" site.
+
+    7. Modification is not permitted with respect to this document. All copies
+       of this document must be verbatim.
+
+B. Restricted Rights Legend. Any technical data or software which is licensed
+   to the United States of America, its agencies and/or instrumentalities
+   under this Agreement is commercial technical data or commercial computer
+   software developed exclusively at private expense as defined in FAR 2.101,
+   or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use,
+   duplication, or disclosure by the Government is subject to restrictions as
+   set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov
+   1995) and this Agreement. For Software, in accordance with FAR 12-212 or
+   DFARS 227-7202, as applicable, use, duplication or disclosure by the
+   Government is subject to the restrictions set forth in this Agreement.
+
+C. Warranties and Disclaimers.
+   1. This publication and/or website may include technical or typographical
+      errors or other inaccuracies . Changes are periodically added to the
+      information herein; these changes will be incorporated in new editions
+      of the publication and/or website. Unicode may make improvements and/or
+      changes in the product(s) and/or program(s) described in this
+      publication and/or website at any time.
+
+    2. If this file has been purchased on magnetic or optical media from
+       Unicode, Inc. the sole and exclusive remedy for any claim will be
+       exchange of the defective media within ninety (90) days of original
+       purchase.
+
+    3. EXCEPT AS PROVIDED IN SECTION C.2, THIS PUBLICATION AND/OR SOFTWARE IS
+       PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED,
+       OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF
+       MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
+       UNICODE AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR
+       OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH
+       ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE.
+
+D. Waiver of Damages. In no event shall Unicode or its licensors be liable for
+   any special, incidental, indirect or consequential damages of any kind, or
+   any damages whatsoever, whether or not Unicode was advised of the
+   possibility of the damage, including, without limitation, those resulting
+   from the following: loss of use, data or profits, in connection with the
+   use, modification or distribution of this information or its derivatives.
+
+E.Trademarks & Logos.
+   1. The Unicode Word Mark and the Unicode Logo are trademarks of Unicode,
+      Inc.  “The Unicode Consortium†and “Unicode, Inc.†are trade names of
+      Unicode, Inc.  Use of the information and materials found on this
+      website indicates your acknowledgement of Unicode, Inc.’s exclusive
+      worldwide rights in the Unicode Word Mark, the Unicode Logo, and the
+      Unicode trade names.
+
+   2. The Unicode Consortium Name and Trademark Usage Policy (“Trademark
+      Policyâ€) are incorporated herein by reference and you agree to abide by
+      the provisions of the Trademark Policy, which may be changed from time
+      to time in the sole discretion of Unicode, Inc.
+
+   3. All third party trademarks referenced herein are the property of their
+      respective owners.
+
+Miscellaneous.
+   1. Jurisdiction and Venue. This server is operated from a location in the
+      State of California, United States of America. Unicode makes no
+      representation that the materials are appropriate for use in other
+      locations. If you access this server from other locations, you are
+      responsible for compliance with local laws. This Agreement, all use of
+      this site and any claims and damages resulting from use of this site are
+      governed solely by the laws of the State of California without regard to
+      any principles which would apply the laws of a different jurisdiction.
+      The user agrees that any disputes regarding this site shall be resolved
+      solely in the courts located in Santa Clara County, California. The user
+      agrees said courts have personal jurisdiction and agree to waive any
+      right to transfer the dispute to any other forum.
+
+   2. Modification by Unicode.  Unicode shall have the right to modify this
+      Agreement at any time by posting it to this site. The user may not
+      assign any part of this Agreement without Unicode’s prior written
+      consent.
+
+   3. Taxes. The user agrees to pay any taxes arising from access to this
+      website or use of the information herein, except for those based on
+      Unicode’s net income.
+
+   4. Severability.  If any provision of this Agreement is declared invalid or
+      unenforceable, the remaining provisions of this Agreement shall remain
+      in effect.
+
+   5. Entire Agreement. This Agreement constitutes the entire agreement
+      between the parties.
+
+EXHIBIT 1
+UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
+
+Unicode Data Files include all data files under the directories
+http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
+http://www.unicode.org/cldr/data/. Unicode Data Files do not include PDF
+online code charts under the directory http://www.unicode.org/Public/.
+Software includes any source code published in the Unicode Standard or under
+the directories http://www.unicode.org/Public/,
+http://www.unicode.org/reports/, and http://www.unicode.org/cldr/data/.
+
+NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING,
+INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA
+FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO
+BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT
+AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR
+SOFTWARE.
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright © 1991-2011 Unicode, Inc. All rights reserved. Distributed under the
+Terms of Use in http://www.unicode.org/copyright.html.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the Unicode data files and any associated documentation (the "Data Files")
+or Unicode software and any associated documentation (the "Software") to deal
+in the Data Files or Software without restriction, including without
+limitation the rights to use, copy, modify, merge, publish, distribute, and/or
+sell copies of the Data Files or Software, and to permit persons to whom the
+Data Files or Software are furnished to do so, provided that (a) the above
+copyright notice(s) and this permission notice appear with all copies of the
+Data Files or Software, (b) both the above copyright notice(s) and this
+permission notice appear in associated documentation, and (c) there is clear
+notice in each modified Data File or in the Software as well as in the
+documentation associated with the Data File(s) or Software that the data or
+software has been modified.
+
+THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD
+PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
+THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
+DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE
+DATA FILES OR SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in these Data Files or Software without prior written authorization of the
+copyright holder.
+
+Unicode and the Unicode logo are trademarks of Unicode, Inc. in the United
+States and other countries. All third party trademarks referenced herein are
+the property of their respective owners.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to UPX v3.01, which is included 
+with JRE 7 on Windows.
+
+--- begin of LICENSE ---
+
+Use of any of this software is governed by the terms of the license below:
+
+
+                 ooooo     ooo ooooooooo.   ooooooo  ooooo
+                 `888'     `8' `888   `Y88.  `8888    d8'
+                  888       8   888   .d88'    Y888..8P
+                  888       8   888ooo88P'      `8888'
+                  888       8   888            .8PY888.
+                  `88.    .8'   888           d8'  `888b
+                    `YbodP'    o888o        o888o  o88888o
+
+
+                    The Ultimate Packer for eXecutables
+          Copyright (c) 1996-2000 Markus Oberhumer & Laszlo Molnar
+               http://wildsau.idv.uni-linz.ac.at/mfx/upx.html
+                          http://www.nexus.hu/upx
+                            http://upx.tsx.org
+
+
+PLEASE CAREFULLY READ THIS LICENSE AGREEMENT, ESPECIALLY IF YOU PLAN
+TO MODIFY THE UPX SOURCE CODE OR USE A MODIFIED UPX VERSION.
+
+
+ABSTRACT
+========
+
+   UPX and UCL are copyrighted software distributed under the terms
+   of the GNU General Public License (hereinafter the "GPL").
+
+   The stub which is imbedded in each UPX compressed program is part
+   of UPX and UCL, and contains code that is under our copyright. The
+   terms of the GNU General Public License still apply as compressing
+   a program is a special form of linking with our stub.
+
+   As a special exception we grant the free usage of UPX for all
+   executables, including commercial programs.
+   See below for details and restrictions.
+
+
+COPYRIGHT
+=========
+
+   UPX and UCL are copyrighted software. All rights remain with the authors.
+
+   UPX is Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer
+   UPX is Copyright (C) 1996-2000 Laszlo Molnar
+
+   UCL is Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer
+
+
+GNU GENERAL PUBLIC LICENSE
+==========================
+
+   UPX and the UCL library are free software; you can redistribute them
+   and/or modify them under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   UPX and UCL are distributed in the hope that they will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING.
+
+
+SPECIAL EXCEPTION FOR COMPRESSED EXECUTABLES
+============================================
+
+   The stub which is imbedded in each UPX compressed program is part
+   of UPX and UCL, and contains code that is under our copyright. The
+   terms of the GNU General Public License still apply as compressing
+   a program is a special form of linking with our stub.
+
+   Hereby Markus F.X.J. Oberhumer and Laszlo Molnar grant you special
+   permission to freely use and distribute all UPX compressed programs
+   (including commercial ones), subject to the following restrictions:
+
+   1. You must compress your program with a completely unmodified UPX
+      version; either with our precompiled version, or (at your option)
+      with a self compiled version of the unmodified UPX sources as
+      distributed by us.
+   2. This also implies that the UPX stub must be completely unmodfied, i.e.
+      the stub imbedded in your compressed program must be byte-identical
+      to the stub that is produced by the official unmodified UPX version.
+   3. The decompressor and any other code from the stub must exclusively get
+      used by the unmodified UPX stub for decompressing your program at
+      program startup. No portion of the stub may get read, copied,
+      called or otherwise get used or accessed by your program.
+
+
+ANNOTATIONS
+===========
+
+  - You can use a modified UPX version or modified UPX stub only for
+    programs that are compatible with the GNU General Public License.
+
+  - We grant you special permission to freely use and distribute all UPX
+    compressed programs. But any modification of the UPX stub (such as,
+    but not limited to, removing our copyright string or making your
+    program non-decompressible) will immediately revoke your right to
+    use and distribute a UPX compressed program.
+
+  - UPX is not a software protection tool; by requiring that you use
+    the unmodified UPX version for your proprietary programs we
+    make sure that any user can decompress your program. This protects
+    both you and your users as nobody can hide malicious code -
+    any program that cannot be decompressed is highly suspicious
+    by definition.
+
+  - You can integrate all or part of UPX and UCL into projects that
+    are compatible with the GNU GPL, but obviously you cannot grant
+    any special exceptions beyond the GPL for our code in your project.
+
+  - We want to actively support manufacturers of virus scanners and
+    similar security software. Please contact us if you would like to
+    incorporate parts of UPX or UCL into such a product.
+
+
+
+Markus F.X.J. Oberhumer                   Laszlo Molnar
+markus.oberhumer@jk.uni-linz.ac.at        ml1050@cdata.tvnet.hu
+
+Linz, Austria, 25 Feb 2000
+
+Additional License(s)
+
+The UPX license file is at http://upx.sourceforge.net/upx-license.html.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to Xfree86-VidMode Extension 1.0,
+which is included with JRE 7, JDK 7, and OpenJDK 7 on Linux and Solaris.
+
+--- begin of LICENSE ---
+
+Version 1.1 of XFree86 ProjectLicence.
+
+Copyright (C) 1994-2004 The XFree86 Project, Inc.    All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicence, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so,subject to the following conditions:
+
+   1. Redistributions of source code must retain the above copyright
+   notice,this list of conditions, and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution, and in the same place
+   and form as other copyright, license and disclaimer information.
+
+   3. The end-user documentation included with the redistribution, if any,must
+   include the following acknowledgment: "This product includes
+   software developed by The XFree86 Project, Inc (http://www.xfree86.org/) and
+   its contributors", in the same place and form as other third-party
+   acknowledgments. Alternately, this acknowledgment may appear in the software
+   itself, in the same form and location as other such third-party
+   acknowledgments.
+
+    4. Except as contained in this notice, the name of The XFree86 Project,Inc
+    shall not be used in advertising or otherwise to promote the sale, use
+    or other dealings in this Software without prior written authorization from
+    The XFree86 Project, Inc.
+
+    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+    WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+    EVENT SHALL THE XFREE86 PROJECT, INC OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL,SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO,PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+    DAMAGE.  
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to X Window System 6.8.2, which is 
+included with JRE 7, JDK 7, and OpenJDK 7 on Linux and Solaris.
+
+--- begin of LICENSE ---
+
+          Licenses
+The X.Org Foundation March 2004
+
+1. Introduction
+
+The X.org Foundation X Window System distribution is a compilation of code and
+documentation from many sources. This document is intended primarily as a
+guide to the licenses used in the distribution: you must check each file
+and/or package for precise redistribution terms. None-the-less, this summary
+may be useful to many users. No software incorporating the XFree86 1.1 license
+has been incorporated.
+
+This document is based on the compilation from XFree86.
+
+2. XFree86 License
+
+XFree86 code without an explicit copyright is covered by the following
+copyright/license:
+
+Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the XFree86 Project shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the XFree86 Project.
+
+3. Other Licenses
+
+Portions of code are covered by the following licenses/copyrights. See
+individual files for the copyright dates.
+
+3.1. X/MIT Copyrights
+
+3.1.1. X Consortium
+
+Copyright (C) <date> X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X
+CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings in
+this Software without prior written authorization from the X Consortium.
+
+X Window System is a trademark of X Consortium, Inc.
+
+3.1.2. The Open Group
+
+Copyright <date> The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that the
+above copyright notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting documentation.
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings in
+this Software without prior written authorization from The Open Group.  3.2.
+Berkeley-based copyrights:
+
+o
+3.2.1. General
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.  3.2.2. UCB/LBL
+
+Copyright (c) 1993 The Regents of the University of California. All rights
+reserved.
+
+This software was developed by the Computer Systems Engineering group at
+Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and contributed to
+Berkeley.
+
+All advertising materials mentioning features or use of this software must
+display the following acknowledgement: This product includes software
+developed by the University of California, Lawrence Berkeley Laboratory.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement: This product includes software
+   developed by the University of California, Berkeley and its contributors.
+
+   4. Neither the name of the University nor the names of its contributors may
+   be used to endorse or promote products derived from this software without
+   specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  3.2.3. The
+NetBSD Foundation, Inc.
+
+Copyright (c) 2003 The NetBSD Foundation, Inc. All rights reserved.
+
+This code is derived from software contributed to The NetBSD Foundation by Ben
+Collver <collver1@attbi.com>
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement: This product includes software
+   developed by the NetBSD Foundation, Inc. and its contributors.
+
+   4. Neither the name of The NetBSD Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from this
+   software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS ``AS
+IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  3.2.4. Theodore
+Ts'o.
+
+Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All rights
+reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   and the entire permission notice in its entirety, including the disclaimer
+   of warranties.
+
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   3. he name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE, ALL OF WHICH ARE HEREBY DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.  3.2.5. Theo de Raadt and Damien Miller
+
+Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. Copyright (c)
+2001-2002 Damien Miller. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.  3.2.6. Todd C. Miller
+
+Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+
+Permission to use, copy, modify, and distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright
+notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  3.2.7. Thomas
+Winischhofer
+
+Copyright (C) 2001-2004 Thomas Winischhofer
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.  3.3. NVIDIA Corp
+
+Copyright (c) 1996 NVIDIA, Corp. All rights reserved.
+
+NOTICE TO USER: The source code is copyrighted under U.S. and international
+laws. NVIDIA, Corp. of Sunnyvale, California owns the copyright and as design
+patents pending on the design and interface of the NV chips. Users and
+possessors of this source code are hereby granted a nonexclusive, royalty-free
+copyright and design patent license to use this code in individual and
+commercial software.
+
+Any use of this source code must include, in the user documentation and
+internal comments to the code, notices to the end user as follows:
+
+Copyright (c) 1996 NVIDIA, Corp. NVIDIA design patents pending in the U.S. and
+foreign countries.
+
+NVIDIA, CORP. MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
+CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED
+WARRANTY OF ANY KIND. NVIDIA, CORP. DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA, CORP. BE LIABLE
+FOR ANY SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY
+DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.  3.4. GLX Public
+License
+
+GLX PUBLIC LICENSE (Version 1.0 (2/11/99)) ("License")
+
+Subject to any third party claims, Silicon Graphics, Inc. ("SGI") hereby
+grants permission to Recipient (defined below), under Recipient's copyrights
+in the Original Software (defined below), to use, copy, modify, merge,
+publish, distribute, sublicense and/or sell copies of Subject Software
+(defined below), and to permit persons to whom the Subject Software is
+furnished in accordance with this License to do the same, subject to all of
+the following terms and conditions, which Recipient accepts by engaging in any
+such use, copying, modifying, merging, publishing, distributing, sublicensing
+or selling:
+
+1. Definitions.
+
+    (a) "Original Software" means source code of computer software code which
+    is described in Exhibit A as Original Software.
+
+    (b) "Modifications" means any addition to or deletion from the substance
+    or structure of either the Original Software or any previous
+    Modifications. When Subject Software is released as a series of files, a
+    Modification means (i) any addition to or deletion from the contents of a
+    file containing Original Software or previous Modifications and (ii) any
+    new file that contains any part of the Original Code or previous
+    Modifications.
+
+    (c) "Subject Software" means the Original Software or Modifications or the
+    combination of the Original Software and Modifications, or portions of any
+    of the foregoing.
+
+    (d) "Recipient" means an individual or a legal entity exercising rights
+    under, and complying with all of the terms of, this License. For legal
+    entities, "Recipient" includes any entity which controls, is controlled
+    by, or is under common control with Recipient. For purposes of this
+    definition, "control" of an entity means (a) the power, direct or
+    indirect, to direct or manage such entity, or (b) ownership of fifty
+    percent (50%) or more of the outstanding shares or beneficial ownership of
+    such entity.
+
+2. Redistribution of Source Code Subject to These Terms. Redistributions of
+Subject Software in source code form must retain the notice set forth in
+Exhibit A, below, in every file. A copy of this License must be included in
+any documentation for such Subject Software where the recipients' rights
+relating to Subject Software are described. Recipient may distribute the
+source code version of Subject Software under a license of Recipient's choice,
+which may contain terms different from this License, provided that (i)
+Recipient is in compliance with the terms of this License, and (ii) the
+license terms include this Section 2 and Sections 3, 4, 7, 8, 10, 12 and 13 of
+this License, which terms may not be modified or superseded by any other terms
+of such license. If Recipient distributes the source code version under a
+different license Recipient must make it absolutely clear that any terms which
+differ from this License are offered by Recipient alone, not by SGI. Recipient
+hereby agrees to indemnify SGI for any liability incurred by SGI as a result
+of any such terms Recipient offers.
+
+3. Redistribution in Executable Form. The notice set forth in Exhibit A must
+be conspicuously included in any notice in an executable version of Subject
+Software, related documentation or collateral in which Recipient describes the
+user's rights relating to the Subject Software. Recipient may distribute the
+executable version of Subject Software under a license of Recipient's choice,
+which may contain terms different from this License, provided that (i)
+Recipient is in compliance with the terms of this License, and (ii) the
+license terms include this Section 3 and Sections 4, 7, 8, 10, 12 and 13 of
+this License, which terms may not be modified or superseded by any other terms
+of such license. If Recipient distributes the executable version under a
+different license Recipient must make it absolutely clear that any terms which
+differ from this License are offered by Recipient alone, not by SGI. Recipient
+hereby agrees to indemnify SGI for any liability incurred by SGI as a result
+of any such terms Recipient offers.
+
+4. Termination. This License and the rights granted hereunder will terminate
+automatically if Recipient fails to comply with terms herein and fails to cure
+such breach within 30 days of the breach. Any sublicense to the Subject
+Software which is properly granted shall survive any termination of this
+License absent termination by the terms of such sublicense. Provisions which,
+by their nature, must remain in effect beyond the termination of this License
+shall survive.
+
+5. No Trademark Rights. This License does not grant any rights to use any
+trade name, trademark or service mark whatsoever. No trade name, trademark or
+service mark of SGI may be used to endorse or promote products derived from
+the Subject Software without prior written permission of SGI.
+
+6. No Other Rights. This License does not grant any rights with respect to the
+OpenGL API or to any software or hardware implementation thereof or to any
+other software whatsoever, nor shall any other rights or licenses not
+expressly granted hereunder arise by implication, estoppel or otherwise with
+respect to the Subject Software. Title to and ownership of the Original
+Software at all times remains with SGI. All rights in the Original Software
+not expressly granted under this License are reserved.
+
+7. Compliance with Laws; Non-Infringement. Recipient shall comply with all
+applicable laws and regulations in connection with use and distribution of the
+Subject Software, including but not limited to, all export and import control
+laws and regulations of the U.S. government and other countries. Recipient may
+not distribute Subject Software that (i) in any way infringes (directly or
+contributorily) the rights (including patent, copyright, trade secret,
+trademark or other intellectual property rights of any kind) of any other
+person or entity or (ii) breaches any representation or warranty, express,
+implied or statutory, which under any applicable law it might be deemed to
+have been distributed.
+
+8. Claims of Infringement. If Recipient at any time has knowledge of any one
+or more third party claims that reproduction, modification, use, distribution,
+import or sale of Subject Software (including particular functionality or code
+incorporated in Subject Software) infringes the third party's intellectual
+property rights, Recipient must place in a well-identified web page bearing
+the title "LEGAL" a description of each such claim and a description of the
+party making each such claim in sufficient detail that a user of the Subject
+Software will know whom to contact regarding the claim. Also, upon gaining
+such knowledge of any such claim, Recipient must conspicuously include the URL
+for such web page in the Exhibit A notice required under Sections 2 and 3,
+above, and in the text of any related documentation, license agreement or
+collateral in which Recipient describes end user's rights relating to the
+Subject Software. If Recipient obtains such knowledge after it makes Subject
+Software available to any other person or entity, Recipient shall take other
+steps (such as notifying appropriate mailing lists or newsgroups) reasonably
+calculated to inform those who received the Subject Software that new
+knowledge has been obtained.
+
+9. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT
+LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS,
+MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON- INFRINGING. SGI ASSUMES NO
+RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE. SHOULD ANY SOFTWARE
+PROVE DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY
+SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN
+ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED
+HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+10. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY,
+WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIABILITY),
+CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK
+STOPPAGE, LOSS OF DATA, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF
+THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY
+TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SGI's NEGLIGENCE TO
+THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT
+ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO RECIPIENT.
+
+11. Indemnity. Recipient shall be solely responsible for damages arising,
+directly or indirectly, out of its utilization of rights under this License.
+Recipient will defend, indemnify and hold harmless Silicon Graphics, Inc. from
+and against any loss, liability, damages, costs or expenses (including the
+payment of reasonable attorneys fees) arising out of Recipient's use,
+modification, reproduction and distribution of the Subject Software or out of
+any representation or warranty made by Recipient.
+
+12. U.S. Government End Users. The Subject Software is a "commercial item"
+consisting of "commercial computer software" as such terms are defined in
+title 48 of the Code of Federal Regulations and all U.S. Government End Users
+acquire only the rights set forth in this License and are subject to the terms
+of this License.
+
+13. Miscellaneous. This License represents the complete agreement concerning
+subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed so as to achieve as nearly as
+possible the same economic effect as the original provision and the remainder
+of this License will remain in effect. This License shall be governed by and
+construed in accordance with the laws of the United States and the State of
+California as applied to agreements entered into and to be performed entirely
+within California between California residents. Any litigation relating to
+this License shall be subject to the exclusive jurisdiction of the Federal
+Courts of the Northern District of California (or, absent subject matter
+jurisdiction in such courts, the courts of the State of California), with
+venue lying exclusively in Santa Clara County, California, with the losing
+party responsible for costs, including without limitation, court costs and
+reasonable attorneys fees and expenses. The application of the United Nations
+Convention on Contracts for the International Sale of Goods is expressly
+excluded. Any law or regulation which provides that the language of a contract
+shall be construed against the drafter shall not apply to this License.
+
+Exhibit A
+
+The contents of this file are subject to Sections 2, 3, 4, 7, 8, 10, 12 and 13
+of the GLX Public License Version 1.0 (the "License"). You may not use this
+file except in compliance with those sections of the License. You may obtain a
+copy of the License at Silicon Graphics, Inc., attn: Legal Services, 2011 N.
+Shoreline Blvd., Mountain View, CA 94043 or at
+http://www.sgi.com/software/opensource/glx/license.html.
+
+Software distributed under the License is distributed on an "AS IS" basis. ALL
+WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED
+WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF NON-
+INFRINGEMENT. See the License for the specific language governing rights and
+limitations under the License.
+
+The Original Software is GLX version 1.2 source code, released February, 1999.
+The developer of the Original Software is Silicon Graphics, Inc. Those
+portions of the Subject Software created by Silicon Graphics, Inc. are
+Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.  3.5. CID
+Font Code Public License
+
+CID FONT CODE PUBLIC LICENSE (Version 1.0 (3/31/99))("License")
+
+Subject to any applicable third party claims, Silicon Graphics, Inc. ("SGI")
+hereby grants permission to Recipient (defined below), under SGI's copyrights
+in the Original Software (defined below), to use, copy, modify, merge,
+publish, distribute, sublicense and/or sell copies of Subject Software
+(defined below) in both source code and executable form, and to permit persons
+to whom the Subject Software is furnished in accordance with this License to
+do the same, subject to all of the following terms and conditions, which
+Recipient accepts by engaging in any such use, copying, modifying, merging,
+publication, distributing, sublicensing or selling:
+
+1. Definitions.
+
+    a. "Original Software" means source code of computer software code that is
+    described in Exhibit A as Original Software.
+
+    b. "Modifications" means any addition to or deletion from the substance or
+    structure of either the Original Software or any previous Modifications.
+    When Subject Software is released as a series of files, a Modification
+    means (i) any addition to or deletion from the contents of a file
+    containing Original Software or previous Modifications and (ii) any new
+    file that contains any part of the Original Code or previous
+    Modifications.
+
+    c. "Subject Software" means the Original Software or Modifications or the
+    combination of the Original Software and Modifications, or portions of any
+    of the foregoing.
+
+    d. "Recipient" means an individual or a legal entity exercising rights
+    under the terms of this License. For legal entities, "Recipient" includes
+    any entity that controls, is controlled by, or is under common control
+    with Recipient. For purposes of this definition, "control" of an entity
+    means (i) the power, direct or indirect, to direct or manage such entity,
+    or (ii) ownership of fifty percent (50%) or more of the outstanding shares
+    or beneficial ownership of such entity.
+
+    e. "Required Notice" means the notice set forth in Exhibit A to this
+    License.
+
+    f. "Accompanying Technology" means any software or other technology that
+    is not a Modification and that is distributed or made publicly available
+    by Recipient with the Subject Software. Separate software files that do
+    not contain any Original Software or any previous Modification shall not
+    be deemed a Modification, even if such software files are aggregated as
+    part of a product, or in any medium of storage, with any file that does
+    contain Original Software or any previous Modification.
+
+2. License Terms. All distribution of the Subject Software must be made
+subject to the terms of this License. A copy of this License and the Required
+Notice must be included in any documentation for Subject Software where
+Recipient's rights relating to Subject Software and/or any Accompanying
+Technology are described. Distributions of Subject Software in source code
+form must also include the Required Notice in every file distributed. In
+addition, a ReadMe file entitled "Important Legal Notice" must be distributed
+with each distribution of one or more files that incorporate Subject Software.
+That file must be included with distributions made in both source code and
+executable form. A copy of the License and the Required Notice must be
+included in that file. Recipient may distribute Accompanying Technology under
+a license of Recipient's choice, which may contain terms different from this
+License, provided that (i) Recipient is in compliance with the terms of this
+License, (ii) such other license terms do not modify or supersede the terms of
+this License as applicable to the Subject Software, (iii) Recipient hereby
+indemnifies SGI for any liability incurred by SGI as a result of the
+distribution of Accompanying Technology or the use of other license terms.
+
+3. Termination. This License and the rights granted hereunder will terminate
+automatically if Recipient fails to comply with terms herein and fails to cure
+such breach within 30 days of the breach. Any sublicense to the Subject
+Software that is properly granted shall survive any termination of this
+License absent termination by the terms of such sublicense. Provisions which,
+by their nature, must remain in effect beyond the termination of this License
+shall survive.
+
+4. Trademark Rights. This License does not grant any rights to use any trade
+name, trademark or service mark whatsoever. No trade name, trademark or
+service mark of SGI may be used to endorse or promote products derived from or
+incorporating any Subject Software without prior written permission of SGI.
+
+5. No Other Rights. No rights or licenses not expressly granted hereunder
+shall arise by implication, estoppel or otherwise. Title to and ownership of
+the Original Software at all times remains with SGI. All rights in the
+Original Software not expressly granted under this License are reserved.
+
+6. Compliance with Laws; Non-Infringement. Recipient shall comply with all
+applicable laws and regulations in connection with use and distribution of the
+Subject Software, including but not limited to, all export and import control
+laws and regulations of the U.S. government and other countries. Recipient may
+not distribute Subject Software that (i) in any way infringes (directly or
+contributorily) the rights (including patent, copyright, trade secret,
+trademark or other intellectual property rights of any kind) of any other
+person or entity, or (ii) breaches any representation or warranty, express,
+implied or statutory, which under any applicable law it might be deemed to
+have been distributed.
+
+7. Claims of Infringement. If Recipient at any time has knowledge of any one
+or more third party claims that reproduction, modification, use, distribution,
+import or sale of Subject Software (including particular functionality or code
+incorporated in Subject Software) infringes the third party's intellectual
+property rights, Recipient must place in a well-identified web page bearing
+the title "LEGAL" a description of each such claim and a description of the
+party making each such claim in sufficient detail that a user of the Subject
+Software will know whom to contact regarding the claim. Also, upon gaining
+such knowledge of any such claim, Recipient must conspicuously include the URL
+for such web page in the Required Notice, and in the text of any related
+documentation, license agreement or collateral in which Recipient describes
+end user's rights relating to the Subject Software. If Recipient obtains such
+knowledge after it makes Subject Software available to any other person or
+entity, Recipient shall take other steps (such as notifying appropriate
+mailing lists or newsgroups) reasonably calculated to provide such knowledge
+to those who received the Subject Software.
+
+8. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
+WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT
+LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS FREE OF DEFECTS,
+MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. SGI ASSUMES NO
+RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE. SHOULD ANY SOFTWARE
+PROVE DEFECTIVE IN ANY RESPECT, SGI ASSUMES NO COST OR LIABILITY FOR ANY
+SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN
+ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED
+HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY,
+WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR STRICT LIABILITY),
+CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SUBJECT SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SUBJECT SOFTWARE. SOME JURISDICTIONS DO NOT
+ALLOW THE EXCLUSION OR LIMITATION OF CERTAIN DAMAGES, SO THIS EXCLUSION AND
+LIMITATION MAY NOT APPLY TO RECIPIENT TO THE EXTENT SO DISALLOWED.
+
+10. Indemnity. Recipient shall be solely responsible for damages arising,
+directly or indirectly, out of its utilization of rights under this License.
+Recipient will defend, indemnify and hold SGI and its successors and assigns
+harmless from and against any loss, liability, damages, costs or expenses
+(including the payment of reasonable attorneys fees) arising out of
+(Recipient's use, modification, reproduction and distribution of the Subject
+Software or out of any representation or warranty made by Recipient.
+
+11. U.S. Government End Users. The Subject Software is a "commercial item"
+consisting of "commercial computer software" as such terms are defined in
+title 48 of the Code of Federal Regulations and all U.S. Government End Users
+acquire only the rights set forth in this License and are subject to the terms
+of this License.
+
+12. Miscellaneous. This License represents the complete agreement concerning
+subject matter hereof. If any provision of this License is held to be
+unenforceable by any judicial or administrative authority having proper
+jurisdiction with respect thereto, such provision shall be reformed so as to
+achieve as nearly as possible the same economic effect as the original
+provision and the remainder of this License will remain in effect. This
+License shall be governed by and construed in accordance with the laws of the
+United States and the State of California as applied to agreements entered
+into and to be performed entirely within California between California
+residents. Any litigation relating to this License shall be subject to the
+exclusive jurisdiction of the Federal Courts of the Northern District of
+California (or, absent subject matter jurisdiction in such courts, the courts
+of the State of California), with venue lying exclusively in Santa Clara
+County, California, with the losing party responsible for costs, including
+without limitation, court costs and reasonable attorneys fees and expenses.
+The application of the United Nations Convention on Contracts for the
+International Sale of Goods is expressly excluded. Any law or regulation that
+provides that the language of a contract shall be construed against the
+drafter shall not apply to this License.
+
+Exhibit A
+
+Copyright (c) 1994-1999 Silicon Graphics, Inc.
+
+The contents of this file are subject to the CID Font Code Public License
+Version 1.0 (the "License"). You may not use this file except in compliance
+with the License. You may obtain a copy of the License at Silicon Graphics,
+Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+or at http://www.sgi.com/software/opensource/cid/license.html
+
+Software distributed under the License is distributed on an "AS IS" basis. ALL
+WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED
+WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF
+NON-INFRINGEMENT. See the License for the specific language governing rights
+and limitations under the License.
+
+The Original Software (as defined in the License) is CID font code that was
+developed by Silicon Graphics, Inc. Those portions of the Subject Software (as
+defined in the License) that were created by Silicon Graphics, Inc. are
+Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved.
+
+[NOTE: When using this text in connection with Subject Software delivered
+solely in object code form, Recipient may replace the words "this file" with
+"this software" in both the first and second sentences.] 3.6. Bitstream Vera
+Fonts Copyright
+
+The fonts have a generous copyright, allowing derivative works (as long as
+"Bitstream" or "Vera" are not in the names), and full redistribution (so long
+as they are not *sold* by themselves). They can be be bundled, redistributed
+and sold with any software.
+
+The fonts are distributed under the following copyright:
+
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a
+trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of the fonts accompanying this license ("Fonts") and associated documentation
+files (the "Font Software"), to reproduce and distribute the Font Software,
+including without limitation the rights to use, copy, merge, publish,
+distribute, and/or sell copies of the Font Software, and to permit persons to
+whom the Font Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright and trademark notices and this permission notice shall be
+included in all copies of one or more of the Font Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in particular the
+designs of glyphs or characters in the Fonts may be modified and additional
+glyphs or characters may be added to the Fonts, only if the fonts are renamed
+to names not containing either the words "Bitstream" or the word "Vera".
+
+This License becomes null and void to the extent applicable to Fonts or Font
+Software that has been modified and is distributed under the "Bitstream Vera"
+names.
+
+The Font Software may be sold as part of a larger software package but no copy
+of one or more of the Font Software typefaces may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL,
+SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO
+USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
+
+Except as contained in this notice, the names of Gnome, the Gnome Foundation,
+and Bitstream Inc., shall not be used in advertising or otherwise to promote
+the sale, use or other dealings in this Font Software without prior written
+authorization from the Gnome Foundation or Bitstream Inc., respectively. For
+further information, contact: fonts at gnome dot org.  3.7. Bigelow & Holmes
+Inc and URW++ GmbH Luxi font license
+
+Luxi fonts copyright (c) 2001 by Bigelow & Holmes Inc. Luxi font instruction
+code copyright (c) 2001 by URW++ GmbH. All Rights Reserved. Luxi is a
+registered trademark of Bigelow & Holmes Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of these Fonts and associated documentation files (the "Font Software"), to
+deal in the Font Software, including without limitation the rights to use,
+copy, merge, publish, distribute, sublicense, and/or sell copies of the Font
+Software, and to permit persons to whom the Font Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright and trademark notices and this permission notice shall be
+included in all copies of one or more of the Font Software.
+
+The Font Software may not be modified, altered, or added to, and in particular
+the designs of glyphs or characters in the Fonts may not be modified nor may
+additional glyphs or characters be added to the Fonts. This License becomes
+null and void when the Fonts or Font Software have been modified.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
+TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BIGELOW & HOLMES INC. OR URW++
+GMBH. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY
+GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR
+INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT
+SOFTWARE.
+
+Except as contained in this notice, the names of Bigelow & Holmes Inc. and
+URW++ GmbH. shall not be used in advertising or otherwise to promote the sale,
+use or other dealings in this Font Software without prior written
+authorization from Bigelow & Holmes Inc. and URW++ GmbH.
+
+For further information, contact:
+
+info@urwpp.de or design@bigelowandholmes.com
+
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to zlib v1.2.3, which is included 
+with JRE 7, JDK 7, and OpenJDK 7
+
+--- begin of LICENSE ---
+
+  version 1.2.3, July 18th, 2005
+
+  Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
+%% This notice is provided with respect to the following which is 
+included with JRE 7, JDK 7, and OpenJDK 7, except where noted:
+
+  Apache Derby 10.8.1.2        [included with JDK 7 only]
+  Apache Jakarta BCEL 5.2 
+  Apache Jakarta Regexp 1.4 
+  Apache Santuario XMLSec-Java 1.4.2
+  Apache Xalan-Java 2.7.1 
+  Apache Xerces2 Java 2.10.0 
+  Apache XML Resolver 1.1 
+
+
+--- begin of LICENSE ---
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/Makefile.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,2715 @@
+# $Id$
+#
+# Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+
+topdir=		@topdir@
+srcdir=		$(topdir)/src
+langdir=	$(topdir)/lang
+exampledir=	$(topdir)/examples
+testdir=	$(topdir)/test
+utildir=	$(topdir)/util
+distdir=	$(topdir)/dist
+builddir=.
+
+##################################################
+# Installation directories and permissions.
+##################################################
+prefix=	@prefix@
+exec_prefix=@exec_prefix@
+bindir=	@bindir@
+includedir=@includedir@
+libdir=	@libdir@
+docdir=	$(prefix)/docs
+
+dmode=	755
+emode=	555
+fmode=	444
+
+transform=@program_transform_name@
+
+##################################################
+# Paths for standard user-level commands.
+##################################################
+AR=	@AR@
+CHMOD=	@CHMOD@
+CP=	@CP@
+LN=	@LN@
+MKDIR=	@MKDIR@
+MV=	@MV@
+RANLIB=	@RANLIB@
+RM=	@RM@
+SHELL=	@db_cv_path_sh@
+STRIP=	@STRIP@
+SED=	@SED@
+PERL=	@PERL@
+
+##################################################
+# General library information.
+##################################################
+DEF_LIB=	@DEFAULT_LIB@
+DEF_LIB_CXX=	@DEFAULT_LIB_CXX@
+DEF_LIB_SQL=	@DEFAULT_LIB_SQL@
+DEF_LIB_SQLITE=	@DEFAULT_LIB_SQLITE@
+DEF_LIB_STL=	@DEFAULT_LIB_STL@
+DEF_LIB_TCL=	@DEFAULT_LIB_TCL@
+INSTALLER=	@INSTALLER@
+LIBTOOL=	@LIBTOOL@
+
+POSTLINK=	@POSTLINK@
+SOLINK=		@MAKEFILE_SOLINK@ @CFLAGS@
+SOFLAGS=	@SOFLAGS@
+LIBMAJOR=	@DB_VERSION_MAJOR@
+LIBVERSION=	@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@
+
+CPPFLAGS=	-I$(builddir) -I$(srcdir) @CPPFLAGS@
+
+##################################################
+# C API.
+##################################################
+CFLAGS=		-c $(CPPFLAGS) @CFLAGS@
+CC=		@MAKEFILE_CC@
+CCLINK=		@MAKEFILE_CCLINK@ @CFLAGS@
+
+LDFLAGS=	@LDFLAGS@
+LIBS=		@LIBSO_LIBS@
+TEST_LIBS=	@TEST_LIBS@
+LIBCSO_LIBS=	@LIBCSO_LIBS@ @LIBSO_LIBS@
+
+libdb_base=	libdb
+libdb=		$(libdb_base).a
+libdb_version=	$(libdb_base)-$(LIBVERSION).a
+libso=		$(libdb_base)-$(LIBVERSION)@SOSUFFIX@
+libso_target=	$(libdb_base)-$(LIBVERSION).la
+libso_default=	$(libdb_base)@SOSUFFIX@
+libso_major=	$(libdb_base)-$(LIBMAJOR)@SOSUFFIX@
+
+##################################################
+# C++ API.
+#
+# C++ support is optional, and can be built with static or shared libraries.
+##################################################
+CXXFLAGS=	-c $(CPPFLAGS) @CXXFLAGS@
+CXX=		@MAKEFILE_CXX@
+CXXLINK=	@MAKEFILE_CXXLINK@ @CXXFLAGS@
+XSOLINK=	@MAKEFILE_XSOLINK@ @CXXFLAGS@
+LIBXSO_LIBS=	@LIBXSO_LIBS@ @LIBSO_LIBS@
+
+libcxx_base=	libdb_cxx
+libcxx=		$(libcxx_base).a
+libcxx_version=	$(libcxx_base)-$(LIBVERSION).a
+libxso=		$(libcxx_base)-$(LIBVERSION)@SOSUFFIX@
+libxso_target=	$(libcxx_base)-$(LIBVERSION).la
+libxso_default=	$(libcxx_base)@SOSUFFIX@
+libxso_major=	$(libcxx_base)-$(LIBMAJOR)@SOSUFFIX@
+
+##################################################
+# SQL API.
+#
+# SQL support is optional, and can be built with static or shared libraries.
+##################################################
+SQLFLAGS=	-I$(builddir) -I$(builddir)/sql -I$(langdir)/sql/generated \
+		-D_HAVE_SQLITE_CONFIG_H @SQL_FLAGS@
+
+libsql_base=	libdb_sql
+libsql=		$(libsql_base).a
+libsql_version=	$(libsql_base)-$(LIBVERSION).a
+libsqlso=	$(libsql_base)-$(LIBVERSION)@SOSUFFIX@
+libsqlso_target=$(libsql_base)-$(LIBVERSION).la
+libsqlso_default=$(libsql_base)@SOSUFFIX@
+libsqlso_major=	$(libsql_base)-$(LIBMAJOR)@SOSUFFIX@
+
+libsqlite_base=	libsqlite3
+libsqlite=	$(libsqlite_base).a
+libsqliteso=	$(libsqlite_base)@SOSUFFIX@
+libsqliteso_target=$(libsqlite_base).la
+
+##################################################
+# STL API.
+#
+# STL support is optional, and can be built with static or shared libraries.
+##################################################
+STLFLAGS=	$(CXXFLAGS) -I$(langdir)/cxx/stl
+LIBSTLSO_LIBS=	@LIBXSO_LIBS@ @LIBSO_LIBS@
+
+libstl_base=	libdb_stl
+libstl=		$(libstl_base).a
+libstl_version=	$(libstl_base)-$(LIBVERSION).a
+libstlso=	$(libstl_base)-$(LIBVERSION)@SOSUFFIX@
+libstlso_target=$(libstl_base)-$(LIBVERSION).la
+libstlso_default=$(libstl_base)@SOSUFFIX@
+libstlso_major=	$(libstl_base)-$(LIBMAJOR)@SOSUFFIX@
+
+##################################################
+# Java API.
+#
+# Java support is optional and requires shared librarires.
+##################################################
+CLASSPATH=	$(JAVA_CLASSTOP)
+LIBJSO_LIBS=	@LIBJSO_LIBS@ @LIBSO_LIBS@
+SWIGCFLAGS=	@SWIGCFLAGS@
+
+JAR=		@JAR@
+JAVA=		env CLASSPATH="$(CLASSPATH)" @JAVA@
+JAVAC=		env CLASSPATH="$(CLASSPATH)" @JAVAC@
+JAVACFLAGS=	@JAVACFLAGS@
+JAVA_CLASSTOP=	./classes
+JAVA_EXCLASSTOP=./classes.ex
+JAVA_SRCDIR=	$(langdir)/java/src
+JAVA_EXDIR=	$(exampledir)/java/src
+JAVA_SLEEPYCAT=	$(langdir)/java/src/com/sleepycat
+JAVA_MANIFEST=	$(langdir)/java/jarManifestEntries
+
+libj_jarfile=	db.jar
+libj_exjarfile=	dbexamples.jar
+libjso_base=	libdb_java
+libjso=		$(libjso_base)-$(LIBVERSION)@JMODSUFFIX@
+libjso_static=	$(libjso_base)-$(LIBVERSION).a
+libjso_target=	$(libjso_base)-$(LIBVERSION).la
+libjso_default=	$(libjso_base)@JMODSUFFIX@
+libjso_major=	$(libjso_base)-$(LIBMAJOR)@JMODSUFFIX@
+libjso_g=	$(libjso_base)-$(LIBVERSION)_g@JMODSUFFIX@
+
+##################################################
+# TCL API.
+#
+# Tcl support is optional.
+##################################################
+TCL_INCLUDE_SPEC=	@TCL_INCLUDE_SPEC@
+LIBTSO_LIBS=	@LIBTSO_LIBS@ @LIBSO_LIBS@
+TCL_SRCDIR=	$(langdir)/tcl
+libtcl_base=	libdb_tcl
+libtcl=		$(libtcl_base).a
+libtcl_version=	$(libtcl_base)-$(LIBVERSION).a
+libtso=		$(libtcl_base)-$(LIBVERSION)@LIBTSO_MODSUFFIX@
+libtso_target=	$(libtcl_base)-$(LIBVERSION).la
+libtso_default=	$(libtcl_base)@LIBTSO_MODSUFFIX@
+libtso_major=	$(libtcl_base)-$(LIBMAJOR)@LIBTSO_MODSUFFIX@
+
+##################################################
+# db_dump185 UTILITY
+#
+# The db_dump185 application should be compiled using the system's db.h file
+# (which should be a DB 1.85/1.86 include file), and the system's 1.85/1.86
+# object library.  To include the right db.h, don't include -I$(builddir) on
+# the compile line.  You may also need to add a local include directory and
+# local libraries, for example.  Do that by adding -I options to the DB185INC
+# line, and -l options to the DB185LIB line.
+##################################################
+DB185INC=	-c @CFLAGS@ -I$(topdir) @CPPFLAGS@
+DB185LIB=
+
+##################################################
+# Performance Event Monitoring definitions
+##################################################
+DTRACE=			@DTRACE@
+DTRACE_PROVIDER=	$(distdir)/db_provider.d
+
+##################################################
+# NOTHING BELOW THIS LINE SHOULD EVER NEED TO BE MODIFIED.
+##################################################
+
+##################################################
+# Object and utility lists.
+##################################################
+BTREE_VRFY_OBJS=\
+	db_ovfl_vrfy@o@ db_vrfy@o@ db_vrfyutil@o@ bt_verify@o@
+HASH_OBJS=\
+	hash@o@ hash_auto@o@ hash_compact@o@ hash_conv@o@ hash_dup@o@ \
+	hash_meta@o@ hash_method@o@ hash_open@o@ hash_page@o@ hash_rec@o@ \
+	hash_reclaim@o@ hash_stat@o@ hash_upgrade@o@
+HASH_VRFY_OBJS=\
+	hash_verify@o@
+HEAP_OBJS=\
+	heap@o@ heap_auto@o@ heap_backup@o@ heap_conv@o@ heap_method@o@ \
+	heap_open@o@ heap_rec@o@ heap_reclaim@o@ heap_stat@o@
+HEAP_VRFY_OBJS=\
+	heap_verify@o@
+QUEUE_OBJS=\
+	qam@o@ qam_auto@o@ qam_conv@o@ qam_files@o@ qam_method@o@ \
+	qam_open@o@ qam_rec@o@ qam_stat@o@ qam_upgrade@o@
+QUEUE_VRFY_OBJS=\
+	qam_verify@o@
+LOCK_OBJS=\
+	db_lock@o@ lock@o@ lock_deadlock@o@ lock_failchk@o@ lock_id@o@ \
+	lock_list@o@ lock_method@o@ lock_region@o@ lock_stat@o@ lock_timer@o@ \
+	lock_util@o@
+LOG_VRFY_OBJS=\
+	log_verify@o@ log_verify_util@o@ log_verify_int@o@ \
+	log_verify_auto@o@ 
+MUTEX_OBJS=\
+	mut_alloc@o@ mut_method@o@ mut_region@o@ mut_stat@o@
+PARTITION_OBJS=\
+	partition@o@
+REP_OBJS=\
+	rep_automsg@o@ rep_backup@o@ rep_elect@o@ rep_lease@o@ rep_log@o@ \
+	rep_method@o@ rep_record@o@ rep_region@o@ rep_stat@o@ \
+	rep_util@o@ rep_verify@o@
+REPMGR_OBJS=\
+	os_addrinfo@o@\
+	repmgr_auto@o@ repmgr_automsg@o@ repmgr_elect@o@ \
+	repmgr_method@o@ repmgr_msg@o@ \
+	repmgr_net@o@ repmgr_posix@o@ repmgr_queue@o@ repmgr_rec@o@ \
+	repmgr_sel@o@ repmgr_stat@o@ repmgr_util@o@
+PRINT_OBJS=\
+	btree_autop@o@ crdel_autop@o@ db_autop@o@ dbreg_autop@o@ \
+	fileops_autop@o@ hash_autop@o@ heap_autop@o@ qam_autop@o@ \
+	repmgr_autop@o@ txn_autop@o@
+STD_OBJS=\
+	bt_compact@o@ bt_compress@o@ bt_rec@o@ bt_upgrade@o@ btree_auto@o@ \
+	crdel_auto@o@ crdel_rec@o@ db_auto@o@ db_backup@o@ db_cds@o@ \
+	db_compact@o@ db_compint@o@  db_copy@o@ db_dispatch@o@ db_join@o@ \
+	db_rec@o@ db_upg@o@ db_upg_opd@o@ dbreg@o@ dbreg_auto@o@ dbreg_rec@o@ \
+	dbreg_stat@o@ dbreg_util@o@ env_backup@o@ env_failchk@o@ \
+	env_recover@o@ env_register@o@ fileops_auto@o@ fop_rec@o@ \
+	hmac@o@ log@o@ \
+	log_archive@o@ log_compare@o@ log_debug@o@ log_get@o@ log_method@o@ \
+	log_print@o@ log_put@o@ log_stat@o@ mp_backup@o@ mp_mvcc@o@ \
+	mut_failchk@o@ openflags@o@ seq_stat@o@ sequence@o@ sha1@o@ txn@o@ txn_auto@o@ \
+	txn_chkpt@o@ txn_failchk@o@ txn_method@o@ txn_rec@o@ txn_recover@o@ \
+	txn_region@o@ txn_stat@o@ txn_util@o@ xa@o@ xa_map@o@ 
+
+# When DTrace is enabled it may need to post-process (with -G) most of the
+# object files in order to generate the additional objects in @FINAL_OBJS@.
+
+DTRACE_OBJS= @ADDITIONAL_OBJS@ @REPLACEMENT_OBJS@ @CRYPTO_OBJS@ \
+	bt_compare@o@ bt_conv@o@ bt_curadj@o@ bt_cursor@o@ bt_delete@o@ \
+	bt_method@o@ bt_open@o@ bt_put@o@ bt_reclaim@o@ bt_recno@o@ \
+	bt_rsearch@o@ bt_search@o@ bt_split@o@ bt_stat@o@ clock@o@ db@o@ \
+	db_am@o@ db_byteorder@o@ db_cam@o@ db_conv@o@ db_dup@o@ db_err@o@ \
+	db_getlong@o@ db_idspace@o@ db_iface@o@ db_log2@o@ db_meta@o@ \
+	db_method@o@ db_open@o@ db_overflow@o@ db_pr@o@ db_reclaim@o@ \
+	db_remove@o@ db_rename@o@ db_ret@o@ db_setid@o@ db_setlsn@o@ \
+	db_shash@o@ db_sort_multiple@o@ db_stati@o@ db_truncate@o@ dbt@o@ \
+	env_alloc@o@ env_config@o@ env_file@o@ env_globals@o@ env_open@o@ \
+	env_method@o@ env_name@o@ env_region@o@ env_sig@o@ env_stat@o@ \
+	fop_basic@o@ fop_util@o@ hash_func@o@ mkpath@o@ mp_alloc@o@ \
+	mp_bh@o@ mp_fget@o@ mp_fmethod@o@ mp_fopen@o@ mp_fput@o@ mp_fset@o@ \
+	mp_method@o@ mp_region@o@ mp_register@o@ mp_resize@o@ mp_stat@o@ \
+	mp_sync@o@ mp_trickle@o@ os_abort@o@ os_abs@o@ os_alloc@o@ \
+	os_clock@o@ os_cpu@o@ os_ctime@o@ os_config@o@ os_dir@o@ os_errno@o@ \
+	os_fid@o@ os_flock@o@ os_fsync@o@ os_getenv@o@ os_handle@o@ os_map@o@ \
+	os_method@o@ os_mkdir@o@ os_open@o@ os_path@o@ os_pid@o@ os_rename@o@ \
+	os_root@o@ os_rpath@o@ os_rw@o@ os_seek@o@ os_stack@o@ os_stat@o@ \
+	os_tmpdir@o@ os_truncate@o@ os_uid@o@ os_unlink@o@ os_yield@o@ \
+	snprintf@o@ zerofill@o@
+
+C_OBJS=	$(DTRACE_OBJS) @FINAL_OBJS@
+
+CUTEST_OBJS=\
+	CuTest@o@ CuTests@o@ Runner@o@ TestChannel@o@ TestDbHotBackup@o@ \
+	TestDbTuner@o@ TestEncryption@o@ TestEnvConfig@o@ TestEnvMethod@o@ \
+	TestKeyExistErrorReturn@o@ TestPartial@o@ TestQueue@o@ \
+
+CXX_OBJS=\
+	cxx_channel@o@ cxx_db@o@ cxx_dbc@o@ cxx_dbt@o@ cxx_env@o@ \
+	cxx_except@o@ cxx_lock@o@ cxx_logc@o@ cxx_mpool@o@ cxx_multi@o@ \
+	cxx_rid@o@ cxx_seq@o@ cxx_site@o@ cxx_txn@o@
+
+CRYPTO_OBJS=\
+	aes_method@o@ crypto@o@ mt19937db@o@ rijndael-alg-fst@o@ \
+	rijndael-api-fst@o@
+
+JAVA_OBJS=\
+	db_java_wrap@o@
+
+JAVA_DBSRCS=\
+	$(JAVA_SLEEPYCAT)/asm/AnnotationVisitor.java \
+	$(JAVA_SLEEPYCAT)/asm/AnnotationWriter.java \
+	$(JAVA_SLEEPYCAT)/asm/Attribute.java \
+	$(JAVA_SLEEPYCAT)/asm/ByteVector.java \
+	$(JAVA_SLEEPYCAT)/asm/ClassReader.java \
+	$(JAVA_SLEEPYCAT)/asm/ClassVisitor.java \
+	$(JAVA_SLEEPYCAT)/asm/ClassWriter.java \
+	$(JAVA_SLEEPYCAT)/asm/Edge.java \
+	$(JAVA_SLEEPYCAT)/asm/FieldVisitor.java \
+	$(JAVA_SLEEPYCAT)/asm/FieldWriter.java \
+	$(JAVA_SLEEPYCAT)/asm/Frame.java \
+	$(JAVA_SLEEPYCAT)/asm/Handle.java \
+	$(JAVA_SLEEPYCAT)/asm/Handler.java \
+	$(JAVA_SLEEPYCAT)/asm/Item.java \
+	$(JAVA_SLEEPYCAT)/asm/Label.java \
+	$(JAVA_SLEEPYCAT)/asm/MethodVisitor.java \
+	$(JAVA_SLEEPYCAT)/asm/MethodWriter.java \
+	$(JAVA_SLEEPYCAT)/asm/Opcodes.java \
+	$(JAVA_SLEEPYCAT)/asm/Type.java \
+	$(JAVA_SLEEPYCAT)/bind/ByteArrayBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/EntityBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/EntryBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/RecordNumberBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/ClassCatalog.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/SerialBase.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/SerialBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/SerialInput.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/SerialOutput.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/SerialSerialBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/SerialSerialKeyCreator.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/StoredClassCatalog.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/TupleSerialBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/TupleSerialKeyCreator.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/TupleSerialMarshalledBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/serial/TupleSerialMarshalledKeyCreator.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/BigDecimalBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/BigIntegerBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/BooleanBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/ByteBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/CharacterBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/DoubleBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/FloatBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/IntegerBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/LongBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/MarshalledTupleEntry.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/MarshalledTupleKeyEntity.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/PackedIntegerBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/PackedLongBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/ShortBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/SortedBigDecimalBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/SortedDoubleBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/SortedFloatBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/SortedPackedIntegerBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/SortedPackedLongBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/StringBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/TupleBase.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/TupleBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/TupleInput.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/TupleInputBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/TupleMarshalledBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/TupleOutput.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleKeyCreator.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleMarshalledBinding.java \
+	$(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleMarshalledKeyCreator.java \
+	$(JAVA_SLEEPYCAT)/collections/BaseIterator.java \
+	$(JAVA_SLEEPYCAT)/collections/BlockIterator.java \
+	$(JAVA_SLEEPYCAT)/collections/CurrentTransaction.java \
+	$(JAVA_SLEEPYCAT)/collections/DataCursor.java \
+	$(JAVA_SLEEPYCAT)/collections/DataView.java \
+	$(JAVA_SLEEPYCAT)/collections/MapEntryParameter.java \
+	$(JAVA_SLEEPYCAT)/collections/MyRangeCursor.java \
+	$(JAVA_SLEEPYCAT)/collections/PrimaryKeyAssigner.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredCollection.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredCollections.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredContainer.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredEntrySet.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredIterator.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredKeySet.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredList.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredMap.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredMapEntry.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredSortedEntrySet.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredSortedKeySet.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredSortedMap.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredSortedValueSet.java \
+	$(JAVA_SLEEPYCAT)/collections/StoredValueSet.java \
+	$(JAVA_SLEEPYCAT)/collections/TransactionRunner.java \
+	$(JAVA_SLEEPYCAT)/collections/TransactionWorker.java \
+	$(JAVA_SLEEPYCAT)/collections/TupleSerialFactory.java \
+	$(JAVA_SLEEPYCAT)/compat/DbCompat.java \
+	$(JAVA_SLEEPYCAT)/db/BackupHandler.java \
+	$(JAVA_SLEEPYCAT)/db/BackupOptions.java \
+	$(JAVA_SLEEPYCAT)/db/BtreeCompressor.java \
+	$(JAVA_SLEEPYCAT)/db/BtreePrefixCalculator.java \
+	$(JAVA_SLEEPYCAT)/db/BtreeStats.java \
+	$(JAVA_SLEEPYCAT)/db/CacheFile.java \
+	$(JAVA_SLEEPYCAT)/db/CacheFilePriority.java \
+	$(JAVA_SLEEPYCAT)/db/CacheFileStats.java \
+	$(JAVA_SLEEPYCAT)/db/CacheStats.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationChannel.java \
+	$(JAVA_SLEEPYCAT)/db/CheckpointConfig.java \
+	$(JAVA_SLEEPYCAT)/db/CompactConfig.java \
+	$(JAVA_SLEEPYCAT)/db/CompactStats.java \
+	$(JAVA_SLEEPYCAT)/db/Cursor.java \
+	$(JAVA_SLEEPYCAT)/db/CursorConfig.java \
+	$(JAVA_SLEEPYCAT)/db/Database.java \
+	$(JAVA_SLEEPYCAT)/db/DatabaseConfig.java \
+	$(JAVA_SLEEPYCAT)/db/DatabaseEntry.java \
+	$(JAVA_SLEEPYCAT)/db/DatabaseException.java \
+	$(JAVA_SLEEPYCAT)/db/DatabaseStats.java \
+	$(JAVA_SLEEPYCAT)/db/DatabaseType.java \
+	$(JAVA_SLEEPYCAT)/db/DeadlockException.java \
+	$(JAVA_SLEEPYCAT)/db/Environment.java \
+	$(JAVA_SLEEPYCAT)/db/EnvironmentConfig.java \
+	$(JAVA_SLEEPYCAT)/db/ErrorHandler.java \
+	$(JAVA_SLEEPYCAT)/db/EventHandler.java \
+	$(JAVA_SLEEPYCAT)/db/EventHandlerAdapter.java \
+	$(JAVA_SLEEPYCAT)/db/FeedbackHandler.java \
+	$(JAVA_SLEEPYCAT)/db/ForeignKeyDeleteAction.java \
+	$(JAVA_SLEEPYCAT)/db/ForeignKeyNullifier.java \
+	$(JAVA_SLEEPYCAT)/db/ForeignMultiKeyNullifier.java \
+	$(JAVA_SLEEPYCAT)/db/HashStats.java \
+	$(JAVA_SLEEPYCAT)/db/Hasher.java \
+	$(JAVA_SLEEPYCAT)/db/HeapRecordId.java \
+	$(JAVA_SLEEPYCAT)/db/HeapFullException.java \
+	$(JAVA_SLEEPYCAT)/db/HeapStats.java \
+	$(JAVA_SLEEPYCAT)/db/JoinConfig.java \
+	$(JAVA_SLEEPYCAT)/db/JoinCursor.java \
+	$(JAVA_SLEEPYCAT)/db/KeyRange.java \
+	$(JAVA_SLEEPYCAT)/db/Lock.java \
+	$(JAVA_SLEEPYCAT)/db/LockDetectMode.java \
+	$(JAVA_SLEEPYCAT)/db/LockMode.java \
+	$(JAVA_SLEEPYCAT)/db/LockNotGrantedException.java \
+	$(JAVA_SLEEPYCAT)/db/LockOperation.java \
+	$(JAVA_SLEEPYCAT)/db/LockRequest.java \
+	$(JAVA_SLEEPYCAT)/db/LockRequestMode.java \
+	$(JAVA_SLEEPYCAT)/db/LockStats.java \
+	$(JAVA_SLEEPYCAT)/db/LogCursor.java \
+	$(JAVA_SLEEPYCAT)/db/LogRecordHandler.java \
+	$(JAVA_SLEEPYCAT)/db/LogSequenceNumber.java \
+	$(JAVA_SLEEPYCAT)/db/LogStats.java \
+	$(JAVA_SLEEPYCAT)/db/LogVerifyConfig.java \
+	$(JAVA_SLEEPYCAT)/db/MemoryException.java \
+	$(JAVA_SLEEPYCAT)/db/MessageHandler.java \
+	$(JAVA_SLEEPYCAT)/db/MultipleNIODataEntry.java \
+	$(JAVA_SLEEPYCAT)/db/MultipleKeyNIODataEntry.java \
+	$(JAVA_SLEEPYCAT)/db/MultipleRecnoNIODataEntry.java \
+	$(JAVA_SLEEPYCAT)/db/MultipleDataEntry.java \
+	$(JAVA_SLEEPYCAT)/db/MultipleEntry.java \
+	$(JAVA_SLEEPYCAT)/db/MultipleKeyDataEntry.java \
+	$(JAVA_SLEEPYCAT)/db/MultipleRecnoDataEntry.java \
+	$(JAVA_SLEEPYCAT)/db/MutexStats.java \
+	$(JAVA_SLEEPYCAT)/db/OperationStatus.java \
+	$(JAVA_SLEEPYCAT)/db/PanicHandler.java \
+	$(JAVA_SLEEPYCAT)/db/PartitionHandler.java \
+	$(JAVA_SLEEPYCAT)/db/PreparedTransaction.java \
+	$(JAVA_SLEEPYCAT)/db/QueueStats.java \
+	$(JAVA_SLEEPYCAT)/db/RecordNumberAppender.java \
+	$(JAVA_SLEEPYCAT)/db/RecoveryOperation.java \
+	$(JAVA_SLEEPYCAT)/db/RegionResourceType.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationConfig.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationDuplicateMasterException.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationHandleDeadException.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationHoldElectionException.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationHostAddress.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationJoinFailureException.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationLeaseExpiredException.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationLockoutException.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationManagerAckPolicy.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationManagerConnectionStatus.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationManagerMessageDispatch.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationManagerSite.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationManagerSiteConfig.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationManagerSiteInfo.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationManagerStats.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationManagerStartPolicy.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationSiteUnavailableException.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationStats.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationStatus.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationTimeoutType.java \
+	$(JAVA_SLEEPYCAT)/db/ReplicationTransport.java \
+	$(JAVA_SLEEPYCAT)/db/RunRecoveryException.java \
+	$(JAVA_SLEEPYCAT)/db/SecondaryConfig.java \
+	$(JAVA_SLEEPYCAT)/db/SecondaryCursor.java \
+	$(JAVA_SLEEPYCAT)/db/SecondaryDatabase.java \
+	$(JAVA_SLEEPYCAT)/db/SecondaryKeyCreator.java \
+	$(JAVA_SLEEPYCAT)/db/SecondaryMultiKeyCreator.java \
+	$(JAVA_SLEEPYCAT)/db/Sequence.java \
+	$(JAVA_SLEEPYCAT)/db/SequenceConfig.java \
+	$(JAVA_SLEEPYCAT)/db/SequenceStats.java \
+	$(JAVA_SLEEPYCAT)/db/StatsConfig.java \
+	$(JAVA_SLEEPYCAT)/db/Transaction.java \
+	$(JAVA_SLEEPYCAT)/db/TransactionConfig.java \
+	$(JAVA_SLEEPYCAT)/db/TransactionStats.java \
+	$(JAVA_SLEEPYCAT)/db/TransactionStatus.java \
+	$(JAVA_SLEEPYCAT)/db/VerboseConfig.java \
+	$(JAVA_SLEEPYCAT)/db/VerifyConfig.java \
+	$(JAVA_SLEEPYCAT)/db/VersionMismatchException.java \
+	$(JAVA_SLEEPYCAT)/db/internal/Db.java \
+	$(JAVA_SLEEPYCAT)/db/internal/DbConstants.java \
+	$(JAVA_SLEEPYCAT)/db/internal/DbChannel.java \
+	$(JAVA_SLEEPYCAT)/db/internal/DbEnv.java \
+	$(JAVA_SLEEPYCAT)/db/internal/DbLock.java \
+	$(JAVA_SLEEPYCAT)/db/internal/DbLogc.java \
+	$(JAVA_SLEEPYCAT)/db/internal/DbMpoolFile.java \
+	$(JAVA_SLEEPYCAT)/db/internal/DbSequence.java \
+	$(JAVA_SLEEPYCAT)/db/internal/DbSite.java \
+	$(JAVA_SLEEPYCAT)/db/internal/DbTxn.java \
+	$(JAVA_SLEEPYCAT)/db/internal/DbUtil.java \
+	$(JAVA_SLEEPYCAT)/db/internal/Dbc.java \
+	$(JAVA_SLEEPYCAT)/db/internal/db_java.java \
+	$(JAVA_SLEEPYCAT)/db/internal/db_javaJNI.java \
+	$(JAVA_SLEEPYCAT)/persist/BasicCursor.java \
+	$(JAVA_SLEEPYCAT)/persist/BasicIndex.java \
+	$(JAVA_SLEEPYCAT)/persist/BasicIterator.java \
+	$(JAVA_SLEEPYCAT)/persist/DataValueAdapter.java \
+	$(JAVA_SLEEPYCAT)/persist/DatabaseNamer.java \
+	$(JAVA_SLEEPYCAT)/persist/EntityCursor.java \
+	$(JAVA_SLEEPYCAT)/persist/EntityIndex.java \
+	$(JAVA_SLEEPYCAT)/persist/EntityJoin.java \
+	$(JAVA_SLEEPYCAT)/persist/EntityStore.java \
+	$(JAVA_SLEEPYCAT)/persist/EntityValueAdapter.java \
+	$(JAVA_SLEEPYCAT)/persist/ForwardCursor.java \
+	$(JAVA_SLEEPYCAT)/persist/IndexNotAvailableException.java \
+	$(JAVA_SLEEPYCAT)/persist/KeySelector.java \
+	$(JAVA_SLEEPYCAT)/persist/KeyValueAdapter.java \
+	$(JAVA_SLEEPYCAT)/persist/KeysIndex.java \
+	$(JAVA_SLEEPYCAT)/persist/PrimaryIndex.java \
+	$(JAVA_SLEEPYCAT)/persist/PrimaryKeyValueAdapter.java \
+	$(JAVA_SLEEPYCAT)/persist/SecondaryIndex.java \
+	$(JAVA_SLEEPYCAT)/persist/StoreConfig.java \
+	$(JAVA_SLEEPYCAT)/persist/StoreConfigBeanInfo.java \
+	$(JAVA_SLEEPYCAT)/persist/StoreExistsException.java \
+	$(JAVA_SLEEPYCAT)/persist/StoreNotFoundException.java \
+	$(JAVA_SLEEPYCAT)/persist/SubIndex.java \
+	$(JAVA_SLEEPYCAT)/persist/SubIndexCursor.java \
+	$(JAVA_SLEEPYCAT)/persist/ValueAdapter.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/Conversion.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/Converter.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/DeletedClassException.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/Deleter.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/EntityConverter.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/EvolveConfig.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/EvolveConfigBeanInfo.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/EvolveEvent.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/EvolveInternal.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/EvolveListener.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/EvolveStats.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/IncompatibleClassException.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/Mutation.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/Mutations.java \
+	$(JAVA_SLEEPYCAT)/persist/evolve/Renamer.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/AbstractInput.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/Accessor.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/Catalog.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/CollectionProxy.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/ComplexFormat.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/ComparatorCatalog.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/CompositeKeyFormat.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/ConverterReader.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/Enhanced.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/EnhancedAccessor.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/EntityInput.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/EntityOutput.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/EnumFormat.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/Evolver.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/FieldInfo.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/Format.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/KeyLocation.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/MapProxy.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/NonPersistentFormat.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/ObjectArrayFormat.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/PersistCatalog.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/PersistComparator.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/PersistEntityBinding.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/PersistKeyAssigner.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/PersistKeyBinding.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/PersistKeyCreator.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/PrimitiveArrayFormat.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/ProxiedFormat.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/RawAbstractInput.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/RawAccessor.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/RawArrayInput.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/RawComplexInput.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/RawSingleInput.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/ReadOnlyCatalog.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/Reader.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/RecordInput.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/RecordOutput.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/ReflectionAccessor.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/RefreshException.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/SimpleCatalog.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/SimpleFormat.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/Store.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/StoredModel.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/VisitedObjects.java \
+	$(JAVA_SLEEPYCAT)/persist/impl/WidenerInput.java \
+	$(JAVA_SLEEPYCAT)/persist/model/AnnotationModel.java \
+	$(JAVA_SLEEPYCAT)/persist/model/BytecodeEnhancer.java \
+	$(JAVA_SLEEPYCAT)/persist/model/ClassEnhancer.java \
+	$(JAVA_SLEEPYCAT)/persist/model/ClassMetadata.java \
+	$(JAVA_SLEEPYCAT)/persist/model/DeleteAction.java \
+	$(JAVA_SLEEPYCAT)/persist/model/Entity.java \
+	$(JAVA_SLEEPYCAT)/persist/model/EntityMetadata.java \
+	$(JAVA_SLEEPYCAT)/persist/model/EntityModel.java \
+	$(JAVA_SLEEPYCAT)/persist/model/FieldMetadata.java \
+	$(JAVA_SLEEPYCAT)/persist/model/KeyField.java \
+	$(JAVA_SLEEPYCAT)/persist/model/ModelInternal.java \
+	$(JAVA_SLEEPYCAT)/persist/model/NotPersistent.java \
+	$(JAVA_SLEEPYCAT)/persist/model/NotTransient.java \
+	$(JAVA_SLEEPYCAT)/persist/model/Persistent.java \
+	$(JAVA_SLEEPYCAT)/persist/model/PersistentProxy.java \
+	$(JAVA_SLEEPYCAT)/persist/model/PrimaryKey.java \
+	$(JAVA_SLEEPYCAT)/persist/model/PrimaryKeyMetadata.java \
+	$(JAVA_SLEEPYCAT)/persist/model/Relationship.java \
+	$(JAVA_SLEEPYCAT)/persist/model/SecondaryKey.java \
+	$(JAVA_SLEEPYCAT)/persist/model/SecondaryKeyMetadata.java \
+	$(JAVA_SLEEPYCAT)/persist/raw/RawField.java \
+	$(JAVA_SLEEPYCAT)/persist/raw/RawObject.java \
+	$(JAVA_SLEEPYCAT)/persist/raw/RawStore.java \
+	$(JAVA_SLEEPYCAT)/persist/raw/RawType.java \
+	$(JAVA_SLEEPYCAT)/util/ClassResolver.java \
+	$(JAVA_SLEEPYCAT)/util/ConfigBeanInfoBase.java \
+	$(JAVA_SLEEPYCAT)/util/ErrorBuffer.java \
+	$(JAVA_SLEEPYCAT)/util/ExceptionUnwrapper.java \
+	$(JAVA_SLEEPYCAT)/util/ExceptionWrapper.java \
+	$(JAVA_SLEEPYCAT)/util/FastInputStream.java \
+	$(JAVA_SLEEPYCAT)/util/FastOutputStream.java \
+	$(JAVA_SLEEPYCAT)/util/IOExceptionWrapper.java \
+	$(JAVA_SLEEPYCAT)/util/PackedInteger.java \
+	$(JAVA_SLEEPYCAT)/util/RuntimeExceptionWrapper.java \
+	$(JAVA_SLEEPYCAT)/util/UtfOps.java \
+	$(JAVA_SLEEPYCAT)/util/keyrange/KeyRange.java \
+	$(JAVA_SLEEPYCAT)/util/keyrange/KeyRangeException.java \
+	$(JAVA_SLEEPYCAT)/util/keyrange/RangeCursor.java
+
+JAVA_EXSRCS=\
+	$(JAVA_EXDIR)/collections/access/AccessExample.java \
+	$(JAVA_EXDIR)/collections/hello/HelloDatabaseWorld.java \
+	$(JAVA_EXDIR)/collections/ship/basic/PartData.java \
+	$(JAVA_EXDIR)/collections/ship/basic/PartKey.java \
+	$(JAVA_EXDIR)/collections/ship/basic/Sample.java \
+	$(JAVA_EXDIR)/collections/ship/basic/SampleDatabase.java \
+	$(JAVA_EXDIR)/collections/ship/basic/SampleViews.java \
+	$(JAVA_EXDIR)/collections/ship/basic/ShipmentData.java \
+	$(JAVA_EXDIR)/collections/ship/basic/ShipmentKey.java \
+	$(JAVA_EXDIR)/collections/ship/basic/SupplierData.java \
+	$(JAVA_EXDIR)/collections/ship/basic/SupplierKey.java \
+	$(JAVA_EXDIR)/collections/ship/basic/Weight.java \
+	$(JAVA_EXDIR)/collections/ship/entity/Part.java \
+	$(JAVA_EXDIR)/collections/ship/entity/PartData.java \
+	$(JAVA_EXDIR)/collections/ship/entity/PartKey.java \
+	$(JAVA_EXDIR)/collections/ship/entity/Sample.java \
+	$(JAVA_EXDIR)/collections/ship/entity/SampleDatabase.java \
+	$(JAVA_EXDIR)/collections/ship/entity/SampleViews.java \
+	$(JAVA_EXDIR)/collections/ship/entity/Shipment.java \
+	$(JAVA_EXDIR)/collections/ship/entity/ShipmentData.java \
+	$(JAVA_EXDIR)/collections/ship/entity/ShipmentKey.java \
+	$(JAVA_EXDIR)/collections/ship/entity/Supplier.java \
+	$(JAVA_EXDIR)/collections/ship/entity/SupplierData.java \
+	$(JAVA_EXDIR)/collections/ship/entity/SupplierKey.java \
+	$(JAVA_EXDIR)/collections/ship/entity/Weight.java \
+	$(JAVA_EXDIR)/collections/ship/factory/Part.java \
+	$(JAVA_EXDIR)/collections/ship/factory/PartKey.java \
+	$(JAVA_EXDIR)/collections/ship/factory/Sample.java \
+	$(JAVA_EXDIR)/collections/ship/factory/SampleDatabase.java \
+	$(JAVA_EXDIR)/collections/ship/factory/SampleViews.java \
+	$(JAVA_EXDIR)/collections/ship/factory/Shipment.java \
+	$(JAVA_EXDIR)/collections/ship/factory/ShipmentKey.java \
+	$(JAVA_EXDIR)/collections/ship/factory/Supplier.java \
+	$(JAVA_EXDIR)/collections/ship/factory/SupplierKey.java \
+	$(JAVA_EXDIR)/collections/ship/factory/Weight.java \
+	$(JAVA_EXDIR)/collections/ship/index/PartData.java \
+	$(JAVA_EXDIR)/collections/ship/index/PartKey.java \
+	$(JAVA_EXDIR)/collections/ship/index/Sample.java \
+	$(JAVA_EXDIR)/collections/ship/index/SampleDatabase.java \
+	$(JAVA_EXDIR)/collections/ship/index/SampleViews.java \
+	$(JAVA_EXDIR)/collections/ship/index/ShipmentData.java \
+	$(JAVA_EXDIR)/collections/ship/index/ShipmentKey.java \
+	$(JAVA_EXDIR)/collections/ship/index/SupplierData.java \
+	$(JAVA_EXDIR)/collections/ship/index/SupplierKey.java \
+	$(JAVA_EXDIR)/collections/ship/index/Weight.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/MarshalledEnt.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/MarshalledKey.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/Part.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/PartKey.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/Sample.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/SampleDatabase.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/SampleViews.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/Shipment.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/ShipmentKey.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/Supplier.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/SupplierKey.java \
+	$(JAVA_EXDIR)/collections/ship/marshal/Weight.java \
+	$(JAVA_EXDIR)/collections/ship/sentity/Part.java \
+	$(JAVA_EXDIR)/collections/ship/sentity/PartKey.java \
+	$(JAVA_EXDIR)/collections/ship/sentity/Sample.java \
+	$(JAVA_EXDIR)/collections/ship/sentity/SampleDatabase.java \
+	$(JAVA_EXDIR)/collections/ship/sentity/SampleViews.java \
+	$(JAVA_EXDIR)/collections/ship/sentity/Shipment.java \
+	$(JAVA_EXDIR)/collections/ship/sentity/ShipmentKey.java \
+	$(JAVA_EXDIR)/collections/ship/sentity/Supplier.java \
+	$(JAVA_EXDIR)/collections/ship/sentity/SupplierKey.java \
+	$(JAVA_EXDIR)/collections/ship/sentity/Weight.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/Part.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/PartData.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/PartKey.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/Sample.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/SampleDatabase.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/SampleViews.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/Shipment.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/ShipmentData.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/ShipmentKey.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/Supplier.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/SupplierData.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/SupplierKey.java \
+	$(JAVA_EXDIR)/collections/ship/tuple/Weight.java \
+	$(JAVA_EXDIR)/db/AccessExample.java \
+	$(JAVA_EXDIR)/db/BtRecExample.java \
+	$(JAVA_EXDIR)/db/BulkAccessExample.java \
+	$(JAVA_EXDIR)/db/BulkAccessNIOExample.java \
+	$(JAVA_EXDIR)/db/BulkExample.java \
+	$(JAVA_EXDIR)/db/EnvExample.java \
+	$(JAVA_EXDIR)/db/GettingStarted/ExampleDatabaseLoad.java \
+	$(JAVA_EXDIR)/db/GettingStarted/ExampleDatabaseRead.java \
+	$(JAVA_EXDIR)/db/GettingStarted/Inventory.java \
+	$(JAVA_EXDIR)/db/GettingStarted/InventoryBinding.java \
+	$(JAVA_EXDIR)/db/GettingStarted/ItemNameKeyCreator.java \
+	$(JAVA_EXDIR)/db/GettingStarted/MyDbs.java \
+	$(JAVA_EXDIR)/db/GettingStarted/Vendor.java \
+	$(JAVA_EXDIR)/db/LockExample.java \
+	$(JAVA_EXDIR)/db/SequenceExample.java \
+	$(JAVA_EXDIR)/db/TpcbExample.java \
+	$(JAVA_EXDIR)/db/repquote/RepConfig.java \
+	$(JAVA_EXDIR)/db/repquote/RepQuoteEnvironment.java \
+	$(JAVA_EXDIR)/db/repquote/RepQuoteExample.java \
+	$(JAVA_EXDIR)/db/repquote/RepRemoteHost.java \
+	$(JAVA_EXDIR)/db/repquote_gsg/RepConfig.java \
+	$(JAVA_EXDIR)/db/repquote_gsg/RepQuoteEnvironment.java \
+	$(JAVA_EXDIR)/db/repquote_gsg/RepQuoteExampleGSG.java \
+	$(JAVA_EXDIR)/db/repquote_gsg/SimpleConfig.java \
+	$(JAVA_EXDIR)/db/repquote_gsg/SimpleTxn.java \
+	$(JAVA_EXDIR)/db/txn/DBWriter.java \
+	$(JAVA_EXDIR)/db/txn/PayloadData.java \
+	$(JAVA_EXDIR)/db/txn/TxnGuide.java \
+	$(JAVA_EXDIR)/db/txn/TxnGuideInMemory.java \
+	$(JAVA_EXDIR)/persist/CustomKeyOrderExample.java \
+	$(JAVA_EXDIR)/persist/DplDump.java \
+	$(JAVA_EXDIR)/persist/EventExample.java \
+	$(JAVA_EXDIR)/persist/EventExampleDPL.java \
+	$(JAVA_EXDIR)/persist/PersonExample.java \
+	$(JAVA_EXDIR)/persist/gettingStarted/SimpleDA.java \
+	$(JAVA_EXDIR)/persist/gettingStarted/SimpleEntityClass.java \
+	$(JAVA_EXDIR)/persist/gettingStarted/SimpleStoreGet.java \
+	$(JAVA_EXDIR)/persist/gettingStarted/SimpleStorePut.java \
+	$(JAVA_EXDIR)/persist/txn/PayloadDataEntity.java \
+	$(JAVA_EXDIR)/persist/txn/StoreWriter.java \
+	$(JAVA_EXDIR)/persist/txn/TxnGuideDPL.java 
+
+SQL_OBJS=\
+	 sqlite3@o@ $(C_OBJS)
+
+STL_OBJS=\
+	dbstl_container@o@ dbstl_resource_manager@o@
+
+TCL_STD_OBJS=\
+	tcl_lock@o@ tcl_log@o@ tcl_mp@o@ tcl_mutex@o@ \
+	tcl_rep@o@  tcl_seq@o@ tcl_txn@o@ 
+
+TCL_OBJS=\
+	tcl_compat@o@ tcl_db@o@ tcl_db_pkg@o@ tcl_dbcursor@o@ tcl_env@o@ \
+	tcl_internal@o@  tcl_util@o@ \
+	@TCL_ADDITIONAL_OBJS@
+
+TEST_MICRO_OBJS=\
+	b_curalloc@o@ b_curwalk@o@ b_del@o@ b_get@o@ b_inmem@o@ b_latch@o@ \
+	b_load@o@ b_open@o@ b_put@o@ b_recover@o@ b_txn@o@ b_txn_write@o@ \
+	b_uname@o@ b_util@o@ b_workload@o@ test_micro@o@ util_arg@o@
+
+
+STD_PROGS=\
+	db_archive db_checkpoint db_deadlock \
+	db_hotbackup db_log_verify db_printlog db_recover \
+	db_replicate db_tuner db_upgrade
+
+UTIL_PROGS=\
+	db_dump db_load db_stat db_verify \
+	@ADDITIONAL_PROGS@
+
+##################################################
+# List of files installed into the library directory.
+##################################################
+LIB_INSTALL_FILE_LIST=\
+	$(libdb) \
+	$(libso) \
+	$(libso_default) \
+	$(libso_major) \
+	$(libdb_version) \
+	$(libcxx) \
+	$(libxso) \
+	$(libxso_default) \
+	$(libxso_major) \
+	$(libcxx_version) \
+	$(libsql) \
+	$(libsqlso) \
+	$(libsqlso_default) \
+	$(libsqlso_major) \
+	$(libsql_version) \
+	$(libstl) \
+	$(libstlso) \
+	$(libstlso_default) \
+	$(libstlso_major) \
+	$(libstl_version) \
+	$(libtcl) \
+	$(libtso) \
+	$(libtso_default) \
+	$(libtso_major) \
+	$(libtcl_version) \
+	$(libjso) \
+	$(libjso_default) \
+	$(libjso_g) \
+	$(libjso_major) \
+	$(libjso_static) \
+	$(libj_exjarfile) \
+	$(libj_jarfile) \
+	@INSTALL_LIBS@ @INSTALL_LIBS_EXTRA@
+
+##################################################
+# Note: "all" must be the first target in the Makefile.
+##################################################
+all: @BUILD_TARGET@
+
+install: all @INSTALL_TARGET@
+
+##################################################
+# Library and standard utilities build.
+##################################################
+library_build: @INSTALL_LIBS@ @ADDITIONAL_LANG@ $(UTIL_PROGS)
+
+# Static C library named libdb.a.
+$(libdb): $(DEF_LIB)
+
+# Real static C library.
+$(libdb_version): $(C_OBJS)
+	$(AR) cr $@ $(C_OBJS)
+	$(RANLIB) $@
+	$(RM) $(libdb)
+	$(LN) -s $(libdb_version) $(libdb)
+
+# Shared C library.
+$(libso_target): $(C_OBJS)
+	$(SOLINK) $(SOFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) \
+		$(LIBCSO_LIBS)
+	$(RM) $(libdb)
+	$(LN) -s .libs/$(libdb_version) $(libdb)
+
+# Static C++ library named libdb_cxx.a.
+$(libcxx): $(DEF_LIB_CXX)
+
+# Real static C++ library.
+$(libcxx_version): $(CXX_OBJS) $(C_OBJS)
+	$(AR) cr $@ $(CXX_OBJS) $(C_OBJS)
+	$(RANLIB) $@
+	$(RM) $(libcxx)
+	$(LN) -s $(libcxx_version) $(libcxx)
+
+# Shared C++ library.
+$(libxso_target): $(CXX_OBJS) $(C_OBJS)
+	$(XSOLINK) $(SOFLAGS) $(LDFLAGS) \
+	    -o $@ $(CXX_OBJS) $(C_OBJS) $(LIBXSO_LIBS)
+	$(RM) $(libcxx)
+	$(LN) -s .libs/$(libcxx_version) $(libcxx)
+
+# Static SQL library named libdb_sql.a.
+$(libsql): $(DEF_LIB_SQL)
+
+# Static SQL library.
+$(libsql_version): $(SQL_OBJS)
+	$(AR) cr $@ $(SQL_OBJS)
+	$(RANLIB) $@
+	$(RM) $(libsql)
+	$(LN) -s $(libsql_version) $(libsql)
+
+# Shared SQL library.
+$(libsqlso_target): $(SQL_OBJS)
+	$(SOLINK) $(SOFLAGS) $(LDFLAGS) -o $@ $(SQL_OBJS) $(LIBCSO_LIBS)
+	$(RM) $(libsql)
+	$(LN) -s .libs/$(libsql_version) $(libsql)
+
+dbsql: shell@o@ $(DEF_LIB_SQL)
+	$(CCLINK) -o $@ $(LDFLAGS) shell@o@ $(DEF_LIB_SQL) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+jdbc: $(DEF_LIB)
+	@(test -d jdbc && cd jdbc && PWD='.' $(MAKE))
+
+sql-test: $(DEF_LIB)
+	@(cd sql && $(MAKE) LTLINK_EXTRAS="../$(DEF_LIB) $(LIBS)" testfixture@EXEEXT@)
+
+# SQL API header file to be installed
+# Some configurations of Solaris make don't handle $< as an explicit dependency
+# so duplicate the name in the rule.
+dbsql.h: $(langdir)/sql/generated/sqlite3.h
+	$(CP) $(langdir)/sql/generated/sqlite3.h $@
+
+# SQLite drop-in replacements
+$(libsqlite): $(SQL_OBJS)
+	$(AR) cr $@ $(SQL_OBJS)
+	$(RANLIB) $@
+
+$(libsqliteso_target): $(SQL_OBJS)
+	$(SOLINK) $(SOFLAGS) $(LDFLAGS) -version-info "8:6:8" -o $@ \
+		$(SQL_OBJS) $(LIBCSO_LIBS)
+
+sqlite3: shell@o@ $(DEF_LIB_SQLITE)
+	$(CCLINK) -o $@ $(LDFLAGS) shell@o@ $(DEF_LIB_SQLITE) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+# Static STL library named libdb_stl.a.
+$(libstl): $(DEF_LIB_STL)
+
+# Real static STL library.
+$(libstl_version): $(STL_OBJS) $(CXX_OBJS) $(C_OBJS)
+	$(AR) cr $@ $(STL_OBJS) $(CXX_OBJS) $(C_OBJS)
+	$(RANLIB) $@
+	$(RM) $(libstl)
+	$(LN) -s $(libstl_version) $(libstl)
+
+# Shared STL library.
+$(libstlso_target): $(STL_OBJS) $(CXX_OBJS) $(C_OBJS)
+	$(XSOLINK) $(SOFLAGS) $(LDFLAGS) -o $@ $(STL_OBJS) \
+	    $(LIBSTLSO_LIBS) $(CXX_OBJS) $(C_OBJS) $(LIBXSO_LIBS)
+	$(RM) $(libstl)
+	$(LN) -s .libs/$(libstl_version) $(libstl)
+
+# Shared Java library.
+$(libjso_target): $(JAVA_OBJS) $(C_OBJS)
+	$(SOLINK) -shrext @JMODSUFFIX@ $(SOFLAGS) $(LDFLAGS) \
+	    -o $@ $(JAVA_OBJS) $(C_OBJS) $(LIBJSO_LIBS)
+
+# Static Tcl library
+$(libtcl): $(DEF_LIB_TCL)
+
+# Real static Tcl library.
+$(libtcl_version): $(TCL_OBJS) $(C_OBJS)
+	$(AR) cr $@ $(TCL_OBJS) $(C_OBJS)
+	$(RANLIB) $@
+	$(RM) $(libtcl)
+	$(LN) -s $(libtcl_version) $(libtcl)
+
+# Shared Tcl library.
+$(libtso_target): $(TCL_OBJS) $(C_OBJS)
+	$(SOLINK) @LIBTSO_MODULE@ $(SOFLAGS) $(LDFLAGS) \
+	    -o $@ $(TCL_OBJS) $(C_OBJS) $(LIBTSO_LIBS)
+	$(RM) $(libtcl)
+	$(LN) -s .libs/$(libtcl_version) $(libtcl)
+
+##################################################
+# Creating individual dependencies and actions for building class
+# files is possible, but it is very messy and error prone.
+##################################################
+java:	$(libj_jarfile) $(libj_exjarfile)
+
+$(libj_jarfile): $(JAVA_DBSRCS)
+	@test -d $(JAVA_CLASSTOP) || \
+	   ($(MKDIR) -p $(JAVA_CLASSTOP) && \
+	   $(CHMOD) $(dmode) $(JAVA_CLASSTOP))
+	$(JAVAC) -d $(JAVA_CLASSTOP) $(JAVACFLAGS) $(JAVA_DBSRCS)
+	$(JAVA) -classpath $(JAVA_CLASSTOP) \
+	    com.sleepycat.persist.model.ClassEnhancer $(JAVA_CLASSTOP)
+	cd $(JAVA_CLASSTOP) && \
+	     $(JAR) cfm ../$(libj_jarfile) ../$(JAVA_MANIFEST) ./com/sleepycat
+
+$(libj_exjarfile): $(libj_jarfile) $(JAVA_EXSRCS)
+	@test -d $(JAVA_EXCLASSTOP) || \
+	   ($(MKDIR) -p $(JAVA_EXCLASSTOP) && \
+		$(CHMOD) $(dmode) $(JAVA_EXCLASSTOP))
+	$(JAVAC) -classpath $(libj_jarfile) -d $(JAVA_EXCLASSTOP) \
+		$(JAVACFLAGS) $(JAVA_EXSRCS)
+	cd $(JAVA_EXCLASSTOP) && $(JAR) cf ../$(libj_exjarfile) .
+
+##################################################
+# Utilities
+##################################################
+db_archive: db_archive@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_archive@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_checkpoint: db_checkpoint@o@ util_log@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_checkpoint@o@ util_log@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_deadlock: db_deadlock@o@ util_log@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_deadlock@o@ util_log@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_dump: db_dump@o@ util_cache@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_dump@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_dump185: db_dump185@o@ @REPLACEMENT_OBJS@
+	$(CCLINK) -o $@ $(LDFLAGS) db_dump185@o@ @REPLACEMENT_OBJS@ $(DB185LIB)
+	$(POSTLINK) $@
+
+db_hotbackup: db_hotbackup@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_hotbackup@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_load: db_load@o@ util_cache@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_load@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_printlog: db_printlog@o@ @PRINTLOG_OBJS@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_printlog@o@ @PRINTLOG_OBJS@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_recover: db_recover@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_recover@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_replicate: db_replicate@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_replicate@o@ util_log@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+DBSQL_CODEGEN_OBJS=\
+          db_sql_codegen@o@ parse@o@ preparser@o@ parsefuncs@o@ tokenize@o@ \
+          sqlprintf@o@ buildpt@o@ utils@o@ generate@o@ generate_test@o@ \
+          generation_utils@o@ generate_verification@o@ hint_comment@o@
+
+db_sql_codegen: $(DBSQL_CODEGEN_OBJS) $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) $(DBSQL_CODEGEN_OBJS) $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_stat: db_stat@o@ util_cache@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_stat@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_tuner: db_tuner@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_tuner@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_upgrade: db_upgrade@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_upgrade@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_verify: db_verify@o@ util_cache@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_verify@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+db_log_verify: db_log_verify@o@ util_cache@o@ util_sig@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    db_log_verify@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+##################################################
+# Library and standard utilities install.
+##################################################
+library_install: install_setup
+library_install: install_include install_lib install_utilities install_docs
+
+uninstall: uninstall_include uninstall_lib uninstall_utilities uninstall_docs
+
+install_setup:
+	@test -d $(DESTDIR)$(prefix) || \
+	    ($(MKDIR) -p $(DESTDIR)$(prefix) && \
+	    $(CHMOD) $(dmode) $(DESTDIR)$(prefix))
+
+INCDOT=	db.h db_cxx.h @ADDITIONAL_INCS@
+install_include: $(INCDOT)
+	@echo "Installing DB include files: $(DESTDIR)$(includedir) ..."
+	@test -d $(DESTDIR)$(includedir) || \
+	    ($(MKDIR) -p $(DESTDIR)$(includedir) && \
+	    $(CHMOD) $(dmode) $(DESTDIR)$(includedir))
+	@for f in $(INCDOT); do \
+	    basef=`echo $$f | $(SED) 's,.*/,,'` ; \
+	    $(RM) $(DESTDIR)$(includedir)/$$basef ; \
+	    $(CP) -p $$f $(DESTDIR)$(includedir) ; \
+	    $(CHMOD) $(fmode) $(DESTDIR)$(includedir)/$$basef ; \
+	done
+
+uninstall_include:
+	@for f in $(INCDOT); do \
+	    basef=`echo $$f | $(SED) 's,.*/,,'` ; \
+	    $(RM) $(DESTDIR)$(includedir)/$$basef ; \
+	done
+
+install_lib:
+	@echo "Installing DB library: $(DESTDIR)$(libdir) ..."
+	@test -d $(DESTDIR)$(libdir) || \
+	    ($(MKDIR) -p $(DESTDIR)$(libdir) && \
+	    $(CHMOD) $(dmode) $(DESTDIR)$(libdir))
+	@cd $(DESTDIR)$(libdir) && $(RM) $(LIB_INSTALL_FILE_LIST)
+	@$(INSTALLER) @INSTALL_LIBS@ $(DESTDIR)$(libdir)
+	@(cd $(DESTDIR)$(libdir) && \
+	    test -f $(libso) && $(LN) -s $(libso) $(libso_default); \
+	    test -f $(libso) && $(LN) -s $(libso) $(libso_major); \
+	    test -f $(libxso) && $(LN) -s $(libxso) $(libxso_default); \
+	    test -f $(libxso) && $(LN) -s $(libxso) $(libxso_major); \
+	    test -f $(libsqlso) && $(LN) -s $(libsqlso) $(libsqlso_default); \
+	    test -f $(libsqlso) && $(LN) -s $(libsqlso) $(libsqlso_major); \
+	    test -f $(libstlso) && $(LN) -s $(libstlso) $(libstlso_default); \
+	    test -f $(libstlso) && $(LN) -s $(libstlso) $(libstlso_major); \
+	    test -f $(libtso) && $(LN) -s $(libtso) $(libtso_default); \
+	    test -f $(libtso) && $(LN) -s $(libtso) $(libtso_major); \
+	    test -f $(libjso) && $(LN) -s $(libjso) $(libjso_default); \
+	    test -f $(libjso) && $(LN) -s $(libjso) $(libjso_major); \
+	    test -f $(libjso) && $(LN) -s $(libjso) $(libjso_g)) || exit 0
+	@(test -f $(libj_jarfile) && \
+	    $(CP) $(libj_jarfile) $(DESTDIR)$(libdir) && \
+	    $(CHMOD) $(fmode) $(DESTDIR)$(libdir)/$(libj_jarfile)) || exit 0
+	@(test -d jdbc && cd jdbc && make install && cd -) || exit 0
+
+uninstall_lib:
+	@cd $(DESTDIR)$(libdir) && $(RM) $(LIB_INSTALL_FILE_LIST)
+
+install_utilities:
+	@echo "Installing DB utilities: $(DESTDIR)$(bindir) ..."
+	@test -d $(DESTDIR)$(bindir) || \
+	    ($(MKDIR) -p $(DESTDIR)$(bindir) && \
+	    $(CHMOD) $(dmode) $(DESTDIR)$(bindir))
+	@for i in $(UTIL_PROGS); do \
+		test -f $$i.exe && i=$$i.exe; \
+		e=`echo $$i | $(SED) '$(transform)'`; \
+		$(RM) $(DESTDIR)$(bindir)/$$e; \
+		$(INSTALLER) $$i $(DESTDIR)$(bindir)/$$e; \
+		$(STRIP) $(DESTDIR)$(bindir)/$$e; \
+		$(CHMOD) $(emode) $(DESTDIR)$(bindir)/$$e; \
+	done
+
+uninstall_utilities:
+	@(cd $(DESTDIR)$(bindir); for i in $(UTIL_PROGS); do \
+		i=`echo $$i | $(SED) '$(transform)'`; \
+		test -f $$i.exe && i=$$i.exe; \
+		$(RM) $$i; \
+	done)
+
+# We install csharp docs even on UNIX so we don't have a 
+# broken link on the landing page.
+DOCLIST=api_reference articles bdb-sql collections csharp \
+	gsg gsg_db_rep gsg_txn index.html installation java \
+	license porting programmer_reference upgrading
+
+install_docs:
+	@echo "Installing documentation: $(DESTDIR)$(docdir) ..."
+	@test -d $(DESTDIR)$(docdir) || \
+	    ($(MKDIR) -p $(DESTDIR)$(docdir) && \
+	    $(CHMOD) $(dmode) $(DESTDIR)$(docdir))
+	@cd $(DESTDIR)$(docdir) && $(RM) -r $(DOCLIST)
+	@cd $(topdir)/docs && $(CP) -pr $(DOCLIST) $(DESTDIR)$(docdir)/
+
+uninstall_docs:
+	@cd $(DESTDIR)$(docdir) && $(RM) -r $(DOCLIST)
+
+##################################################
+# Remaining standard Makefile targets.
+##################################################
+CLEAN_LIST=\
+	StlTxnGuide TxnGuide TxnGuideInMemory berkeley_db_cxxsvc \
+	berkeley_db_svc cutest db_dump185 db_perf db_repsite db_reptest dbs \
+	ex_access ex_apprec ex_btrec ex_bulk ex_dbclient ex_env ex_heap ex_lock \
+	ex_mpool ex_rep_base ex_rep_chan ex_rep_gsg_repmgr ex_rep_gsg_simple \
+	ex_rep_mgr ex_sequence ex_stream ex_thread ex_tpcb \
+	example_database_load example_database_read excxx_access \
+	excxx_btrec excxx_env excxx_example_database_load \
+	excxx_example_database_read excxx_lock excxx_mpool \
+	excxx_repquote excxx_repquote_gsg_repmgr excxx_repquote_gsg_simple \
+	excxx_sequence excxx_tpcb ex_sql_binding ex_sql_fts3 ex_sql_index \
+	ex_sql_load ex_sql_multi_thread ex_sql_query ex_sql_rtree \
+	ex_sql_savepoint ex_sql_statement ex_sql_transaction exstl_access \
+	exstl_advancedfeatures exstl_repquote exstl_tpcb txn_guide test_dbstl \
+	test_dbstl_ms_examples test_dbstl_stlport  txn_guide_inmemory
+
+mostly-clean clean:
+	$(RM) -r $(C_OBJS) $(CUTEST_OBJS)
+	$(RM) -r $(CXX_OBJS) $(JAVA_OBJS) $(SQL_OBJS) $(SQL_OBJS) $(STL_OBJS)
+	$(RM) -r $(TCL_OBJS) $(UTIL_PROGS) *.exe $(CLEAN_LIST)
+	$(RM) -r $(JAVA_CLASSTOP) $(JAVA_EXCLASSTOP)
+	$(RM) -r $(DB_STL_TEST_OBJS) $(TEST_MICRO_OBJS)
+	$(RM) -r tags *@o@ *.o *.o.lock *.lo core *.core core.*
+	$(RM) -r ALL.OUT.* PARALLEL_TESTDIR.*
+	$(RM) -r RUN_LOG RUNQUEUE TESTDIR TESTDIR.A TEST.LIST
+	$(RM) -r logtrack_seen.db test_micro test_mutex .libs
+	$(RM) -r $(LIB_INSTALL_FILE_LIST)
+	@subdir_cmd@
+
+REALCLEAN_LIST=\
+	Makefile clib_port.h confdefs.h config.cache config.log config.status \
+	configure.lineno db.h db185_int.h db_185.h db_config.h db_cxx.h \
+	db_int.h db_int_def.h db_provider.c db_provider.h dbstl_common.h \
+	db_server.h db_server_clnt.c db_server_svc.c db_server_xdr.c \
+	gen_db_server.c include.tcl dbsql.h $(builddir)/sql $(builddir)/jdbc
+
+distclean maintainer-clean realclean: clean
+	$(RM) -r $(REALCLEAN_LIST)
+	$(RM) -r libtool
+
+check depend dvi info obj TAGS:
+	@echo "make: $@ target not available"
+
+dist rpm rpmbuild:
+	@echo "make: $@ target not available" && exit 1
+
+##################################################
+# Testers, benchmarks.
+##################################################
+dbs@o@: $(testdir)/server/dbs.c
+	$(CC) $(CFLAGS) $?
+dbs_am@o@: $(testdir)/server/dbs_am.c
+	$(CC) $(CFLAGS) $?
+dbs_checkpoint@o@: $(testdir)/server/dbs_checkpoint.c
+	$(CC) $(CFLAGS) $?
+dbs_debug@o@: $(testdir)/server/dbs_debug.c
+	$(CC) $(CFLAGS) $?
+dbs_handles@o@: $(testdir)/server/dbs_handles.c
+	$(CC) $(CFLAGS) $?
+dbs_log@o@: $(testdir)/server/dbs_log.c
+	$(CC) $(CFLAGS) $?
+dbs_qam@o@: $(testdir)/server/dbs_qam.c
+	$(CC) $(CFLAGS) $?
+dbs_spawn@o@: $(testdir)/server/dbs_spawn.c
+	$(CC) $(CFLAGS) $?
+dbs_trickle@o@: $(testdir)/server/dbs_trickle.c
+	$(CC) $(CFLAGS) $?
+dbs_util@o@: $(testdir)/server/dbs_util.c
+	$(CC) $(CFLAGS) $?
+dbs_yield@o@: $(testdir)/server/dbs_yield.c
+	$(CC) $(CFLAGS) $?
+DBS_OBJS=\
+	dbs@o@ dbs_am@o@ dbs_checkpoint@o@ dbs_debug@o@ dbs_handles@o@ \
+	dbs_log@o@ dbs_qam@o@ dbs_spawn@o@ dbs_trickle@o@ dbs_util@o@ \
+	dbs_yield@o@
+dbs: $(DBS_OBJS) $(DEF_LIB)
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) $(DBS_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+db_perf@o@: $(testdir)/perf/db_perf.c
+	$(CC) $(CFLAGS) $?
+perf_checkpoint@o@: $(testdir)/perf/perf_checkpoint.c
+	$(CC) $(CFLAGS) $?
+perf_config@o@: $(testdir)/perf/perf_config.c
+	$(CC) $(CFLAGS) $?
+perf_dbs@o@: $(testdir)/perf/perf_dbs.c
+	$(CC) $(CFLAGS) $?
+perf_dead@o@: $(testdir)/perf/perf_dead.c
+	$(CC) $(CFLAGS) $?
+perf_debug@o@: $(testdir)/perf/perf_debug.c
+	$(CC) $(CFLAGS) $?
+perf_file@o@: $(testdir)/perf/perf_file.c
+	$(CC) $(CFLAGS) $?
+perf_key@o@: $(testdir)/perf/perf_key.c
+	$(CC) $(CFLAGS) $?
+perf_log@o@: $(testdir)/perf/perf_log.c
+	$(CC) $(CFLAGS) $?
+perf_misc@o@: $(testdir)/perf/perf_misc.c
+	$(CC) $(CFLAGS) $?
+perf_op@o@: $(testdir)/perf/perf_op.c
+	$(CC) $(CFLAGS) $?
+perf_parse@o@: $(testdir)/perf/perf_parse.c
+	$(CC) $(CFLAGS) $?
+perf_rand@o@: $(testdir)/perf/perf_rand.c
+	$(CC) $(CFLAGS) $?
+perf_spawn@o@: $(testdir)/perf/perf_spawn.c
+	$(CC) $(CFLAGS) $?
+perf_stat@o@: $(testdir)/perf/perf_stat.c
+	$(CC) $(CFLAGS) $?
+perf_sync@o@: $(testdir)/perf/perf_sync.c
+	$(CC) $(CFLAGS) $?
+perf_thread@o@: $(testdir)/perf/perf_thread.c
+	$(CC) $(CFLAGS) $?
+perf_trickle@o@: $(testdir)/perf/perf_trickle.c
+	$(CC) $(CFLAGS) $?
+perf_txn@o@: $(testdir)/perf/perf_txn.c
+	$(CC) $(CFLAGS) $?
+perf_util@o@: $(testdir)/perf/perf_util.c
+	$(CC) $(CFLAGS) $?
+perf_vx@o@: $(testdir)/perf/perf_vx.c
+	$(CC) $(CFLAGS) $?
+DBPERF_OBJS=\
+	db_perf@o@ perf_checkpoint@o@ perf_config@o@ perf_dbs@o@ \
+	perf_dead@o@ perf_debug@o@ perf_file@o@ perf_key@o@ perf_log@o@ \
+	perf_misc@o@ perf_op@o@ perf_parse@o@ perf_rand@o@ perf_spawn@o@ \
+	perf_stat@o@ perf_sync@o@ perf_thread@o@ perf_trickle@o@ \
+	perf_txn@o@ perf_util@o@ perf_vx@o@ util_sig@o@
+db_perf: $(DBPERF_OBJS) $(DEF_LIB)
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) $(DBPERF_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+# C unit test suite.
+CUTEST_FLAGS= $(CFLAGS) -I$(testdir)/c/cutest -I$(testdir)/c/suites -I$(testdir)/c/common
+
+CuTest@o@: $(testdir)/c/cutest/CuTest.c
+	$(CC) $(CUTEST_FLAGS) $?
+CuTests@o@: $(testdir)/c/cutest/CuTests.c
+	$(CC) $(CUTEST_FLAGS) $?
+Runner@o@: $(testdir)/c/cutest/Runner.c
+	$(CC) $(CUTEST_FLAGS) $?
+TestChannel@o@: $(testdir)/c/suites/TestChannel.c
+	$(CC) $(CUTEST_FLAGS) $?
+TestDbHotBackup@o@: $(testdir)/c/suites/TestDbHotBackup.c
+	$(CC) $(CUTEST_FLAGS) $?
+TestDbTuner@o@: $(testdir)/c/suites/TestDbTuner.c
+	$(CC) $(CUTEST_FLAGS) $?
+TestEncryption@o@: $(testdir)/c/suites/TestEncryption.c
+	$(CC) $(CUTEST_FLAGS) $?
+TestEnvConfig@o@: $(testdir)/c/suites/TestEnvConfig.c
+	$(CC) $(CUTEST_FLAGS) $?
+TestEnvMethod@o@: $(testdir)/c/suites/TestEnvMethod.c
+	$(CC) $(CUTEST_FLAGS) $?
+TestKeyExistErrorReturn@o@: $(testdir)/c/suites/TestKeyExistErrorReturn.c
+	$(CC) $(CUTEST_FLAGS) $?
+TestPartial@o@: $(testdir)/c/suites/TestPartial.c
+	$(CC) $(CUTEST_FLAGS) $?
+TestQueue@o@: $(testdir)/c/suites/TestQueue.c
+	$(CC) $(CUTEST_FLAGS) $?
+
+cutest: $(CUTEST_OBJS) $(DEF_LIB) db_tuner.lo
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) $(CUTEST_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+db_repsite@o@: $(testdir)/repmgr/db_repsite.cpp
+	$(CXX) $(CXXFLAGS) $?
+DBREPSITE_OBJS=db_repsite@o@
+db_repsite: $(DBREPSITE_OBJS) $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ \
+	   $(LDFLAGS) $(DBREPSITE_OBJS) $(DEF_LIB_CXX) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@ 
+
+db_reptest@o@: $(testdir)/repmgr/db_reptest.c
+	$(CC) $(CFLAGS) $?
+reptest_am@o@: $(testdir)/repmgr/reptest_am.c
+	$(CC) $(CFLAGS) $?
+reptest_handles@o@: $(testdir)/repmgr/reptest_handles.c
+	$(CC) $(CFLAGS) $?
+reptest_spawn@o@: $(testdir)/repmgr/reptest_spawn.c
+	$(CC) $(CFLAGS) $?
+reptest_util@o@: $(testdir)/repmgr/reptest_util.c
+	$(CC) $(CFLAGS) $?
+DBREPTEST_OBJS=\
+	db_reptest@o@ reptest_am@o@ reptest_handles@o@ \
+	reptest_spawn@o@ reptest_util@o@ 
+
+db_reptest: $(DBREPTEST_OBJS) $(DEF_LIB)
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) $(DBREPTEST_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+test_dbstl@o@: $(testdir)/stl/base/test_dbstl.cpp
+	$(CXX) $(STLFLAGS) $?
+test_util@o@: $(testdir)/stl/base/test_util.cpp
+	$(CXX) $(STLFLAGS) $?
+
+stl_test@o@: $(testdir)/stl/stlport/stl_test.cpp
+	$(CXX) $(STLFLAGS) $?
+utility@o@: $(testdir)/stl/stlport/utility.cpp
+	$(CXX) $(STLFLAGS) $?
+stlport_test_builder@o@: $(testdir)/stl/stlport/stlport_test_builder.cpp
+	$(CXX) $(STLFLAGS) $?
+
+ms_stl_main@o@: $(testdir)/stl/ms_examples/ms_stl_main.cpp
+	$(CXX) $(STLFLAGS) -DGCC_BAD_AUTO_CONVERSION  $?
+ms_stl_common@o@: $(testdir)/stl/ms_examples/ms_stl_common.cpp
+	$(CXX) $(STLFLAGS) -DGCC_BAD_AUTO_CONVERSION  $?
+test_builder@o@: $(testdir)/stl/ms_examples/test_builder.cpp
+	$(CXX) $(STLFLAGS) -DGCC_BAD_AUTO_CONVERSION  $?
+
+DB_STL_TEST_OBJS=test_dbstl@o@ test_util@o@
+DB_STL_STLPORT_TEST_OBJS=stl_test@o@ stlport_test_builder@o@ utility@o@
+DB_STL_MS_TEST_OBJS=ms_stl_main@o@ ms_stl_common@o@ \
+	test_builder@o@
+
+test_dbstl: $(DB_STL_TEST_OBJS) $(DEF_LIB_CXX) $(DEF_LIB_STL)
+	$(CXXLINK) -o $@ $(LDFLAGS) $(DB_STL_TEST_OBJS) \
+	    $(DEF_LIB_CXX) $(DEF_LIB_STL) $(LIBS) $(LIBSTLSO_LIBS)
+	$(POSTLINK) $@
+
+test_dbstl_ms_examples: $(DB_STL_MS_TEST_OBJS) $(DEF_LIB_CXX) $(DEF_LIB_STL)
+	$(CXXLINK) -o $@ $(LDFLAGS) $(DB_STL_MS_TEST_OBJS) \
+	    $(DEF_LIB_CXX) $(DEF_LIB_STL) $(LIBS) $(LIBSTLSO_LIBS)
+	$(POSTLINK) $@
+test_dbstl_stlport: $(DB_STL_STLPORT_TEST_OBJS) $(DEF_LIB_CXX) $(DEF_LIB_STL)
+	$(CXXLINK) -o $@ $(LDFLAGS) $(DB_STL_STLPORT_TEST_OBJS) \
+	    $(DEF_LIB_CXX) $(DEF_LIB_STL) $(LIBS) $(LIBSTLSO_LIBS)
+	$(POSTLINK) $@
+
+b_curalloc@o@: $(testdir)/micro/source/b_curalloc.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_curwalk@o@: $(testdir)/micro/source/b_curwalk.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_del@o@: $(testdir)/micro/source/b_del.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_get@o@: $(testdir)/micro/source/b_get.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_inmem@o@: $(testdir)/micro/source/b_inmem.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_latch@o@: $(testdir)/micro/source/b_latch.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_load@o@: $(testdir)/micro/source/b_load.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_open@o@: $(testdir)/micro/source/b_open.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_put@o@: $(testdir)/micro/source/b_put.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_recover@o@: $(testdir)/micro/source/b_recover.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_txn@o@: $(testdir)/micro/source/b_txn.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_txn_write@o@: $(testdir)/micro/source/b_txn_write.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_uname@o@: $(testdir)/micro/source/b_uname.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_util@o@: $(testdir)/micro/source/b_util.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+b_workload@o@: $(testdir)/micro/source/b_workload.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+test_micro@o@: $(testdir)/micro/source/test_micro.c
+	$(CC) $(CFLAGS) -I$(testdir)/micro/source $?
+test_micro: $(TEST_MICRO_OBJS) $(DEF_LIB)
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) $(TEST_MICRO_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+test_mutex@o@: $(srcdir)/mutex/test_mutex.c
+	$(CC) $(CFLAGS) $?
+test_mutex: test_mutex@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) test_mutex@o@ $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+##################################################
+# Targets for example programs.
+##################################################
+examples_c: ex_access ex_apprec ex_btrec ex_bulk ex_env ex_heap ex_lock \
+	ex_mpool ex_rep_base ex_rep_chan ex_rep_gsg_repmgr ex_rep_gsg_simple \
+	ex_rep_mgr ex_sequence ex_stream ex_thread ex_tpcb \
+	example_database_load example_database_read txn_guide txn_guide_inmemory
+
+examples_cxx: TxnGuide TxnGuideInMemory excxx_access \
+	excxx_example_database_load excxx_example_database_read \
+	excxx_lock excxx_mpool excxx_repquote excxx_repquote_gsg_repmgr \
+	excxx_repquote_gsg_simple excxx_sequence excxx_tpcb
+
+examples_stl: StlTxnGuide exstl_access exstl_advancedfeatures exstl_repquote \
+	exstl_tpcb
+
+examples_sql: ex_sql_binding ex_sql_fts3 ex_sql_index ex_sql_load \
+	ex_sql_multi_thread ex_sql_query ex_sql_rtree ex_sql_savepoint \
+	ex_sql_statement ex_sql_transaction
+
+examples: examples_c examples_cxx examples_stl examples_sql
+
+##################################################
+# Example programs for C.
+##################################################
+ex_access@o@: $(exampledir)/c/ex_access.c
+	$(CC) $(CFLAGS) $?
+ex_access: ex_access@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_access@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+ex_apprec@o@: $(exampledir)/c/ex_apprec/ex_apprec.c
+	$(CC) $(CFLAGS) $?
+ex_apprec_auto@o@: $(exampledir)/c/ex_apprec/ex_apprec_auto.c
+	$(CC) $(CFLAGS) $?
+ex_apprec_autop@o@: $(exampledir)/c/ex_apprec/ex_apprec_autop.c
+	$(CC) $(CFLAGS) $?
+ex_apprec_rec@o@: $(exampledir)/c/ex_apprec/ex_apprec_rec.c
+	$(CC) $(CFLAGS) $?
+EX_APPREC_OBJS=\
+	ex_apprec@o@ ex_apprec_auto@o@ ex_apprec_autop@o@ ex_apprec_rec@o@
+ex_apprec: $(EX_APPREC_OBJS) $(DEF_LIB)
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) $(EX_APPREC_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+
+ex_btrec@o@: $(exampledir)/c/ex_btrec.c
+	$(CC) $(CFLAGS) $?
+ex_btrec: ex_btrec@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_btrec@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+ex_bulk@o@: $(exampledir)/c/ex_bulk.c
+	$(CC) $(CFLAGS) $?
+ex_bulk: ex_bulk@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_bulk@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+ex_dbclient@o@: $(exampledir)/c/ex_dbclient.c
+	$(CC) $(CFLAGS) $?
+ex_dbclient: ex_dbclient@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_dbclient@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+ex_env@o@: @LOCALEXAMPLES@/c/ex_env.c
+	$(CC) $(CFLAGS) $?
+ex_env: ex_env@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_env@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+ex_heap@o@: $(exampledir)/c/ex_heap.c
+	$(CC) $(CFLAGS) $?
+ex_heap: ex_heap@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_heap@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+ex_lock@o@: $(exampledir)/c/ex_lock.c
+	$(CC) $(CFLAGS) $?
+ex_lock: ex_lock@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_lock@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+ex_mpool@o@: $(exampledir)/c/ex_mpool.c
+	$(CC) $(CFLAGS) $?
+ex_mpool: ex_mpool@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_mpool@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+rep_base@o@: $(exampledir)/c/ex_rep/base/rep_base.c
+	$(CC) $(CFLAGS) $?
+rep_common@o@: $(exampledir)/c/ex_rep/common/rep_common.c
+	$(CC) $(CFLAGS) $?
+rep_msg@o@: $(exampledir)/c/ex_rep/base/rep_msg.c
+	$(CC) $(CFLAGS) $?
+rep_net@o@: $(exampledir)/c/ex_rep/base/rep_net.c
+	$(CC) $(CFLAGS) $?
+EX_REP_BASE_OBJS=\
+	rep_base@o@ rep_common@o@ rep_msg@o@ rep_net@o@
+ex_rep_base: $(EX_REP_BASE_OBJS) $(DEF_LIB)
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) $(EX_REP_BASE_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+rep_chan@o@: $(exampledir)/c/ex_rep_chan/rep_chan.c
+	$(CC) $(CFLAGS) $?
+rep_chan_util@o@: $(exampledir)/c/ex_rep_chan/rep_chan_util.c
+	$(CC) $(CFLAGS) $?
+EX_REP_CHAN_OBJS=\
+	rep_chan@o@ rep_chan_util@o@
+ex_rep_chan: $(EX_REP_CHAN_OBJS) $(DEF_LIB)
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) $(EX_REP_CHAN_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+simple_txn@o@: $(exampledir)/c/ex_rep_gsg/simple_txn.c
+	$(CC) $(CFLAGS) $?
+ex_rep_gsg_simple: simple_txn@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) simple_txn@o@ $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+rep_mgr_gsg@o@: $(exampledir)/c/ex_rep_gsg/rep_mgr_gsg.c
+	$(CC) $(CFLAGS) $?
+ex_rep_gsg_repmgr: rep_mgr_gsg@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) rep_mgr_gsg@o@ $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+rep_mgr@o@: $(exampledir)/c/ex_rep/mgr/rep_mgr.c
+	$(CC) $(CFLAGS) $?
+EX_REP_MGR_OBJS=\
+	rep_common@o@ rep_mgr@o@
+ex_rep_mgr: $(EX_REP_MGR_OBJS) $(DEF_LIB)
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) $(EX_REP_MGR_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+ex_sequence@o@: $(exampledir)/c/ex_sequence.c
+	$(CC) $(CFLAGS) $?
+ex_sequence: ex_sequence@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_sequence@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+ex_stream@o@: $(exampledir)/c/ex_stream.c
+	$(CC) $(CFLAGS) $?
+ex_stream: ex_stream@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_stream@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+ex_thread@o@: @LOCALEXAMPLES@/c/ex_thread.c
+	$(CC) $(CFLAGS) $?
+ex_thread: ex_thread@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ \
+	    $(LDFLAGS) ex_thread@o@ $(DEF_LIB) $(TEST_LIBS) $(LIBS)
+	$(POSTLINK) $@
+
+ex_tpcb@o@: $(exampledir)/c/ex_tpcb.c
+	$(CC) $(CFLAGS) $?
+ex_tpcb: ex_tpcb@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_tpcb@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+gettingstarted_common@o@: \
+    $(exampledir)/c/getting_started/gettingstarted_common.c
+	$(CC) -I$(exampledir)/c/getting_started $(CFLAGS) $?
+example_database_load@o@: \
+    $(exampledir)/c/getting_started/example_database_load.c
+	$(CC) $(CFLAGS) $?
+example_database_read@o@: \
+    $(exampledir)/c/getting_started/example_database_read.c
+	$(CC) $(CFLAGS) $?
+example_database_load: example_database_load@o@ gettingstarted_common@o@ \
+    $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    example_database_load@o@ gettingstarted_common@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+example_database_read: example_database_read@o@ gettingstarted_common@o@ \
+    $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) \
+	    example_database_read@o@ gettingstarted_common@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+txn_guide_inmemory@o@: $(exampledir)/c/txn_guide/txn_guide_inmemory.c
+	$(CC) $(CFLAGS) $?
+txn_guide_inmemory: txn_guide_inmemory@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) txn_guide_inmemory@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+txn_guide@o@: $(exampledir)/c/txn_guide/txn_guide.c
+	$(CC) $(CFLAGS) $?
+txn_guide: txn_guide@o@ $(DEF_LIB)
+	$(CCLINK) -o $@ $(LDFLAGS) txn_guide@o@ $(DEF_LIB) $(LIBS)
+	$(POSTLINK) $@
+
+##################################################
+# Example programs for C++.
+##################################################
+AccessExample@o@: $(exampledir)/cxx/AccessExample.cpp
+	$(CXX) $(CXXFLAGS) $?
+excxx_access: AccessExample@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) AccessExample@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+BtRecExample@o@: $(exampledir)/cxx/BtRecExample.cpp
+	$(CXX) $(CXXFLAGS) $?
+excxx_btrec: BtRecExample@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) BtRecExample@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+EnvExample@o@: $(exampledir)/cxx/EnvExample.cpp
+	$(CXX) $(CXXFLAGS) $?
+excxx_env: EnvExample@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) EnvExample@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+LockExample@o@: $(exampledir)/cxx/LockExample.cpp
+	$(CXX) $(CXXFLAGS) $?
+excxx_lock: LockExample@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) LockExample@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+MpoolExample@o@: $(exampledir)/cxx/MpoolExample.cpp
+	$(CXX) $(CXXFLAGS) $?
+excxx_mpool: MpoolExample@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) MpoolExample@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+RepQuoteExample@o@: $(exampledir)/cxx/excxx_repquote/RepQuoteExample.cpp
+	$(CXX) -I$(exampledir)/cxx/excxx_repquote $(CXXFLAGS) $?
+RepConfigInfo@o@: $(exampledir)/cxx/excxx_repquote/RepConfigInfo.cpp
+	$(CXX) -I$(exampledir)/cxx/excxx_repquote $(CXXFLAGS) $?
+excxx_repquote: RepQuoteExample@o@ RepConfigInfo@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) \
+	    RepQuoteExample@o@ RepConfigInfo@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+RepMgrGSG@o@: $(exampledir)/cxx/excxx_repquote_gsg/RepMgrGSG.cpp
+	$(CXX) -I$(exampledir)/cxx/excxx_repquote_gsg $(CXXFLAGS) $?
+excxx_repquote_gsg_repmgr: RepMgrGSG@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) RepMgrGSG@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+SimpleTxn@o@: $(exampledir)/cxx/excxx_repquote_gsg/SimpleTxn.cpp
+	$(CXX) -I$(exampledir)/cxx/excxx_repquote_gsg $(CXXFLAGS) $?
+excxx_repquote_gsg_simple: SimpleTxn@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) SimpleTxn@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+SequenceExample@o@: $(exampledir)/cxx/SequenceExample.cpp
+	$(CXX) $(CXXFLAGS) $?
+excxx_sequence: SequenceExample@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) SequenceExample@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+TpcbExample@o@: $(exampledir)/cxx/TpcbExample.cpp
+	$(CXX) $(CXXFLAGS) $?
+excxx_tpcb: TpcbExample@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) TpcbExample@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+excxx_example_database_load@o@: \
+    $(exampledir)/cxx/getting_started/excxx_example_database_load.cpp
+	$(CXX) -I$(exampledir)/cxx/getting_started $(CXXFLAGS) $?
+excxx_example_database_read@o@: \
+    $(exampledir)/cxx/getting_started/excxx_example_database_read.cpp
+	$(CXX) -I$(exampledir)/cxx/getting_started $(CXXFLAGS) $?
+MyDb@o@: $(exampledir)/cxx/getting_started/MyDb.cpp
+	$(CXX) -I$(exampledir)/cxx/getting_started $(CXXFLAGS) $?
+excxx_example_database_load: \
+    excxx_example_database_load@o@ MyDb@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) \
+	    excxx_example_database_load@o@ MyDb@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+excxx_example_database_read: \
+    excxx_example_database_read@o@ MyDb@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) \
+	    excxx_example_database_read@o@ MyDb@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+TxnGuideInMemory@o@: $(exampledir)/cxx/txn_guide/TxnGuideInMemory.cpp
+	$(CXX) $(CXXFLAGS) $?
+TxnGuideInMemory: TxnGuideInMemory@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) TxnGuideInMemory@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+TxnGuide@o@: $(exampledir)/cxx/txn_guide/TxnGuide.cpp
+	$(CXX) $(CXXFLAGS) $?
+TxnGuide: TxnGuide@o@ $(DEF_LIB_CXX)
+	$(CXXLINK) -o $@ $(LDFLAGS) TxnGuide@o@ $(DEF_LIB_CXX) $(LIBS)
+	$(POSTLINK) $@
+
+##################################################
+# Example programs for STL.
+##################################################
+StlAccessExample@o@: $(exampledir)/stl/StlAccessExample.cpp
+	$(CXX) $(STLFLAGS) $?
+exstl_access: StlAccessExample@o@ $(DEF_LIB_STL)
+	$(CXXLINK) -o $@ $(LDFLAGS) StlAccessExample@o@ $(DEF_LIB_STL) $(LIBS)
+	$(POSTLINK) $@
+
+StlAdvancedFeatures@o@: $(exampledir)/stl/StlAdvancedFeatures.cpp
+	$(CXX) -I$(exampledir)/stl $(STLFLAGS) $?
+exstl_advancedfeatures: StlAdvancedFeatures@o@ $(DEF_LIB_STL)
+	$(CXXLINK) -o $@ $(LDFLAGS) StlAdvancedFeatures@o@ $(DEF_LIB_STL) $(LIBS)
+	$(POSTLINK) $@
+
+StlRepQuoteExample@o@: $(exampledir)/stl/repquote/StlRepQuoteExample.cpp
+	$(CXX) -I$(exampledir)/stl/repquote $(STLFLAGS) $?
+StlRepConfigInfo@o@: $(exampledir)/stl/repquote/StlRepConfigInfo.cpp
+	$(CXX) -I$(exampledir)/stl/repquote $(STLFLAGS) $?
+exstl_repquote: StlRepQuoteExample@o@ StlRepConfigInfo@o@ $(DEF_LIB_STL)
+	$(CXXLINK) -o $@ $(LDFLAGS) \
+	    StlRepQuoteExample@o@ StlRepConfigInfo@o@ $(DEF_LIB_STL) $(LIBS)
+	$(POSTLINK) $@
+
+StlTpcbExample@o@: $(exampledir)/stl/StlTpcbExample.cpp
+	$(CXX) $(STLFLAGS) $?
+exstl_tpcb: StlTpcbExample@o@ $(DEF_LIB_STL)
+	$(CXXLINK) -o $@ $(LDFLAGS) StlTpcbExample@o@ $(DEF_LIB_STL) $(LIBS)
+	$(POSTLINK) $@
+
+StlTransactionGuideExample@o@: $(exampledir)/stl/StlTransactionGuideExample.cpp
+	$(CXX) $(STLFLAGS) $?
+StlTxnGuide: StlTransactionGuideExample@o@ $(DEF_LIB_STL)
+	$(CXXLINK) -o $@ $(LDFLAGS) StlTransactionGuideExample@o@ $(DEF_LIB_STL) $(LIBS)
+	$(POSTLINK) $@
+
+##################################################
+# Example programs for SQL.
+##################################################
+ex_sql_binding: ex_sql_binding@o@ ex_sql_utils@o@ $(DEF_LIB_SQL)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_sql_binding@o@ ex_sql_utils@o@ $(DEF_LIB_SQL) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+ex_sql_fts3: ex_sql_fts3@o@ ex_sql_utils@o@ $(DEF_LIB_SQL)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_sql_fts3@o@ ex_sql_utils@o@ $(DEF_LIB_SQL) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+ex_sql_index: ex_sql_index@o@ ex_sql_utils@o@ $(DEF_LIB_SQL)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_sql_index@o@ ex_sql_utils@o@ $(DEF_LIB_SQL) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+ex_sql_load: ex_sql_load@o@ ex_sql_utils@o@ $(DEF_LIB_SQL)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_sql_load@o@ ex_sql_utils@o@ $(DEF_LIB_SQL) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+ex_sql_multi_thread: ex_sql_multi_thread@o@ ex_sql_utils@o@ $(DEF_LIB_SQL)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_sql_multi_thread@o@ ex_sql_utils@o@ $(DEF_LIB_SQL) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+ex_sql_query: ex_sql_query@o@ ex_sql_utils@o@ $(DEF_LIB_SQL)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_sql_query@o@ ex_sql_utils@o@ $(DEF_LIB_SQL) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+ex_sql_rtree: ex_sql_rtree@o@ ex_sql_utils@o@ $(DEF_LIB_SQL)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_sql_rtree@o@ ex_sql_utils@o@ $(DEF_LIB_SQL) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+ex_sql_savepoint: ex_sql_savepoint@o@ ex_sql_utils@o@ $(DEF_LIB_SQL)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_sql_savepoint@o@ ex_sql_utils@o@ $(DEF_LIB_SQL) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+ex_sql_statement: ex_sql_statement@o@ ex_sql_utils@o@ $(DEF_LIB_SQL)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_sql_statement@o@ ex_sql_utils@o@ $(DEF_LIB_SQL) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+ex_sql_transaction: ex_sql_transaction@o@ ex_sql_utils@o@ $(DEF_LIB_SQL)
+	$(CCLINK) -o $@ $(LDFLAGS) ex_sql_transaction@o@ ex_sql_utils@o@ $(DEF_LIB_SQL) @SQL_LIBS@ $(LIBS)
+	$(POSTLINK) $@
+
+ex_sql_binding@o@: $(exampledir)/sql/c/ex_sql_binding.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+ex_sql_fts3@o@: $(exampledir)/sql/c/ex_sql_fts3.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+ex_sql_index@o@: $(exampledir)/sql/c/ex_sql_index.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+ex_sql_load@o@: $(exampledir)/sql/c/ex_sql_load.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+ex_sql_multi_thread@o@: $(exampledir)/sql/c/ex_sql_multi_thread.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+ex_sql_utils@o@: $(exampledir)/sql/c/ex_sql_utils.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+ex_sql_query@o@: $(exampledir)/sql/c/ex_sql_query.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+ex_sql_rtree@o@: $(exampledir)/sql/c/ex_sql_rtree.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+ex_sql_savepoint@o@: $(exampledir)/sql/c/ex_sql_savepoint.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+ex_sql_statement@o@: $(exampledir)/sql/c/ex_sql_statement.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+ex_sql_transaction@o@: $(exampledir)/sql/c/ex_sql_transaction.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+
+##################################################
+# C API build rules.
+##################################################
+aes_method@o@: $(srcdir)/crypto/aes_method.c
+	 $(CC) $(CFLAGS) $?
+bt_compare@o@: $(srcdir)/btree/bt_compare.c
+	 $(CC) $(CFLAGS) $?
+bt_compress@o@: $(srcdir)/btree/bt_compress.c
+	 $(CC) $(CFLAGS) $?
+bt_conv@o@: $(srcdir)/btree/bt_conv.c
+	 $(CC) $(CFLAGS) $?
+bt_curadj@o@: $(srcdir)/btree/bt_curadj.c
+	 $(CC) $(CFLAGS) $?
+bt_cursor@o@: $(srcdir)/btree/bt_cursor.c
+	 $(CC) $(CFLAGS) $?
+bt_delete@o@: $(srcdir)/btree/bt_delete.c
+	 $(CC) $(CFLAGS) $?
+bt_method@o@: @LOCALSRC@/btree/bt_method.c
+	 $(CC) $(CFLAGS) $?
+bt_open@o@: $(srcdir)/btree/bt_open.c
+	 $(CC) $(CFLAGS) $?
+bt_put@o@: $(srcdir)/btree/bt_put.c
+	 $(CC) $(CFLAGS) $?
+bt_rec@o@: $(srcdir)/btree/bt_rec.c
+	 $(CC) $(CFLAGS) $?
+bt_reclaim@o@: $(srcdir)/btree/bt_reclaim.c
+	 $(CC) $(CFLAGS) $?
+bt_recno@o@: $(srcdir)/btree/bt_recno.c
+	 $(CC) $(CFLAGS) $?
+bt_rsearch@o@: $(srcdir)/btree/bt_rsearch.c
+	 $(CC) $(CFLAGS) $?
+bt_search@o@: $(srcdir)/btree/bt_search.c
+	 $(CC) $(CFLAGS) $?
+bt_split@o@: $(srcdir)/btree/bt_split.c
+	 $(CC) $(CFLAGS) $?
+bt_stat@o@: $(srcdir)/btree/bt_stat.c
+	 $(CC) $(CFLAGS) $?
+bt_compact@o@: $(srcdir)/btree/bt_compact.c
+	 $(CC) $(CFLAGS) $?
+bt_upgrade@o@: $(srcdir)/btree/bt_upgrade.c
+	 $(CC) $(CFLAGS) $?
+bt_verify@o@: $(srcdir)/btree/bt_verify.c
+	 $(CC) $(CFLAGS) $?
+btree_auto@o@: $(srcdir)/btree/btree_auto.c
+	 $(CC) $(CFLAGS) $?
+btree_autop@o@: $(srcdir)/btree/btree_autop.c
+	 $(CC) $(CFLAGS) $?
+clock@o@: $(srcdir)/common/clock.c
+	 $(CC) $(CFLAGS) $?
+crdel_auto@o@: $(srcdir)/db/crdel_auto.c
+	 $(CC) $(CFLAGS) $?
+crdel_autop@o@: $(srcdir)/db/crdel_autop.c
+	 $(CC) $(CFLAGS) $?
+crdel_rec@o@: $(srcdir)/db/crdel_rec.c
+	 $(CC) $(CFLAGS) $?
+crypto@o@: $(srcdir)/crypto/crypto.c
+	 $(CC) $(CFLAGS) $?
+crypto_stub@o@: $(srcdir)/common/crypto_stub.c
+	 $(CC) $(CFLAGS) $?
+db185@o@: $(langdir)/db185/db185.c
+	 $(CC) $(CFLAGS) $?
+db@o@: $(srcdir)/db/db.c
+	 $(CC) $(CFLAGS) $?
+db_am@o@: $(srcdir)/db/db_am.c
+	 $(CC) $(CFLAGS) $?
+db_auto@o@: $(srcdir)/db/db_auto.c
+	 $(CC) $(CFLAGS) $?
+db_autop@o@: $(srcdir)/db/db_autop.c
+	 $(CC) $(CFLAGS) $?
+db_byteorder@o@: $(srcdir)/common/db_byteorder.c
+	 $(CC) $(CFLAGS) $?
+db_backup@o@: $(srcdir)/db/db_backup.c
+	 $(CC) $(CFLAGS) $?
+db_cam@o@: $(srcdir)/db/db_cam.c
+	 $(CC) $(CFLAGS) $?
+db_cds@o@: $(srcdir)/db/db_cds.c
+	 $(CC) $(CFLAGS) $?
+db_compact@o@: $(srcdir)/db/db_compact.c
+	 $(CC) $(CFLAGS) $?
+db_compint@o@: $(srcdir)/common/db_compint.c
+	 $(CC) $(CFLAGS) $?
+db_conv@o@: $(srcdir)/db/db_conv.c
+	 $(CC) $(CFLAGS) $?
+db_copy@o@: $(srcdir)/db/db_copy.c
+	$(CC) $(CFLAGS) $?
+db_dispatch@o@: $(srcdir)/db/db_dispatch.c
+	 $(CC) $(CFLAGS) $?
+db_dup@o@: $(srcdir)/db/db_dup.c
+	 $(CC) $(CFLAGS) $?
+db_err@o@: $(srcdir)/common/db_err.c
+	 $(CC) $(CFLAGS) $?
+db_getlong@o@: @LOCALSRC@/common/db_getlong.c
+	 $(CC) $(CFLAGS) $?
+db_idspace@o@: $(srcdir)/common/db_idspace.c
+	 $(CC) $(CFLAGS) $?
+db_iface@o@: $(srcdir)/db/db_iface.c
+	 $(CC) $(CFLAGS) $?
+db_join@o@: $(srcdir)/db/db_join.c
+	 $(CC) $(CFLAGS) $?
+db_lock@o@: $(srcdir)/lock/db_lock.c
+	 $(CC) $(CFLAGS) $?
+db_log2@o@: $(srcdir)/common/db_log2.c
+	 $(CC) $(CFLAGS) $?
+db_meta@o@: $(srcdir)/db/db_meta.c
+	 $(CC) $(CFLAGS) $?
+db_method@o@: @LOCALSRC@/db/db_method.c
+	 $(CC) $(CFLAGS) $?
+db_open@o@: $(srcdir)/db/db_open.c
+	 $(CC) $(CFLAGS) $?
+db_overflow@o@: $(srcdir)/db/db_overflow.c
+	 $(CC) $(CFLAGS) $?
+db_ovfl_vrfy@o@: $(srcdir)/db/db_ovfl_vrfy.c
+	 $(CC) $(CFLAGS) $?
+db_pr@o@: $(srcdir)/db/db_pr.c
+	 $(CC) $(CFLAGS) $?
+db_rec@o@: $(srcdir)/db/db_rec.c
+	 $(CC) $(CFLAGS) $?
+db_reclaim@o@: $(srcdir)/db/db_reclaim.c
+	 $(CC) $(CFLAGS) $?
+db_rename@o@: $(srcdir)/db/db_rename.c
+	 $(CC) $(CFLAGS) $?
+db_remove@o@: $(srcdir)/db/db_remove.c
+	 $(CC) $(CFLAGS) $?
+db_ret@o@: $(srcdir)/db/db_ret.c
+	 $(CC) $(CFLAGS) $?
+db_setid@o@: $(srcdir)/db/db_setid.c
+	 $(CC) $(CFLAGS) $?
+db_setlsn@o@: $(srcdir)/db/db_setlsn.c
+	 $(CC) $(CFLAGS) $?
+db_shash@o@: $(srcdir)/common/db_shash.c
+	 $(CC) $(CFLAGS) $?
+db_sort_multiple@o@: $(srcdir)/db/db_sort_multiple.c
+	 $(CC) $(CFLAGS) $?
+db_stati@o@: $(srcdir)/db/db_stati.c
+	 $(CC) $(CFLAGS) $?
+db_truncate@o@: $(srcdir)/db/db_truncate.c
+	 $(CC) $(CFLAGS) $?
+db_upg@o@: $(srcdir)/db/db_upg.c
+	 $(CC) $(CFLAGS) $?
+db_upg_opd@o@: $(srcdir)/db/db_upg_opd.c
+	 $(CC) $(CFLAGS) $?
+db_vrfy@o@: $(srcdir)/db/db_vrfy.c
+	 $(CC) $(CFLAGS) $?
+db_vrfyutil@o@: $(srcdir)/db/db_vrfyutil.c
+	 $(CC) $(CFLAGS) $?
+db_vrfy_stub@o@: $(srcdir)/db/db_vrfy_stub.c
+	$(CC) $(CFLAGS) $?
+dbm@o@: $(langdir)/dbm/dbm.c
+	 $(CC) $(CFLAGS) $?
+dbreg@o@: $(srcdir)/dbreg/dbreg.c
+	 $(CC) $(CFLAGS) $?
+dbreg_auto@o@: $(srcdir)/dbreg/dbreg_auto.c
+	 $(CC) $(CFLAGS) $?
+dbreg_autop@o@: $(srcdir)/dbreg/dbreg_autop.c
+	 $(CC) $(CFLAGS) $?
+dbreg_rec@o@: $(srcdir)/dbreg/dbreg_rec.c
+	 $(CC) $(CFLAGS) $?
+dbreg_stat@o@: $(srcdir)/dbreg/dbreg_stat.c
+	 $(CC) $(CFLAGS) $?
+dbreg_util@o@: $(srcdir)/dbreg/dbreg_util.c
+	 $(CC) $(CFLAGS) $?
+dbt@o@: $(srcdir)/common/dbt.c
+	 $(CC) $(CFLAGS) $?
+env_alloc@o@: $(srcdir)/env/env_alloc.c
+	 $(CC) $(CFLAGS) $?
+env_config@o@: $(srcdir)/env/env_config.c
+	 $(CC) $(CFLAGS) $?
+env_backup@o@: $(srcdir)/env/env_backup.c
+	 $(CC) $(CFLAGS) $?
+env_failchk@o@: $(srcdir)/env/env_failchk.c
+	 $(CC) $(CFLAGS) $?
+env_file@o@: $(srcdir)/env/env_file.c
+	 $(CC) $(CFLAGS) $?
+env_globals@o@: $(srcdir)/env/env_globals.c
+	 $(CC) $(CFLAGS) $?
+env_method@o@: @LOCALSRC@/env/env_method.c
+	 $(CC) $(CFLAGS) $?
+env_name@o@: $(srcdir)/env/env_name.c
+	 $(CC) $(CFLAGS) $?
+env_open@o@: $(srcdir)/env/env_open.c
+	 $(CC) $(CFLAGS) $?
+env_recover@o@: $(srcdir)/env/env_recover.c
+	 $(CC) $(CFLAGS) $?
+env_region@o@: $(srcdir)/env/env_region.c
+	 $(CC) $(CFLAGS) $?
+env_register@o@: $(srcdir)/env/env_register.c
+	 $(CC) $(CFLAGS) $?
+env_sig@o@: @LOCALSRC@/env/env_sig.c
+	 $(CC) $(CFLAGS) $?
+env_stat@o@: $(srcdir)/env/env_stat.c
+	 $(CC) $(CFLAGS) $?
+fileops_auto@o@: $(srcdir)/fileops/fileops_auto.c
+	 $(CC) $(CFLAGS) $?
+fileops_autop@o@: $(srcdir)/fileops/fileops_autop.c
+	 $(CC) $(CFLAGS) $?
+fop_basic@o@: $(srcdir)/fileops/fop_basic.c
+	 $(CC) $(CFLAGS) $?
+fop_rec@o@: $(srcdir)/fileops/fop_rec.c
+	 $(CC) $(CFLAGS) $?
+fop_util@o@: @LOCALSRC@/fileops/fop_util.c
+	 $(CC) $(CFLAGS) $?
+hash@o@: $(srcdir)/hash/hash.c
+	 $(CC) $(CFLAGS) $?
+hash_auto@o@: $(srcdir)/hash/hash_auto.c
+	 $(CC) $(CFLAGS) $?
+hash_autop@o@: $(srcdir)/hash/hash_autop.c
+	 $(CC) $(CFLAGS) $?
+hash_compact@o@: $(srcdir)/hash/hash_compact.c
+	 $(CC) $(CFLAGS) $?
+hash_conv@o@: $(srcdir)/hash/hash_conv.c
+	 $(CC) $(CFLAGS) $?
+hash_dup@o@: $(srcdir)/hash/hash_dup.c
+	 $(CC) $(CFLAGS) $?
+hash_func@o@: $(srcdir)/hash/hash_func.c
+	 $(CC) $(CFLAGS) $?
+hash_meta@o@: $(srcdir)/hash/hash_meta.c
+	 $(CC) $(CFLAGS) $?
+hash_method@o@: $(srcdir)/hash/hash_method.c
+	 $(CC) $(CFLAGS) $?
+hash_open@o@: $(srcdir)/hash/hash_open.c
+	 $(CC) $(CFLAGS) $?
+hash_page@o@: $(srcdir)/hash/hash_page.c
+	 $(CC) $(CFLAGS) $?
+hash_rec@o@: $(srcdir)/hash/hash_rec.c
+	 $(CC) $(CFLAGS) $?
+hash_reclaim@o@: $(srcdir)/hash/hash_reclaim.c
+	 $(CC) $(CFLAGS) $?
+hash_stat@o@: $(srcdir)/hash/hash_stat.c
+	 $(CC) $(CFLAGS) $?
+hash_stub@o@: $(srcdir)/hash/hash_stub.c
+	 $(CC) $(CFLAGS) $?
+hash_upgrade@o@: $(srcdir)/hash/hash_upgrade.c
+	 $(CC) $(CFLAGS) $?
+hash_verify@o@: $(srcdir)/hash/hash_verify.c
+	 $(CC) $(CFLAGS) $?
+heap@o@: $(srcdir)/heap/heap.c
+	 $(CC) $(CFLAGS) $?
+heap_auto@o@: $(srcdir)/heap/heap_auto.c
+	 $(CC) $(CFLAGS) $?
+heap_autop@o@: $(srcdir)/heap/heap_autop.c
+	 $(CC) $(CFLAGS) $?
+heap_backup@o@: $(srcdir)/heap/heap_backup.c
+	 $(CC) $(CFLAGS) $?
+heap_conv@o@: $(srcdir)/heap/heap_conv.c
+	 $(CC) $(CFLAGS) $?
+heap_method@o@: $(srcdir)/heap/heap_method.c
+	 $(CC) $(CFLAGS) $?
+heap_open@o@: $(srcdir)/heap/heap_open.c
+	 $(CC) $(CFLAGS) $?
+heap_rec@o@: $(srcdir)/heap/heap_rec.c
+	 $(CC) $(CFLAGS) $?
+heap_reclaim@o@: $(srcdir)/heap/heap_reclaim.c
+	 $(CC) $(CFLAGS) $?
+heap_stat@o@: $(srcdir)/heap/heap_stat.c
+	 $(CC) $(CFLAGS) $?
+heap_stub@o@: $(srcdir)/heap/heap_stub.c
+	 $(CC) $(CFLAGS) $?
+heap_verify@o@: $(srcdir)/heap/heap_verify.c
+	 $(CC) $(CFLAGS) $?
+hmac@o@: $(srcdir)/hmac/hmac.c
+	 $(CC) $(CFLAGS) $?
+hsearch@o@: $(langdir)/hsearch/hsearch.c
+	 $(CC) $(CFLAGS) $?
+lock@o@: $(srcdir)/lock/lock.c $(srcdir)/lock/lock_alloc.incl
+	 $(CC) $(CFLAGS) $(srcdir)/lock/lock.c
+lock_deadlock@o@:$(srcdir)/lock/lock_deadlock.c
+	 $(CC) $(CFLAGS) $?
+lock_failchk@o@:$(srcdir)/lock/lock_failchk.c
+	 $(CC) $(CFLAGS) $?
+lock_id@o@:$(srcdir)/lock/lock_id.c
+	 $(CC) $(CFLAGS) $?
+lock_list@o@:$(srcdir)/lock/lock_list.c
+	 $(CC) $(CFLAGS) $?
+lock_method@o@:$(srcdir)/lock/lock_method.c
+	 $(CC) $(CFLAGS) $?
+lock_region@o@:$(srcdir)/lock/lock_region.c
+	 $(CC) $(CFLAGS) $?
+lock_stat@o@:$(srcdir)/lock/lock_stat.c
+	 $(CC) $(CFLAGS) $?
+lock_stub@o@: $(srcdir)/lock/lock_stub.c
+	 $(CC) $(CFLAGS) $?
+lock_timer@o@:$(srcdir)/lock/lock_timer.c
+	 $(CC) $(CFLAGS) $?
+lock_util@o@:$(srcdir)/lock/lock_util.c
+	 $(CC) $(CFLAGS) $?
+log@o@: $(srcdir)/log/log.c
+	 $(CC) $(CFLAGS) $?
+log_archive@o@: $(srcdir)/log/log_archive.c
+	 $(CC) $(CFLAGS) $?
+log_compare@o@: $(srcdir)/log/log_compare.c
+	 $(CC) $(CFLAGS) $?
+log_debug@o@: $(srcdir)/log/log_debug.c
+	 $(CC) $(CFLAGS) $?
+log_get@o@: $(srcdir)/log/log_get.c
+	 $(CC) $(CFLAGS) $?
+log_method@o@: $(srcdir)/log/log_method.c
+	 $(CC) $(CFLAGS) $?
+log_print@o@: $(srcdir)/log/log_print.c
+	 $(CC) $(CFLAGS) $?
+log_put@o@: $(srcdir)/log/log_put.c
+	 $(CC) $(CFLAGS) $?
+log_stat@o@: $(srcdir)/log/log_stat.c
+	 $(CC) $(CFLAGS) $?
+log_verify@o@: $(srcdir)/log/log_verify.c
+	 $(CC) $(CFLAGS) $?
+log_verify_auto@o@: $(srcdir)/log/log_verify_auto.c
+	 $(CC) $(CFLAGS) $?
+log_verify_int@o@: $(srcdir)/log/log_verify_int.c
+	 $(CC) $(CFLAGS) $?
+log_verify_util@o@: $(srcdir)/log/log_verify_util.c
+	 $(CC) $(CFLAGS) $?
+log_verify_stub@o@: $(srcdir)/log/log_verify_stub.c
+	 $(CC) $(CFLAGS) $?
+db_log_verify@o@: $(utildir)/db_log_verify.c
+	 $(CC) $(CFLAGS) $?
+mkpath@o@: $(srcdir)/common/mkpath.c
+	 $(CC) $(CFLAGS) $?
+mp_alloc@o@: @LOCALSRC@/mp/mp_alloc.c
+	 $(CC) $(CFLAGS) $?
+mp_bh@o@: $(srcdir)/mp/mp_bh.c
+	 $(CC) $(CFLAGS) $?
+mp_backup@o@: $(srcdir)/mp/mp_backup.c
+	 $(CC) $(CFLAGS) $?
+mp_fget@o@: @LOCALSRC@/mp/mp_fget.c
+	 $(CC) $(CFLAGS) $?
+mp_fmethod@o@: $(srcdir)/mp/mp_fmethod.c
+	 $(CC) $(CFLAGS) $?
+mp_fopen@o@: $(srcdir)/mp/mp_fopen.c
+	 $(CC) $(CFLAGS) $?
+mp_fput@o@: $(srcdir)/mp/mp_fput.c
+	 $(CC) $(CFLAGS) $?
+mp_fset@o@: @LOCALSRC@/mp/mp_fset.c
+	 $(CC) $(CFLAGS) $?
+mp_method@o@: $(srcdir)/mp/mp_method.c
+	 $(CC) $(CFLAGS) $?
+mp_mvcc@o@: $(srcdir)/mp/mp_mvcc.c
+	 $(CC) $(CFLAGS) $?
+mp_region@o@: $(srcdir)/mp/mp_region.c
+	 $(CC) $(CFLAGS) $?
+mp_register@o@: $(srcdir)/mp/mp_register.c
+	 $(CC) $(CFLAGS) $?
+mp_resize@o@: @LOCALSRC@/mp/mp_resize.c
+	 $(CC) $(CFLAGS) $?
+mp_stat@o@: $(srcdir)/mp/mp_stat.c
+	 $(CC) $(CFLAGS) $?
+mp_sync@o@: $(srcdir)/mp/mp_sync.c
+	 $(CC) $(CFLAGS) $?
+mp_trickle@o@: $(srcdir)/mp/mp_trickle.c
+	 $(CC) $(CFLAGS) $?
+mt19937db@o@: $(srcdir)/crypto/mersenne/mt19937db.c
+	 $(CC) $(CFLAGS) $?
+mut_alloc@o@: $(srcdir)/mutex/mut_alloc.c
+	 $(CC) $(CFLAGS) $?
+mut_failchk@o@: $(srcdir)/mutex/mut_failchk.c
+	 $(CC) $(CFLAGS) $?
+mut_fcntl@o@: $(srcdir)/mutex/mut_fcntl.c
+	 $(CC) $(CFLAGS) $?
+mut_method@o@: $(srcdir)/mutex/mut_method.c
+	 $(CC) $(CFLAGS) $?
+mut_pthread@o@: $(srcdir)/mutex/mut_pthread.c
+	 $(CC) $(CFLAGS) $?
+mut_region@o@: $(srcdir)/mutex/mut_region.c
+	 $(CC) $(CFLAGS) $?
+mut_stat@o@: $(srcdir)/mutex/mut_stat.c
+	 $(CC) $(CFLAGS) $?
+mut_stub@o@: $(srcdir)/mutex/mut_stub.c
+	 $(CC) $(CFLAGS) $?
+mut_tas@o@: $(srcdir)/mutex/mut_tas.c
+	 $(CC) $(CFLAGS) $?
+mut_win32@o@: $(srcdir)/mutex/mut_win32.c
+	 $(CC) $(CFLAGS) $?
+openflags@o@: $(srcdir)/common/openflags.c
+	 $(CC) $(CFLAGS) $?
+os_abs@o@: $(srcdir)/@OSDIR@/os_abs.c
+	 $(CC) $(CFLAGS) $?
+os_abort@o@: $(srcdir)/os/os_abort.c
+	 $(CC) $(CFLAGS) $?
+os_addrinfo@o@: $(srcdir)/os/os_addrinfo.c
+	$(CC) $(CFLAGS) $?
+os_alloc@o@: $(srcdir)/os/os_alloc.c
+	 $(CC) $(CFLAGS) $?
+os_clock@o@: $(srcdir)/@OSDIR@/os_clock.c
+	 $(CC) $(CFLAGS) $?
+os_config@o@: $(srcdir)/@OSDIR@/os_config.c
+	 $(CC) $(CFLAGS) $?
+os_cpu@o@: $(srcdir)/@OSDIR@/os_cpu.c
+	 $(CC) $(CFLAGS) $?
+os_ctime@o@: $(srcdir)/os/os_ctime.c
+	 $(CC) $(CFLAGS) $?
+os_dir@o@: $(srcdir)/@OSDIR@/os_dir.c
+	 $(CC) $(CFLAGS) $?
+os_errno@o@: $(srcdir)/@OSDIR@/os_errno.c
+	 $(CC) $(CFLAGS) $?
+os_fid@o@: $(srcdir)/@OSDIR@/os_fid.c
+	 $(CC) $(CFLAGS) $?
+os_flock@o@: $(srcdir)/@OSDIR@/os_flock.c
+	 $(CC) $(CFLAGS) $?
+os_fsync@o@: $(srcdir)/@OSDIR@/os_fsync.c
+	 $(CC) $(CFLAGS) $?
+os_getenv@o@: $(srcdir)/@OSDIR@/os_getenv.c
+	 $(CC) $(CFLAGS) $?
+os_handle@o@: $(srcdir)/@OSDIR@/os_handle.c
+	 $(CC) $(CFLAGS) $?
+os_map@o@: $(srcdir)/@OSDIR@/os_map.c
+	 $(CC) $(CFLAGS) $?
+os_method@o@: $(srcdir)/common/os_method.c
+	 $(CC) $(CFLAGS) $?
+os_mkdir@o@: $(srcdir)/@OSDIR@/os_mkdir.c
+	 $(CC) $(CFLAGS) $?
+os_open@o@: $(srcdir)/@OSDIR@/os_open.c
+	 $(CC) $(CFLAGS) $?
+os_path@o@: $(srcdir)/os/os_path.c
+	 $(CC) $(CFLAGS) $?
+os_pid@o@: $(srcdir)/os/os_pid.c
+	 $(CC) $(CFLAGS) $?
+os_qnx_fsync@o@: $(srcdir)/os_qnx/os_qnx_fsync.c
+	 $(CC) $(CFLAGS) $?
+os_qnx_open@o@: $(srcdir)/os_qnx/os_qnx_open.c
+	 $(CC) $(CFLAGS) $?
+os_rename@o@: $(srcdir)/@OSDIR@/os_rename.c
+	 $(CC) $(CFLAGS) $?
+os_root@o@: $(srcdir)/os/os_root.c
+	 $(CC) $(CFLAGS) $?
+os_rpath@o@: $(srcdir)/os/os_rpath.c
+	 $(CC) $(CFLAGS) $?
+os_rw@o@: $(srcdir)/@OSDIR@/os_rw.c
+	 $(CC) $(CFLAGS) $?
+os_seek@o@: $(srcdir)/@OSDIR@/os_seek.c
+	 $(CC) $(CFLAGS) $?
+os_stack@o@: $(srcdir)/os/os_stack.c
+	 $(CC) $(CFLAGS) $?
+os_stat@o@: $(srcdir)/@OSDIR@/os_stat.c
+	 $(CC) $(CFLAGS) $?
+os_tmpdir@o@: $(srcdir)/os/os_tmpdir.c
+	 $(CC) $(CFLAGS) $?
+os_truncate@o@: $(srcdir)/@OSDIR@/os_truncate.c
+	 $(CC) $(CFLAGS) $?
+os_uid@o@: $(srcdir)/os/os_uid.c
+	 $(CC) $(CFLAGS) $?
+os_unlink@o@: $(srcdir)/@OSDIR@/os_unlink.c
+	 $(CC) $(CFLAGS) $?
+os_yield@o@: $(srcdir)/@OSDIR@/os_yield.c
+	 $(CC) $(CFLAGS) $?
+partition@o@: $(srcdir)/db/partition.c
+	 $(CC) $(CFLAGS) $?
+partition_stub@o@: $(srcdir)/db/partition_stub.c
+	 $(CC) $(CFLAGS) $?
+qam@o@: $(srcdir)/qam/qam.c
+	 $(CC) $(CFLAGS) $?
+qam_auto@o@: $(srcdir)/qam/qam_auto.c
+	 $(CC) $(CFLAGS) $?
+qam_autop@o@: $(srcdir)/qam/qam_autop.c
+	 $(CC) $(CFLAGS) $?
+qam_conv@o@: $(srcdir)/qam/qam_conv.c
+	 $(CC) $(CFLAGS) $?
+qam_files@o@: $(srcdir)/qam/qam_files.c
+	 $(CC) $(CFLAGS) $?
+qam_method@o@: $(srcdir)/qam/qam_method.c
+	 $(CC) $(CFLAGS) $?
+qam_open@o@: $(srcdir)/qam/qam_open.c
+	 $(CC) $(CFLAGS) $?
+qam_rec@o@: $(srcdir)/qam/qam_rec.c
+	 $(CC) $(CFLAGS) $?
+qam_stat@o@: $(srcdir)/qam/qam_stat.c
+	 $(CC) $(CFLAGS) $?
+qam_stub@o@: $(srcdir)/qam/qam_stub.c
+	 $(CC) $(CFLAGS) $?
+qam_upgrade@o@: $(srcdir)/qam/qam_upgrade.c
+	 $(CC) $(CFLAGS) $?
+qam_verify@o@: $(srcdir)/qam/qam_verify.c
+	 $(CC) $(CFLAGS) $?
+rds_stub@o@: $(srcdir)/common/rds_stub.c
+	 $(CC) $(CFLAGS) $?
+rep_automsg@o@: $(srcdir)/rep/rep_automsg.c
+	 $(CC) $(CFLAGS) $?
+rep_backup@o@: $(srcdir)/rep/rep_backup.c
+	 $(CC) $(CFLAGS) $?
+rep_elect@o@: $(srcdir)/rep/rep_elect.c
+	 $(CC) $(CFLAGS) $?
+rep_lease@o@: $(srcdir)/rep/rep_lease.c
+	 $(CC) $(CFLAGS) $?
+rep_log@o@: $(srcdir)/rep/rep_log.c
+	 $(CC) $(CFLAGS) $?
+rep_method@o@: $(srcdir)/rep/rep_method.c
+	 $(CC) $(CFLAGS) $?
+rep_record@o@: $(srcdir)/rep/rep_record.c
+	 $(CC) $(CFLAGS) $?
+rep_region@o@: $(srcdir)/rep/rep_region.c
+	 $(CC) $(CFLAGS) $?
+rep_stub@o@: $(srcdir)/rep/rep_stub.c
+	 $(CC) $(CFLAGS) $?
+rep_stat@o@: $(srcdir)/rep/rep_stat.c
+	 $(CC) $(CFLAGS) $?
+rep_util@o@: $(srcdir)/rep/rep_util.c
+	 $(CC) $(CFLAGS) $?
+rep_verify@o@: $(srcdir)/rep/rep_verify.c
+	 $(CC) $(CFLAGS) $?
+repmgr_auto@o@: $(srcdir)/repmgr/repmgr_auto.c
+	 $(CC) $(CFLAGS) $?
+repmgr_automsg@o@: $(srcdir)/repmgr/repmgr_automsg.c
+	 $(CC) $(CFLAGS) $?
+repmgr_autop@o@: $(srcdir)/repmgr/repmgr_autop.c
+	 $(CC) $(CFLAGS) $?
+repmgr_elect@o@: $(srcdir)/repmgr/repmgr_elect.c
+	$(CC) $(CFLAGS) $?
+repmgr_method@o@: $(srcdir)/repmgr/repmgr_method.c
+	$(CC) $(CFLAGS) $?
+repmgr_msg@o@: $(srcdir)/repmgr/repmgr_msg.c
+	$(CC) $(CFLAGS) $?
+repmgr_net@o@: $(srcdir)/repmgr/repmgr_net.c
+	$(CC) $(CFLAGS) $?
+repmgr_posix@o@: $(srcdir)/repmgr/repmgr_posix.c
+	$(CC) $(CFLAGS) $?
+repmgr_queue@o@: $(srcdir)/repmgr/repmgr_queue.c
+	$(CC) $(CFLAGS) $?
+repmgr_rec@o@: $(srcdir)/repmgr/repmgr_rec.c
+	$(CC) $(CFLAGS) $?
+repmgr_sel@o@: $(srcdir)/repmgr/repmgr_sel.c
+	$(CC) $(CFLAGS) $?
+repmgr_stat@o@: $(srcdir)/repmgr/repmgr_stat.c
+	$(CC) $(CFLAGS) $?
+repmgr_stub@o@: $(srcdir)/repmgr/repmgr_stub.c
+	$(CC) $(CFLAGS) $?
+repmgr_util@o@: $(srcdir)/repmgr/repmgr_util.c
+	$(CC) $(CFLAGS) $?
+rijndael-alg-fst@o@: $(srcdir)/crypto/rijndael/rijndael-alg-fst.c
+	$(CC) $(CFLAGS) $?
+rijndael-api-fst@o@: $(srcdir)/crypto/rijndael/rijndael-api-fst.c
+	$(CC) $(CFLAGS) $?
+seq_stat@o@: $(srcdir)/sequence/seq_stat.c
+	 $(CC) $(CFLAGS) $?
+sequence@o@: $(srcdir)/sequence/sequence.c
+	 $(CC) $(CFLAGS) $?
+sha1@o@: $(srcdir)/hmac/sha1.c
+	$(CC) $(CFLAGS) $?
+stat_stub@o@: $(srcdir)/common/stat_stub.c
+	 $(CC) $(CFLAGS) $?
+txn@o@: $(srcdir)/txn/txn.c
+	 $(CC) $(CFLAGS) $?
+txn_auto@o@: $(srcdir)/txn/txn_auto.c
+	 $(CC) $(CFLAGS) $?
+txn_autop@o@: $(srcdir)/txn/txn_autop.c
+	 $(CC) $(CFLAGS) $?
+txn_chkpt@o@: $(srcdir)/txn/txn_chkpt.c
+	 $(CC) $(CFLAGS) $?
+txn_failchk@o@: $(srcdir)/txn/txn_failchk.c
+	 $(CC) $(CFLAGS) $?
+txn_method@o@: $(srcdir)/txn/txn_method.c
+	 $(CC) $(CFLAGS) $?
+txn_rec@o@: $(srcdir)/txn/txn_rec.c
+	 $(CC) $(CFLAGS) $?
+txn_recover@o@: $(srcdir)/txn/txn_recover.c
+	 $(CC) $(CFLAGS) $?
+txn_region@o@: $(srcdir)/txn/txn_region.c
+	 $(CC) $(CFLAGS) $?
+txn_stat@o@: $(srcdir)/txn/txn_stat.c
+	 $(CC) $(CFLAGS) $?
+txn_util@o@: $(srcdir)/txn/txn_util.c
+	 $(CC) $(CFLAGS) $?
+util_arg@o@: $(srcdir)/common/util_arg.c
+	 $(CC) $(CFLAGS) $?
+util_cache@o@: $(srcdir)/common/util_cache.c
+	 $(CC) $(CFLAGS) $?
+util_log@o@: $(srcdir)/common/util_log.c
+	 $(CC) $(CFLAGS) $?
+util_sig@o@: $(srcdir)/common/util_sig.c
+	 $(CC) $(CFLAGS) $?
+uts4_cc@o@: $(srcdir)/mutex/uts4_cc.s
+	$(AS) $(ASFLAGS) -o $@ $?
+xa@o@: $(srcdir)/xa/xa.c
+	$(CC) $(CFLAGS) $?
+xa_map@o@: $(srcdir)/xa/xa_map.c
+	$(CC) $(CFLAGS) $?
+zerofill@o@: $(srcdir)/common/zerofill.c
+	 $(CC) $(CFLAGS) $?
+
+##################################################
+# C++ API build rules.
+##################################################
+cxx_channel@o@: $(langdir)/cxx/cxx_channel.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_db@o@: $(langdir)/cxx/cxx_db.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_dbc@o@: $(langdir)/cxx/cxx_dbc.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_dbt@o@: $(langdir)/cxx/cxx_dbt.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_env@o@: $(langdir)/cxx/cxx_env.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_except@o@: $(langdir)/cxx/cxx_except.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_lock@o@: $(langdir)/cxx/cxx_lock.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_logc@o@: $(langdir)/cxx/cxx_logc.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_mpool@o@: $(langdir)/cxx/cxx_mpool.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_multi@o@: $(langdir)/cxx/cxx_multi.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_rid@o@: $(langdir)/cxx/cxx_rid.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_seq@o@: $(langdir)/cxx/cxx_seq.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_site@o@: $(langdir)/cxx/cxx_site.cpp
+	$(CXX) $(CXXFLAGS) $?
+cxx_txn@o@: $(langdir)/cxx/cxx_txn.cpp
+	$(CXX) $(CXXFLAGS) $?
+
+##################################################
+# Java API build rules.
+##################################################
+db_java_wrap@o@: $(langdir)/java/libdb_java/db_java_wrap.c
+	$(CC) $(CFLAGS) $(SWIGCFLAGS) $?
+
+##################################################
+# SQL API build rules.
+##################################################
+sqlite3@o@: $(langdir)/sql/generated/sqlite3.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+shell@o@: $(langdir)/sql/sqlite/src/shell.c
+	$(CC) $(CFLAGS) $(SQLFLAGS) $?
+
+##################################################
+# STL API build rules.
+##################################################
+dbstl_container@o@: $(langdir)/cxx/stl/dbstl_container.cpp
+	$(CXX) $(STLFLAGS) $?
+dbstl_resource_manager@o@: $(langdir)/cxx/stl/dbstl_resource_manager.cpp
+	$(CXX) $(STLFLAGS) $?
+
+##################################################
+# Tcl API build rules.
+##################################################
+tcl_compat@o@: $(TCL_SRCDIR)/tcl_compat.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_db@o@: $(TCL_SRCDIR)/tcl_db.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_db_pkg@o@: $(TCL_SRCDIR)/tcl_db_pkg.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_dbcursor@o@: $(TCL_SRCDIR)/tcl_dbcursor.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_env@o@: $(TCL_SRCDIR)/tcl_env.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_internal@o@: $(TCL_SRCDIR)/tcl_internal.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_lock@o@: $(TCL_SRCDIR)/tcl_lock.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_log@o@: $(TCL_SRCDIR)/tcl_log.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_mp@o@: $(TCL_SRCDIR)/tcl_mp.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_mutex@o@: $(TCL_SRCDIR)/tcl_mutex.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_rep@o@: $(TCL_SRCDIR)/tcl_rep.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_seq@o@: $(TCL_SRCDIR)/tcl_seq.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_txn@o@: $(TCL_SRCDIR)/tcl_txn.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+tcl_util@o@: $(TCL_SRCDIR)/tcl_util.c
+	$(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $?
+
+##################################################
+# Utility build rules.
+##################################################
+db_archive@o@: $(utildir)/db_archive.c
+	$(CC) $(CFLAGS) $?
+db_checkpoint@o@: $(utildir)/db_checkpoint.c
+	$(CC) $(CFLAGS) $?
+db_deadlock@o@: $(utildir)/db_deadlock.c
+	$(CC) $(CFLAGS) $?
+db_dump@o@: $(utildir)/db_dump.c
+	$(CC) $(CFLAGS) $?
+db_dump185@o@: $(utildir)/db_dump185.c
+	$(CC) $(DB185INC) $?
+db_hotbackup@o@: $(utildir)/db_hotbackup.c
+	$(CC) $(CFLAGS) $?
+db_load@o@: @LOCALUTILS@/db_load.c
+	$(CC) $(CFLAGS) $?
+db_printlog@o@: $(utildir)/db_printlog.c
+	$(CC) $(CFLAGS) $?
+db_recover@o@: $(utildir)/db_recover.c
+	$(CC) $(CFLAGS) $?
+db_replicate@o@: $(utildir)/db_replicate.c
+	$(CC) $(CFLAGS) $?
+db_stat@o@: @LOCALUTILS@/db_stat.c
+	$(CC) $(CFLAGS) $?
+db_tuner@o@: $(utildir)/db_tuner.c
+	$(CC) $(CFLAGS) $?
+db_upgrade@o@: $(utildir)/db_upgrade.c
+	$(CC) $(CFLAGS) $?
+db_verify@o@: $(utildir)/db_verify.c
+	$(CC) $(CFLAGS) $?
+
+db_sql_codegen@o@: $(utildir)/db_sql_codegen/db_sql_codegen.c
+	$(CC) $(CFLAGS) $?
+preparser@o@: $(utildir)/db_sql_codegen/preparser.c
+	$(CC) $(CFLAGS) $?
+parsefuncs@o@: $(utildir)/db_sql_codegen/parsefuncs.c
+	$(CC) $(CFLAGS) $?
+tokenize@o@: $(utildir)/db_sql_codegen/tokenize.c
+	$(CC) $(CFLAGS) $?
+buildpt@o@: $(utildir)/db_sql_codegen/buildpt.c
+	$(CC) $(CFLAGS) $?
+utils@o@: $(utildir)/db_sql_codegen/utils.c
+	$(CC) $(CFLAGS) $?
+generate@o@: $(utildir)/db_sql_codegen/generate.c
+	$(CC) $(CFLAGS) $?
+generate_test@o@: $(utildir)/db_sql_codegen/generate_test.c
+	$(CC) $(CFLAGS) $?
+generate_verification@o@: $(utildir)/db_sql_codegen/generate_verification.c
+	$(CC) $(CFLAGS) $?
+generation_utils@o@: $(utildir)/db_sql_codegen/generation_utils.c
+	$(CC) $(CFLAGS) $?
+hint_comment@o@: $(utildir)/db_sql_codegen/hint_comment.c
+	$(CC) $(CFLAGS) $?
+sqlprintf@o@: $(utildir)/db_sql_codegen/sqlite/sqlprintf.c
+	$(CC) $(CFLAGS) $?
+parse@o@: $(utildir)/db_sql_codegen/sqlite/parse.c
+	$(CC) $(CFLAGS) $?
+
+##################################################
+# C library replacement files.
+##################################################
+atoi@o@: $(srcdir)/clib/atoi.c
+	$(CC) $(CFLAGS) $?
+atol@o@: $(srcdir)/clib/atol.c
+	$(CC) $(CFLAGS) $?
+bsearch@o@: $(srcdir)/clib/bsearch.c
+	$(CC) $(CFLAGS) $?
+getcwd@o@: $(srcdir)/clib/getcwd.c
+	$(CC) $(CFLAGS) $?
+getopt@o@: $(srcdir)/clib/getopt.c
+	$(CC) $(CFLAGS) $?
+isalpha@o@: $(srcdir)/clib/isalpha.c
+	$(CC) $(CFLAGS) $?
+isdigit@o@: $(srcdir)/clib/isdigit.c
+	$(CC) $(CFLAGS) $?
+isprint@o@: $(srcdir)/clib/isprint.c
+	$(CC) $(CFLAGS) $?
+isspace@o@: $(srcdir)/clib/isspace.c
+	$(CC) $(CFLAGS) $?
+memcmp@o@: $(srcdir)/clib/memcmp.c
+	$(CC) $(CFLAGS) $?
+memcpy@o@: $(srcdir)/clib/memmove.c
+	$(CC) -DMEMCOPY $(CFLAGS) $? -o $@
+memmove@o@: $(srcdir)/clib/memmove.c
+	$(CC) -DMEMMOVE $(CFLAGS) $?
+printf@o@: $(srcdir)/clib/printf.c
+	$(CC) $(CFLAGS) $?
+qsort@o@: $(srcdir)/clib/qsort.c
+	$(CC) $(CFLAGS) $?
+raise@o@: $(srcdir)/clib/raise.c
+	$(CC) $(CFLAGS) $?
+rand@o@: $(srcdir)/clib/rand.c
+	$(CC) $(CFLAGS) $?
+strcasecmp@o@: $(srcdir)/clib/strcasecmp.c
+	$(CC) $(CFLAGS) $?
+strdup@o@: $(srcdir)/clib/strdup.c
+	$(CC) $(CFLAGS) $?
+snprintf@o@: $(srcdir)/clib/snprintf.c
+	$(CC) $(CFLAGS) $?
+strcat@o@: $(srcdir)/clib/strcat.c
+	$(CC) $(CFLAGS) $?
+strchr@o@: $(srcdir)/clib/strchr.c
+	$(CC) $(CFLAGS) $?
+strerror@o@: $(srcdir)/clib/strerror.c
+	$(CC) $(CFLAGS) $?
+strncat@o@: $(srcdir)/clib/strncat.c
+	$(CC) $(CFLAGS) $?
+strncmp@o@: $(srcdir)/clib/strncmp.c
+	$(CC) $(CFLAGS) $?
+strrchr@o@: $(srcdir)/clib/strrchr.c
+	$(CC) $(CFLAGS) $?
+strsep@o@: $(srcdir)/clib/strsep.c
+	$(CC) $(CFLAGS) $?
+strtol@o@: $(srcdir)/clib/strtol.c
+	$(CC) $(CFLAGS) $?
+strtoul@o@: $(srcdir)/clib/strtoul.c
+	$(CC) $(CFLAGS) $?
+time@o@: $(srcdir)/clib/time.c
+	$(CC) $(CFLAGS) $?
+
+##################################################
+# Performance Event Monitoring build rules
+##################################################
+
+# DTrace rules:
+# The DTrace DB provider description (db_provider.d) is included in the
+# distribution. It needs to be rebuilt when adding events to
+# $(distdir)/events.in.  The C/C++ header file db_provider.h is
+# created at configure time, and is rebuilt when db_provider.d changes.
+# It has lower-case versions of the event class and type names.
+#
+# To list the DB static probes, try:
+#	[pfexec | sudo] dtrace -l -n 'bdb$target:::'  -c "<application> <args>"
+#	[sudo] stap -l 'process(".libs/libdb-@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.so").mark("*")'
+listevents listprobes: @LISTPROBES_DEPENDENCY@
+	@LISTPROBES_COMMAND@
+
+$(DTRACE_PROVIDER): $(distdir)/gen_provider.pl $(distdir)/events.in
+	-@$(RM) $@
+	$(PERL) $(distdir)/gen_provider.pl $(distdir)/events.in > $@
+
+SED_PROVIDER_PATTERN='/^\#define[ 	]*BDB_[A-Z_]*(/y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'
+db_provider.h : $(DTRACE_PROVIDER)
+	-@$(RM) $@
+	@if test -z "$(DTRACE)" ; then echo "$@ is used only with dtrace or stap"; exit 1; fi
+	($(DTRACE) -h @DTRACE_CPP@ -I$(utildir)/dtrace -s $(DTRACE_PROVIDER) -o $@ && \
+	    $(MV) $@ $@.tmp && \
+	    $(SED) -e $(SED_PROVIDER_PATTERN) $@.tmp > $@) || $(RM) $@
+	@$(RM) $@.tmp
+
+# DTrace on platforms which require dtrace -G (e.g., Solaris) need to include
+# an extra object file when linking. This placeholder 'db_provider.lo' has a
+# special update rule which knows that the PIC object files may be in .libs.
+# If that directory exists, the object files located there are updated by a
+# separate dtrace -G call.
+#
+#	Should this be added to libtool's --mode=link step on Solaris?
+#
+DTRACE_OFILES=`echo $(DTRACE_OBJS) " " | $(SED) -e 's/\.lo /\.o /g'`
+
+db_provider@o@: db_provider.c $(DTRACE_OBJS) $(DTRACE_PROVIDER)
+	$(RM) db_provider.o .libs/db_provider.o
+	@# A compilation warning such as 'empty translation unit' is harmless.
+	$(CC) $(CFLAGS) db_provider.c
+	if test -f db_provider.o ; then \
+		$(DTRACE) -G @DTRACE_CPP@ -I$(utildir)/dtrace -s $(DTRACE_PROVIDER) $(DTRACE_OFILES) ; \
+	fi
+	if test -f .libs/db_provider.o ; then \
+	    (cd .libs && \
+	      $(DTRACE) -G @DTRACE_CPP@ -I../$(utildir)/dtrace -s ../$(DTRACE_PROVIDER) $(DTRACE_OFILES)) || \
+	      $(RM) $@ ; \
+	fi
+
+# db_provider.c is created as an empty file at configure time with
+# --enable-dtrace. If missing then configure should be re-run.
+# So far only Solaris needs it.
+db_provider.c:
+	@echo "The file db_provider@o@ is used only for configurations requiring dtrace -G"
+	@echo "Re-run configure with --enable-dtrace if needed"
+	@exit 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/RELEASE	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,40 @@
+# $Id$
+# Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+
+DB_VERSION_FAMILY=11
+DB_VERSION_LETTER="g"
+DB_VERSION_RELEASE=2
+DB_VERSION_MAJOR=5
+DB_VERSION_MINOR=4
+DB_VERSION_PATCH=0
+DB_VERSION="$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH"
+DB_VERSION_FULL="$DB_VERSION_FAMILY.$DB_VERSION_RELEASE.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH"
+
+DB_VERSION_UNIQUE_NAME=`printf "_%d%03d" $DB_VERSION_MAJOR $DB_VERSION_MINOR`
+
+DB_RELEASE_DATE="May  7, 2012"
+DB_PRODUCT_NAME="Berkeley DB"
+DB_VERSION_STRING="$DB_PRODUCT_NAME $DB_VERSION: ($DB_RELEASE_DATE)"
+DB_VERSION_FULL_STRING="$DB_PRODUCT_NAME $DB_VERSION_FAMILY$DB_VERSION_LETTER Release $DB_VERSION_RELEASE, library version $DB_VERSION_FULL: ($DB_RELEASE_DATE)"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/api_flags	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,565 @@
+# Copyright (c) 2008, 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+db_env_create
+	DB_CXX_NO_EXCEPTIONS		# C++: return error values
+
+DbEnv.backup
+	# Remove all files from the target directory tree first.
+	DB_BACKUP_CLEAN
+	DB_BACKUP_FILES			# Copy plain files too.
+	DB_BACKUP_NO_LOGS		# Don't backup log files.
+	DB_BACKUP_SINGLE_DIR		# All files go to a single directory.
+	DB_BACKUP_UPDATE		# Incremental backup.
+	DB_CREATE			# Create the target directories.
+	DB_EXCL				# Error if a target file exists.
+	
+DbEnv.close
+	# Sync database when automatically closing its db handles.
+	DB_FORCESYNC			
+
+DbEnv.dbremove
+	DB_AUTO_COMMIT			# Implied transaction
+	DB_LOG_NO_DATA			# UNDOC: Don't log the data.
+	DB_NOSYNC			# UNDOC: Don't sync for a subdb remove
+	DB_TXN_NOT_DURABLE		# UNDOC: Don't log the remove
+
+DbEnv.dbrename
+	DB_AUTO_COMMIT			# Implied transaction
+	DB_NOSYNC			# Don't sync for a subdb rename
+
+DbEnv.fileid_reset
+	DB_ENCRYPT			# File contains encrypted databases
+
+DbEnv.log_verify
+	DB_LOG_VERIFY_ERR		# Verify failed.
+	DB_LOG_VERIFY_CAF		# Continue after a failed check.
+	# Not the entire logs are verified, due to user specified log range,
+	# archiving, or other reasons. Only part of the entire logs verified.
+	DB_LOG_VERIFY_PARTIAL
+	DB_LOG_VERIFY_DBFILE		# Verify only logs of one db file.
+	# Pre-scan log from last to first record to get aborts and timestamps.
+	DB_LOG_VERIFY_FORWARD		
+	DB_LOG_VERIFY_INTERR		# Got internal error during verify.
+	DB_LOG_VERIFY_WARNING		# Got warnings during verify.
+	DB_LOG_VERIFY_VERBOSE		# Output verbose information.
+
+DbEnv.open
+	DB_CREATE			# Create as necessary
+	DB_FAILCHK			# Run failchk on open
+	DB_FAILCHK_ISALIVE		# UNDOC: failchk with isalive, for SQL
+	DB_INIT_CDB			# Concurrent Access Methods
+	DB_INIT_LOCK			# Initialize locking
+	DB_INIT_LOG			# Initialize logging
+	DB_INIT_MPOOL			# Initialize mpool
+	DB_INIT_MUTEX			# Initialize mutex
+	DB_INIT_REP			# Initialize replication
+	DB_INIT_TXN			# Initialize transactions
+	DB_LOCKDOWN			# Lock memory into physical core
+	DB_NO_CHECKPOINT		# UNDOC: Recover but do not checkpoint
+	DB_PRIVATE			# DB_ENV is process local
+	DB_RECOVER			# Run normal recovery
+	DB_RECOVER_FATAL		# Run catastrophic recovery
+	DB_REGISTER			# Multi-process registry
+	DB_SYSTEM_MEM			# Use system-backed memory
+	DB_THREAD			# Handle is free-threaded
+	DB_USE_ENVIRON			# Use the environment
+	DB_USE_ENVIRON_ROOT		# Use the environment if root
+
+DbEnv.lock_stat
+	DB_STAT_CLEAR			# Clear stats after return
+
+DbEnv.lock_stat_print
+	DB_STAT_ALL			# Everything
+	DB_STAT_ALLOC			# Print allocation information
+	DB_STAT_CLEAR			# Clear stats after return
+	DB_STAT_LOCK_CONF		# Print lock conflict matrix
+	DB_STAT_LOCK_LOCKERS		# Print lockers
+	DB_STAT_LOCK_OBJECTS		# Print lock objects
+	DB_STAT_LOCK_PARAMS		# Print lock parameters
+	DB_STAT_SUBSYSTEM		# Print subsystems
+
+DbEnv.lock_vec
+	DB_LOCK_CHECK			# UNDOC: check for a lock
+	DB_LOCK_IGNORE_REC		# UNDOC: get lock during recovery
+	DB_LOCK_NOWAIT			# Don't wait for an unavailable lock
+	DB_LOCK_RECORD			# UNDOC: record lock
+	DB_LOCK_SET_TIMEOUT		# UNDOC: set lock timeout
+	DB_LOCK_SWITCH			# UNDOC: switch existing lock
+	DB_LOCK_UPGRADE			# UNDOC: upgrade existing lock
+
+DbEnv.log_archive
+	DB_ARCH_ABS			# Absolute pathnames
+	DB_ARCH_DATA			# Data files
+	DB_ARCH_LOG			# Log files
+	DB_ARCH_REMOVE			# Remove log files
+
+DbEnv.log_put
+	DB_FLUSH			# Flush data to disk
+	DB_LOG_CHKPNT			# UNDOC: Flush supports a checkpoint
+	DB_LOG_COMMIT			# UNDOC: Flush supports a commit
+	DB_LOG_NOCOPY			# UNDOC: Don't copy data
+	DB_LOG_NOT_DURABLE		# UNDOC: Do not log; keep in memory
+	DB_LOG_WRNOSYNC			# UNDOC: Write, don't sync log_put
+
+DbEnv.log_set_config
+	DB_LOG_DIRECT			# Don't buffer log files in the OS
+	DB_LOG_DSYNC			# Set O_DSYNC on the log
+	DB_LOG_AUTO_REMOVE		# Automatically remove log files
+	DB_LOG_IN_MEMORY		# Store logs in buffers in memory
+	DB_LOG_ZERO			# Zero log file on creation
+
+DbEnv.log_stat
+	DB_STAT_CLEAR			# Clear stats after return
+
+DbEnv.log_stat_print
+	DB_STAT_ALL			# Everything
+	DB_STAT_ALLOC			# Print allocation information
+	DB_STAT_CLEAR			# Clear stats after return
+	DB_STAT_SUBSYSTEM		# Print subsystems
+
+DbEnv.lsn_reset
+	DB_ENCRYPT			# File contains encrypted databases
+
+DbEnv.memp_stat
+	DB_STAT_CLEAR			# Clear stats after return
+
+DbEnv.memp_stat_print
+	DB_STAT_ALL			# Everything
+	DB_STAT_ALLOC			# Print allocation information
+	DB_STAT_CLEAR			# Clear stats after return
+	DB_STAT_MEMP_HASH		# Print mpool hash buckets
+	DB_STAT_MEMP_NOERROR		# UNDOC: continue on error
+	DB_STAT_SUBSYSTEM		# Print subsystems
+
+DbEnv.mutex_alloc
+	DB_MUTEX_ALLOCATED		# UNDOC: Mutex currently allocated
+	DB_MUTEX_LOCKED			# UNDOC: Mutex currently locked
+	DB_MUTEX_LOGICAL_LOCK		# UNDOC: Mutex backs a database lock
+	DB_MUTEX_PROCESS_ONLY		# Mutex private to a process
+	DB_MUTEX_SELF_BLOCK		# Must be able to block self
+	DB_MUTEX_SHARED			# Shared (read/write) mutex
+
+DbEnv.mutex_stat
+	DB_STAT_CLEAR			# Clear stats after return
+
+DbEnv.mutex_stat_print
+	DB_STAT_ALL			# Everything
+	DB_STAT_ALLOC			# Print allocation information
+	DB_STAT_CLEAR			# Clear stats after return
+	DB_STAT_SUBSYSTEM		# Print subsystems
+
+DbEnv.remove
+	DB_FORCE
+	DB_USE_ENVIRON			# Use the environment
+	DB_USE_ENVIRON_ROOT		# Use the environment if root
+
+DbEnv.rep_set_config
+	DB_REPMGR_CONF_2SITE_STRICT	# Don't cheat on election votes
+	DB_REPMGR_CONF_ELECTIONS	# Manage elections to choose master
+	DB_REP_CONF_AUTOINIT		# automatic client init
+	DB_REP_CONF_AUTOROLLBACK	# UNDOC: discard txns to sync w/ master
+	DB_REP_CONF_BULK		# Bulk transfer
+	DB_REP_CONF_DELAYCLIENT		# Delay client synchronization
+	DB_REP_CONF_INMEM		# In-memory replication
+	DB_REP_CONF_LEASE		# Master leases
+	DB_REP_CONF_NOWAIT		# Don't wait, return error
+
+DbEnv.rep_set_transport
+	DB_REP_ANYWHERE			# Message can be serviced anywhere
+	DB_REP_NOBUFFER			# Do not buffer this message
+	DB_REP_PERMANENT		# Important -- app may want to flush
+	DB_REP_REREQUEST		# This msg already been requested
+
+DbEnv.rep_start
+	DB_REP_CLIENT			# Client
+	DB_REP_MASTER			# Master
+
+DbEnv.rep_stat
+	DB_STAT_CLEAR			# Clear stats after return
+
+DbEnv.rep_stat_print
+	DB_STAT_ALL			# Everything
+	DB_STAT_ALLOC			# Print allocation information
+	DB_STAT_CLEAR			# Clear stats after return
+	DB_STAT_SUBSYSTEM		# Print subsystems
+	DB_STAT_SUMMARY			# UNDOC: print summary
+
+# Covers both flags to the callback-setting method, and the callback itself
+DbEnv.repmgr_msg_dispatch
+	DB_REPMGR_NEED_RESPONSE		# Synchronous request message type
+
+DbEnv.repmgr_start
+	DB_REP_CLIENT			# Client
+	DB_REP_ELECTION			# Election
+	DB_REP_MASTER			# Master
+
+DbEnv.repmgr_stat
+	DB_STAT_CLEAR			# Clear stats after return
+
+DbEnv.repmgr_stat_print
+	DB_STAT_ALL			# Everything
+	DB_STAT_ALLOC			# Print allocation information
+	DB_STAT_CLEAR			# Clear stats after return
+	DB_STAT_SUBSYSTEM		# Print subsystems
+
+DbEnv.set_encrypt
+	DB_ENCRYPT_AES			# AES, assumes SHA1 checksum
+
+DbEnv.set_feedback.op
+	DB_RECOVER			# Running recovery.
+
+DbEnv.set_flags
+	DB_AUTO_COMMIT			# Implied transaction
+	DB_CDB_ALLDB			# Set CDB locking per environment
+	DB_DATABASE_LOCKING		# UNDOC: try database-level locking
+	DB_DIRECT_DB			# Don't buffer databases in the OS
+	DB_DSYNC_DB			# Set O_DSYNC on the databases
+	DB_HOTBACKUP_IN_PROGRESS	# Inhibit bulk loading optimization
+	DB_MULTIVERSION			# Multiversion concurrency control
+	DB_NOLOCKING			# Set locking/mutex behavior
+	DB_NOMMAP			# Don't mmap the underlying file
+	DB_NOPANIC			# Set panic state per environment
+	DB_NOFLUSH			# UNDOC: don't flush cache on close
+	DB_OVERWRITE			# Overwrite unlinked region files
+	DB_PANIC_ENVIRONMENT		# Set panic state per environment
+	DB_REGION_INIT			# Page-fault regions on open
+	DB_TIME_NOTGRANTED		# Return NOTGRANTED on timeout
+	DB_TXN_NOSYNC			# Do not sync log on commit
+	DB_TXN_NOWAIT			# Do not wait for locks
+	DB_TXN_SNAPSHOT			# Snapshot isolation
+	DB_TXN_WRITE_NOSYNC		# Write the log bug don't sync
+	DB_YIELDCPU			# Yield the CPU (a lot)
+
+DbEnv.set_isalive
+	DB_MUTEX_ALLOCATED		# UNDOC: Mutex currently allocated
+	DB_MUTEX_LOCKED			# UNDOC: Mutex currently locked
+	DB_MUTEX_LOGICAL_LOCK		# UNDOC: Mutex backs a database lock
+	DB_MUTEX_PROCESS_ONLY		# Mutex private to a process
+	DB_MUTEX_SELF_BLOCK		# Must be able to block self
+
+DbEnv.set_timeout
+	DB_SET_LOCK_TIMEOUT		# Set lock timeout
+	DB_SET_TXN_NOW			# UNDOC: Timeout lock now
+	DB_SET_TXN_TIMEOUT		# Set transaction timeout
+	DB_SET_REG_TIMEOUT		# Set dbregister timeout
+
+DbEnv.set_verbose
+	DB_VERB_BACKUP			# Backup information
+	DB_VERB_DEADLOCK		# Deadlock detection information
+	DB_VERB_FILEOPS			# Major file operations
+	DB_VERB_FILEOPS_ALL		# All file operations
+	DB_VERB_RECOVERY		# Recovery information
+	DB_VERB_REGISTER		# Dump waits-for table
+	DB_VERB_REPLICATION		# All replication and repmgr output
+	DB_VERB_REPMGR_CONNFAIL		# Repmgr connection failure output
+	DB_VERB_REPMGR_MISC		# Miscellaneous repmgr output
+	DB_VERB_REP_ELECT		# Replication election output
+	DB_VERB_REP_LEASE		# Replication master lease output
+	DB_VERB_REP_MISC		# Miscellaneous replication output
+	DB_VERB_REP_MSGS		# Replication message output
+	DB_VERB_REP_SYNC		# Replication client sync output
+	DB_VERB_REP_SYSTEM		# Replication system messages
+	DB_VERB_REP_TEST		# Replication temporary test output
+	DB_VERB_WAITSFOR		# Dump waits-for table
+
+DbEnv.stat_print
+	DB_STAT_ALL			# Everything
+	DB_STAT_ALLOC			# Print allocation information
+	DB_STAT_CLEAR			# Clear stats after return
+	DB_STAT_SUBSYSTEM		# Print subsystems
+
+DbEnv.txn_begin
+	DB_IGNORE_LEASE			# UNDOC: Ignore leases
+	DB_READ_COMMITTED		# Degree 2 isolation
+	DB_READ_UNCOMMITTED		# Degree 1 isolation
+	DB_TXN_NOSYNC			# Do not sync log on commit
+	DB_TXN_NOWAIT			# Do not wait for locks
+	DB_TXN_FAMILY			# Cursors and child txns are
+					# independent but lock-compatible
+	DB_TXN_SNAPSHOT			# Snapshot isolation
+	DB_TXN_SYNC			# Always sync log on commit
+	DB_TXN_WAIT			# Always wait for locks in this txn
+	DB_TXN_WRITE_NOSYNC		# Write the log but don't sync
+	DB_TXN_BULK			# Enable transactional bulk loading 
+
+DbEnv.txn_checkpoint
+	DB_CKP_INTERNAL			# UNDOC: internally generated checkpoint
+	DB_FORCE			# Force
+
+DbEnv.txn_recover
+	__MASK=0xff			# Berkeley DB operation codes.
+
+DbEnv.txn_stat
+	DB_STAT_CLEAR			# Clear stats after return
+
+DbEnv.txn_stat_print
+	DB_STAT_ALL			# Everything
+	DB_STAT_ALLOC			# Print allocation information
+	DB_STAT_CLEAR			# Clear stats after return
+	DB_STAT_SUBSYSTEM		# Print subsystems
+
+DbLogc.get
+	__MASK=0xff			# Berkeley DB operation codes.
+
+DbMpoolFile.close
+	DB_MPOOL_DISCARD		# UNDOC: Discard file
+	DB_FLUSH			# UNDOC: opened to flush a page
+	DB_MPOOL_NOLOCK			# UNDOC: Already have mpf locked
+
+DbMpoolFile.get
+	DB_MPOOL_CREATE			# Create a page
+	DB_MPOOL_DIRTY			# Get page for an update
+	DB_MPOOL_EDIT			# Modify without copying
+	DB_MPOOL_FREE			# UNDOC: Free page if present
+	DB_MPOOL_LAST			# Return the last page
+	DB_MPOOL_NEW			# Create a new page
+	DB_MPOOL_TRY			# Try to read a page, but don't block
+
+DbMpoolFile.open
+	DB_CREATE			# Create as necessary
+	DB_DIRECT			# Don't buffer the file in the OS
+	DB_DURABLE_UNKNOWN		# UNDOC: Durability on open
+	DB_EXTENT			# UNDOC: dealing with an extent
+	DB_FLUSH			# UNDOC: opened to flush a page
+	DB_MULTIVERSION			# Multiversion concurrency control
+	DB_NOMMAP			# Don't mmap underlying file
+	DB_ODDFILESIZE			# Truncate file to N * pgsize
+	DB_RDONLY			# Read-only (O_RDONLY)
+	DB_TXN_NOT_DURABLE		# UNDOC: Mark file not durable on open
+
+DbMpoolFile.set_flags
+	DB_MPOOL_NOFILE			# Never open a backing file
+	DB_MPOOL_UNLINK			# Unlink the file on last close
+
+DbSequence.get
+	DB_AUTO_COMMIT			# UNDOC: compatibility only
+	DB_TXN_NOSYNC			# Do not sync log on commit
+
+DbSequence.open
+	DB_AUTO_COMMIT			# UNDOC: compatibility only
+	DB_CREATE			# Create as necessary
+	DB_EXCL				# Exclusive open (O_EXCL)
+	DB_THREAD			# Handle is free-threaded
+
+DbSequence.remove
+	DB_TXN_NOSYNC			# Do not sync log on commit
+
+DbSequence.set_flags
+	DB_SEQ_DEC			# Decrement sequence
+	DB_SEQ_INC			# Increment sequence
+	DB_SEQ_RANGE_SET		# UNDOC: Range set
+	DB_SEQ_WRAP			# Wrap sequence at min/max
+	DB_SEQ_WRAPPED			# UNDOC: Just wrapped
+
+DbSequence.stat
+	DB_STAT_CLEAR			# Clear stats after return
+
+DbSequence.stat_print
+	DB_STAT_CLEAR			# Clear stats after return
+	DB_STAT_SUBSYSTEM		# Print subsystems
+
+DbSite.set_config
+	DB_BOOTSTRAP_HELPER		# Join target for new group member
+	DB_GROUP_CREATOR		# Primordial membership DB creator
+	DB_LEGACY			# Upgrading pre-5.2 group
+	DB_LOCAL_SITE			# Identifies this as the local site
+	DB_REPMGR_PEER			# C2C synchronization
+
+DbTxn.commit
+	DB_TXN_NOSYNC			# Do not sync log on commit
+	DB_TXN_SYNC			# Always sync log on commit
+
+DbTxn.set_timeout
+	DB_SET_LOCK_TIMEOUT		# Set lock timeout
+	DB_SET_TXN_TIMEOUT		# Set transaction timeout
+
+db_create
+	DB_CXX_NO_EXCEPTIONS		# C++: return error values
+	DB_XA_CREATE			# Create a DBP for an XA database
+
+Db.associate
+	DB_AUTO_COMMIT			# UNDOC: compatibility only
+	DB_CREATE			# Create as necessary
+	DB_IMMUTABLE_KEY		# Secondary key is immutable
+
+Db.associate_foreign
+	DB_FOREIGN_ABORT		# If foreign key exists, delete aborts
+	DB_FOREIGN_CASCADE		# If foreign key exists, delete cascades
+	DB_FOREIGN_NULLIFY		# If foreign key exists, nullify it
+
+Db.close
+	DB_NOSYNC			# Berkeley DB operation codes.
+
+Db.compact
+	DB_FREELIST_ONLY		# Just sort and truncate
+	DB_FREE_SPACE			# Free space
+
+Db.cursor
+	DB_CURSOR_BULK			# Optimize for bulk updates
+	DB_CURSOR_TRANSIENT		# UNDOC: Single-use cursor
+	DB_READ_COMMITTED		# Degree 2 isolation
+	DB_READ_UNCOMMITTED		# Degree 1 isolation
+	DB_RECOVER			# Called from recovery (internal)
+	DB_WRITECURSOR			# Cursor can update (CDB)
+	DB_WRITELOCK			# Cursor should get write locks
+	DB_TXN_SNAPSHOT			# Snapshot isolation
+
+Db.del
+	DB_AUTO_COMMIT			# UNDOC: compatibility only
+	DB_MULTIPLE			# Delete multiple data values
+	DB_MULTIPLE_KEY			# Delete multiple key/data pairs
+
+Db.exists
+	DB_READ_COMMITTED		# Degree 2 isolation
+	DB_READ_UNCOMMITTED		# Degree 1 isolation
+	DB_RMW				# Acquire write lock immediately
+
+Db.get
+	__MASK=0xff			# Berkeley DB operation codes.
+	DB_AUTO_COMMIT			# UNDOC: compatibility only
+	DB_IGNORE_LEASE			# Ignore leases
+	DB_MULTIPLE			# Return multiple data values
+	DB_READ_COMMITTED		# Degree 2 isolation
+	DB_READ_UNCOMMITTED		# Degree 1 isolation
+	DB_RMW				# Acquire write lock immediately
+
+Db.pget
+	__MASK=0xff			# Berkeley DB operation codes.
+	DB_IGNORE_LEASE			# Ignore leases
+	DB_MULTIPLE			# Return multiple data values
+	DB_READ_COMMITTED		# Degree 2 isolation
+	DB_READ_UNCOMMITTED		# Degree 1 isolation
+	DB_RMW				# Acquire write lock immediately
+
+Db.join
+	DB_JOIN_NOSORT			# Don't try to optmize join
+
+Db.open
+	DB_AUTO_COMMIT			# Implied transaction
+	DB_CREATE			# Create file as necessary
+	DB_EXCL				# Exclusive open (O_EXCL)
+	DB_FCNTL_LOCKING		# UNDOC: fcntl(2) locking
+	DB_MULTIVERSION			# Multiversion concurrency control
+	DB_NOMMAP			# Don't mmap underlying file
+	DB_NO_AUTO_COMMIT		# UNDOC: override env's AUTO_COMMIT
+	DB_RDONLY			# Read-only (O_RDONLY)
+	DB_RDWRMASTER			# UNDOC: allow subdb master open R/W
+	DB_READ_UNCOMMITTED		# Degree 1 isolation
+	DB_THREAD			# Handle is free-threaded
+	DB_TRUNCATE			# Discard existing DB (O_TRUNC)
+
+	# The following flags aren't actually part of the Db.open method
+	# API, but they are accepted by the underlying __db_open function.
+	DB_DURABLE_UNKNOWN		# UNDOC: Durability on open
+	DB_INTERNAL_PERSISTENT_DB	# UNDOC: Open db in metadata dir
+	DB_INTERNAL_TEMPORARY_DB	# UNDOC: Open db in env home dir
+	DB_NOERROR			# UNDOC: Don't raise errors.
+	DB_ODDFILESIZE			# UNDOC: Truncate file to N * pgsize
+	DB_WRITEOPEN			# UNDOC: open with write lock
+
+	# The following flags are DB constructor flags.  However, create and/or
+	# open of BDB XML containers is done in a single call (rather than the
+	# two-call "construct the object, then open it" paradigm used by DB),
+	# and they can't collide for that reason.
+	DB_CXX_NO_EXCEPTIONS		# C++: return error values
+
+Db.put
+	__MASK=0xff			# Berkeley DB operation codes.
+	DB_AUTO_COMMIT			# UNDOC: compatibility only
+	DB_MULTIPLE			# Put multiple (from key and data DBTs)
+	DB_MULTIPLE_KEY			# Put multiple (from key DBT)
+
+Db.set_encrypt
+	DB_ENCRYPT_AES			# AES, assumes SHA1 checksum
+
+Db.set_feedback
+	DB_UPGRADE			# Upgrading
+	DB_VERIFY			# Verifying
+
+Db.set_flags
+	DB_CHKSUM			# Checksums
+	DB_DUP				# Btree, Hash: duplicate keys
+	DB_DUPSORT			# Btree, Hash: sorted duplicated
+	DB_ENCRYPT			# AES, assumes SHA1 checksum
+	DB_INORDER			# Queue: strict ordering on consume
+	DB_RECNUM			# Btree: record numbers
+	DB_RENUMBER			# Recno: renumber on insert/delete
+	DB_REVSPLITOFF			# Btree: turn off reverse splits
+	DB_SNAPSHOT			# Recno: snapshot the input
+	DB_TXN_NOT_DURABLE		# Do not log changes
+
+Db.stat
+	DB_FAST_STAT			# Don't traverse the database
+	DB_READ_COMMITTED		# Degree 2 isolation
+	DB_READ_UNCOMMITTED		# Degree 1 isolation
+
+Db.truncate
+	DB_AUTO_COMMIT			# UNDOC: compatibility only
+
+Db.upgrade
+	DB_DUPSORT			# Upgrade duplicate data items
+
+Db.verify
+	DB_AGGRESSIVE			# Salvage whatever could be data
+	DB_NOORDERCHK			# Skip sort order/hashing check
+	DB_ORDERCHKONLY			# Only perform the order check
+	DB_PRINTABLE			# Use printable format for salvage
+	DB_PR_PAGE			# UNDOC: Show page contents (-da)
+	DB_PR_RECOVERYTEST		# UNDOC: Recover test (-dr)
+	DB_SALVAGE			# Salvage what looks like data
+	DB_UNREF			# UNDOC: Report unreferenced pages
+	DB_VERIFY_PARTITION		# Verifying a partition
+
+	# Flags understood by the btree structure checks (__bam_vrfy_subtree).
+	# These share the same space as the global flags to Db.verify.
+	DB_ST_DUPOK			# UNDOC: Duplicates are acceptable
+	DB_ST_DUPSET			# UNDOC: Subtree is in a duplicate tree
+	DB_ST_DUPSORT			# UNDOC: Duplicates are sorted
+	DB_ST_IS_RECNO			# UNDOC: Subtree is a recno
+	DB_ST_OVFL_LEAF			# UNDOC: Overflow reffed from leaf page
+	DB_ST_RECNUM			# UNDOC: Subtree has record numbering on
+	DB_ST_RELEN			# UNDOC: Subtree has fixed-length recs
+	DB_ST_TOPLEVEL			# UNDOC: Subtree == entire tree
+
+	# Flags understood by __bam_salvage and __db_salvage.  These need not
+	# share name space with the __bam_vrfy_subtree flags, but must share
+	# with Db.verify.
+	DB_SA_SKIPFIRSTKEY		# UNDOC: I have no idea what this does.
+	DB_SA_UNKNOWNKEY		# UNDOC: The salvage key is unknown
+
+DbCursor.dup
+	__MASK=0xff			# Berkeley DB operation codes.
+	DB_SHALLOW_DUP			# UNDOC: Don't duplicate compression info
+
+DbCursor.get
+	__MASK=0xff			# Berkeley DB operation codes.
+	DB_IGNORE_LEASE			# Ignore leases
+	DB_MULTIPLE			# Return multiple data values
+	DB_MULTIPLE_KEY			# Return multiple key/data pairs
+	DB_READ_COMMITTED		# Degree 2 isolation
+	DB_READ_UNCOMMITTED		# Degree 1 isolation
+	DB_RMW				# Acquire write lock immediately
+
+DbCursor.put
+	__MASK=0xff			# Berkeley DB operation codes.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/api_flags.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,466 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+typedef struct {
+	char	*name;			/* API name */
+
+	u_int	used_mask;		/* Bits used. */
+} API;
+API	**api_list, **api_end;
+
+typedef struct {
+	char	 *name;			/* Flag name */
+
+	int	api_cnt;		/* APIs that use this flag. */
+	API	**api, **api_end;
+
+	u_int	value;			/* Bit value */
+} FLAG;
+FLAG	**flag_list, **flag_end;
+
+int	verbose;
+char	*progname;
+
+int	add_entry(char *, char *);
+void	define_print(char *, u_int);
+void	dump_api(void);
+void	dump_flags(void);
+int	flag_cmp_alpha(const void *, const void *);
+int	flag_cmp_api_cnt(const void *, const void *);
+int	generate_flags(void);
+int	parse(void);
+void	print_api_mask(void);
+void	print_api_remainder(void);
+void	print_flag_value(void);
+int	syserr(void);
+int	usage(void);
+
+int
+main(int argc, char *argv[])
+{
+	enum { API_MASK, API_REMAINDER, FLAG_VALUE } output;
+	int ch;
+
+	if ((progname = strrchr(argv[0], '/')) == NULL)
+		progname = argv[0];
+	else
+		++progname;
+
+	output = FLAG_VALUE;
+	while ((ch = getopt(argc, argv, "mrv")) != EOF)
+		switch (ch) {
+		case 'm':
+			output = API_MASK;
+			break;
+		case 'r':
+			output = API_REMAINDER;
+			break;
+		case 'v':
+			verbose = 1;
+			break;
+		case '?':
+		default:
+			return (usage());
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (parse() || generate_flags())
+		return (EXIT_FAILURE);
+
+	switch (output) {
+	case API_MASK:
+		print_api_mask();
+		break;
+	case API_REMAINDER:
+		print_api_remainder();
+		break;
+	case FLAG_VALUE:
+		print_flag_value();
+		break;
+	}
+
+	if (verbose) {
+		dump_api();
+		dump_flags();
+	}
+
+	return (EXIT_SUCCESS);
+}
+
+int
+parse()
+{
+	int lc;
+	char *p, *api, buf[256];
+
+	api = NULL;
+
+	/*
+	 * Read the method name/flag pairs.
+	 */
+	for (lc = 1; fgets(buf, sizeof(buf), stdin) != NULL; ++lc) {
+		if ((p = strchr(buf, '\n')) != NULL)
+			*p = '\0';
+		else {
+			fprintf(
+			    stderr, "%s: %d: line too long\n", progname, lc);
+			return (1);
+		}
+
+		/* Ignore any empty line or hash mark. */
+		if (buf[0] == '\0' || buf[0] == '#')
+			continue;
+
+		/*
+		 * A line without leading whitespace is an API name, a line
+		 * with leading whitespace is a flag name.
+		 */
+		if (isspace(buf[0])) {
+			if ((p = strtok(buf, " \t")) == NULL || *p == '#')
+				continue;
+
+			/* A flag without an API makes no sense. */
+			if (api == NULL)
+				goto format;
+
+			/* Enter the pair into the array. */
+			if (add_entry(api, p))
+				return (1);
+		} else {
+			if ((p = strtok(buf, " \t")) == NULL)
+				continue;
+			if (api != NULL)
+				free(api);
+			if ((api = strdup(p)) == NULL)
+				return (syserr());
+		}
+		if ((p = strtok(NULL, " \t")) != NULL && *p != '#')
+			goto format;
+	}
+
+	return (0);
+
+format:	fprintf(stderr, "%s: format error: line %d\n", progname, lc);
+	return (1);
+}
+
+int
+add_entry(char *api_name, char *flag_name)
+{
+	FLAG **fpp, *fp;
+	API **app, *ap, **p;
+	u_int cnt;
+
+	/* Search for this api's API structure. */
+	for (app = api_list;
+	    app != NULL && *app != NULL && app < api_end; ++app)
+		if (strcmp(api_name, (*app)->name) == 0)
+			break;
+
+	/* Allocate new space in the API array if necessary. */
+	if (app == NULL || app == api_end) {
+		cnt = app == NULL ? 100 : (u_int)(api_end - api_list) + 100;
+		if ((api_list = realloc(api_list, sizeof(API *) * cnt)) == NULL)
+			return (syserr());
+		api_end = api_list + cnt;
+		app = api_list + (cnt - 100);
+		memset(app, 0, (u_int)(api_end - app) * sizeof(API *));
+	}
+
+	/* Allocate a new API structure and fill in the name if necessary. */
+	if (*app == NULL &&
+	    ((*app = calloc(sizeof(API), 1)) == NULL ||
+	    ((*app)->name = strdup(api_name)) == NULL))
+		return (syserr());
+
+	ap = *app;
+
+	/*
+	 * There's a special keyword, "__MASK=<value>" that sets the initial
+	 * flags value for an API, and so prevents those flag bits from being
+	 * chosen for that API's flags.
+	 */
+	if (strncmp(flag_name, "__MASK=", sizeof("__MASK=") - 1) == 0) {
+		ap->used_mask |=
+		    strtoul(flag_name + sizeof("__MASK=") - 1, NULL, 0);
+		return (0);
+	}
+
+	/* Search for this flag's FLAG structure. */
+	for (fpp = flag_list;
+	    fpp != NULL && *fpp != NULL && fpp < flag_end; ++fpp)
+		if (strcmp(flag_name, (*fpp)->name) == 0)
+			break;
+
+	/* Realloc space in the FLAG array if necessary. */
+	if (fpp == NULL || fpp == flag_end) {
+		cnt = fpp == NULL ? 100 : (u_int)(flag_end - flag_list) + 100;
+		if ((flag_list =
+		    realloc(flag_list, sizeof(FLAG *) * cnt)) == NULL)
+			return (syserr());
+		flag_end = flag_list + cnt;
+		fpp = flag_list + (cnt - 100);
+		memset(fpp, 0, (u_int)(flag_end - fpp) * sizeof(FLAG *));
+	}
+
+	/* Allocate a new FLAG structure and fill in the name if necessary. */
+	if (*fpp == NULL &&
+	    ((*fpp = calloc(sizeof(FLAG), 1)) == NULL ||
+	    ((*fpp)->name = strdup(flag_name)) == NULL))
+		return (syserr());
+
+	fp = *fpp;
+	++fp->api_cnt;
+
+	/* Check to see if this API is already listed for this flag. */
+	for (p = fp->api; p != NULL && *p != NULL && p < fp->api_end; ++p)
+		if (strcmp(api_name, (*p)->name) == 0) {
+			fprintf(stderr,
+			    "duplicate entry: %s / %s\n", api_name, flag_name);
+			return (1);
+		}
+
+	/* Realloc space in the FLAG's API array if necessary. */
+	if (p == NULL || p == fp->api_end) {
+		cnt = p == NULL ? 20 : (u_int)(fp->api_end - fp->api) + 20;
+		if ((fp->api = realloc(fp->api, sizeof(API *) * cnt)) == NULL)
+			return (syserr());
+		fp->api_end = fp->api + cnt;
+		p = fp->api + (cnt - 20);
+		memset(p, 0, (u_int)(fp->api_end - fp->api) * sizeof(API *));
+	}
+	*p = ap;
+
+	return (0);
+}
+
+void
+dump_api()
+{
+	API **app;
+
+	printf("=============================\nAPI:\n");
+	for (app = api_list; *app != NULL; ++app)
+		printf("%s (%#x)\n", (*app)->name, (*app)->used_mask);
+}
+
+void
+dump_flags()
+{
+	FLAG **fpp;
+	API **api;
+	char *sep;
+
+	printf("=============================\nFLAGS:\n");
+	for (fpp = flag_list; *fpp != NULL; ++fpp) {
+		printf("%s (%#x, %d): ",
+		    (*fpp)->name, (*fpp)->value, (*fpp)->api_cnt);
+		sep = "";
+		for (api = (*fpp)->api; *api != NULL; ++api) {
+			printf("%s%s", sep, (*api)->name);
+			sep = ", ";
+		}
+		printf("\n");
+	}
+}
+
+int
+flag_cmp_api_cnt(const void *a, const void *b)
+{
+	FLAG *af, *bf;
+
+	af = *(FLAG **)a;
+	bf = *(FLAG **)b;
+
+	if (af == NULL) {
+		if (bf == NULL)
+			return (0);
+		return (1);
+	}
+	if (bf == NULL) {
+		if (af == NULL)
+			return (0);
+		return (-1);
+	}
+	if (af->api_cnt > bf->api_cnt)
+		return (-1);
+	if (af->api_cnt < bf->api_cnt)
+		return (1);
+	return (strcmp(af->name, bf->name));
+}
+
+int
+generate_flags()
+{
+	FLAG **fpp;
+	API **api;
+	u_int mask;
+
+	/* Sort the FLAGS array by reference count, in reverse order. */
+	qsort(flag_list,
+	    (u_int)(flag_end - flag_list), sizeof(FLAG *), flag_cmp_api_cnt);
+
+	/*
+	 * Here's the plan: walk the list of flags, allocating bits.  For
+	 * each flag, we walk the list of APIs that use it and find a bit
+	 * none of them are using.  That bit becomes the flag's value.
+	 */
+	for (fpp = flag_list; *fpp != NULL; ++fpp) {
+		mask = 0xffffffff;			/* Set to all 1's */
+		for (api = (*fpp)->api; *api != NULL; ++api)
+			mask &= ~(*api)->used_mask;	/* Clear API's bits */
+		if (mask == 0) {
+			fprintf(stderr, "%s: ran out of bits at flag %s\n",
+			   progname, (*fpp)->name);
+			return (1);
+		}
+		(*fpp)->value = mask = 1 << (ffs(mask) - 1);
+		for (api = (*fpp)->api; *api != NULL; ++api)
+			(*api)->used_mask |= mask;	/* Set bit for API */
+	}
+
+	return (0);
+}
+
+int
+flag_cmp_alpha(const void *a, const void *b)
+{
+	FLAG *af, *bf;
+
+	af = *(FLAG **)a;
+	bf = *(FLAG **)b;
+
+	if (af == NULL) {
+		if (bf == NULL)
+			return (0);
+		return (1);
+	}
+	if (bf == NULL) {
+		if (af == NULL)
+			return (0);
+		return (-1);
+	}
+	return (strcmp(af->name, bf->name));
+}
+
+void
+print_api_mask()
+{
+	API **app;
+	char *p, buf[256];
+
+	/* Output a mask for the API. */
+	for (app = api_list; *app != NULL; ++app) {
+		(void)snprintf(
+		    buf, sizeof(buf), "_%s_API_MASK", (*app)->name);
+		for (p = buf; *p != '\0'; ++p)
+			if (islower(*p))
+				*p = toupper(*p);
+			else if (!isalpha(*p))
+				*p = '_';
+		define_print(buf, (*app)->used_mask);
+	}
+}
+
+void
+print_api_remainder()
+{
+	API **app;
+	int unused, i;
+
+	/* Output the bits remaining for the API. */
+	for (app = api_list; *app != NULL; ++app) {
+		for (i = unused = 0; i < 32; ++i)
+			if (!((*app)->used_mask & (1 << i)))
+				++unused;
+		printf("%s: %d bits unused\n", (*app)->name, unused);
+	}
+}
+
+void
+print_flag_value()
+{
+	FLAG **fpp;
+
+	/* Sort the FLAGS array in alphabetical order. */
+	qsort(flag_list,
+	    (u_int)(flag_end - flag_list), sizeof(FLAG *), flag_cmp_alpha);
+
+	/* Output each flag's value. */
+	for (fpp = flag_list; *fpp != NULL; ++fpp)
+		define_print((*fpp)->name, (*fpp)->value);
+}
+
+void
+define_print(char *name, u_int value)
+{
+	char *sep;
+
+	switch (strlen(name) / 8) {
+	case 0:
+		sep = "\t\t\t\t\t";
+		break;
+	case 1:
+		sep = "\t\t\t\t";
+		break;
+	case 2:
+		sep = "\t\t\t";
+		break;
+	case 3:
+		sep = "\t\t";
+		break;
+	default:
+		sep = "\t";
+		break;
+	}
+	printf("#define\t%s%s%#010x\n", name, sep, value);
+}
+
+int
+syserr(void)
+{
+	fprintf(stderr, "%s: %s\n", progname, strerror(errno));
+	return (1);
+}
+
+int
+usage()
+{
+	(void)fprintf(stderr, "usage: %s [-mrv]\n", progname);
+	return (EXIT_FAILURE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/buildpkg	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,267 @@
+#!/bin/sh
+# Copyright (c) 2009, 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+# $Id: $
+#
+die()
+{
+	echo >&2 "$@"
+	exit 1
+}
+
+# Build the distribution package.
+. ./RELEASE || die "Can't read the RELEASE file"
+
+CSHARP_DOC_SRC=""
+# 0 is none, 1 is local dir, 2 is remote dir
+CSHARP_DOC_LOCATION=0
+test_run=0
+
+while [ $# -gt 0 ]
+do
+	case "$1" in
+	-n)
+		nodocs=true;;
+	-csharp_doc_src)
+		shift
+		if [ ! $# -gt 0 ]; then
+	       		die "csharp_doc_dir param requires argument."
+		fi
+		CSHARP_DOC_SRC=$1
+		CSHARP_DOC_LOCATION=1
+		if [ ! -f $CSHARP_DOC_SRC ]; then
+			die "CSharp doc archive must exist."
+		fi;;
+	-csharp_doc_url)
+		shift
+		if [ ! $# -gt 0 ]; then
+	       		die "csharp_doc_dir param requires argument."
+		fi
+		CSHARP_DOC_SRC=$1
+		CSHARP_DOC_LOCATION=2;;
+	-test)
+		echo "Doing a test run - this may contain changes that aren't\
+reflected in a tag, so the package won't be reproducible."
+		test_run=1;;
+	esac
+	shift
+done
+
+# A version string can be specified on the command line (e.g., "20080219").
+# Otherwise, use the standard X.X.X format.
+VERSION=${1:-${DB_VERSION_MAJOR}.${DB_VERSION_MINOR}.${DB_VERSION_PATCH}}
+
+# Use "ustar" as the archiver
+TAR=ustar
+
+# Set root directory where we do the work, can be anywhere.
+START_DIR=`pwd`
+D=`pwd`/../release
+R="$D/db-${VERSION}"
+RNC="$D/db-$VERSION.NC"
+DOCS=`pwd`/../../docs_books
+DB_ADDONS=`pwd`/../../db_addons
+
+if [ ! -d $DB_ADDONS ]; then
+	echo "buildpkg requires a db_addons repository at the same level as the db repository."
+	exit 1
+fi
+
+# Create directory, remove any previous release tree.
+rm -rf $R $RNC
+mkdir -p $R
+
+echo "Removed old release build from $R"
+
+# Copy the files in the current tip to $R
+hg archive $R
+
+# If doing a test run, apply any local changes to the new tree.
+if [ $test_run != 0 ]; then
+	hg diff | patch -p1 -d $R
+fi
+
+echo "Created hg archive in $R"
+
+if [ "$nodocs" = true ] ; then
+	rm -rf $R/docs
+else
+	[ -d $DOCS ] || die "buildpkg requires a docs_books repository at the same level as the db repository."
+
+	# Check that the doc repo is up to date, and create a tag if necessary.
+	cd $DOCS
+	hg pull -u
+	if [ $? != 0 ]; then
+		rm -rf $R
+		die "Failed updating the docs_books repository."
+	fi
+	has_tag=`hg tags | grep "db-${VERSION}"`
+	if [ "$has_tag" = "" ]; then
+		hg tag "db-${VERSION}"
+		TAG_CREATED="true"
+	else
+		hg up -r "db-${VERSION}"
+	fi
+
+	# Build a copy of the documentation in the release tree.
+	cd $R/dist
+	sh s_docs db-${VERSION} $DOCS
+
+	if [ $? != 0 ]; then
+		rm -rf $R
+		die "Failed generating documentation."
+	fi
+
+	# Copy in the C sharp doc.
+	if [ $CSHARP_DOC_LOCATION -eq 2 ]; then
+		scp $CSHARP_DOC_SRC .
+		CSHARP_DOC_SRC="csharp_docs.tgz"
+		if [ ! -f $CSHARP_DOC_SRC ]; then
+			echo "WARNING: Invalid csharp doc file - csharp_docs.tgz expected."
+		fi
+	fi
+	if [ $CSHARP_DOC_LOCATION -eq 0 -o ! -f $CSHARP_DOC_SRC ]; then
+		echo "WARNING: No csharp docs, skipping."
+		CSHARP_DOC_LOCATION=0
+	fi
+	if [ $CSHARP_DOC_LOCATION != 0 ]; then
+		rm -rf $R/docs/csharp
+		mkdir -p $R/docs/csharp
+		$TAR zxf $CSHARP_DOC_SRC -C $R/docs/csharp
+	fi
+
+	# Build the Java documentation.
+	cd $R/dist && sh s_javadoc
+fi
+
+# Pull a copy of the JDBC and ODBC libraries into the package.
+# Build the ADO.NET package, including moving the ADO.NET doc built above
+# into that package.
+# Tell the script where to look for packages.
+cd $R/dist && sh s_sql_drivers -addons ../../../..
+# Warn if s_sql_drivers didn't move its docs.
+if [ -e "$R/docs/bdb-sql-ado" ]; then
+	echo "WARNING: ADO.NET doc is still in the non ADO.NET package."
+fi
+
+cd $START_DIR
+
+# Pull a copy of the bfile directory into the package.
+cd $DB_ADDONS
+hg pull -u
+if [ $? != 0 ]; then
+	echo "Failed updating the db_addons repository. Exiting."
+	rm -rf $R
+	exit 1
+fi
+
+cd $START_DIR
+SQL_EXT_DIR=$R/lang/sql/sqlite/ext
+if [ ! -d $SQL_EXT_DIR ]; then
+	mkdir -p $SQL_EXT_DIR
+fi
+if [ -d $SQL_EXT_DIR/bfile ]; then
+	rm -rf $SQL_EXT_DIR/bfile
+fi
+cp -rp $DB_ADDONS/bfile $SQL_EXT_DIR
+
+# Remove source directories we don't distribute.
+cd $R && rm -rf test/tcl/TODO test/upgrade test/scr036 test/erlang
+cd $R && rm -rf test/perf test/purify test/repmgr
+cd $R && rm -rf test/server test/stl test/vxworks
+cd $R && find . -name '.hg*' | xargs rm -f
+cd $R && find . -name 'tags' | xargs rm -f
+
+# Create symbolic links and cscope output, fix permissions.
+#cd $R/dist && sh s_perm
+#cd $R/dist && sh s_cscope
+
+# Build a regular version and smoke test.
+### cd $R && rm -rf build_run && mkdir build_run
+### cd $R/build_run && ../dist/configure && make >& mklog
+### cd $R/build_run && make ex_access && echo "test" | ./ex_access
+# Check the install
+### cd $R/build_run && make prefix=`pwd`/BDB install
+
+# Build a small-footprint version and smoke test.
+### cd $R && rm -rf build_run && mkdir build_run
+### cd $R/build_run && ../dist/configure --enable-smallbuild && make >& mklog
+### cd $R/build_run && make ex_access && echo "test" | ./ex_access
+
+# Remove the build directory
+### cd $R && rm -rf build_run
+
+(cd $R/dist && ./s_perm)
+
+# Check for file names differing only in case.
+cd $R && find . | sort -f | uniq -ic | sed '/1 /d'
+
+# Create the crypto tar archive release.
+T="$D/db-$VERSION.tar.gz"
+rm -f $T
+cd $D || die "Can't find $D"
+# Move package files in db-$VERSION/release to current directory so that
+# regular packages won't includes generated package twice.
+if [ -d "db-$VERSION/release" ]; then
+	mv db-$VERSION/release/* .
+	rm -rf db-$VERSION/release
+fi
+$TAR czf $T -find db-$VERSION -chown 100 -chgrp 100
+chmod 444 $T
+
+# Create the non-crypto tree.
+cd $D && mv -i db-$VERSION $RNC && $TAR xzf $T
+cd $RNC/dist && sh s_crypto
+
+(cd $RNC/dist && ./s_perm)
+
+# Create the non-crypto tar archive release.
+T="$D/db-$VERSION.NC.tar.gz"
+rm -f $T
+cd $RNC/.. && $TAR czf $T -find db-$VERSION.NC -chown 100 -chgrp 100
+chmod 444 $T
+
+t=__tmp
+cd $R && awk '{print $0 "\r"}' < LICENSE > $t && rm -f LICENSE && cp $t LICENSE
+cd $R && awk '{print $0 "\r"}' < README > $t && rm -f README && cp $t README && rm $t
+cd $RNC && awk '{print $0 "\r"}' < LICENSE > $t && rm -f LICENSE && cp $t LICENSE
+cd $RNC && awk '{print $0 "\r"}' < README > $t && rm -f README && cp $t README && rm $t
+
+# Create the crypto zip archive release.
+T="$D/db-$VERSION.zip"
+rm -f $T
+cd $R/.. && rm -f $T && zip -q -r $T db-$VERSION
+chmod 444 $T
+
+# Create the non-crypto zip archive release.
+T="$D/db-$VERSION.NC.zip"
+rm -f $T
+cd $RNC/.. && rm -f $T && zip -q -r $T db-$VERSION.NC 
+chmod 444 $T
+
+rm -rf $R $RNC
+
+if [ "$TAG_CREATED" = "true" ]; then
+	echo "Created a tag in docs_books repository. Please push."
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/bumprel	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,82 @@
+#!/bin/sh
+# Copyright (c) 2009, 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+# $Id: $
+#
+# Bump the Berkeley DB version
+
+P=`pwd`
+R=`dirname $P`
+progname="$0"
+VERSION="$1"
+assembly="../lang/csharp/src/Properties/AssemblyInfo.cs"
+t=/tmp/__assembly
+
+# Sanity check
+if [ ! -f $R/dist/RELEASE ] ; then
+	echo "$progname must be run in the dist directory of a Berkeley DB tree"
+	exit 1
+fi
+
+OIFS="$IFS"
+IFS=.
+set -- $VERSION
+
+if [ $# != 5 ] ; then
+	echo "Usage: $progname X.X.X.X.X -- sets the Berkeley DB version to X.X.X.X.X"
+	exit 1
+fi
+FAMILY="$1" RELEASE="$2" MAJOR="$3" MINOR="$4" PATCH="$5"
+DATE=`date "+%B %e, %Y"`
+
+IFS="$OFS"
+
+# Update the change log patch number -- there's 1 location to update in
+# the change log "table of contents", and 2 in the Change Log itself.
+#cd $R/docs_src/ref/changelog && vi toc.so ${MAJOR}.${MINOR}.html
+
+# Update the release number.
+cd $R/dist &&\
+    (echo "/^DB_VERSION_FAMILY/s/=.*/=$FAMILY/" &&\
+     echo "/^DB_VERSION_RELEASE/s/=.*/=$RELEASE/" &&\
+     echo "/^DB_VERSION_MAJOR/s/=.*/=$MAJOR/" &&\
+     echo "/^DB_VERSION_MINOR/s/=.*/=$MINOR/" &&\
+     echo "/^DB_VERSION_PATCH/s/=.*/=$PATCH/" &&\
+     echo "/^DB_RELEASE_DATE/s/=.*/=\"$DATE\"/" &&\
+     echo w &&\
+     echo q) | ed RELEASE > /dev/null
+VERSION=`sh -c '. ./RELEASE; echo $DB_VERSION'`
+echo "Berkeley DB release $VERSION."
+
+# Build auto-generated files.
+cd $R/dist && sh s_all
+
+# Update the CSharp assembly information
+sed -e "s:AssemblyVersion(\"[0-9]*\.[0-9]*\.[0-9]*\"):AssemblyVersion(\"$MAJOR\.$MINOR\.$PATCH\"):" < $assembly > $t
+cmp $t $assembly > /dev/null 2>&1 ||
+    (rm -f $assembly && cp $t $assembly && rm -f $t && chmod 444 $assembly)
+
+# Commit all of the changes.
+echo "Now run 'hg commit && hg tag db-$MAJOR.$MINOR.$PATCH && hg push'"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/clib_port.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,304 @@
+/* DO NOT EDIT: automatically built from dist/clib_port.in.
+ *
+ * Copyright (c) 2006, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Minimum/maximum values for various types.
+ */
+#ifndef	UINT16_MAX			/* Maximum 16-bit unsigned. */
+#define	UINT16_MAX	65535
+#endif
+#ifndef	UINT32_MAX			/* Maximum 32-bit unsigned. */
+#define	UINT32_MAX	4294967295U
+#endif
+
+#ifndef	INT_MAX
+#if SIZEOF_INT == 4
+#define	INT_MAX		2147483647
+#endif
+#if SIZEOF_INT == 8
+#define	INT_MAX		9223372036854775807
+#endif
+#endif
+
+#ifndef	INT_MIN				/* minimum (signed) int value */
+#define	INT_MIN		(-INT_MAX-1)
+#endif
+
+#ifndef	UINT_MAX			/* maximum (signed) int value */
+#if SIZEOF_INT == 4
+#define	UINT_MAX	4294967295U
+#endif
+#if SIZEOF_INT == 8
+#define	UINT_MAX	18446744073709551615U
+#endif
+#endif
+
+#ifndef	LONG_MAX			/* maximum (signed) long value */
+#if SIZEOF_LONG == 4
+#define	LONG_MAX	2147483647
+#endif
+#if SIZEOF_LONG == 8
+#define	LONG_MAX	9223372036854775807L
+#endif
+#endif
+
+#ifndef	LONG_MIN			/* minimum (signed) long value */
+#define	LONG_MIN	(-LONG_MAX-1)
+#endif
+
+#ifndef	ULONG_MAX			/* maximum (unsigned) long value */
+#if SIZEOF_LONG == 4
+#define	ULONG_MAX	4294967295U
+#endif
+#if SIZEOF_LONG == 8
+#define	ULONG_MAX	18446744073709551615UL
+#endif
+#endif
+
+#if defined(HAVE_64BIT_TYPES)
+/*
+ * Override the system's 64-bit min/max constants.  AIX's 32-bit compiler can
+ * handle 64-bit values, but the system's constants don't include the LL/ULL
+ * suffix, and so can't be compiled using the 32-bit compiler.
+ */
+#undef	INT64_MAX
+#undef	INT64_MIN
+#undef	UINT64_MAX
+
+#ifdef	DB_WIN32
+#define	INT64_MAX	_I64_MAX
+#define	INT64_MIN	_I64_MIN
+#define	UINT64_MAX	_UI64_MAX
+#else
+#define	INT64_MAX	9223372036854775807LL
+#define	INT64_MIN	(-INT64_MAX-1)
+#define	UINT64_MAX	18446744073709551615ULL
+#endif	/* DB_WIN32 */
+
+@INT64_FMT@
+@UINT64_FMT@
+#endif	/* HAVE_64BIT_TYPES */
+
+/*
+ * Exit success/failure macros.
+ */
+#ifndef	HAVE_EXIT_SUCCESS
+#define	EXIT_FAILURE	1
+#define	EXIT_SUCCESS	0
+#endif
+
+/*
+ * File modes.
+ */
+#ifdef DB_WIN32
+#ifndef S_IREAD				/* WinCE doesn't have S_IREAD. */
+#define	S_IREAD		0
+#endif
+#ifndef S_IWRITE			/* WinCE doesn't have S_IWRITE. */
+#define	S_IWRITE	0
+#endif
+#ifndef	S_IRUSR
+#define	S_IRUSR		S_IREAD		/* R for owner */
+#endif
+#ifndef	S_IWUSR
+#define	S_IWUSR		S_IWRITE	/* W for owner */
+#endif
+#ifndef	S_IXUSR
+#define	S_IXUSR		0		/* X for owner */
+#endif
+#ifndef	S_IRGRP
+#define	S_IRGRP		0		/* R for group */
+#endif
+#ifndef	S_IWGRP
+#define	S_IWGRP		0		/* W for group */
+#endif
+#ifndef	S_IXGRP
+#define	S_IXGRP		0		/* X for group */
+#endif
+#ifndef	S_IROTH
+#define	S_IROTH		0		/* R for other */
+#endif
+#ifndef	S_IWOTH
+#define	S_IWOTH		0		/* W for other */
+#endif
+#ifndef	S_IXOTH
+#define	S_IXOTH		0		/* X for other */
+#endif
+#else /* !DB_WIN32 */
+#ifndef	S_IRUSR
+#define	S_IRUSR		0000400		/* R for owner */
+#endif
+#ifndef	S_IWUSR
+#define	S_IWUSR		0000200		/* W for owner */
+#endif
+#ifndef	S_IXUSR
+#define	S_IXUSR		0000100		/* X for owner */
+#endif
+#ifndef	S_IRGRP
+#define	S_IRGRP		0000040		/* R for group */
+#endif
+#ifndef	S_IWGRP
+#define	S_IWGRP		0000020		/* W for group */
+#endif
+#ifndef	S_IXGRP
+#define	S_IXGRP		0000010		/* X for group */
+#endif
+#ifndef	S_IROTH
+#define	S_IROTH		0000004		/* R for other */
+#endif
+#ifndef	S_IWOTH
+#define	S_IWOTH		0000002		/* W for other */
+#endif
+#ifndef	S_IXOTH
+#define	S_IXOTH		0000001		/* X for other */
+#endif
+#endif /* !DB_WIN32 */
+
+/*
+ * Don't step on the namespace.  Other libraries may have their own
+ * implementations of these functions, we don't want to use their
+ * implementations or force them to use ours based on the load order.
+ */
+#ifndef	HAVE_ATOI
+#define	atoi		__db_Catoi
+#endif
+#ifndef	HAVE_ATOL
+#define	atol		__db_Catol
+#endif
+#ifndef	HAVE_BSEARCH
+#define	bsearch		__db_Cbsearch
+#endif
+#ifndef	HAVE_FCLOSE
+#define	fclose		__db_Cfclose
+#endif
+#ifndef	HAVE_FGETC
+#define	fgetc		__db_Cfgetc
+#endif
+#ifndef	HAVE_FGETS
+#define	fgets		__db_Cfgets
+#endif
+#ifndef	HAVE_FOPEN
+#define	fopen		__db_Cfopen
+#endif
+#ifndef	HAVE_FWRITE
+#define	fwrite		__db_Cfwrite
+#endif
+#ifndef	HAVE_GETADDRINFO
+#define	freeaddrinfo(a)		__db_Cfreeaddrinfo(a)
+#define	getaddrinfo(a, b, c, d)	__db_Cgetaddrinfo(a, b, c, d)
+#endif
+#ifndef	HAVE_GETCWD
+#define	getcwd		__db_Cgetcwd
+#endif
+#ifndef	HAVE_GETOPT
+#define	getopt		__db_Cgetopt
+#define	optarg		__db_Coptarg
+#define	opterr		__db_Copterr
+#define	optind		__db_Coptind
+#define	optopt		__db_Coptopt
+#define	optreset	__db_Coptreset
+#endif
+#ifndef	HAVE_ISALPHA
+#define	isalpha		__db_Cisalpha
+#endif
+#ifndef	HAVE_ISDIGIT
+#define	isdigit		__db_Cisdigit
+#endif
+#ifndef	HAVE_ISPRINT
+#define	isprint		__db_Cisprint
+#endif
+#ifndef	HAVE_ISSPACE
+#define	isspace		__db_Cisspace
+#endif
+#ifndef	HAVE_LOCALTIME
+#define	localtime	__db_Clocaltime
+#endif
+#ifndef	HAVE_MEMCMP
+#define	memcmp		__db_Cmemcmp
+#endif
+#ifndef	HAVE_MEMCPY
+#define	memcpy		__db_Cmemcpy
+#endif
+#ifndef	HAVE_MEMMOVE
+#define	memmove		__db_Cmemmove
+#endif
+#ifndef	HAVE_PRINTF
+#define	printf		__db_Cprintf
+#define	fprintf		__db_Cfprintf
+#endif
+#ifndef	HAVE_QSORT
+#define	qsort		__db_Cqsort
+#endif
+#ifndef	HAVE_RAISE
+#define	raise		__db_Craise
+#endif
+#ifndef	HAVE_RAND
+#define	rand		__db_Crand
+#define	srand		__db_Csrand
+#endif
+#ifndef	HAVE_SNPRINTF
+#define	snprintf	__db_Csnprintf
+#endif
+#ifndef	HAVE_STRCASECMP
+#define	strcasecmp	__db_Cstrcasecmp
+#define	strncasecmp	__db_Cstrncasecmp
+#endif
+#ifndef	HAVE_STRCAT
+#define	strcat		__db_Cstrcat
+#endif
+#ifndef	HAVE_STRCHR
+#define	strchr		__db_Cstrchr
+#endif
+#ifndef	HAVE_STRDUP
+#define	strdup		__db_Cstrdup
+#endif
+#ifndef	HAVE_STRERROR
+#define	strerror	__db_Cstrerror
+#endif
+#ifndef	HAVE_STRNCAT
+#define	strncat		__db_Cstrncat
+#endif
+#ifndef	HAVE_STRNCMP
+#define	strncmp		__db_Cstrncmp
+#endif
+#ifndef	HAVE_STRRCHR
+#define	strrchr		__db_Cstrrchr
+#endif
+#ifndef	HAVE_STRSEP
+#define	strsep		__db_Cstrsep
+#endif
+#ifndef	HAVE_STRTOL
+#define	strtol		__db_Cstrtol
+#endif
+#ifndef	HAVE_STRTOUL
+#define	strtoul		__db_Cstrtoul
+#endif
+#ifndef	HAVE_TIME
+#define	time		__db_Ctime
+#endif
+#ifndef	HAVE_VSNPRINTF
+#define	vsnprintf	__db_Cvsnprintf
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/config.guess	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1522 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
+
+timestamp='2011-11-11'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+		os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+	echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+	echo m68k-milan-mint${UNAME_RELEASE}
+	exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+	echo m68k-hades-mint${UNAME_RELEASE}
+	exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+	echo m68k-unknown-mint${UNAME_RELEASE}
+	exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+	# DG/UX returns AViiON for all architectures
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[4567])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+		    case "${sc_cpu_version}" in
+		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+		      532)                      # CPU_PA_RISC2_0
+			case "${sc_kernel_bits}" in
+			  32) HP_ARCH="hppa2.0n" ;;
+			  64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+			esac ;;
+		    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^		//' << EOF >$dummy.c
+
+		#define _HPUX_SOURCE
+		#include <stdlib.h>
+		#include <unistd.h>
+
+		int main ()
+		{
+		#if defined(_SC_KERNEL_BITS)
+		    long bits = sysconf(_SC_KERNEL_BITS);
+		#endif
+		    long cpu  = sysconf (_SC_CPU_VERSION);
+
+		    switch (cpu)
+			{
+			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+			case CPU_PA_RISC2_0:
+		#if defined(_SC_KERNEL_BITS)
+			    switch (bits)
+				{
+				case 64: puts ("hppa2.0w"); break;
+				case 32: puts ("hppa2.0n"); break;
+				default: puts ("hppa2.0"); break;
+				} break;
+		#else  /* !defined(_SC_KERNEL_BITS) */
+			    puts ("hppa2.0"); break;
+		#endif
+			default: puts ("hppa1.0"); break;
+			}
+		    exit (0);
+		}
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+	exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+	exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+	exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+	exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    5000:UNIX_System_V:4.*:*)
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	case ${UNAME_PROCESSOR} in
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:MSYS*:*)
+	echo ${UNAME_MACHINE}-pc-msys
+	exit ;;
+    i*:windows32*:*)
+	# uname -m includes "-pc" on this system.
+	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+	esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-gnu
+	else
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+	    fi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+	echo frv-unknown-linux-gnu
+	exit ;;
+    hexagon:Linux:*:*)
+	echo hexagon-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	LIBC=gnu
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-gnu
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    xtensa*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+	# Unixware is an offshoot of SVR4, but it has its own version
+	# number series starting with 2...
+	# I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+	# Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+	# uname -m prints for DJGPP always 'pc', but it prints nothing about
+	# the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+	exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+			# says <Richard.M.Bartel@ccMail.Census.GOV>
+	echo i586-unisys-sysv4
+	exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+		echo mips-nec-sysv${UNAME_RELEASE}
+	else
+		echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+	exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    i386)
+		eval $set_cc_for_build
+		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		      grep IS_64BIT_ARCH >/dev/null
+		  then
+		      UNAME_PROCESSOR="x86_64"
+		  fi
+		fi ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+	echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+	"4"
+#else
+	""
+#endif
+	); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/config.hin	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,670 @@
+/* config.hin.  Generated from configure.ac by autoheader.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* Define to 1 if you want to build a version for running the test suite. */
+#undef CONFIG_TEST
+
+/* Defined to a size to limit the stack size of Berkeley DB threads. */
+#undef DB_STACKSIZE
+
+/* We use DB_WIN32 much as one would use _WIN32 -- to specify that we're using
+   an operating system environment that supports Win32 calls and semantics. We
+   don't use _WIN32 because Cygwin/GCC also defines _WIN32, even though
+   Cygwin/GCC closely emulates the Unix environment. */
+#undef DB_WIN32
+
+/* Define to 1 if you want a debugging version. */
+#undef DEBUG
+
+/* Define to 1 if you want a version that logs read operations. */
+#undef DEBUG_ROP
+
+/* Define to 1 if you want a version that logs write operations. */
+#undef DEBUG_WOP
+
+/* Define to 1 if you want a version with run-time diagnostic checking. */
+#undef DIAGNOSTIC
+
+/* Define to 1 if 64-bit types are available. */
+#undef HAVE_64BIT_TYPES
+
+/* Define to 1 if you have the `abort' function. */
+#undef HAVE_ABORT
+
+/* Define to 1 if you have the `atoi' function. */
+#undef HAVE_ATOI
+
+/* Define to 1 if you have the `atol' function. */
+#undef HAVE_ATOL
+
+/* Define to 1 if platform reads and writes files atomically. */
+#undef HAVE_ATOMICFILEREAD
+
+/* Define to 1 to use Solaris library routes for atomic operations. */
+#undef HAVE_ATOMIC_SOLARIS
+
+/* Define to 1 to use native atomic operations. */
+#undef HAVE_ATOMIC_SUPPORT
+
+/* Define to 1 to use GCC and x86 or x86_64 assemlby language atomic
+   operations. */
+#undef HAVE_ATOMIC_X86_GCC_ASSEMBLY
+
+/* Define to 1 if you have the `backtrace' function. */
+#undef HAVE_BACKTRACE
+
+/* Define to 1 if you have the `backtrace_symbols' function. */
+#undef HAVE_BACKTRACE_SYMBOLS
+
+/* Define to 1 if you have the `bsearch' function. */
+#undef HAVE_BSEARCH
+
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
+/* Define to 1 if clock_gettime supports CLOCK_MONOTONIC. */
+#undef HAVE_CLOCK_MONOTONIC
+
+/* Define to 1 if building compression support. */
+#undef HAVE_COMPRESSION
+
+/* Define to 1 if building cryptography support. */
+#undef HAVE_CRYPTO
+
+/* Define to 1 if using Intel IPP for cryptography. */
+#undef HAVE_CRYPTO_IPP
+
+/* Define to 1 if you have the `ctime_r' function. */
+#undef HAVE_CTIME_R
+
+/* Define to 1 if ctime_r takes a buffer length as a third argument. */
+#undef HAVE_CTIME_R_3ARG
+
+/* Define to 1 if building the DBM API. */
+#undef HAVE_DBM
+
+/* Define to 1 if you have the `directio' function. */
+#undef HAVE_DIRECTIO
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 to use dtrace for performance monitoring. */
+#undef HAVE_DTRACE
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+#undef HAVE_EXECINFO_H
+
+/* Define to 1 if platform has EXIT_SUCCESS/EXIT_FAILURE #defines. */
+#undef HAVE_EXIT_SUCCESS
+
+/* Define to 1 if you have the `fchmod' function. */
+#undef HAVE_FCHMOD
+
+/* Define to 1 if you have the `fclose' function. */
+#undef HAVE_FCLOSE
+
+/* Define to 1 if you have the `fcntl' function. */
+#undef HAVE_FCNTL
+
+/* Define to 1 if fcntl/F_SETFD denies child access to file descriptors. */
+#undef HAVE_FCNTL_F_SETFD
+
+/* Define to 1 if you have the `fdatasync' function. */
+#undef HAVE_FDATASYNC
+
+/* Define to 1 if you have the `fgetc' function. */
+#undef HAVE_FGETC
+
+/* Define to 1 if you have the `fgets' function. */
+#undef HAVE_FGETS
+
+/* Define to 1 if allocated filesystem blocks are not zeroed. */
+#undef HAVE_FILESYSTEM_NOTZERO
+
+/* Define to 1 if you have the `fopen' function. */
+#undef HAVE_FOPEN
+
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the `fwrite' function. */
+#undef HAVE_FWRITE
+
+/* Define to 1 if you have the `getaddrinfo' function. */
+#undef HAVE_GETADDRINFO
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `getenv' function. */
+#undef HAVE_GETENV
+
+/* Define to 1 if you have the `getgid' function. */
+#undef HAVE_GETGID
+
+/* Define to 1 if you have the `getopt' function. */
+#undef HAVE_GETOPT
+
+/* Define to 1 if getopt supports the optreset variable. */
+#undef HAVE_GETOPT_OPTRESET
+
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the `getuid' function. */
+#undef HAVE_GETUID
+
+/* Define to 1 if building Hash access method. */
+#undef HAVE_HASH
+
+/* Define to 1 if building Heap access method. */
+#undef HAVE_HEAP
+
+/* Define to 1 if you have the `hstrerror' function. */
+#undef HAVE_HSTRERROR
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `isalpha' function. */
+#undef HAVE_ISALPHA
+
+/* Define to 1 if you have the `isdigit' function. */
+#undef HAVE_ISDIGIT
+
+/* Define to 1 if you have the `isprint' function. */
+#undef HAVE_ISPRINT
+
+/* Define to 1 if you have the `isspace' function. */
+#undef HAVE_ISSPACE
+
+/* Define to 1 if you have localization function to support globalization. */
+#undef HAVE_LOCALIZATION
+
+/* Define to 1 if you have the `localtime' function. */
+#undef HAVE_LOCALTIME
+
+/* Define to 1 if enabling checksums in log records. */
+#undef HAVE_LOG_CHECKSUM
+
+/* Define to 1 if you have the `memcmp' function. */
+#undef HAVE_MEMCMP
+
+/* Define to 1 if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mlock' function. */
+#undef HAVE_MLOCK
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Define to 1 where mmap() incrementally extends the accessible mapping as
+   the underlying file grows. */
+#undef HAVE_MMAP_EXTEND
+
+/* Define to 1 if you have the `mprotect' function. */
+#undef HAVE_MPROTECT
+
+/* Define to 1 if you have the `munlock' function. */
+#undef HAVE_MUNLOCK
+
+/* Define to 1 if you have the `munmap' function. */
+#undef HAVE_MUNMAP
+
+/* Define to 1 to use the GCC compiler and 68K assembly language mutexes. */
+#undef HAVE_MUTEX_68K_GCC_ASSEMBLY
+
+/* Define to 1 to use the AIX _check_lock mutexes. */
+#undef HAVE_MUTEX_AIX_CHECK_LOCK
+
+/* Define to 1 to use the GCC compiler and Alpha assembly language mutexes. */
+#undef HAVE_MUTEX_ALPHA_GCC_ASSEMBLY
+
+/* Define to 1 to use the GCC compiler and ARM assembly language mutexes. */
+#undef HAVE_MUTEX_ARM_GCC_ASSEMBLY
+
+/* Define to 1 to use the Apple/Darwin _spin_lock_try mutexes. */
+#undef HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY
+
+/* Define to 1 to use the UNIX fcntl system call mutexes. */
+#undef HAVE_MUTEX_FCNTL
+
+/* Define to 1 to use the GCC compiler and PaRisc assembly language mutexes.
+   */
+#undef HAVE_MUTEX_HPPA_GCC_ASSEMBLY
+
+/* Define to 1 to use the msem_XXX mutexes on HP-UX. */
+#undef HAVE_MUTEX_HPPA_MSEM_INIT
+
+/* Define to 1 to use test-and-set mutexes with blocking mutexes. */
+#undef HAVE_MUTEX_HYBRID
+
+/* Define to 1 to use the GCC compiler and IA64 assembly language mutexes. */
+#undef HAVE_MUTEX_IA64_GCC_ASSEMBLY
+
+/* Define to 1 to use the GCC compiler and MIPS assembly language mutexes. */
+#undef HAVE_MUTEX_MIPS_GCC_ASSEMBLY
+
+/* Define to 1 to use the msem_XXX mutexes on systems other than HP-UX. */
+#undef HAVE_MUTEX_MSEM_INIT
+
+/* Define to 1 to use the GCC compiler and PowerPC assembly language mutexes.
+   */
+#undef HAVE_MUTEX_PPC_GCC_ASSEMBLY
+
+/* Define to 1 to use POSIX 1003.1 pthread_XXX mutexes. */
+#undef HAVE_MUTEX_PTHREADS
+
+/* Define to 1 to use Reliant UNIX initspin mutexes. */
+#undef HAVE_MUTEX_RELIANTUNIX_INITSPIN
+
+/* Define to 1 to use the IBM C compiler and S/390 assembly language mutexes.
+   */
+#undef HAVE_MUTEX_S390_CC_ASSEMBLY
+
+/* Define to 1 to use the GCC compiler and S/390 assembly language mutexes. */
+#undef HAVE_MUTEX_S390_GCC_ASSEMBLY
+
+/* Define to 1 to use the SCO compiler and x86 assembly language mutexes. */
+#undef HAVE_MUTEX_SCO_X86_CC_ASSEMBLY
+
+/* Define to 1 to use the obsolete POSIX 1003.1 sema_XXX mutexes. */
+#undef HAVE_MUTEX_SEMA_INIT
+
+/* Define to 1 to use the SGI XXX_lock mutexes. */
+#undef HAVE_MUTEX_SGI_INIT_LOCK
+
+/* Define to 1 to use the Solaris _lock_XXX mutexes. */
+#undef HAVE_MUTEX_SOLARIS_LOCK_TRY
+
+/* Define to 1 to use the Solaris lwp threads mutexes. */
+#undef HAVE_MUTEX_SOLARIS_LWP
+
+/* Define to 1 to use the GCC compiler and Sparc assembly language mutexes. */
+#undef HAVE_MUTEX_SPARC_GCC_ASSEMBLY
+
+/* Define to 1 if the Berkeley DB library should support mutexes. */
+#undef HAVE_MUTEX_SUPPORT
+
+/* Define to 1 if mutexes hold system resources. */
+#undef HAVE_MUTEX_SYSTEM_RESOURCES
+
+/* Define to 1 to configure mutexes intra-process only. */
+#undef HAVE_MUTEX_THREAD_ONLY
+
+/* Define to 1 to use the CC compiler and Tru64 assembly language mutexes. */
+#undef HAVE_MUTEX_TRU64_CC_ASSEMBLY
+
+/* Define to 1 to use the UNIX International mutexes. */
+#undef HAVE_MUTEX_UI_THREADS
+
+/* Define to 1 to use the UTS compiler and assembly language mutexes. */
+#undef HAVE_MUTEX_UTS_CC_ASSEMBLY
+
+/* Define to 1 to use VMS mutexes. */
+#undef HAVE_MUTEX_VMS
+
+/* Define to 1 to use VxWorks mutexes. */
+#undef HAVE_MUTEX_VXWORKS
+
+/* Define to 1 to use the MSVC compiler and Windows mutexes. */
+#undef HAVE_MUTEX_WIN32
+
+/* Define to 1 to use the GCC compiler and Windows mutexes. */
+#undef HAVE_MUTEX_WIN32_GCC
+
+/* Define to 1 to use the GCC compiler and 64-bit x86 assembly language
+   mutexes. */
+#undef HAVE_MUTEX_X86_64_GCC_ASSEMBLY
+
+/* Define to 1 to use the GCC compiler and 32-bit x86 assembly language
+   mutexes. */
+#undef HAVE_MUTEX_X86_GCC_ASSEMBLY
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the O_DIRECT flag. */
+#undef HAVE_O_DIRECT
+
+/* Define to 1 if building partitioned database support. */
+#undef HAVE_PARTITION
+
+/* Define to 1 to enable some kind of performance event monitoring. */
+#undef HAVE_PERFMON
+
+/* Define to 1 to enable performance event monitoring of *_stat() statistics.
+   */
+#undef HAVE_PERFMON_STATISTICS
+
+/* Define to 1 if you have the `pread' function. */
+#undef HAVE_PREAD
+
+/* Define to 1 if you have the `printf' function. */
+#undef HAVE_PRINTF
+
+/* Define to 1 if you have the `pstat_getdynamic' function. */
+#undef HAVE_PSTAT_GETDYNAMIC
+
+/* Define to 1 if it is OK to initialize an already initialized
+   pthread_cond_t. */
+#undef HAVE_PTHREAD_COND_REINIT_OKAY
+
+/* Define to 1 if it is OK to initialize an already initialized
+   pthread_rwlock_t. */
+#undef HAVE_PTHREAD_RWLOCK_REINIT_OKAY
+
+/* Define to 1 if you have the `pthread_self' function. */
+#undef HAVE_PTHREAD_SELF
+
+/* Define to 1 if you have the `pthread_yield' function. */
+#undef HAVE_PTHREAD_YIELD
+
+/* Define to 1 if you have the `pwrite' function. */
+#undef HAVE_PWRITE
+
+/* Define to 1 if building on QNX. */
+#undef HAVE_QNX
+
+/* Define to 1 if you have the `qsort' function. */
+#undef HAVE_QSORT
+
+/* Define to 1 if building Queue access method. */
+#undef HAVE_QUEUE
+
+/* Define to 1 if you have the `raise' function. */
+#undef HAVE_RAISE
+
+/* Define to 1 if you have the `rand' function. */
+#undef HAVE_RAND
+
+/* Define to 1 if you have the `random' function. */
+#undef HAVE_RANDOM
+
+/* Define to 1 if building only the most basic features. */
+#undef HAVE_RDS_BUILD
+
+/* Define to 1 if building replication support. */
+#undef HAVE_REPLICATION
+
+/* Define to 1 if building the Berkeley DB replication framework. */
+#undef HAVE_REPLICATION_THREADS
+
+/* Define to 1 if you have the `sched_yield' function. */
+#undef HAVE_SCHED_YIELD
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define to 1 if you have the `setgid' function. */
+#undef HAVE_SETGID
+
+/* Define to 1 if you have the `setuid' function. */
+#undef HAVE_SETUID
+
+/* Define to 1 to configure Berkeley DB to use read/write latches. */
+#undef HAVE_SHARED_LATCHES
+
+/* Define to 1 if shmctl/SHM_LOCK locks down shared memory segments. */
+#undef HAVE_SHMCTL_SHM_LOCK
+
+/* Define to 1 if you have the `shmget' function. */
+#undef HAVE_SHMGET
+
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if thread identifier type db_threadid_t is integral. */
+#undef HAVE_SIMPLE_THREAD_TYPE
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Define to 1 if you have the `stat' function. */
+#undef HAVE_STAT
+
+/* Define to 1 if building statistics support. */
+#undef HAVE_STATISTICS
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strcat' function. */
+#undef HAVE_STRCAT
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if building without output message content. */
+#undef HAVE_STRIPPED_MESSAGES
+
+/* Define to 1 if you have the `strncat' function. */
+#undef HAVE_STRNCAT
+
+/* Define to 1 if you have the `strncmp' function. */
+#undef HAVE_STRNCMP
+
+/* Define to 1 if you have the `strrchr' function. */
+#undef HAVE_STRRCHR
+
+/* Define to 1 if you have the `strsep' function. */
+#undef HAVE_STRSEP
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Define to 1 if you have the `strtoul' function. */
+#undef HAVE_STRTOUL
+
+/* Define to 1 if `st_blksize' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLKSIZE
+
+/* Define to 1 if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if port includes files in the Berkeley DB source code. */
+#undef HAVE_SYSTEM_INCLUDE_FILES
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/sdt.h> header file. */
+#undef HAVE_SYS_SDT_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the `time' function. */
+#undef HAVE_TIME
+
+/* Define to 1 if building in transaction support. */
+#undef HAVE_TRANSACTIONS
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if unlink of file with open file descriptors will fail. */
+#undef HAVE_UNLINK_WITH_OPEN_FAILURE
+
+/* Define to 1 if port includes historic database upgrade support. */
+#undef HAVE_UPGRADE_SUPPORT
+
+/* Define to 1 if building access method verification support. */
+#undef HAVE_VERIFY
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define to 1 if building on VxWorks. */
+#undef HAVE_VXWORKS
+
+/* Define to 1 if you have the `yield' function. */
+#undef HAVE_YIELD
+
+/* Define to 1 if you have the `_fstati64' function. */
+#undef HAVE__FSTATI64
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of `char', as computed by sizeof. */
+#undef SIZEOF_CHAR
+
+/* The size of `char *', as computed by sizeof. */
+#undef SIZEOF_CHAR_P
+
+/* The size of `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The size of `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* The size of `size_t', as computed by sizeof. */
+#undef SIZEOF_SIZE_T
+
+/* The size of `unsigned char', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_CHAR
+
+/* The size of `unsigned int', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_INT
+
+/* The size of `unsigned long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG
+
+/* The size of `unsigned long long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG_LONG
+
+/* The size of `unsigned short', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_SHORT
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+#undef STAT_MACROS_BROKEN
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 to mask harmless uninitialized memory read/writes. */
+#undef UMRW
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* type to use in place of socklen_t if not defined */
+#undef socklen_t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/config.sub	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1771 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011 Free Software Foundation, Inc.
+
+timestamp='2011-11-11'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze)
+		os=
+		basic_machine=$1
+		;;
+	-bluegene*)
+		os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+	-chorusrdb)
+		os=-chorusrdb
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+        | be32 | be64 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| epiphany \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| hexagon \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| le32 | le64 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nds32 | nds32le | nds32be \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| open8 \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pyramid \
+	| rl78 | rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+	| we32k \
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| be32-* | be64-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| hexagon-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| le32-* | le64-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pyramid-* \
+	| rl78-* | romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+	| tahoe-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile*-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+	| vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16 | cr16-*)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	microblaze)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	msys)
+		basic_machine=i386-pc
+		os=-msys
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	nacl)
+		basic_machine=le32-unknown
+		os=-nacl
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc | ppcbe)	basic_machine=powerpc-unknown
+		;;
+	ppc-* | ppcbe-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tile*)
+		basic_machine=$basic_machine-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+	# First match some system type aliases
+	# that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-auroraux)
+		os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	score-*)
+		os=-elf
+		;;
+	spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/configure	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,27505 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.68 for Berkeley DB 5.4.0.
+#
+# Report bugs to <Oracle Technology Network Berkeley DB forum>.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	# Preserve -v and -x to the replacement shell.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	case $- in # ((((
+	  *v*x* | *x*v* ) as_opts=-vx ;;
+	  *v* ) as_opts=-v ;;
+	  *x* ) as_opts=-x ;;
+	  * ) as_opts= ;;
+	esac
+	exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org and Oracle Technology
+$0: Network Berkeley DB forum about your system, including
+$0: any error possibly output before this message. Then
+$0: install a modern shell, or manually run the script
+$0: under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='Berkeley DB'
+PACKAGE_TARNAME='db-5.4.0'
+PACKAGE_VERSION='5.4.0'
+PACKAGE_STRING='Berkeley DB 5.4.0'
+PACKAGE_BUGREPORT='Oracle Technology Network Berkeley DB forum'
+PACKAGE_URL=''
+
+ac_unique_file="../src/db/db.c"
+enable_option_checking=no
+ac_default_prefix=/usr/local/BerkeleyDB.5.4
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+db_seq_decl
+UINT64_FMT
+INT64_FMT
+TCL_TCLSH
+TCL_SRC_DIR
+TCL_LIB_FILE
+TCL_INCLUDE_SPEC
+TCL_BIN_DIR
+LIBOBJS
+LISTPROBES_COMMAND
+LISTPROBES_DEPENDENCY
+DTRACE_CPP
+db_threadid_t_decl
+thread_h_decl
+uintptr_t_decl
+uintmax_t_decl
+ssize_t_decl
+time_t_decl
+size_t_decl
+pid_t_decl
+off_t_decl
+FILE_t_decl
+int64_decl
+u_int64_decl
+int32_decl
+u_int32_decl
+int16_decl
+u_int16_decl
+u_int8_decl
+u_long_decl
+u_int_decl
+u_short_decl
+u_char_decl
+unistd_h_decl
+stddef_h_decl
+stdint_h_decl
+inttypes_h_decl
+TLS_defn
+TLS_decl
+WSTRING_decl
+_ACJNI_JAVAC
+uudecode
+JAVA
+JAVAC
+JMODSUFFIX
+MODSUFFIX
+SOSUFFIX
+CPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+AWK
+RANLIB
+STRIP
+ac_ct_AR
+AR
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+cxx_have_stdheaders
+CXXCPP
+ac_ct_CXX
+CCC
+OBJEXT
+EXEEXT
+ac_ct_CC
+CC
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+db_cv_path_sh
+PERL
+SED
+STAP
+MV
+RM
+MKDIR
+LN
+KILL
+CP
+CHMOD
+DB_VERSION_UNIQUE_NAME
+DB_VERSION_FULL_STRING
+DB_VERSION_STRING
+DB_VERSION_PATCH
+DB_VERSION_MINOR
+DB_VERSION_MAJOR
+DB_VERSION_RELEASE
+DB_VERSION_FAMILY
+platform_footer
+platform_header
+topdir
+subdir_cmd
+o
+db_int_def
+TEST_LIBS
+TCL_ADDITIONAL_OBJS
+SWIGCFLAGS
+SQL_LIBS
+SQL_FLAGS
+SOFLAGS
+REPLACEMENT_OBJS
+PRINTLOG_OBJS
+POSTLINK
+OSDIR
+MAKEFILE_XSOLINK
+MAKEFILE_SOLINK
+MAKEFILE_CXXLINK
+MAKEFILE_CXX
+MAKEFILE_CCLINK
+MAKEFILE_CC
+LOCALUTILS
+LOCALSRC
+LOCALEXAMPLES
+LIBXSO_LIBS
+LIBTSO_MODULE
+LIBTSO_MODSUFFIX
+LIBTSO_LIBS
+LIBTOOL
+LIBSO_LIBS
+LIBJSO_LIBS
+LIBCSO_LIBS
+LDFLAGS
+JAVACFLAGS
+JAR
+INSTALL_TARGET
+INSTALL_LIBS_EXTRA
+INSTALL_LIBS
+INSTALLER
+FINAL_OBJS
+DTRACE
+DEFAULT_LIB_TCL
+DEFAULT_LIB_STL
+DEFAULT_LIB_SQLITE
+DEFAULT_LIB_SQL
+DEFAULT_LIB_CXX
+DEFAULT_LIB
+DB_STRUCT_ALIGN8
+DB_PROTO2
+DB_PROTO1
+DB_CONST
+CXXFLAGS
+CXX
+CRYPTO_OBJS
+CPPFLAGS
+CONFIGURATION_PATH
+CONFIGURATION_ARGS
+CFLAGS
+BUILD_TARGET
+ADDITIONAL_PROGS
+ADDITIONAL_OBJS
+ADDITIONAL_LANG
+ADDITIONAL_INCS
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_smallbuild
+enable_rdsbuild
+enable_atomicsupport
+enable_bigfile
+enable_compression
+enable_hash
+enable_heap
+enable_mutexsupport
+enable_log_checksum
+enable_partition
+enable_queue
+enable_replication
+enable_statistics
+enable_verify
+enable_compat185
+enable_cxx
+enable_debug
+enable_debug_rop
+enable_debug_wop
+enable_diagnostic
+enable_dump185
+enable_java
+enable_mingw
+enable_o_direct
+enable_posixmutexes
+enable_pthread_self
+enable_pthread_api
+enable_rpc
+enable_sql
+enable_sql_compat
+enable_jdbc
+with_jdbc
+enable_amalgamation
+enable_sql_codegen
+enable_stl
+enable_tcl
+enable_test
+enable_localization
+enable_stripped_messages
+enable_dbm
+enable_dtrace
+enable_systemtap
+enable_perfmon_statistics
+enable_uimutexes
+enable_umrw
+enable_atomicfileread
+enable_cryptography
+with_cryptography
+with_mutex
+with_mutexalign
+with_stacksize
+with_tcl
+with_uniquename
+enable_readline
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+enable_largefile
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC
+CXXCPP
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used" >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures Berkeley DB 5.4.0 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root
+                          [DATAROOTDIR/doc/db-5.4.0]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of Berkeley DB 5.4.0:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-smallbuild     Build small footprint version of the library.
+  --enable-rdsbuild       Build the restricted-DS version of the library.
+  --disable-atomicsupport Do not build any native atomic operation support.
+  --disable-bigfile       Obsolete; use --disable-largefile instead.
+  --disable-compression   Do not build compression support.
+  --disable-hash          Do not build Hash access method.
+  --disable-heap          Do not build Heap access method.
+  --disable-mutexsupport  Do not build any mutex support.
+  --disable-log_checksum  Disable log checksums.
+  --disable-partition     Do not build partitioned database support.
+  --disable-queue         Do not build Queue access method.
+  --disable-replication   Do not build database replication support.
+  --disable-statistics    Do not build statistics support.
+  --disable-verify        Do not build database verification support.
+  --enable-compat185      Build DB 1.85 compatibility API.
+  --enable-cxx            Build C++ API.
+  --enable-debug          Build a debugging version.
+  --enable-debug_rop      Build a version that logs read operations.
+  --enable-debug_wop      Build a version that logs write operations.
+  --enable-diagnostic     Build a version with run-time diagnostics.
+  --enable-dump185        Build db_dump185(1) to dump 1.85 databases.
+  --enable-java           Build Java API.
+  --enable-mingw          Build Berkeley DB for MinGW.
+  --enable-o_direct       Enable the O_DIRECT flag for direct I/O.
+  --enable-posixmutexes   Force use of POSIX standard mutexes.
+
+  --enable-sql            Build the SQL API.
+  --enable-sql_compat     Build a drop-in replacement sqlite3 library.
+  --enable-jdbc           Build BDB SQL JDBC library.
+  --enable-amalgamation   Build a SQL amalgamation instead of building files
+                          separately.
+  --enable-sql_codegen    Build the SQL-to-C code generation tool.
+  --enable-stl            Build STL API.
+  --enable-tcl            Build Tcl API.
+  --enable-test           Configure to run the test suite.
+  --enable-localization   Configure to enable localization.
+  --enable-stripped_messages
+                          Configure to enable stripped messages.
+  --enable-dbm            Configure to enable the historic dbm interface.
+  --enable-dtrace         Configure to build in dtrace static probes
+  --enable-systemtap      Configure to use systemtap to emulate dtrace static
+                          probes
+  --enable-perfmon-statistics
+                          Configure to build in performance monitoring of
+                          statistics values [default=no].
+  --enable-uimutexes      Force use of Unix International mutexes.
+  --enable-umrw           Mask harmless uninitialized memory read/writes.
+  --enable-atomicfileread Indicate that the platform reads and writes files
+                          atomically.
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+  --disable-largefile     omit support for large files
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-jdbc=DIR         Specify source directory of JDBC.
+  --with-cryptography=yes|no|ipp
+                          Build database cryptography support [default=yes].
+  --with-mutex=MUTEX      Select non-default mutex implementation.
+  --with-mutexalign=ALIGNMENT
+                          Obsolete; use DbEnv::mutex_set_align instead.
+  --with-stacksize=SIZE   Set the stack size for Berkeley DB threads.
+  --with-tcl=DIR          Directory location of tclConfig.sh.
+  --with-uniquename=NAME  Build a uniquely named library.
+  --with-pic              try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CXXCPP      C++ preprocessor
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <Oracle Technology Network Berkeley DB forum>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+Berkeley DB configure 5.4.0
+generated by GNU Autoconf 2.68
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ---------------------------------------------------------- ##
+## Report this to Oracle Technology Network Berkeley DB forum ##
+## ---------------------------------------------------------- ##"
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_member
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Berkeley DB $as_me 5.4.0, which was
+generated by GNU Autoconf 2.68.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_config_headers="$ac_config_headers db_config.h:config.hin"
+
+
+
+
+# We're going to pass options through to SQLite, don't check them first.
+
+
+
+# Configure setup.
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+
+# Don't build in the dist directory.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if building in the top-level or dist directories" >&5
+$as_echo_n "checking if building in the top-level or dist directories... " >&6; }
+if  test -f configure.ac  ; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	as_fn_error $? "\
+Berkeley DB should not be built in the \"dist\" directory. \
+Change directory to the build_unix directory and run ../dist/configure \
+from there." "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+topdir=`echo "$srcdir/.." | sed 's,/dist/\.\.,,'`
+# Substitution variables. BDB additions need to be documented.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# The Windows public header has two extra symbols we need to remove.
+
+
+
+# Set the default installation location.
+
+
+# Configure the version information.
+
+DB_VERSION_FAMILY="11"
+
+DB_VERSION_RELEASE="2"
+
+DB_VERSION_MAJOR="5"
+
+DB_VERSION_MINOR="4"
+
+DB_VERSION_PATCH="0"
+
+DB_VERSION_STRING='"Berkeley DB 5.4.0: (May  7, 2012)"'
+
+DB_VERSION_FULL_STRING='"Berkeley DB 11g Release 2, library version 11.2.5.4.0: (May  7, 2012)"'
+
+
+# Process all options before using them.
+
+
+db_cv_build_full="yes"
+db_cv_build_main="yes"
+# db_rdsbuild_default is set to yes by buildrds
+db_rdsbuild_default="yes"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-smallbuild option specified" >&5
+$as_echo_n "checking if --enable-smallbuild option specified... " >&6; }
+# Check whether --enable-smallbuild was given.
+if test "${enable_smallbuild+set}" = set; then :
+  enableval=$enable_smallbuild; db_cv_smallbuild="$enable_smallbuild"
+else
+  db_cv_smallbuild="no"
+fi
+
+case "$db_cv_smallbuild" in
+yes) db_cv_build_full="no"
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_smallbuild" >&5
+$as_echo "$db_cv_smallbuild" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-rdsbuild option specified" >&5
+$as_echo_n "checking if --enable-rdsbuild option specified... " >&6; }
+# Check whether --enable-rdsbuild was given.
+if test "${enable_rdsbuild+set}" = set; then :
+  enableval=$enable_rdsbuild; db_cv_rdsbuild="$enable_rdsbuild"
+else
+  db_cv_rdsbuild=$db_rdsbuild_default
+fi
+
+case "$db_cv_rdsbuild" in
+yes) db_cv_build_full="no"
+     db_cv_build_main="no";;
+*) db_cv_rdsbuild="no";;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_rdsbuild" >&5
+$as_echo "$db_cv_rdsbuild" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-atomicsupport option specified" >&5
+$as_echo_n "checking if --disable-atomicsupport option specified... " >&6; }
+# Check whether --enable-atomicsupport was given.
+if test "${enable_atomicsupport+set}" = set; then :
+  enableval=$enable_atomicsupport;
+else
+  enableval="yes"
+fi
+
+db_cv_build_atomicsupport="$enableval"
+case "$enableval" in
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };;
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };;
+esac
+
+# --enable-bigfile was the configuration option that Berkeley DB used before
+# autoconf 2.50 was released (which had --enable-largefile integrated in).
+# Check whether --enable-bigfile was given.
+if test "${enable_bigfile+set}" = set; then :
+  enableval=$enable_bigfile; as_fn_error $? "--enable-bigfile no longer supported, use --enable-largefile" "$LINENO" 5
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-compression option specified" >&5
+$as_echo_n "checking if --disable-compression option specified... " >&6; }
+# Check whether --enable-compression was given.
+if test "${enable_compression+set}" = set; then :
+  enableval=$enable_compression;
+else
+  enableval=$db_cv_build_full
+fi
+
+db_cv_build_compression="$enableval"
+case "$enableval" in
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };;
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-hash option specified" >&5
+$as_echo_n "checking if --disable-hash option specified... " >&6; }
+# Check whether --enable-hash was given.
+if test "${enable_hash+set}" = set; then :
+  enableval=$enable_hash;
+else
+  enableval=$db_cv_build_full
+fi
+
+db_cv_build_hash="$enableval"
+case "$enableval" in
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };;
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-heap option specified" >&5
+$as_echo_n "checking if --disable-heap option specified... " >&6; }
+# Check whether --enable-heap was given.
+if test "${enable_heap+set}" = set; then :
+  enableval=$enable_heap;
+else
+  enableval=$db_cv_build_full
+fi
+
+db_cv_build_heap="$enableval"
+case "$enableval" in
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };;
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-mutexsupport option specified" >&5
+$as_echo_n "checking if --disable-mutexsupport option specified... " >&6; }
+# Check whether --enable-mutexsupport was given.
+if test "${enable_mutexsupport+set}" = set; then :
+  enableval=$enable_mutexsupport;
+else
+  enableval="yes"
+fi
+
+db_cv_build_mutexsupport="$enableval"
+case "$enableval" in
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };;
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-log_checksum option specified" >&5
+$as_echo_n "checking if --disable-log_checksum option specified... " >&6; }
+# Check whether --enable-log_checksum was given.
+if test "${enable_log_checksum+set}" = set; then :
+  enableval=$enable_log_checksum; case "$enableval" in
+	 no | yes) db_cv_log_checksum="$enableval" ;;
+	  *) db_cv_log_checksum="yes" ;;
+ 	 esac
+else
+  db_cv_log_checksum=$db_cv_build_main
+fi
+
+case "$db_cv_log_checksum" in
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };;
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-partition option specified" >&5
+$as_echo_n "checking if --disable-partition option specified... " >&6; }
+# Check whether --enable-partition was given.
+if test "${enable_partition+set}" = set; then :
+  enableval=$enable_partition;
+else
+  enableval=$db_cv_build_full
+fi
+
+db_cv_build_partition="$enableval"
+case "$enableval" in
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };;
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-queue option specified" >&5
+$as_echo_n "checking if --disable-queue option specified... " >&6; }
+# Check whether --enable-queue was given.
+if test "${enable_queue+set}" = set; then :
+  enableval=$enable_queue;
+else
+  enableval=$db_cv_build_full
+fi
+
+db_cv_build_queue="$enableval"
+case "$enableval" in
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };;
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-replication option specified" >&5
+$as_echo_n "checking if --disable-replication option specified... " >&6; }
+# Check whether --enable-replication was given.
+if test "${enable_replication+set}" = set; then :
+  enableval=$enable_replication;
+else
+  enableval=$db_cv_build_full
+fi
+
+db_cv_build_replication="$enableval"
+case "$enableval" in
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };;
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-statistics option specified" >&5
+$as_echo_n "checking if --disable-statistics option specified... " >&6; }
+# Check whether --enable-statistics was given.
+if test "${enable_statistics+set}" = set; then :
+  enableval=$enable_statistics;
+else
+  enableval=$db_cv_build_full
+fi
+
+db_cv_build_statistics="$enableval"
+case "$enableval" in
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };;
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --disable-verify option specified" >&5
+$as_echo_n "checking if --disable-verify option specified... " >&6; }
+# Check whether --enable-verify was given.
+if test "${enable_verify+set}" = set; then :
+  enableval=$enable_verify;
+else
+  enableval=$db_cv_build_full
+fi
+
+db_cv_build_verify="$enableval"
+case "$enableval" in
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };;
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; };;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-compat185 option specified" >&5
+$as_echo_n "checking if --enable-compat185 option specified... " >&6; }
+# Check whether --enable-compat185 was given.
+if test "${enable_compat185+set}" = set; then :
+  enableval=$enable_compat185; db_cv_compat185="$enable_compat185"
+else
+  db_cv_compat185="no"
+fi
+
+if test $db_cv_compat185 = "yes" -a "$db_cv_rds" = "yes"; then
+	as_fn_error $? "--enable-compat185 is not compatible with --enable-rdsbuild" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_compat185" >&5
+$as_echo "$db_cv_compat185" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-cxx option specified" >&5
+$as_echo_n "checking if --enable-cxx option specified... " >&6; }
+# Check whether --enable-cxx was given.
+if test "${enable_cxx+set}" = set; then :
+  enableval=$enable_cxx; db_cv_cxx="$enable_cxx"
+else
+  db_cv_cxx="no"
+fi
+
+if test $db_cv_cxx = "yes" -a "$db_cv_rds" = "yes"; then
+	as_fn_error $? "--enable-cxx is not compatible with --enable-rdsbuild" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_cxx" >&5
+$as_echo "$db_cv_cxx" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-debug option specified" >&5
+$as_echo_n "checking if --enable-debug option specified... " >&6; }
+# Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug; db_cv_debug="$enable_debug"
+else
+  db_cv_debug="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_debug" >&5
+$as_echo "$db_cv_debug" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-debug_rop option specified" >&5
+$as_echo_n "checking if --enable-debug_rop option specified... " >&6; }
+# Check whether --enable-debug_rop was given.
+if test "${enable_debug_rop+set}" = set; then :
+  enableval=$enable_debug_rop; db_cv_debug_rop="$enable_debug_rop"
+else
+  db_cv_debug_rop="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_debug_rop" >&5
+$as_echo "$db_cv_debug_rop" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-debug_wop option specified" >&5
+$as_echo_n "checking if --enable-debug_wop option specified... " >&6; }
+# Check whether --enable-debug_wop was given.
+if test "${enable_debug_wop+set}" = set; then :
+  enableval=$enable_debug_wop; db_cv_debug_wop="$enable_debug_wop"
+else
+  db_cv_debug_wop="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_debug_wop" >&5
+$as_echo "$db_cv_debug_wop" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-diagnostic option specified" >&5
+$as_echo_n "checking if --enable-diagnostic option specified... " >&6; }
+# Check whether --enable-diagnostic was given.
+if test "${enable_diagnostic+set}" = set; then :
+  enableval=$enable_diagnostic; db_cv_diagnostic="$enable_diagnostic"
+else
+  db_cv_diagnostic="no"
+fi
+
+if test "$db_cv_diagnostic" = "yes"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_diagnostic" >&5
+$as_echo "$db_cv_diagnostic" >&6; }
+fi
+if test "$db_cv_diagnostic" = "no" -a "$db_cv_debug_rop" = "yes"; then
+	db_cv_diagnostic="yes"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: by --enable-debug_rop" >&5
+$as_echo "by --enable-debug_rop" >&6; }
+fi
+if test "$db_cv_diagnostic" = "no" -a "$db_cv_debug_wop" = "yes"; then
+	db_cv_diagnostic="yes"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: by --enable-debug_wop" >&5
+$as_echo "by --enable-debug_wop" >&6; }
+fi
+if test "$db_cv_diagnostic" = "no"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_diagnostic" >&5
+$as_echo "$db_cv_diagnostic" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-dump185 option specified" >&5
+$as_echo_n "checking if --enable-dump185 option specified... " >&6; }
+# Check whether --enable-dump185 was given.
+if test "${enable_dump185+set}" = set; then :
+  enableval=$enable_dump185; db_cv_dump185="$enable_dump185"
+else
+  db_cv_dump185="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_dump185" >&5
+$as_echo "$db_cv_dump185" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-java option specified" >&5
+$as_echo_n "checking if --enable-java option specified... " >&6; }
+# Check whether --enable-java was given.
+if test "${enable_java+set}" = set; then :
+  enableval=$enable_java; db_cv_java="$enable_java"
+else
+  db_cv_java="no"
+fi
+
+if test $db_cv_java = "yes" -a "$db_cv_rds" = "yes"; then
+	as_fn_error $? "--enable-java is not compatible with --enable-rdsbuild" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_java" >&5
+$as_echo "$db_cv_java" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-mingw option specified" >&5
+$as_echo_n "checking if --enable-mingw option specified... " >&6; }
+# Check whether --enable-mingw was given.
+if test "${enable_mingw+set}" = set; then :
+  enableval=$enable_mingw; db_cv_mingw="$enable_mingw"
+else
+  db_cv_mingw="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_mingw" >&5
+$as_echo "$db_cv_mingw" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-o_direct option specified" >&5
+$as_echo_n "checking if --enable-o_direct option specified... " >&6; }
+# Check whether --enable-o_direct was given.
+if test "${enable_o_direct+set}" = set; then :
+  enableval=$enable_o_direct; db_cv_o_direct="$enable_o_direct"
+else
+  db_cv_o_direct="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_o_direct" >&5
+$as_echo "$db_cv_o_direct" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-posixmutexes option specified" >&5
+$as_echo_n "checking if --enable-posixmutexes option specified... " >&6; }
+# Check whether --enable-posixmutexes was given.
+if test "${enable_posixmutexes+set}" = set; then :
+  enableval=$enable_posixmutexes; db_cv_posixmutexes="$enable_posixmutexes"
+else
+  db_cv_posixmutexes="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_posixmutexes" >&5
+$as_echo "$db_cv_posixmutexes" >&6; }
+
+# Check whether --enable-pthread_self was given.
+if test "${enable_pthread_self+set}" = set; then :
+  enableval=$enable_pthread_self; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-pthread_self is now always enabled" >&5
+$as_echo "$as_me: WARNING: --enable-pthread_self is now always enabled" >&2;}
+fi
+
+
+# Check whether --enable-pthread_api was given.
+if test "${enable_pthread_api+set}" = set; then :
+  enableval=$enable_pthread_api; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-pthread_api is now always enabled" >&5
+$as_echo "$as_me: WARNING: --enable-pthread_api is now always enabled" >&2;}
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-rpc option specified" >&5
+$as_echo_n "checking if --enable-rpc option specified... " >&6; }
+# Check whether --enable-rpc was given.
+if test "${enable_rpc+set}" = set; then :
+  enableval=$enable_rpc; as_fn_error $? "RPC support has been removed from Berkeley DB." "$LINENO" 5
+
+else
+  db_cv_rpc="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_rpc" >&5
+$as_echo "$db_cv_rpc" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-sql option specified" >&5
+$as_echo_n "checking if --enable-sql option specified... " >&6; }
+# Check whether --enable-sql was given.
+if test "${enable_sql+set}" = set; then :
+  enableval=$enable_sql; db_cv_sql="$enable_sql"
+else
+  db_cv_sql="no"
+fi
+
+if test $db_cv_sql = "yes" -a "$db_cv_rds" = "yes"; then
+	as_fn_error $? "--enable-sql is not compatible with --enable-rdsbuild" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_sql" >&5
+$as_echo "$db_cv_sql" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-sql_compat option specified" >&5
+$as_echo_n "checking if --enable-sql_compat option specified... " >&6; }
+# Check whether --enable-sql_compat was given.
+if test "${enable_sql_compat+set}" = set; then :
+  enableval=$enable_sql_compat; db_cv_sql_compat="$enable_sql_compat"
+else
+  db_cv_sql_compat="no"
+fi
+
+if test $db_cv_sql_compat = "yes" -a "$db_cv_rds" = "yes"; then
+	as_fn_error $? "--enable-sql_compat is not compatible with --enable-rdsbuild" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_sql_compat" >&5
+$as_echo "$db_cv_sql_compat" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-jdbc option specified" >&5
+$as_echo_n "checking if --enable-jdbc option specified... " >&6; }
+# Check whether --enable-jdbc was given.
+if test "${enable_jdbc+set}" = set; then :
+  enableval=$enable_jdbc; db_cv_jdbc="$enable_jdbc"
+else
+  db_cv_jdbc="no"
+fi
+
+if test $db_cv_jdbc = "yes" -a "$db_cv_rds" = "yes"; then
+	as_fn_error $? "--enable-jdbc is not compatible with --enable-rdsbuild" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_jdbc" >&5
+$as_echo "$db_cv_jdbc" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-jdbc=DIR option specified" >&5
+$as_echo_n "checking if --with-jdbc=DIR option specified... " >&6; }
+
+# Check whether --with-jdbc was given.
+if test "${with_jdbc+set}" = set; then :
+  withval=$with_jdbc; with_jdbc="$withval"
+else
+  with_jdbc="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_jdbc" >&5
+$as_echo "$with_jdbc" >&6; }
+if test "$with_jdbc" != "no"; then
+	db_cv_jdbc="yes"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-amalgamation option specified" >&5
+$as_echo_n "checking if --enable-amalgamation option specified... " >&6; }
+# Check whether --enable-amalgamation was given.
+if test "${enable_amalgamation+set}" = set; then :
+  enableval=$enable_amalgamation; db_cv_sql_amalgamation="$enable_amalgamation"
+else
+  db_cv_sql_amalgamation="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_sql_amalgamation" >&5
+$as_echo "$db_cv_sql_amalgamation" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-sql_codegen option specified" >&5
+$as_echo_n "checking if --enable-sql_codegen option specified... " >&6; }
+# Check whether --enable-sql_codegen was given.
+if test "${enable_sql_codegen+set}" = set; then :
+  enableval=$enable_sql_codegen; db_cv_sql_codegen="$enable_sql_codegen"
+else
+  db_cv_sql_codegen="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_sql_codegen" >&5
+$as_echo "$db_cv_sql_codegen" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-stl option specified" >&5
+$as_echo_n "checking if --enable-stl option specified... " >&6; }
+# Check whether --enable-stl was given.
+if test "${enable_stl+set}" = set; then :
+  enableval=$enable_stl; db_cv_stl="$enable_stl"
+else
+  db_cv_stl="no"
+fi
+
+if test $db_cv_stl = "yes" -a "$db_cv_rds" = "yes"; then
+	as_fn_error $? "--enable-stl is not compatible with --enable-rdsbuild" "$LINENO" 5
+fi
+if test "$db_cv_stl" = "yes" -a "$db_cv_cxx" = "no"; then
+	db_cv_cxx="yes"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_stl" >&5
+$as_echo "$db_cv_stl" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-tcl option specified" >&5
+$as_echo_n "checking if --enable-tcl option specified... " >&6; }
+# Check whether --enable-tcl was given.
+if test "${enable_tcl+set}" = set; then :
+  enableval=$enable_tcl; db_cv_tcl="$enable_tcl"
+else
+  db_cv_tcl="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_tcl" >&5
+$as_echo "$db_cv_tcl" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-test option specified" >&5
+$as_echo_n "checking if --enable-test option specified... " >&6; }
+# Check whether --enable-test was given.
+if test "${enable_test+set}" = set; then :
+  enableval=$enable_test; db_cv_test="$enable_test"
+else
+  db_cv_test="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_test" >&5
+$as_echo "$db_cv_test" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-localization option specified" >&5
+$as_echo_n "checking if --enable-localization option specified... " >&6; }
+# Check whether --enable-localization was given.
+if test "${enable_localization+set}" = set; then :
+  enableval=$enable_localization; db_cv_localization="$enable_localization"
+else
+  db_cv_localization="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_localization" >&5
+$as_echo "$db_cv_localization" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-stripped_messages option specified" >&5
+$as_echo_n "checking if --enable-stripped_messages option specified... " >&6; }
+# Check whether --enable-stripped_messages was given.
+if test "${enable_stripped_messages+set}" = set; then :
+  enableval=$enable_stripped_messages; db_cv_stripped_messages="$enable_stripped_messages"
+else
+  db_cv_stripped_messages="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_stripped_messages" >&5
+$as_echo "$db_cv_stripped_messages" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-dbm option specified" >&5
+$as_echo_n "checking if --enable-dbm option specified... " >&6; }
+# Check whether --enable-dbm was given.
+if test "${enable_dbm+set}" = set; then :
+  enableval=$enable_dbm; db_cv_dbm="$enable_dbm"
+else
+  db_cv_dbm="$db_cv_test"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_dbm" >&5
+$as_echo "$db_cv_dbm" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-dtrace option specified" >&5
+$as_echo_n "checking if --enable-dtrace option specified... " >&6; }
+# Check whether --enable-dtrace was given.
+if test "${enable_dtrace+set}" = set; then :
+  enableval=$enable_dtrace; db_cv_dtrace="$enable_dtrace"
+else
+  db_cv_dtrace="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_dtrace" >&5
+$as_echo "$db_cv_dtrace" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-systemtap option specified" >&5
+$as_echo_n "checking if --enable-systemtap option specified... " >&6; }
+# Check whether --enable-systemtap was given.
+if test "${enable_systemtap+set}" = set; then :
+  enableval=$enable_systemtap; db_cv_systemtap="$enable_systemtap"
+else
+  db_cv_systemtap="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_systemtap" >&5
+$as_echo "$db_cv_systemtap" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-perfmon-statistics option specified" >&5
+$as_echo_n "checking if --enable-perfmon-statistics option specified... " >&6; }
+# Check whether --enable-perfmon_statistics was given.
+if test "${enable_perfmon_statistics+set}" = set; then :
+  enableval=$enable_perfmon_statistics; db_cv_perfmon_statistics="$enable_perfmon_statistics"
+else
+  db_cv_perfmon_statistics="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_perfmon_statistics" >&5
+$as_echo "$db_cv_perfmon_statistics" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-uimutexes option specified" >&5
+$as_echo_n "checking if --enable-uimutexes option specified... " >&6; }
+# Check whether --enable-uimutexes was given.
+if test "${enable_uimutexes+set}" = set; then :
+  enableval=$enable_uimutexes; db_cv_uimutexes="$enable_uimutexes"
+else
+  db_cv_uimutexes="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_uimutexes" >&5
+$as_echo "$db_cv_uimutexes" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-umrw option specified" >&5
+$as_echo_n "checking if --enable-umrw option specified... " >&6; }
+# Check whether --enable-umrw was given.
+if test "${enable_umrw+set}" = set; then :
+  enableval=$enable_umrw; db_cv_umrw="$enable_umrw"
+else
+  db_cv_umrw="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_umrw" >&5
+$as_echo "$db_cv_umrw" >&6; }
+
+# Solaris, AI/X, OS/X and other BSD-derived systems default to POSIX-conforming
+# disk i/o: A single read or write call is atomic. Other systems do not
+# guarantee atomicity; in particular Linux and Microsoft Windows.
+atomicfileread="no"
+case "$host_os" in
+solaris* | aix* | bsdi3* | freebsd* | darwin*)
+	atomicfileread="yes";;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-atomicfileread option specified" >&5
+$as_echo_n "checking if --enable-atomicfileread option specified... " >&6; }
+# Check whether --enable-atomicfileread was given.
+if test "${enable_atomicfileread+set}" = set; then :
+  enableval=$enable_atomicfileread; db_cv_atomicfileread="$enable_atomicfileread"
+else
+  db_cv_atomicfileread=$atomicfileread
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_atomicfileread" >&5
+$as_echo "$db_cv_atomicfileread" >&6; }
+if test "$db_cv_atomicfileread" = "yes"; then
+	$as_echo "#define HAVE_ATOMICFILEREAD 1" >>confdefs.h
+
+
+fi
+
+# Cryptography support.
+# Until Berkeley DB 5.0, this was a simple yes/no decision.
+# With the addition of support for Intel Integrated Performance Primitives (ipp)
+# things are more complex.  There are now three options:
+#   1) don't build cryptography (no)
+#   2) build using the built-in software implementation (yes)
+#   3) build using the Intel IPP implementation (ipp)
+# We handle this by making the primary configuration method:
+#   --with-cryptography={yes|no|ipp}
+# which defaults to yes.  The old enable/disable-cryptography argument is still
+# supported for backwards compatibility.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-cryptography option specified" >&5
+$as_echo_n "checking if --with-cryptography option specified... " >&6; }
+# Check whether --enable-cryptography was given.
+if test "${enable_cryptography+set}" = set; then :
+  enableval=$enable_cryptography;
+else
+  enableval=$db_cv_build_full
+fi
+
+enable_cryptography="$enableval"
+
+# Check whether --with-cryptography was given.
+if test "${with_cryptography+set}" = set; then :
+  withval=$with_cryptography;
+else
+  with_cryptography=$enable_cryptography
+fi
+
+case "$with_cryptography" in
+yes|no|ipp) ;;
+*) as_fn_error $? "unknown --with-cryptography argument \'$with_cryptography\'" "$LINENO" 5 ;;
+esac
+db_cv_build_cryptography="$with_cryptography"
+if test $db_cv_build_cryptography != "no" -a "$db_cv_rds" = "yes"; then
+	as_fn_error $? "--with_cryptography is not compatible with --enable-rdsbuild" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_build_cryptography" >&5
+$as_echo "$db_cv_build_cryptography" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-mutex=MUTEX option specified" >&5
+$as_echo_n "checking if --with-mutex=MUTEX option specified... " >&6; }
+
+# Check whether --with-mutex was given.
+if test "${with_mutex+set}" = set; then :
+  withval=$with_mutex; with_mutex="$withval"
+else
+  with_mutex="no"
+fi
+
+if test "$with_mutex" = "yes"; then
+	as_fn_error $? "--with-mutex requires a mutex name argument" "$LINENO" 5
+fi
+if test "$with_mutex" != "no"; then
+	db_cv_mutex="$with_mutex"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_mutex" >&5
+$as_echo "$with_mutex" >&6; }
+
+# --with-mutexalign=ALIGNMENT was the configuration option that Berkeley DB
+# used before the DbEnv::mutex_set_align method was added.
+
+# Check whether --with-mutexalign was given.
+if test "${with_mutexalign+set}" = set; then :
+  withval=$with_mutexalign; as_fn_error $? "--with-mutexalign no longer supported, use DbEnv::mutex_set_align" "$LINENO" 5
+fi
+
+
+
+# Check whether --with-stacksize was given.
+if test "${with_stacksize+set}" = set; then :
+  withval=$with_stacksize; with_stacksize="$withval"
+else
+  with_stacksize="no"
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-tcl=DIR option specified" >&5
+$as_echo_n "checking if --with-tcl=DIR option specified... " >&6; }
+
+# Check whether --with-tcl was given.
+if test "${with_tcl+set}" = set; then :
+  withval=$with_tcl; with_tclconfig="$withval"
+else
+  with_tclconfig="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_tclconfig" >&5
+$as_echo "$with_tclconfig" >&6; }
+if test "$with_tclconfig" != "no"; then
+	db_cv_tcl="yes"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --with-uniquename=NAME option specified" >&5
+$as_echo_n "checking if --with-uniquename=NAME option specified... " >&6; }
+
+# Check whether --with-uniquename was given.
+if test "${with_uniquename+set}" = set; then :
+  withval=$with_uniquename; with_uniquename="$withval"
+else
+  with_uniquename="no"
+fi
+
+if test "$with_uniquename" = "no"; then
+	db_cv_uniquename="no"
+	DB_VERSION_UNIQUE_NAME=""
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_uniquename" >&5
+$as_echo "$with_uniquename" >&6; }
+else
+	db_cv_uniquename="yes"
+	if test "$db_cv_rds" = "yes"; then
+		as_fn_error $? "--with-uniquename is not compatible with --enable-rdsbuild" "$LINENO" 5
+	fi
+	if test "$with_uniquename" = "yes"; then
+		DB_VERSION_UNIQUE_NAME="_5004"
+	else
+		DB_VERSION_UNIQUE_NAME="$with_uniquename"
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DB_VERSION_UNIQUE_NAME" >&5
+$as_echo "$DB_VERSION_UNIQUE_NAME" >&6; }
+fi
+
+# Undocumented option used for the dbsql command line tool (to match SQLite).
+# Check whether --enable-readline was given.
+if test "${enable_readline+set}" = set; then :
+  enableval=$enable_readline; with_readline=$enableval
+else
+  with_readline=no
+fi
+
+
+# --enable-sql_compat implies --enable-sql
+if test "$db_cv_sql_compat" = "yes" -a "$db_cv_sql" = "no"; then
+	db_cv_sql=$db_cv_sql_compat
+fi
+
+# --enable-jdbc implies --enable-sql
+if test "$db_cv_jdbc" = "yes" -a "$db_cv_sql" = "no"; then
+	db_cv_sql=$db_cv_jdbc
+fi
+
+# Testing requires Tcl.
+if test "$db_cv_test" = "yes" -a "$db_cv_tcl" = "no"; then
+	as_fn_error $? "--enable-test requires --enable-tcl" "$LINENO" 5
+fi
+
+# Set some #defines based on configuration options.
+if test "$db_cv_diagnostic" = "yes"; then
+	$as_echo "#define DIAGNOSTIC 1" >>confdefs.h
+
+
+fi
+if test "$db_cv_debug_rop" = "yes"; then
+	$as_echo "#define DEBUG_ROP 1" >>confdefs.h
+
+
+fi
+if test "$db_cv_debug_wop" = "yes"; then
+	$as_echo "#define DEBUG_WOP 1" >>confdefs.h
+
+
+fi
+if test "$db_cv_umrw" = "yes"; then
+	$as_echo "#define UMRW 1" >>confdefs.h
+
+
+
+fi
+if test "$db_cv_test" = "yes"; then
+	$as_echo "#define CONFIG_TEST 1" >>confdefs.h
+
+
+fi
+
+
+$as_echo "#define HAVE_UPGRADE_SUPPORT 1" >>confdefs.h
+
+
+# Check for programs used in building and installation.
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}chmod", so it can be a program name with args.
+set dummy ${ac_tool_prefix}chmod; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CHMOD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CHMOD"; then
+  ac_cv_prog_CHMOD="$CHMOD" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CHMOD="${ac_tool_prefix}chmod"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CHMOD=$ac_cv_prog_CHMOD
+if test -n "$CHMOD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CHMOD" >&5
+$as_echo "$CHMOD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CHMOD"; then
+  ac_ct_CHMOD=$CHMOD
+  # Extract the first word of "chmod", so it can be a program name with args.
+set dummy chmod; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CHMOD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CHMOD"; then
+  ac_cv_prog_ac_ct_CHMOD="$ac_ct_CHMOD" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CHMOD="chmod"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CHMOD=$ac_cv_prog_ac_ct_CHMOD
+if test -n "$ac_ct_CHMOD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CHMOD" >&5
+$as_echo "$ac_ct_CHMOD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CHMOD" = x; then
+    CHMOD="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CHMOD=$ac_ct_CHMOD
+  fi
+else
+  CHMOD="$ac_cv_prog_CHMOD"
+fi
+
+test "$CHMOD" = "none" && as_fn_error $? "No chmod utility found." "$LINENO" 5
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cp", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cp; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CP"; then
+  ac_cv_prog_CP="$CP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CP="${ac_tool_prefix}cp"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CP=$ac_cv_prog_CP
+if test -n "$CP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CP" >&5
+$as_echo "$CP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CP"; then
+  ac_ct_CP=$CP
+  # Extract the first word of "cp", so it can be a program name with args.
+set dummy cp; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CP"; then
+  ac_cv_prog_ac_ct_CP="$ac_ct_CP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CP="cp"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CP=$ac_cv_prog_ac_ct_CP
+if test -n "$ac_ct_CP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CP" >&5
+$as_echo "$ac_ct_CP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CP" = x; then
+    CP="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CP=$ac_ct_CP
+  fi
+else
+  CP="$ac_cv_prog_CP"
+fi
+
+test "$CP" = "none" && as_fn_error $? "No cp utility found." "$LINENO" 5
+
+# The Tcl test suite requires a kill utility.
+if test "$db_cv_test" = "yes"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}kill", so it can be a program name with args.
+set dummy ${ac_tool_prefix}kill; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_KILL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$KILL"; then
+  ac_cv_prog_KILL="$KILL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_KILL="${ac_tool_prefix}kill"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+KILL=$ac_cv_prog_KILL
+if test -n "$KILL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KILL" >&5
+$as_echo "$KILL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_KILL"; then
+  ac_ct_KILL=$KILL
+  # Extract the first word of "kill", so it can be a program name with args.
+set dummy kill; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_KILL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_KILL"; then
+  ac_cv_prog_ac_ct_KILL="$ac_ct_KILL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_KILL="kill"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_KILL=$ac_cv_prog_ac_ct_KILL
+if test -n "$ac_ct_KILL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_KILL" >&5
+$as_echo "$ac_ct_KILL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_KILL" = x; then
+    KILL="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    KILL=$ac_ct_KILL
+  fi
+else
+  KILL="$ac_cv_prog_KILL"
+fi
+
+	test "$KILL" = "none" && as_fn_error $? "No kill utility found." "$LINENO" 5
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ln", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ln; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LN"; then
+  ac_cv_prog_LN="$LN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_LN="${ac_tool_prefix}ln"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LN=$ac_cv_prog_LN
+if test -n "$LN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LN" >&5
+$as_echo "$LN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LN"; then
+  ac_ct_LN=$LN
+  # Extract the first word of "ln", so it can be a program name with args.
+set dummy ln; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_LN"; then
+  ac_cv_prog_ac_ct_LN="$ac_ct_LN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_LN="ln"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LN=$ac_cv_prog_ac_ct_LN
+if test -n "$ac_ct_LN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LN" >&5
+$as_echo "$ac_ct_LN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_LN" = x; then
+    LN="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    LN=$ac_ct_LN
+  fi
+else
+  LN="$ac_cv_prog_LN"
+fi
+
+test "$LN" = "none" && as_fn_error $? "No ln utility found." "$LINENO" 5
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mkdir", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mkdir; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MKDIR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MKDIR"; then
+  ac_cv_prog_MKDIR="$MKDIR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_MKDIR="${ac_tool_prefix}mkdir"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MKDIR=$ac_cv_prog_MKDIR
+if test -n "$MKDIR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5
+$as_echo "$MKDIR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MKDIR"; then
+  ac_ct_MKDIR=$MKDIR
+  # Extract the first word of "mkdir", so it can be a program name with args.
+set dummy mkdir; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MKDIR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MKDIR"; then
+  ac_cv_prog_ac_ct_MKDIR="$ac_ct_MKDIR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_MKDIR="mkdir"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MKDIR=$ac_cv_prog_ac_ct_MKDIR
+if test -n "$ac_ct_MKDIR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MKDIR" >&5
+$as_echo "$ac_ct_MKDIR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MKDIR" = x; then
+    MKDIR="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    MKDIR=$ac_ct_MKDIR
+  fi
+else
+  MKDIR="$ac_cv_prog_MKDIR"
+fi
+
+test "$MKDIR" = "none" && as_fn_error $? "No mkdir utility found." "$LINENO" 5
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}rm", so it can be a program name with args.
+set dummy ${ac_tool_prefix}rm; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RM+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RM"; then
+  ac_cv_prog_RM="$RM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RM="${ac_tool_prefix}rm"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RM=$ac_cv_prog_RM
+if test -n "$RM"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RM" >&5
+$as_echo "$RM" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RM"; then
+  ac_ct_RM=$RM
+  # Extract the first word of "rm", so it can be a program name with args.
+set dummy rm; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RM+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RM"; then
+  ac_cv_prog_ac_ct_RM="$ac_ct_RM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RM="rm"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RM=$ac_cv_prog_ac_ct_RM
+if test -n "$ac_ct_RM"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RM" >&5
+$as_echo "$ac_ct_RM" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RM" = x; then
+    RM="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RM=$ac_ct_RM
+  fi
+else
+  RM="$ac_cv_prog_RM"
+fi
+
+test "$RM" = "none" && as_fn_error $? "No rm utility found." "$LINENO" 5
+
+# We always want to force removes, and libtool assumes the same.
+RM="$RM -f"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mv", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mv; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MV+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MV"; then
+  ac_cv_prog_MV="$MV" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_MV="${ac_tool_prefix}mv"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MV=$ac_cv_prog_MV
+if test -n "$MV"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MV" >&5
+$as_echo "$MV" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MV"; then
+  ac_ct_MV=$MV
+  # Extract the first word of "mv", so it can be a program name with args.
+set dummy mv; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MV+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MV"; then
+  ac_cv_prog_ac_ct_MV="$ac_ct_MV" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_MV="mv"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MV=$ac_cv_prog_ac_ct_MV
+if test -n "$ac_ct_MV"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MV" >&5
+$as_echo "$ac_ct_MV" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MV" = x; then
+    MV="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    MV=$ac_ct_MV
+  fi
+else
+  MV="$ac_cv_prog_MV"
+fi
+
+test "$MV" = "none" && as_fn_error $? "No mv utility found." "$LINENO" 5
+
+if test "$db_cv_systemtap" = "yes" -o "$db_cv_dtrace" = "yes"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}stap", so it can be a program name with args.
+set dummy ${ac_tool_prefix}stap; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STAP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STAP"; then
+  ac_cv_prog_STAP="$STAP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STAP="${ac_tool_prefix}stap"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STAP=$ac_cv_prog_STAP
+if test -n "$STAP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STAP" >&5
+$as_echo "$STAP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STAP"; then
+  ac_ct_STAP=$STAP
+  # Extract the first word of "stap", so it can be a program name with args.
+set dummy stap; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STAP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STAP"; then
+  ac_cv_prog_ac_ct_STAP="$ac_ct_STAP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STAP="stap"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STAP=$ac_cv_prog_ac_ct_STAP
+if test -n "$ac_ct_STAP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STAP" >&5
+$as_echo "$ac_ct_STAP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STAP" = x; then
+    STAP="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STAP=$ac_ct_STAP
+  fi
+else
+  STAP="$ac_cv_prog_STAP"
+fi
+
+	test "$STAP" = "none" -a "$db_cv_systemtap" = "yes" && \
+		as_fn_error $? "No stap utility found." "$LINENO" 5
+	db_cv_dtrace=yes
+fi
+
+if test "$db_cv_dtrace" = "yes"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dtrace", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dtrace; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DTRACE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DTRACE"; then
+  ac_cv_prog_DTRACE="$DTRACE" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DTRACE="${ac_tool_prefix}dtrace"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DTRACE=$ac_cv_prog_DTRACE
+if test -n "$DTRACE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DTRACE"; then
+  ac_ct_DTRACE=$DTRACE
+  # Extract the first word of "dtrace", so it can be a program name with args.
+set dummy dtrace; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DTRACE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DTRACE"; then
+  ac_cv_prog_ac_ct_DTRACE="$ac_ct_DTRACE" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DTRACE="dtrace"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DTRACE=$ac_cv_prog_ac_ct_DTRACE
+if test -n "$ac_ct_DTRACE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DTRACE" >&5
+$as_echo "$ac_ct_DTRACE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DTRACE" = x; then
+    DTRACE="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DTRACE=$ac_ct_DTRACE
+  fi
+else
+  DTRACE="$ac_cv_prog_DTRACE"
+fi
+
+	test "$DTRACE" = "none" && as_fn_error $? "No dtrace utility found." "$LINENO" 5
+	# Sed and perl are needed only if events are added after building
+	# the distribution; if either is missing it is not an error for now.
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}sed", so it can be a program name with args.
+set dummy ${ac_tool_prefix}sed; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_SED+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$SED"; then
+  ac_cv_prog_SED="$SED" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_SED="${ac_tool_prefix}sed"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+SED=$ac_cv_prog_SED
+if test -n "$SED"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SED" >&5
+$as_echo "$SED" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_SED"; then
+  ac_ct_SED=$SED
+  # Extract the first word of "sed", so it can be a program name with args.
+set dummy sed; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_SED+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_SED"; then
+  ac_cv_prog_ac_ct_SED="$ac_ct_SED" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_SED="sed"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_SED=$ac_cv_prog_ac_ct_SED
+if test -n "$ac_ct_SED"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_SED" >&5
+$as_echo "$ac_ct_SED" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_SED" = x; then
+    SED="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    SED=$ac_ct_SED
+  fi
+else
+  SED="$ac_cv_prog_SED"
+fi
+
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}perl", so it can be a program name with args.
+set dummy ${ac_tool_prefix}perl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PERL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PERL"; then
+  ac_cv_prog_PERL="$PERL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_PERL="${ac_tool_prefix}perl"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PERL=$ac_cv_prog_PERL
+if test -n "$PERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5
+$as_echo "$PERL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_PERL"; then
+  ac_ct_PERL=$PERL
+  # Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_PERL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_PERL"; then
+  ac_cv_prog_ac_ct_PERL="$ac_ct_PERL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_PERL="perl"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_PERL=$ac_cv_prog_ac_ct_PERL
+if test -n "$ac_ct_PERL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PERL" >&5
+$as_echo "$ac_ct_PERL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_PERL" = x; then
+    PERL="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PERL=$ac_ct_PERL
+  fi
+else
+  PERL="$ac_cv_prog_PERL"
+fi
+
+fi
+
+# We need a complete path for sh, because some make utility implementations get
+# upset if SHELL is set to just the command name.  Don't use the SHELL variable
+# here because the user likely has the SHELL variable set to something other
+# than the Bourne shell, which is what Make wants.
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}sh", so it can be a program name with args.
+set dummy ${ac_tool_prefix}sh; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_db_cv_path_sh+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $db_cv_path_sh in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_db_cv_path_sh="$db_cv_path_sh" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_db_cv_path_sh="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+db_cv_path_sh=$ac_cv_path_db_cv_path_sh
+if test -n "$db_cv_path_sh"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_path_sh" >&5
+$as_echo "$db_cv_path_sh" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_db_cv_path_sh"; then
+  ac_pt_db_cv_path_sh=$db_cv_path_sh
+  # Extract the first word of "sh", so it can be a program name with args.
+set dummy sh; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_db_cv_path_sh+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_db_cv_path_sh in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_db_cv_path_sh="$ac_pt_db_cv_path_sh" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_ac_pt_db_cv_path_sh="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_db_cv_path_sh=$ac_cv_path_ac_pt_db_cv_path_sh
+if test -n "$ac_pt_db_cv_path_sh"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_db_cv_path_sh" >&5
+$as_echo "$ac_pt_db_cv_path_sh" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_db_cv_path_sh" = x; then
+    db_cv_path_sh="none"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    db_cv_path_sh=$ac_pt_db_cv_path_sh
+  fi
+else
+  db_cv_path_sh="$ac_cv_path_db_cv_path_sh"
+fi
+
+test "$db_cv_path_sh" = "none" && as_fn_error $? "No sh utility found." "$LINENO" 5
+
+# Don't strip the binaries if --enable-debug was specified.
+if test "$db_cv_debug" = yes; then
+	STRIP=":"
+fi
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+BUILD_TARGET="library_build"
+INSTALL_TARGET="library_install"
+
+# Respect the environment LIBS settings
+LIBSO_LIBS="$LIBS"
+
+# This is where we handle stuff that autoconf can't handle: compiler,
+# preprocessor and load flags, libraries that the standard tests don't
+# look for.
+#
+# There are additional libraries we need for some compiler/architecture
+# combinations.
+#
+# Some architectures require DB to be compiled with special flags and/or
+# libraries for threaded applications
+#
+# The makefile CC may be different than the CC used in config testing,
+# because the makefile CC may be set to use $(LIBTOOL).
+#
+# Don't override anything if it's already set from the environment.
+optimize_flag="-O"
+extra_cflags=""
+
+case "$host_os" in
+aix4.3.*|aix[56]*)
+	case "$host_os" in
+	aix4.3.*)
+		CPPFLAGS="$CPPFLAGS -D_LINUX_SOURCE_COMPAT";;
+	esac
+	# IBM's XLC compilers (at least versions 7/8/9) generate incorrect code
+	# when ordinary optimization is enabled because they make strong
+	# assumptions about the types held at each memory location, and some
+	# Berkeley DB code violates those assumptions.  [#16141]
+	extra_cflags=" -qalias=noansi"
+	optimize_flag="-O2"
+	CC=${CC-"xlc_r"}
+	CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"
+	LDFLAGS="$LDFLAGS -Wl,-brtl";;
+bsdi3*)	CC=${CC-"shlicc2"}
+	LIBSO_LIBS="$LIBSO_LIBS -lipc";;
+cygwin*)
+	CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";;
+freebsd*)
+	CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"
+	LDFLAGS="$LDFLAGS -pthread";;
+gnu*|k*bsd*-gnu|linux*)
+	CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";;
+hpux*)	CPPFLAGS="$CPPFLAGS -D_REENTRANT";;
+irix*)	optimize_flag="-O2"
+	CPPFLAGS="$CPPFLAGS -D_SGI_MP_SOURCE";;
+mpeix*)	CPPFLAGS="$CPPFLAGS -D_POSIX_SOURCE -D_SOCKET_SOURCE"
+	LIBSO_LIBS="$LIBSO_LIBS -lsocket -lsvipc";;
+osf*)	CPPFLAGS="$CPPFLAGS -pthread";;
+*qnx*)	qnx_build="yes"
+	$as_echo "#define HAVE_QNX 1" >>confdefs.h
+
+	;;
+solaris*)
+	CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS ";;
+esac
+
+# Set CFLAGS/CXXFLAGS.  We MUST set the flags before we call autoconf
+# compiler configuration macros, because if we don't, they set CFLAGS
+# to no optimization and -g, which isn't what we want.
+#
+# If the user wants a debugging environment, add -g the their compiler flags
+# and don't automatically optimize.  If you want to compile with a different
+# set of flags, specify CFLAGS in the environment before configuring.
+if test "$db_cv_debug" = "yes"; then
+	$as_echo "#define DEBUG 1" >>confdefs.h
+
+
+
+	CFLAGS="-g $CFLAGS"
+else
+	CFLAGS=${CFLAGS-$optimize_flag}
+fi
+
+CFLAGS="$CFLAGS$extra_cflags"
+CXXFLAGS=${CXXFLAGS-"$CFLAGS"}
+
+# The default compiler is cc (NOT gcc), the default CFLAGS is as specified
+# above, NOT what is set by AC_PROG_CC, as it won't set optimization flags
+# for any compiler other than gcc.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in cc gcc
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cc gcc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# We know what compiler we're going to use, now.  Set per-compiler flags.
+if test "$GCC" = "yes"; then
+	# Use -O3 if we're using gcc, unless we're doing a small build, in
+	# which case we use -Os alone.  The code size for -O3 is quite a
+	# bit larger than -O2: a compromise is "-Os -finline-functions",
+	# it's smaller and explicitly inlining the functions helps Berkeley
+	# DB.
+	CFLAGS="$CFLAGS "
+	if test "$db_cv_smallbuild" = "yes" -o "$db_cv_rdsbuild" = "yes" ; then
+		CFLAGS=`echo "$CFLAGS" | sed 's/-O /-Os /g'`
+	else
+		CFLAGS=`echo "$CFLAGS" | sed 's/-O /-O3 /g'`
+	fi
+else
+	case "$host_os" in
+	hpux11.0*)	;;
+	hpux11*)	CPPFLAGS="$CPPFLAGS -mt"
+			test "$host_cpu" = "ia64" &&
+			    CFLAGS="$CFLAGS +u1";;
+	esac
+fi
+
+# Check for "const" and "inline" keywords.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset cs;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *pcpcc;
+  char **ppc;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  pcpcc = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+    if (s) return 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+    if (!foo) return 0;
+  }
+  return !cs[0] && !zero.x;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_const=yes
+else
+  ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+
+# We use prototypes and the keyword "const" in db.h which doesn't include
+# db_config.h, so we have to figure out what to do there.
+#
+# There is an autoconf AC_C_PROTOTYPES macro, but as all it does is define
+# db_config.h variables, it doesn't help us.
+#
+# We don't have much choice, we look at internal autoconf variables.
+if test "$ac_cv_c_const" != "yes"; then
+	DB_CONST="#define const"
+fi
+
+# We use alignment attributes in db.h - figure out if the compiler supports
+# them.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC aligned attribute" >&5
+$as_echo_n "checking for GCC aligned attribute... " >&6; }
+if ${db_cv_aligned_attribute+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__attribute__ ((aligned (8))) int i;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_aligned_attribute=yes
+else
+  db_cv_aligned_attribute=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_aligned_attribute" >&5
+$as_echo "$db_cv_aligned_attribute" >&6; }
+if test "$db_cv_aligned_attribute" = "yes"; then
+	DB_STRUCT_ALIGN8="__attribute__ ((aligned (8)))"
+fi
+
+# Clear __P, some other systems use it too.
+DB_PROTO1="#undef __P"
+if test "$ac_cv_prog_cc_c89" = "no"; then
+	DB_PROTO2="#define	__P(protos)	()"
+else
+	DB_PROTO2="#define	__P(protos)	protos"
+fi
+
+# Because of shared library building, the ${CC} used for config tests
+# may be different than the ${CC} we want to put in the Makefile.
+# The latter is known as ${MAKEFILE_CC} in this script.
+MAKEFILE_CC="${CC}"
+MAKEFILE_CCLINK="${CC}"
+MAKEFILE_CXX="nocxx"
+MAKEFILE_CXXLINK="nocxx"
+
+# See if we need the C++ compiler at all.  If so, we'd like to find one that
+# interoperates with the C compiler we chose.  Since we prefered cc over gcc,
+# we'll also prefer the vendor's compiler over g++/gcc.  If we're wrong, the
+# user can set CC and CXX in their environment before running configure.
+#
+# AC_PROG_CXX sets CXX, but it uses $CXX and $CCC (in that order) as its
+# first choices.
+if test "$db_cv_cxx" = "yes"; then
+	if test "$GCC" != "yes"; then
+		case "$host_os" in
+		aix*)		if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}xlC_r", so it can be a program name with args.
+set dummy ${ac_tool_prefix}xlC_r; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CCC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CCC"; then
+  ac_cv_prog_CCC="$CCC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CCC="${ac_tool_prefix}xlC_r"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CCC=$ac_cv_prog_CCC
+if test -n "$CCC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCC" >&5
+$as_echo "$CCC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CCC"; then
+  ac_ct_CCC=$CCC
+  # Extract the first word of "xlC_r", so it can be a program name with args.
+set dummy xlC_r; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CCC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CCC"; then
+  ac_cv_prog_ac_ct_CCC="$ac_ct_CCC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CCC="xlC_r"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CCC=$ac_cv_prog_ac_ct_CCC
+if test -n "$ac_ct_CCC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CCC" >&5
+$as_echo "$ac_ct_CCC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CCC" = x; then
+    CCC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CCC=$ac_ct_CCC
+  fi
+else
+  CCC="$ac_cv_prog_CCC"
+fi
+
+				LIBXSO_LIBS="-lC_r $LIBXSO_LIBS"
+				LIBSO_LIBS="-lC_r $LIBSO_LIBS";;
+		hpux*)		if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}aCC", so it can be a program name with args.
+set dummy ${ac_tool_prefix}aCC; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CCC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CCC"; then
+  ac_cv_prog_CCC="$CCC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CCC="${ac_tool_prefix}aCC"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CCC=$ac_cv_prog_CCC
+if test -n "$CCC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCC" >&5
+$as_echo "$CCC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CCC"; then
+  ac_ct_CCC=$CCC
+  # Extract the first word of "aCC", so it can be a program name with args.
+set dummy aCC; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CCC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CCC"; then
+  ac_cv_prog_ac_ct_CCC="$ac_ct_CCC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CCC="aCC"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CCC=$ac_cv_prog_ac_ct_CCC
+if test -n "$ac_ct_CCC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CCC" >&5
+$as_echo "$ac_ct_CCC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CCC" = x; then
+    CCC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CCC=$ac_ct_CCC
+  fi
+else
+  CCC="$ac_cv_prog_CCC"
+fi
+;;
+		irix*)		if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}CC", so it can be a program name with args.
+set dummy ${ac_tool_prefix}CC; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CCC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CCC"; then
+  ac_cv_prog_CCC="$CCC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CCC="${ac_tool_prefix}CC"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CCC=$ac_cv_prog_CCC
+if test -n "$CCC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCC" >&5
+$as_echo "$CCC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CCC"; then
+  ac_ct_CCC=$CCC
+  # Extract the first word of "CC", so it can be a program name with args.
+set dummy CC; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CCC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CCC"; then
+  ac_cv_prog_ac_ct_CCC="$ac_ct_CCC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CCC="CC"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CCC=$ac_cv_prog_ac_ct_CCC
+if test -n "$ac_ct_CCC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CCC" >&5
+$as_echo "$ac_ct_CCC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CCC" = x; then
+    CCC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CCC=$ac_ct_CCC
+  fi
+else
+  CCC="$ac_cv_prog_CCC"
+fi
+;;
+		osf*)		if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cxx", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cxx; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CCC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CCC"; then
+  ac_cv_prog_CCC="$CCC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CCC="${ac_tool_prefix}cxx"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CCC=$ac_cv_prog_CCC
+if test -n "$CCC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCC" >&5
+$as_echo "$CCC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CCC"; then
+  ac_ct_CCC=$CCC
+  # Extract the first word of "cxx", so it can be a program name with args.
+set dummy cxx; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CCC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CCC"; then
+  ac_cv_prog_ac_ct_CCC="$ac_ct_CCC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CCC="cxx"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CCC=$ac_cv_prog_ac_ct_CCC
+if test -n "$ac_ct_CCC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CCC" >&5
+$as_echo "$ac_ct_CCC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CCC" = x; then
+    CCC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CCC=$ac_ct_CCC
+  fi
+else
+  CCC="$ac_cv_prog_CCC"
+fi
+
+				CXXFLAGS="$CXXFLAGS -D__USE_STD_IOSTREAM"
+				test -d /usr/include.dtk &&
+				    CXXFLAGS="$CXXFLAGS -I/usr/include.dtk";;
+		solaris*)	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}CC", so it can be a program name with args.
+set dummy ${ac_tool_prefix}CC; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CCC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CCC"; then
+  ac_cv_prog_CCC="$CCC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CCC="${ac_tool_prefix}CC"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CCC=$ac_cv_prog_CCC
+if test -n "$CCC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCC" >&5
+$as_echo "$CCC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CCC"; then
+  ac_ct_CCC=$CCC
+  # Extract the first word of "CC", so it can be a program name with args.
+set dummy CC; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CCC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CCC"; then
+  ac_cv_prog_ac_ct_CCC="$ac_ct_CCC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CCC="CC"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CCC=$ac_cv_prog_ac_ct_CCC
+if test -n "$ac_ct_CCC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CCC" >&5
+$as_echo "$ac_ct_CCC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CCC" = x; then
+    CCC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CCC=$ac_ct_CCC
+  fi
+else
+  CCC="$ac_cv_prog_CCC"
+fi
+;;
+		esac
+	fi
+	ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+	###### WORKAROUND: SEE SR #7938
+	ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+	###############################
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ supports the ISO C++ standard includes" >&5
+$as_echo_n "checking whether C++ supports the ISO C++ standard includes... " >&6; }
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <iostream>
+int
+main ()
+{
+std::ostream *o; return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  db_cv_cxx_have_stdheaders=yes
+else
+  db_cv_cxx_have_stdheaders=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_cxx_have_stdheaders" >&5
+$as_echo "$db_cv_cxx_have_stdheaders" >&6; }
+if test "$db_cv_cxx_have_stdheaders" = yes; then
+	cxx_have_stdheaders="#define	HAVE_CXX_STDHEADERS 1"
+fi
+	MAKEFILE_CXX="${CXX}"
+	MAKEFILE_CXXLINK="${CXX}"
+fi
+
+# Do some gcc specific configuration.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using gcc version 2.96" >&5
+$as_echo_n "checking whether we are using gcc version 2.96... " >&6; }
+if ${db_cv_gcc_2_96+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+db_cv_gcc_2_96=no
+if test "$GCC" = "yes"; then
+	GCC_VERSION=`${MAKEFILE_CC} --version`
+	case ${GCC_VERSION} in
+	2.96*)
+		db_cv_gcc_2_96=yes;;
+	esac
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_gcc_2_96" >&5
+$as_echo "$db_cv_gcc_2_96" >&6; }
+if test "$db_cv_gcc_2_96" = "yes"; then
+	CFLAGS=`echo "$CFLAGS" | sed 's/-O2/-O/'`
+	CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-O2/-O/'`
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: INSTALLED GCC COMPILER HAS SERIOUS BUGS; PLEASE UPGRADE." >&5
+$as_echo "$as_me: WARNING: INSTALLED GCC COMPILER HAS SERIOUS BUGS; PLEASE UPGRADE." >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: GCC OPTIMIZATION LEVEL SET TO -O." >&5
+$as_echo "$as_me: WARNING: GCC OPTIMIZATION LEVEL SET TO -O." >&2;}
+fi
+
+# We need the -Kthread/-pthread flag when compiling on SCO/Caldera's UnixWare
+# and OpenUNIX releases.  We can't make the test until we know which compiler
+# we're using.
+case "$host_os" in
+sysv5UnixWare*|sysv5OpenUNIX8*)
+	if test "$GCC" == "yes"; then
+		CPPFLAGS="$CPPFLAGS -pthread"
+		LDFLAGS="$LDFLAGS -pthread"
+	else
+		CPPFLAGS="$CPPFLAGS -Kthread"
+		LDFLAGS="$LDFLAGS -Kthread"
+	fi;;
+esac
+
+# Export our compiler preferences for the libtool configuration.
+export CC CCC
+CCC=$CXX
+
+# Libtool configuration.
+case `pwd` in
+  *\ * | *\	*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4'
+macro_revision='1.3293'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in fgrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DUMPBIN"; then
+  ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$DUMPBIN" && break
+  done
+fi
+if test -z "$DUMPBIN"; then
+  ac_ct_DUMPBIN=$DUMPBIN
+  for ac_prog in dumpbin "link -dump"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DUMPBIN"; then
+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_DUMPBIN" && break
+done
+
+  if test "x$ac_ct_DUMPBIN" = x; then
+    DUMPBIN=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DUMPBIN=$ac_ct_DUMPBIN
+  fi
+fi
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+  cat conftest.out >&5
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[	 ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+  ac_ct_DLLTOOL=$DLLTOOL
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DLLTOOL"; then
+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DLLTOOL" = x; then
+    DLLTOOL="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DLLTOOL=$ac_ct_DLLTOOL
+  fi
+else
+  DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_AR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK '"\
+"     {last_section=section; section=\$ 3};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+  enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_cc_needs_belf=yes
+else
+  lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  case $host_os in
+    rhapsody* | darwin*)
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DSYMUTIL"; then
+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+  ac_ct_DSYMUTIL=$DSYMUTIL
+  # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DSYMUTIL"; then
+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DSYMUTIL" = x; then
+    DSYMUTIL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DSYMUTIL=$ac_ct_DSYMUTIL
+  fi
+else
+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NMEDIT"; then
+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+  ac_ct_NMEDIT=$NMEDIT
+  # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_NMEDIT"; then
+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_NMEDIT="nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_NMEDIT" = x; then
+    NMEDIT=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    NMEDIT=$ac_ct_NMEDIT
+  fi
+else
+  NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LIPO"; then
+  ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+  ac_ct_LIPO=$LIPO
+  # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_LIPO"; then
+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_LIPO="lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_LIPO" = x; then
+    LIPO=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    LIPO=$ac_ct_LIPO
+  fi
+else
+  LIPO="$ac_cv_prog_LIPO"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL"; then
+  ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+  ac_ct_OTOOL=$OTOOL
+  # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL"; then
+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL="otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL" = x; then
+    OTOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL=$ac_ct_OTOOL
+  fi
+else
+  OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL64"; then
+  ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+  ac_ct_OTOOL64=$OTOOL64
+  # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL64"; then
+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL64="otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL64" = x; then
+    OTOOL64=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL64=$ac_ct_OTOOL64
+  fi
+else
+  OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&5
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_ld_exported_symbols_list=yes
+else
+  lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+    case $host_os in
+    rhapsody* | darwin1.[012])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[012]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=no
+
+
+            # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+  # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+  withval=$with_pic; pic_mode="$withval"
+else
+  pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+  # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+
+
+
+
+
+  lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      lt_prog_compiler_pic='-Xcompiler -fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='--shared'
+	lt_prog_compiler_static='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fpic'
+	lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ F* | *Sun*Fortran*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl=''
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  always_export_symbols=no
+  archive_cmds=
+  archive_expsym_cmds=
+  compiler_needs_object=no
+  enable_shared_with_static_runtimes=no
+  export_dynamic_flag_spec=
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic=no
+  hardcode_direct=no
+  hardcode_direct_absolute=no
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_flag_spec_ld=
+  hardcode_libdir_separator=
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  inherit_rpath=no
+  link_all_deplibs=unknown
+  module_cmds=
+  module_expsym_cmds=
+  old_archive_from_new_cmds=
+  old_archive_from_expsyms_cmds=
+  thread_safe_flag_spec=
+  whole_archive_flag_spec=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  whole_archive_flag_spec=
+	  tmp_sharedflag='--shared' ;;
+	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+	  hardcode_libdir_flag_spec=
+	  hardcode_libdir_flag_spec_ld='-rpath $libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_direct_absolute=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      file_list_spec='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      export_dynamic_flag_spec='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  archive_cmds_need_lc=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	old_archive_from_new_cmds='true'
+	# FIXME: Should let the user specify the lib program.
+	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  else
+    whole_archive_flag_spec=''
+  fi
+  link_all_deplibs=yes
+  allow_undefined_flag="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+  else
+  ld_shlibs=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_flag_spec_ld='+b $libdir'
+	hardcode_libdir_separator=:
+	hardcode_direct=yes
+	hardcode_direct_absolute=yes
+	export_dynamic_flag_spec='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	*)
+	  hardcode_direct=yes
+	  hardcode_direct_absolute=yes
+	  export_dynamic_flag_spec='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+           LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      inherit_rpath=yes
+      link_all_deplibs=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct=yes
+	hardcode_shlibpath_var=no
+	hardcode_direct_absolute=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	export_dynamic_flag_spec='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$lt_prog_compiler_wl
+	  pic_flag=$lt_prog_compiler_pic
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag
+	  allow_undefined_flag=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	  then
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+haiku*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+   test -n "$runpath_var" ||
+   test "X$hardcode_automatic" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+  if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+    ;;
+
+  *)
+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+  lt_cv_dlopen="shl_load"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_svld_dlopen=yes
+else
+  ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_dld_link=yes
+else
+  ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    fi
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+  # Report which library types will actually be built
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[4-9]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+else
+  _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_flag_spec_ld_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+  # save warnings/boilerplate of simple test code
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_CFLAGS=$CFLAGS
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  compiler_CXX=$CC
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+    else
+      lt_prog_compiler_no_builtin_flag_CXX=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          whole_archive_flag_spec_CXX=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+    ld_shlibs_CXX=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+      aix[4-9]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        archive_cmds_CXX=''
+        hardcode_direct_CXX=yes
+        hardcode_direct_absolute_CXX=yes
+        hardcode_libdir_separator_CXX=':'
+        link_all_deplibs_CXX=yes
+        file_list_spec_CXX='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[012]|aix4.[012].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    hardcode_direct_CXX=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    hardcode_minus_L_CXX=yes
+	    hardcode_libdir_flag_spec_CXX='-L$libdir'
+	    hardcode_libdir_separator_CXX=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        export_dynamic_flag_spec_CXX='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        always_export_symbols_CXX=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          allow_undefined_flag_CXX='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+	    allow_undefined_flag_CXX="-z nodefs"
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    no_undefined_flag_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      whole_archive_flag_spec_CXX='$convenience'
+	    fi
+	    archive_cmds_need_lc_CXX=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  allow_undefined_flag_CXX=unsupported
+	  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX=' '
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=yes
+	  file_list_spec_CXX='@'
+	  # Tell ltmain to make .lib files, not .a files.
+	  libext=lib
+	  # Tell ltmain to make .dll files, not .so files.
+	  shrext_cmds=".dll"
+	  # FIXME: Setting linknames here is a bad hack.
+	  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+	  enable_shared_with_static_runtimes_CXX=yes
+	  # Don't use ranlib
+	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
+	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX='-L$libdir'
+	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=no
+	  enable_shared_with_static_runtimes_CXX=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	  else
+	    ld_shlibs_CXX=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc_CXX=no
+  hardcode_direct_CXX=no
+  hardcode_automatic_CXX=yes
+  hardcode_shlibpath_var_CXX=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+  else
+    whole_archive_flag_spec_CXX=''
+  fi
+  link_all_deplibs_CXX=yes
+  allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+
+  else
+  ld_shlibs_CXX=no
+  fi
+
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      freebsd[12]*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        ld_shlibs_CXX=no
+        ;;
+
+      freebsd-elf*)
+        archive_cmds_need_lc_CXX=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        ld_shlibs_CXX=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      haiku*)
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        link_all_deplibs_CXX=yes
+        ;;
+
+      hpux9*)
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        export_dynamic_flag_spec_CXX='${wl}-E'
+        hardcode_direct_CXX=yes
+        hardcode_minus_L_CXX=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            ld_shlibs_CXX=no
+            ;;
+          aCC*)
+            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              ld_shlibs_CXX=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      export_dynamic_flag_spec_CXX='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct_CXX=no
+            hardcode_shlibpath_var_CXX=no
+            ;;
+          *)
+            hardcode_direct_CXX=yes
+            hardcode_direct_absolute_CXX=yes
+            hardcode_minus_L_CXX=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[3-9]*)
+	hardcode_direct_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    link_all_deplibs_CXX=yes
+	    ;;
+        esac
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        inherit_rpath_CXX=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    archive_cmds_need_lc_CXX=no
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+	      prelink_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      old_archive_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      archive_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      no_undefined_flag_CXX=' -zdefs'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      hardcode_libdir_flag_spec_CXX='-R$libdir'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      compiler_needs_object_CXX=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='func_echo_all'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  hardcode_libdir_flag_spec_CXX='-R$libdir'
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        ld_shlibs_CXX=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	  hardcode_direct_absolute_CXX=yes
+	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        allow_undefined_flag_CXX=' -expect_unresolved \*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+		;;
+	    esac
+
+	    hardcode_libdir_separator_CXX=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	      hardcode_libdir_separator_CXX=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            archive_cmds_need_lc_CXX=yes
+	    no_undefined_flag_CXX=' -zdefs'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    hardcode_libdir_flag_spec_CXX='-R$libdir'
+	    hardcode_shlibpath_var_CXX=no
+	    case $host_os in
+	      solaris2.[0-5] | solaris2.[0-5].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    link_all_deplibs_CXX=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[0-5] | solaris2.[0-5].*) ;;
+		*)
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_CXX='${wl}-z,text'
+      archive_cmds_need_lc_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
+	archive_cmds_need_lc_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+	hardcode_libdir_separator_CXX=':'
+	link_all_deplibs_CXX=yes
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+	      '"$old_archive_cmds_CXX"
+	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+	      '"$reload_cmds_CXX"
+	    ;;
+	  *)
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+    esac
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+    GCC_CXX="$GXX"
+    LD_CXX="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+esac
+
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case ${prev}${p} in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
+	 -L | -R)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$compiler_lib_search_path_CXX"; then
+	     compiler_lib_search_path_CXX="${prev}${p}"
+	   else
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$postdeps_CXX"; then
+	   postdeps_CXX="${prev}${p}"
+	 else
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$predep_objects_CXX"; then
+	   predep_objects_CXX="$p"
+	 else
+	   predep_objects_CXX="$predep_objects_CXX $p"
+	 fi
+       else
+	 if test -z "$postdep_objects_CXX"; then
+	   postdep_objects_CXX="$p"
+	 else
+	   postdep_objects_CXX="$postdep_objects_CXX $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix[3-9]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_CXX='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic_CXX='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static_CXX=
+      ;;
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic_CXX=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	lt_prog_compiler_pic_CXX='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_CXX='-fPIC -shared'
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[4-9]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  lt_prog_compiler_static_CXX='-Bstatic'
+	else
+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      mingw* | cygwin* | os2* | pw32* | cegcc*)
+	# This hack is so that the source file can tell whether it is being
+	# built for inclusion in a dll (and should export symbols for example).
+	lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      lt_prog_compiler_pic_CXX='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      lt_prog_compiler_pic_CXX='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fpic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-qpic'
+	    lt_prog_compiler_static_CXX='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      lt_prog_compiler_pic_CXX='-KPIC'
+	      lt_prog_compiler_static_CXX='-Bstatic'
+	      lt_prog_compiler_wl_CXX='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    lt_prog_compiler_pic_CXX='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        lt_prog_compiler_pic_CXX='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    lt_prog_compiler_wl_CXX='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    lt_prog_compiler_pic_CXX='-pic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	lt_prog_compiler_can_build_shared_CXX=no
+	;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works_CXX=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works_CXX=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works_CXX=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works_CXX=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+fi
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  case $host_os in
+  aix[4-9]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*) ;;
+    *)
+      export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+      ;;
+    esac
+    ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$lt_prog_compiler_wl_CXX
+	  pic_flag=$lt_prog_compiler_pic_CXX
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+	  allow_undefined_flag_CXX=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	  then
+	    lt_cv_archive_cmds_need_lc_CXX=no
+	  else
+	    lt_cv_archive_cmds_need_lc_CXX=yes
+	  fi
+	  allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+      archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+haiku*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+   test -n "$runpath_var_CXX" ||
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct_CXX" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+        ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+SOFLAGS="-rpath \$(libdir)"
+
+# Set SOSUFFIX and friends
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking SOSUFFIX from libtool" >&5
+$as_echo_n "checking SOSUFFIX from libtool... " >&6; }
+	module=no
+
+	versuffix=""
+	release=""
+	libname=libfoo
+	eval _SOSUFFIX=\"$shrext_cmds\"
+	if test "$_SOSUFFIX" = "" ; then
+		_SOSUFFIX=".so"
+		if test "$enable_shared" != "yes"; then
+			if test "$_SOSUFFIX_MESSAGE" = ""; then
+				_SOSUFFIX_MESSAGE=yes
+        			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libtool may not know about this architecture." >&5
+$as_echo "$as_me: WARNING: libtool may not know about this architecture." >&2;}
+               			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&5
+$as_echo "$as_me: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&2;}
+			fi
+        	fi
+        fi
+
+        SOSUFFIX=$_SOSUFFIX
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SOSUFFIX" >&5
+$as_echo "$SOSUFFIX" >&6; }
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking MODSUFFIX from libtool" >&5
+$as_echo_n "checking MODSUFFIX from libtool... " >&6; }
+	module=yes
+
+	versuffix=""
+	release=""
+	libname=libfoo
+	eval _SOSUFFIX=\"$shrext_cmds\"
+	if test "$_SOSUFFIX" = "" ; then
+		_SOSUFFIX=".so"
+		if test "$enable_shared" != "yes"; then
+			if test "$_SOSUFFIX_MESSAGE" = ""; then
+				_SOSUFFIX_MESSAGE=yes
+        			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libtool may not know about this architecture." >&5
+$as_echo "$as_me: WARNING: libtool may not know about this architecture." >&2;}
+               			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&5
+$as_echo "$as_me: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&2;}
+			fi
+        	fi
+        fi
+
+        MODSUFFIX=$_SOSUFFIX
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MODSUFFIX" >&5
+$as_echo "$MODSUFFIX" >&6; }
+
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking JMODSUFFIX from libtool" >&5
+$as_echo_n "checking JMODSUFFIX from libtool... " >&6; }
+	module=yes
+
+	versuffix=""
+	release=""
+	libname=libfoo
+	eval _SOSUFFIX=\"$shrext_cmds\"
+	if test "$_SOSUFFIX" = "" ; then
+		_SOSUFFIX=".so"
+		if test "$enable_shared" != "yes"; then
+			if test "$_SOSUFFIX_MESSAGE" = ""; then
+				_SOSUFFIX_MESSAGE=yes
+        			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libtool may not know about this architecture." >&5
+$as_echo "$as_me: WARNING: libtool may not know about this architecture." >&2;}
+               			{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&5
+$as_echo "$as_me: WARNING: assuming $_SOSUFFIX suffix for dynamic libraries." >&2;}
+			fi
+        	fi
+        fi
+
+	if test `uname` = "Darwin"; then
+	    JMODSUFFIX=".jnilib"
+	else
+            JMODSUFFIX=$_SOSUFFIX
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $JMODSUFFIX" >&5
+$as_echo "$JMODSUFFIX" >&6; }
+
+
+
+LIBTOOL="./libtool"
+
+INSTALLER="\$(LIBTOOL) --mode=install cp -p"
+
+MAKEFILE_CC="\$(LIBTOOL) --mode=compile ${MAKEFILE_CC}"
+MAKEFILE_SOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK} -avoid-version"
+MAKEFILE_CCLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK}"
+MAKEFILE_CXX="\$(LIBTOOL) --mode=compile ${MAKEFILE_CXX}"
+MAKEFILE_XSOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK} -avoid-version"
+MAKEFILE_CXXLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK}"
+
+
+case "$host_os" in
+cygwin* | mingw*)
+	MAKEFILE_SOLINK="$MAKEFILE_SOLINK -no-undefined"
+	MAKEFILE_XSOLINK="$MAKEFILE_XSOLINK -no-undefined";;
+esac
+
+case "$host_os" in
+    darwin*)
+        LIBTSO_MODULE=""
+        LIBTSO_MODSUFFIX=".dylib";;
+    *qnx*)
+        LIBTSO_MODULE=""
+        LIBTSO_MODSUFFIX=$MODSUFFIX;;
+    *)
+        LIBTSO_MODULE="-module"
+        LIBTSO_MODSUFFIX=$MODSUFFIX;;
+esac
+
+if test "$enable_static" = "yes"; then
+	test "$AR" = "false" && as_fn_error $? "No ar utility found." "$LINENO" 5
+fi
+
+# C API.
+if test "$enable_shared" = "no"; then
+	DEFAULT_LIB="\$(libdb_version)"
+	POSTLINK=": "
+	o=".o"
+else
+	DEFAULT_LIB="\$(libso_target)"
+	POSTLINK="\$(LIBTOOL) --mode=execute true"
+	o=".lo"
+fi
+INSTALL_LIBS="$DEFAULT_LIB"
+if test "$enable_static" = "yes"; then
+	INSTALL_LIBS="$INSTALL_LIBS \$(libdb)"
+fi
+
+# Optional C++ API.
+if test "$db_cv_cxx" = "yes"; then
+	if test "$enable_shared" = "no"; then
+		DEFAULT_LIB_CXX="\$(libcxx_version)"
+	fi
+	if test "$enable_shared" = "yes"; then
+		DEFAULT_LIB_CXX="\$(libxso_target)"
+	fi
+	INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_CXX"
+	if test "$enable_static" = "yes"; then
+		INSTALL_LIBS="$INSTALL_LIBS \$(libcxx)"
+	fi
+fi
+
+# Optional Java API / JDBC.
+if test "$db_cv_java" = "yes" -o "$db_cv_jdbc" = "yes"; then
+	# BDB Java API requires shared libraries.
+	if test "$db_cv_java" = "yes" -a "$enable_shared" = "no"; then
+		as_fn_error $? "Java requires shared libraries" "$LINENO" 5
+	fi
+
+        # A classpath that includes . is needed to check for Java
+	# Since Cygwin uses Windows' javac, we need Windows path separators
+	case "$host_os" in
+	cygwin*)	CLASSPATH=".;$CLASSPATH";;
+	*)		CLASSPATH=".:$CLASSPATH";;
+	esac
+	export CLASSPATH
+
+
+if test "x$JAVAPREFIX" = x; then
+        test "x$JAVAC" = x && for ac_prog in javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_JAVAC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$JAVAC"; then
+  ac_cv_prog_JAVAC="$JAVAC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_JAVAC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+JAVAC=$ac_cv_prog_JAVAC
+if test -n "$JAVAC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAC" >&5
+$as_echo "$JAVAC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$JAVAC" && break
+done
+
+else
+        test "x$JAVAC" = x && for ac_prog in javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_JAVAC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$JAVAC"; then
+  ac_cv_prog_JAVAC="$JAVAC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_JAVAC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+JAVAC=$ac_cv_prog_JAVAC
+if test -n "$JAVAC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAC" >&5
+$as_echo "$JAVAC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$JAVAC" && break
+done
+test -n "$JAVAC" || JAVAC="$JAVAPREFIX"
+
+fi
+test "x$JAVAC" = x && as_fn_error $? "no acceptable Java compiler found in \$PATH" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $JAVAC works" >&5
+$as_echo_n "checking if $JAVAC works... " >&6; }
+if ${ac_cv_prog_javac_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+JAVA_TEST=Test.java
+CLASS_TEST=Test.class
+cat << \EOF > $JAVA_TEST
+/* #line 17944 "configure" */
+public class Test {
+}
+EOF
+if { ac_try='$JAVAC $JAVACFLAGS $JAVA_TEST'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null 2>&1; then
+  ac_cv_prog_javac_works=yes
+else
+  as_fn_error $? "The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)" "$LINENO" 5
+  echo "configure: failed program was:" >&5
+  cat $JAVA_TEST >&5
+fi
+rm -f $JAVA_TEST $CLASS_TEST
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_javac_works" >&5
+$as_echo "$ac_cv_prog_javac_works" >&6; }
+
+
+
+if test "x$JAVAPREFIX" = x; then
+        test "x$JAR" = x && for ac_prog in jar$EXEEXT
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_JAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$JAR"; then
+  ac_cv_prog_JAR="$JAR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_JAR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+JAR=$ac_cv_prog_JAR
+if test -n "$JAR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAR" >&5
+$as_echo "$JAR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$JAR" && break
+done
+
+else
+        test "x$JAR" = x && for ac_prog in jar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_JAR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$JAR"; then
+  ac_cv_prog_JAR="$JAR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_JAR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+JAR=$ac_cv_prog_JAR
+if test -n "$JAR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAR" >&5
+$as_echo "$JAR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$JAR" && break
+done
+test -n "$JAR" || JAR="$JAVAPREFIX"
+
+fi
+test "x$JAR" = x && as_fn_error $? "no acceptable jar program found in \$PATH" "$LINENO" 5
+
+
+if test x$JAVAPREFIX = x; then
+        test x$JAVA = x && for ac_prog in java$EXEEXT kaffe$EXEEXT
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_JAVA+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$JAVA"; then
+  ac_cv_prog_JAVA="$JAVA" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_JAVA="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+JAVA=$ac_cv_prog_JAVA
+if test -n "$JAVA"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA" >&5
+$as_echo "$JAVA" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$JAVA" && break
+done
+
+else
+        test x$JAVA = x && for ac_prog in java$EXEEXT kaffe$EXEEXT
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_JAVA+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$JAVA"; then
+  ac_cv_prog_JAVA="$JAVA" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_JAVA="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+JAVA=$ac_cv_prog_JAVA
+if test -n "$JAVA"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA" >&5
+$as_echo "$JAVA" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$JAVA" && break
+done
+test -n "$JAVA" || JAVA="$JAVAPREFIX"
+
+fi
+test x$JAVA = x && as_fn_error $? "no acceptable Java virtual machine found in \$PATH" "$LINENO" 5
+
+# Extract the first word of "uudecode$EXEEXT", so it can be a program name with args.
+set dummy uudecode$EXEEXT; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_uudecode+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$uudecode"; then
+  ac_cv_prog_uudecode="$uudecode" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_uudecode="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+uudecode=$ac_cv_prog_uudecode
+if test -n "$uudecode"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $uudecode" >&5
+$as_echo "$uudecode" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test x$uudecode = xyes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if uudecode can decode base 64 file" >&5
+$as_echo_n "checking if uudecode can decode base 64 file... " >&6; }
+if ${ac_cv_prog_uudecode_base64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+cat << \EOF > Test.uue
+begin-base64 644 Test.class
+yv66vgADAC0AFQcAAgEABFRlc3QHAAQBABBqYXZhL2xhbmcvT2JqZWN0AQAE
+bWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARDb2RlAQAPTGluZU51
+bWJlclRhYmxlDAAKAAsBAARleGl0AQAEKEkpVgoADQAJBwAOAQAQamF2YS9s
+YW5nL1N5c3RlbQEABjxpbml0PgEAAygpVgwADwAQCgADABEBAApTb3VyY2VG
+aWxlAQAJVGVzdC5qYXZhACEAAQADAAAAAAACAAkABQAGAAEABwAAACEAAQAB
+AAAABQO4AAyxAAAAAQAIAAAACgACAAAACgAEAAsAAQAPABAAAQAHAAAAIQAB
+AAEAAAAFKrcAErEAAAABAAgAAAAKAAIAAAAEAAQABAABABMAAAACABQ=
+====
+EOF
+if uudecode$EXEEXT Test.uue; then
+        ac_cv_prog_uudecode_base64=yes
+else
+        echo "configure: 18207: uudecode had trouble decoding base 64 file 'Test.uue'" >&5
+        echo "configure: failed file was:" >&5
+        cat Test.uue >&5
+        ac_cv_prog_uudecode_base64=no
+fi
+rm -f Test.uue
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_uudecode_base64" >&5
+$as_echo "$ac_cv_prog_uudecode_base64" >&6; }
+fi
+if test x$ac_cv_prog_uudecode_base64 != xyes; then
+        rm -f Test.class
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: I have to compile Test.class from scratch" >&5
+$as_echo "$as_me: WARNING: I have to compile Test.class from scratch" >&2;}
+        if test x$ac_cv_prog_javac_works = xno; then
+                as_fn_error $? "Cannot compile java source. $JAVAC does not work properly" "$LINENO" 5
+        fi
+        if test x$ac_cv_prog_javac_works = x; then
+
+if test "x$JAVAPREFIX" = x; then
+        test "x$JAVAC" = x && for ac_prog in javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_JAVAC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$JAVAC"; then
+  ac_cv_prog_JAVAC="$JAVAC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_JAVAC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+JAVAC=$ac_cv_prog_JAVAC
+if test -n "$JAVAC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAC" >&5
+$as_echo "$JAVAC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$JAVAC" && break
+done
+
+else
+        test "x$JAVAC" = x && for ac_prog in javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_JAVAC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$JAVAC"; then
+  ac_cv_prog_JAVAC="$JAVAC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_JAVAC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+JAVAC=$ac_cv_prog_JAVAC
+if test -n "$JAVAC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAC" >&5
+$as_echo "$JAVAC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$JAVAC" && break
+done
+test -n "$JAVAC" || JAVAC="$JAVAPREFIX"
+
+fi
+test "x$JAVAC" = x && as_fn_error $? "no acceptable Java compiler found in \$PATH" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $JAVAC works" >&5
+$as_echo_n "checking if $JAVAC works... " >&6; }
+if ${ac_cv_prog_javac_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+JAVA_TEST=Test.java
+CLASS_TEST=Test.class
+cat << \EOF > $JAVA_TEST
+/* #line 18325 "configure" */
+public class Test {
+}
+EOF
+if { ac_try='$JAVAC $JAVACFLAGS $JAVA_TEST'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null 2>&1; then
+  ac_cv_prog_javac_works=yes
+else
+  as_fn_error $? "The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)" "$LINENO" 5
+  echo "configure: failed program was:" >&5
+  cat $JAVA_TEST >&5
+fi
+rm -f $JAVA_TEST $CLASS_TEST
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_javac_works" >&5
+$as_echo "$ac_cv_prog_javac_works" >&6; }
+
+
+        fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $JAVA works" >&5
+$as_echo_n "checking if $JAVA works... " >&6; }
+if ${ac_cv_prog_java_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+JAVA_TEST=Test.java
+CLASS_TEST=Test.class
+TEST=Test
+cat << \EOF > $JAVA_TEST
+/* [#]line 18360 "configure" */
+public class Test {
+public static void main (String args[]) {
+        System.exit (0);
+} }
+EOF
+if test x$ac_cv_prog_uudecode_base64 != xyes; then
+        if { ac_try='$JAVAC $JAVACFLAGS $JAVA_TEST'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } && test -s $CLASS_TEST; then
+                :
+        else
+          echo "configure: failed program was:" >&5
+          cat $JAVA_TEST >&5
+          as_fn_error $? "The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)" "$LINENO" 5
+        fi
+fi
+if { ac_try='$JAVA $JAVAFLAGS $TEST'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null 2>&1; then
+  ac_cv_prog_java_works=yes
+else
+  echo "configure: failed program was:" >&5
+  cat $JAVA_TEST >&5
+  as_fn_error $? "The Java VM $JAVA failed (see config.log, check the CLASSPATH?)" "$LINENO" 5
+fi
+rm -fr $JAVA_TEST $CLASS_TEST Test.uue
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_java_works" >&5
+$as_echo "$ac_cv_prog_java_works" >&6; }
+
+
+
+
+
+JNI_INCLUDE_DIRS=""
+
+test "x$JAVAC" = x && as_fn_error $? "'$JAVAC' undefined" "$LINENO" 5
+# Extract the first word of "$JAVAC", so it can be a program name with args.
+set dummy $JAVAC; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path__ACJNI_JAVAC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $_ACJNI_JAVAC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path__ACJNI_JAVAC="$_ACJNI_JAVAC" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path__ACJNI_JAVAC="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path__ACJNI_JAVAC" && ac_cv_path__ACJNI_JAVAC="$JAVAC"
+  ;;
+esac
+fi
+_ACJNI_JAVAC=$ac_cv_path__ACJNI_JAVAC
+if test -n "$_ACJNI_JAVAC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_ACJNI_JAVAC" >&5
+$as_echo "$_ACJNI_JAVAC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+test ! -x "$_ACJNI_JAVAC" && as_fn_error $? "$JAVAC could not be found in path" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute path of $JAVAC" >&5
+$as_echo_n "checking absolute path of $JAVAC... " >&6; }
+case "$_ACJNI_JAVAC" in
+/*)	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_ACJNI_JAVAC" >&5
+$as_echo "$_ACJNI_JAVAC" >&6; };;
+*)	as_fn_error $? "$_ACJNI_JAVAC is not an absolute path name" "$LINENO" 5;;
+esac
+
+
+# find the include directory relative to the javac executable
+_cur=""$_ACJNI_JAVAC""
+while ls -ld "$_cur" 2>/dev/null | grep " -> " >/dev/null; do
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking symlink for $_cur" >&5
+$as_echo_n "checking symlink for $_cur... " >&6; }
+	_slink=`ls -ld "$_cur" | sed 's/.* -> //'`
+	case "$_slink" in
+	/*) _cur="$_slink";;
+	# 'X' avoids triggering unwanted echo options.
+	*) _cur=`echo "X$_cur" | sed -e 's/^X//' -e 's:[^/]*$::'`"$_slink";;
+	esac
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_cur" >&5
+$as_echo "$_cur" >&6; }
+done
+_ACJNI_FOLLOWED="$_cur"
+
+_JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[^/]*$::'`
+case "$host_os" in
+	darwin*)	_JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[^/]*$::'`
+			_JINC="$_JTOPDIR/Headers";;
+	*)		_JINC="$_JTOPDIR/include";;
+esac
+
+# If we find jni.h in /usr/include, then it's not a java-only tree, so
+# don't add /usr/include or subdirectories to the list of includes.
+# An extra -I/usr/include can foul things up with newer gcc's.
+#
+# If we don't find jni.h, just keep going.  Hopefully javac knows where
+# to find its include files, even if we can't.
+if test -r "$_JINC/jni.h"; then
+	if test "$_JINC" != "/usr/include"; then
+		JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JINC"
+	fi
+else
+	_JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[^/]*$::'`
+	if test -r "$_JTOPDIR/include/jni.h"; then
+		if test "$_JTOPDIR" != "/usr"; then
+			JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include"
+		fi
+	fi
+fi
+
+# get the likely subdirectories for system specific java includes
+if test "$_JTOPDIR" != "/usr"; then
+	case "$host_os" in
+	aix*)		_JNI_INC_SUBDIRS="aix";;
+	bsdi*)		_JNI_INC_SUBDIRS="bsdos";;
+	cygwin*)	_JNI_INC_SUBDIRS="win32";;
+	freebsd*)	_JNI_INC_SUBDIRS="freebsd";;
+	hp*)		_JNI_INC_SUBDIRS="hp-ux";;
+	linux*)		_JNI_INC_SUBDIRS="linux genunix";;
+	osf*)		_JNI_INC_SUBDIRS="alpha";;
+	solaris*)	_JNI_INC_SUBDIRS="solaris";;
+	*)		_JNI_INC_SUBDIRS="genunix";;
+	esac
+fi
+
+# add any subdirectories that are present
+for _JINCSUBDIR in $_JNI_INC_SUBDIRS
+do
+	if test -d "$_JTOPDIR/include/$_JINCSUBDIR"; then
+		JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$_JINCSUBDIR"
+	fi
+done
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking java version" >&5
+$as_echo_n "checking java version... " >&6; }
+        case "$JAVA" in
+	*kaffe* )
+		JAVA_VERSION=`$JAVA -version 2>&1 |
+			sed -e '/Java Version:/!d' -e 's/.*Java Version: \([^ 	]*\)[ 	]*/\1/'` ;;
+	* )	JAVA_VERSION=`$JAVA -version 2>&1 |
+        	       	sed -e '/ version /!d' -e 's/.*"\(.*\)".*/\1/'` ;;
+	esac
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA_VERSION" >&5
+$as_echo "$JAVA_VERSION" >&6; }
+	case "$JAVA_VERSION" in
+	1.[3456789]* | 1.[1-9][0-9]* | [23456789]* ) ;;
+	* )
+		as_fn_error $? "Java version 1.3 or higher required, got $JAVA_VERSION" "$LINENO" 5 ;;
+	esac
+
+	# Because of the code that SWIG generates to cast between pointers and
+	# integers, we need to add the flag "-fno-strict-aliasing" to the gcc
+	# command line when compiling the JNI code.  This is documented in
+	# [#14953] and at http://www.swig.org/Doc1.3/Java.html
+	if test "${GCC}" = "yes"; then
+		SWIGCFLAGS="-fno-strict-aliasing"
+	fi
+
+	for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS
+	do
+		CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR"
+	done
+
+	if test "$db_cv_java" = "yes"; then
+		ADDITIONAL_LANG="$ADDITIONAL_LANG java"
+		INSTALL_LIBS="$INSTALL_LIBS \$(libjso_target)"
+	fi
+else
+	JAVAC=nojavac
+fi
+
+# MinGW support.
+if test "$db_cv_mingw" = "yes"; then
+	OSDIR=os_windows
+	PATH_SEPARATOR="\\\\/:"
+
+	$as_echo "#define DB_WIN32 1" >>confdefs.h
+
+	$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+else
+	OSDIR=os
+	PATH_SEPARATOR="/"
+	$as_echo "#define HAVE_SYSTEM_INCLUDE_FILES 1" >>confdefs.h
+
+fi
+
+# Optional SQL API.
+if test "$db_cv_sql" = "yes"; then
+	ADDITIONAL_INCS="$ADDITIONAL_INCS dbsql.h"
+	ADDITIONAL_PROGS="$ADDITIONAL_PROGS dbsql"
+
+	# Link against libdl, if found. It is only needed for the load
+	# extension, but shouldn't hurt.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ldl" >&5
+$as_echo_n "checking for main in -ldl... " >&6; }
+if ${ac_cv_lib_dl_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_main=yes
+else
+  ac_cv_lib_dl_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_main" >&5
+$as_echo "$ac_cv_lib_dl_main" >&6; }
+if test "x$ac_cv_lib_dl_main" = xyes; then :
+  SQL_LIBS="$SQL_LIBS -ldl"
+fi
+ac_cv_lib_dl=ac_cv_lib_dl_main
+
+
+	# Link against libedit or readline for command-line editing.
+	if test x"$with_readline" != xno; then
+		header=readline.h
+		for rl_lib in edit readline; do
+			found="yes"
+			save_LIBS=""
+			LIBS=""
+			{ ac_cv_search_tgetent=; unset ac_cv_search_tgetent;}
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tgetent" >&5
+$as_echo_n "checking for library containing tgetent... " >&6; }
+if ${ac_cv_search_tgetent+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char tgetent ();
+int
+main ()
+{
+return tgetent ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' $rl_lib ncurses curses termcap; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_tgetent=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_tgetent+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_tgetent+:} false; then :
+
+else
+  ac_cv_search_tgetent=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_tgetent" >&5
+$as_echo "$ac_cv_search_tgetent" >&6; }
+ac_res=$ac_cv_search_tgetent
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+  term_LIBS="$LIBS"
+else
+  term_LIBS=""
+fi
+
+			as_ac_Lib=`$as_echo "ac_cv_lib_$rl_lib''_readline" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -l$rl_lib" >&5
+$as_echo_n "checking for readline in -l$rl_lib... " >&6; }
+if eval \${$as_ac_Lib+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$rl_lib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char readline ();
+int
+main ()
+{
+return readline ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
+  SQL_LIBS="$SQL_LIBS -l$rl_lib $term_LIBS"
+else
+  found="no"
+fi
+
+			LIBS="$save_LIBS"
+			test "$found" = "yes" && break
+		done
+
+		if test x"$rl_lib" = xedit; then
+			header="editline/readline.h"
+		fi
+
+		if test "$found" = "yes"; then
+			as_ac_Header=`$as_echo "ac_cv_header_$header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  found="yes"
+else
+
+				found="no"
+				if test "$cross_compiling" != yes; then
+					for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do
+						for subdir in include include/readline; do
+							as_ac_File=`$as_echo "ac_cv_file_$dir/$subdir/$header" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $dir/$subdir/$header" >&5
+$as_echo_n "checking for $dir/$subdir/$header... " >&6; }
+if eval \${$as_ac_File+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  test "$cross_compiling" = yes &&
+  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
+if test -r "$dir/$subdir/$header"; then
+  eval "$as_ac_File=yes"
+else
+  eval "$as_ac_File=no"
+fi
+fi
+eval ac_res=\$$as_ac_File
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
+  found=yes
+fi
+
+							if test "$found" = "yes"; then
+								SQL_FLAGS="$SQL_FLAGS -I$dir/$subdir"
+								break
+							fi
+						done
+						test "$found" = "yes" && break
+					done
+				fi
+fi
+
+
+		fi
+	fi
+
+	if test "$enable_shared" = "no"; then
+		DEFAULT_LIB_SQL="\$(libsql_version)"
+	else
+		DEFAULT_LIB_SQL="\$(libsqlso_target)"
+	fi
+	INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_SQL"
+	if test "$enable_static" = "yes"; then
+		INSTALL_LIBS="$INSTALL_LIBS \$(libsql)"
+	fi
+
+	if test "$db_cv_test" = "yes"; then
+		subdirs="$subdirs sql"
+		ADDITIONAL_LANG="$ADDITIONAL_LANG sql-test"
+	fi
+
+	if test "$db_cv_jdbc" = "yes"; then
+		subdirs="$subdirs jdbc"
+		ADDITIONAL_LANG="$ADDITIONAL_LANG jdbc"
+	fi
+
+	if test "$db_cv_debug" = "yes"; then
+		SQL_FLAGS="$SQL_FLAGS -DSQLITE_DEBUG=1"
+	fi
+
+	if test "$db_cv_build_cryptography" = "yes"; then
+		SQL_FLAGS="$SQL_FLAGS -DSQLITE_HAS_CODEC=1"
+	fi
+fi
+
+if test "$db_cv_sql_compat" = "yes"; then
+	if test "$enable_shared" = "no"; then
+		DEFAULT_LIB_SQLITE="\$(libsqlite)"
+	else
+		DEFAULT_LIB_SQLITE="\$(libsqliteso_target)"
+	fi
+
+	ADDITIONAL_INCS="$ADDITIONAL_INCS \$(langdir)/sql/generated/sqlite3.h"
+	ADDITIONAL_PROGS="$ADDITIONAL_PROGS sqlite3"
+	INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_SQLITE"
+
+	# This is different to the other libraries: we need to be very
+	# careful not to delete an existing installation of SQLite unless
+	# we are installing over it.
+	if test "$enable_shared" = "yes"; then
+		INSTALL_LIBS_EXTRA="$INSTALL_LIBS_EXTRA \$(libsqliteso)"
+	fi
+	if test "$enable_static" = "yes"; then
+		INSTALL_LIBS="$INSTALL_LIBS \$(libsqlite)"
+	fi
+fi
+
+# Optional SQL code generation tool.
+if test "$db_cv_sql_codegen" = "yes"; then
+	ADDITIONAL_PROGS="$ADDITIONAL_PROGS db_sql_codegen"
+fi
+
+# Optional STL API.
+if test "$db_cv_stl" = "yes"; then
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler supports templates for STL" >&5
+$as_echo_n "checking whether the C++ compiler supports templates for STL... " >&6; }
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <iostream>
+#include <string>
+#include <vector>
+
+using std::string;
+using std::vector;
+namespace dbstl_configure_test {
+
+template<typename T1, typename T2 = int>
+class MyClass
+{
+public:
+	explicit MyClass(int i) { imem = i;}
+
+	MyClass(const T1& t1, const T2& t2, int i)
+	{
+		mem1 = t1;
+		mem2 = t2;
+		imem = i;
+	}
+
+	template <typename T3>
+	T2 templ_mem_func(T1 t1, T3 t3)
+	{
+		mem2 = t1;
+		T3 t32 = t3;
+		T2 t2;
+		return t2;
+	}
+
+	double templ_mem_func(T1 t1, double t3)
+	{
+		mem1 = t1;
+		double t32 = t3;
+		return t3;
+	}
+
+	template <typename ReturnType, typename T7, typename T8>
+	ReturnType templ_mem_func(T7, T8);
+
+	operator T1() const {return mem1;}
+private:
+	T1 mem1;
+	T2 mem2;
+	int imem;
+};
+
+template<typename T1, typename T2>
+template <typename ReturnType, typename T7, typename T8>
+ReturnType MyClass<T1, T2>::templ_mem_func(T7, T8)
+{
+	ReturnType rt;
+	return rt;
+}
+
+template<>
+class MyClass<double, float>
+{
+public:
+	explicit MyClass(int i) { imem = i;}
+
+	MyClass(const double& t1, const float& t2, int i)
+	{
+		mem1 = t1;
+		mem2 = t2;
+		imem = i;
+	}
+
+	template <typename T3>
+	float templ_mem_func(double t1, T3 t3)
+	{
+		mem2 = t1;
+		T3 t32 = t3;
+		float t2;
+		return t2;
+	}
+
+	double templ_mem_func(double t1, double t3)
+	{
+		mem1 = t1;
+		double t32 = t3;
+		return t3;
+	}
+
+	template <typename ReturnType, typename T7, typename T8>
+	ReturnType templ_mem_func(T7, T8);
+
+	operator double() const {return mem1;}
+private:
+	double mem1;
+	float mem2;
+	int imem;
+};
+
+template <typename ReturnType, typename T7, typename T8>
+ReturnType MyClass<double, float>::templ_mem_func(T7, T8)
+{
+	ReturnType rt;
+	return rt;
+}
+
+template <typename T1, typename T2>
+class MyClass2 {
+public:
+	MyClass2(const T1& t1, const T2&t2){}
+};
+
+// partial specialization: both template parameters have same type
+template <typename T>
+class MyClass2<T,T> {
+public:
+	MyClass2(const T& t1, const T&t2){}
+};
+
+// partial specialization: second type is int
+template <typename T>
+class MyClass2<T,int> {
+public:
+	MyClass2(const T& t1, const int&t2){}
+};
+
+// partial specialization: both template parameters are pointer types
+template <typename T1, typename T2>
+class MyClass2<T1*,T2*> {
+public:
+	MyClass2(const T1* t1, const T2*t2){}
+};
+
+template <typename T>
+class MyClass2<T*,T*> {
+public:
+	MyClass2(const T* t1, const T*t2){}
+};
+
+template <typename T4, typename T5>
+int part_spec_func(T4 t4, T5 t5)
+{
+	// Zero Initialization should work.
+	T4 t44 = T4();
+	T5 t55 = T5();
+
+	t44 = t4;
+	t55 = t5;
+}
+
+template <typename T4>
+int part_spec_func(T4 t4, std::vector<T4> t55)
+{
+	T4 t44 = t4;
+	std::vector<T4> abc = t55;
+}
+
+// maximum of two int values
+inline int const& max (int const& a, int const& b)
+{
+    return a<b?b:a;
+}
+
+// maximum of two values of any type
+template <typename T1, typename T2>
+inline T2 const max (T1 const& a, T2 const& b)
+{
+    return a<b?b:a;
+}
+// maximum of two values of any type
+template <typename T>
+inline T const& max (T const& a, T const& b)
+{
+    return a<b?b:a;
+}
+
+// maximum of three values of any type
+template <typename T>
+inline T const& max (T const& a, T const& b, T const& c)
+{
+    return max (max(a,b), c);
+}
+
+template <typename T>
+class Base {
+public:
+	void exit2(){}
+	Base(){}
+};
+
+template <typename T>
+class Derived : public Base<T> {
+public:
+	// Call Base<T>() explicitly here, otherwise can't access it.
+	// Kind of like this->.
+	Derived() : Base<T>(){}
+
+	void foo() {
+        	this->exit2();
+	}
+};
+
+} // dbstl_configure_test
+
+using namespace dbstl_configure_test;
+int
+main ()
+{
+
+	char cc = 'a';
+	int i = 4;
+	double pi = 3.14;
+	float gold = 0.618;
+
+	MyClass2<int,float> mif(i, gold);	// uses MyClass2<T1,T2>
+	MyClass2<float,float> mff(gold, gold);	// uses MyClass2<T,T>
+	MyClass2<float,int> mfi(gold, i);	// uses MyClass2<T,int>
+	MyClass2<int*,float*> mp(&i, &gold);	// uses MyClass2<T1*,T2*>
+	MyClass2<int*,int*> m(&i, &i);		// uses MyClass2<T*, T*>
+
+	MyClass<char> obj1(i);
+	obj1.templ_mem_func(cc, pi);
+	obj1.templ_mem_func(cc, gold);
+	obj1.templ_mem_func(i, pi);
+	obj1.templ_mem_func(cc, cc);
+	char ch = (char)obj1;
+
+	string str1("abc"), str2("def");
+	MyClass<const char*, std::string> obj2(str1.c_str(), str2, i);
+	obj2.templ_mem_func("klm", str2);
+	obj2.templ_mem_func("hij", pi);
+
+	// Use j to help distinguish, otherwise unable to use the one defined
+	// outside of class body.
+	int j = obj2.templ_mem_func<int, char, char>(cc, cc);
+	// Call explicitly.
+	obj2.templ_mem_func<int, float, double>(gold, pi);
+	const char *pch = (const char*)obj2;
+
+	MyClass<double, float> obj3(pi, gold, i);
+	obj3.templ_mem_func(pi, i);
+	obj3.templ_mem_func(pi, str1);
+	obj3.templ_mem_func(pi, pi);
+	obj3.templ_mem_func(cc, pi);
+	obj3.templ_mem_func(cc, cc);
+	double tmpd = (double)obj3;
+
+	MyClass<double, float> obj4(i);
+	obj4.templ_mem_func(pi, i);
+	obj4.templ_mem_func(pi, str1);
+	obj4.templ_mem_func(pi, pi);
+	obj4.templ_mem_func(gold, pi);
+	tmpd = (double)obj4;
+
+	// Function template partial specialization.
+	part_spec_func(pi, gold);
+	part_spec_func(gold, i);
+	part_spec_func(str1, str2);
+	std::vector<std::string> strv;
+	part_spec_func(str1, strv);
+	std::vector<double> dblv;
+	part_spec_func(pi, dblv);
+
+	// Function template overloads and explicit call and deduction.
+	dbstl_configure_test::max(7, 42, 68);     // calls the template for three arguments
+	dbstl_configure_test::max(7.0, 42.0);     // calls max<double> (by argument deduction)
+	dbstl_configure_test::max('a', 'b');      // calls max<char> (by argument deduction)
+	dbstl_configure_test::max(7, 42.0);
+	dbstl_configure_test::max<double>(4,4.2); // instantiate T as double
+	dbstl_configure_test::max(7, 42);         // calls the nontemplate for two ints
+	dbstl_configure_test::max<>(7, 42);       // calls max<int> (by argument deduction)
+	dbstl_configure_test::max<double, double>(7, 42); // calls max<double> (no argument deduction)
+	dbstl_configure_test::max('a', 42.7);     // calls the nontemplate for two ints
+
+	Base<double> bobj;
+	bobj.exit2();
+	// Using this-> to access base class members.
+	Derived<double> dobj;
+	dobj.foo();
+	dobj.exit2();
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  as_fn_error $? "no" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ supports the wstring class" >&5
+$as_echo_n "checking whether C++ supports the wstring class... " >&6; }
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string>
+	std::wstring ws; ws.find_first_of(ws);
+int
+main ()
+{
+
+  ;
+  return 0;
+},
+	WSTRING_decl="#define	HAVE_WSTRING 1" ; AC_MSG_RESULT(yes),
+	WSTRING_decl="#undef	HAVE_WSTRING" ; AC_MSG_RESULT(no)
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for thread local storage (TLS) class" >&5
+$as_echo_n "checking for thread local storage (TLS) class... " >&6; }
+
+
+  ac_cv_tls=none
+
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  ax_tls_keywords="__thread __declspec(thread) __declspec(__thread)"
+  for ax_tls_decl_keyword in $ax_tls_keywords ""; do
+      for ax_tls_defn_keyword in $ax_tls_keywords ""; do
+          test -z "$ax_tls_decl_keyword" &&
+              test -z "$ax_tls_defn_keyword" && continue
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+template <typename T>class TLSClass {
+              public: static  $ax_tls_decl_keyword  T *tlsvar;
+              };
+              class TLSClass2 {
+              public: static  $ax_tls_decl_keyword int tlsvar;
+              };
+              template<typename T>  $ax_tls_defn_keyword  T* TLSClass<T>::tlsvar = NULL;
+              $ax_tls_defn_keyword int TLSClass2::tlsvar = 1;
+              static $ax_tls_decl_keyword int x = 0;
+int
+main ()
+{
+TLSClass<int>::tlsvar = NULL; TLSClass2::tlsvar = 1;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_tls=modifier ; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+      done
+      test "$ac_cv_tls" = none || break
+  done
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+  if test "$ac_cv_tls" = "none" ; then
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+         #include <pthread.h>
+
+         static pthread_once_t once_control_ = PTHREAD_ONCE_INIT;
+         static pthread_key_t key;
+
+         static void init_once(void) {
+             pthread_key_create(&key, NULL);
+         }
+         static void *get_tls() {
+             return (void *)pthread_getspecific(&key);
+         }
+         static void set_tls(void *p) {
+              pthread_setspecific(&key, p);
+         }
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_tls=pthread
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  fi
+
+  case "$ac_cv_tls" in
+  none) break ;;
+  pthread)
+      TLS_decl="#define	HAVE_PTHREAD_TLS"
+      TLS_defn="" ;;
+  modifier)
+      TLS_decl="#define	TLS_DECL_MODIFIER	$ax_tls_decl_keyword"
+      TLS_defn="#define	TLS_DEFN_MODIFIER	$ax_tls_defn_keyword" ;;
+  esac
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tls" >&5
+$as_echo "$ac_cv_tls" >&6; }
+
+	if test "$enable_shared" = "no"; then
+		DEFAULT_LIB_STL="\$(libstl_version)"
+	fi
+	if test "$enable_shared" = "yes"; then
+		DEFAULT_LIB_STL="\$(libstlso_target)"
+	fi
+	ADDITIONAL_INCS="$ADDITIONAL_INCS dbstl_common.h"
+	for f in dbstl_set.h dbstl_vector.h dbstl_exception.h dbstl_map.h dbstl_utility.h dbstl_dbc.h dbstl_dbt.h dbstl_base_iterator.h dbstl_container.h dbstl_element_ref.h dbstl_inner_utility.h dbstl_resource_manager.h ; do
+		ADDITIONAL_INCS="$ADDITIONAL_INCS \$(topdir)/lang/cxx/stl/$f"
+	done
+	INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_STL"
+	if test "$enable_static" = "yes"; then
+		INSTALL_LIBS="$INSTALL_LIBS \$(libstl)"
+	fi
+fi
+
+# Checks for include files, structures, C types.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat file-mode macros are broken" >&5
+$as_echo_n "checking whether stat file-mode macros are broken... " >&6; }
+if ${ac_cv_header_stat_broken+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if defined S_ISBLK && defined S_IFDIR
+extern char c1[S_ISBLK (S_IFDIR) ? -1 : 1];
+#endif
+
+#if defined S_ISBLK && defined S_IFCHR
+extern char c2[S_ISBLK (S_IFCHR) ? -1 : 1];
+#endif
+
+#if defined S_ISLNK && defined S_IFREG
+extern char c3[S_ISLNK (S_IFREG) ? -1 : 1];
+#endif
+
+#if defined S_ISSOCK && defined S_IFREG
+extern char c4[S_ISSOCK (S_IFREG) ? -1 : 1];
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stat_broken=no
+else
+  ac_cv_header_stat_broken=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stat_broken" >&5
+$as_echo "$ac_cv_header_stat_broken" >&6; }
+if test $ac_cv_header_stat_broken = yes; then
+
+$as_echo "#define STAT_MACROS_BROKEN 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if ${ac_cv_header_time+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_time=yes
+else
+  ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if eval \${$as_ac_Header+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_ac_Header=yes"
+else
+  eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_opendir+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_opendir+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+for ac_header in execinfo.h sys/select.h sys/socket.h sys/time.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+_ACEOF
+
+
+fi
+
+
+
+# db.h includes <sys/types.h> and <stdio.h>, not the other default includes
+# autoconf usually includes.  For that reason, we specify a set of includes
+# for all type checking tests. [#5060]
+#
+# C99 says types should be in <stdint.h>; include <stdint.h> if it exists.
+#
+# Some systems have types in <stddef.h>; include <stddef.h> if it exists.
+#
+# IBM's OS/390 and z/OS releases have types in <inttypes.h> not also found
+# in <sys/types.h>; include <inttypes.h> if it exists.
+db_includes="#include <sys/types.h>"
+
+ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default"
+if test "x$ac_cv_header_inttypes_h" = xyes; then :
+
+	db_includes="$db_includes
+#include <inttypes.h>"
+	inttypes_h_decl="#include <inttypes.h>"
+fi
+
+
+
+# IRIX has stdint.h that is only available when using c99 (i.e. __c99
+# is defined). Problem with having it in a public header is that a c++
+# compiler cannot #include <db.h> if db.h #includes stdint.h, so we
+# need to check that stdint.h is available for all cases.  Also the
+# IRIX compiler does not exit with a non-zero exit code when it sees
+# #error, so we actually need to use the header for the compiler to fail.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdint.h" >&5
+$as_echo_n "checking for stdint.h... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdint.h>
+  int main() {
+  uint_least8_t x=0;
+  return x;
+  }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+if test "$db_cv_cxx" = "yes"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if stdint.h can be used by C++" >&5
+$as_echo_n "checking if stdint.h can be used by C++... " >&6; }
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdint.h>
+    int main() {
+    uint_least8_t x=0;
+    return x;
+  }
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    stdint_h_decl="#include <stdint.h>"
+    db_includes="$db_includes
+#include <stdint.h>"
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    stdint_h_decl="#ifndef __cplusplus
+#include <stdint.h>
+#endif"
+	db_includes="$db_includes
+#ifndef __cplusplus
+#include <stdint.h>
+#endif"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+else
+    stdint_h_decl="#include <stdint.h>"
+    db_includes="$db_includes
+#include <stdint.h>"
+fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "stddef.h" "ac_cv_header_stddef_h" "$ac_includes_default"
+if test "x$ac_cv_header_stddef_h" = xyes; then :
+
+	db_includes="$db_includes
+#include <stddef.h>"
+	stddef_h_decl="#include <stddef.h>"
+fi
+
+
+
+ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_unistd_h" = xyes; then :
+
+	db_includes="$db_includes
+#include <unistd.h>"
+	unistd_h_decl="#include <unistd.h>"
+fi
+
+
+db_includes="$db_includes
+#include <stdio.h>"
+
+# We need to know the sizes of various objects on this system.
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5
+$as_echo_n "checking size of char... " >&6; }
+if ${ac_cv_sizeof_char+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_char" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (char)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_char=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5
+$as_echo "$ac_cv_sizeof_char" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_CHAR $ac_cv_sizeof_char
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned char" >&5
+$as_echo_n "checking size of unsigned char... " >&6; }
+if ${ac_cv_sizeof_unsigned_char+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned char))" "ac_cv_sizeof_unsigned_char"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_unsigned_char" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned char)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_unsigned_char=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_char" >&5
+$as_echo "$ac_cv_sizeof_unsigned_char" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_CHAR $ac_cv_sizeof_unsigned_char
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
+$as_echo_n "checking size of short... " >&6; }
+if ${ac_cv_sizeof_short+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_short" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (short)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_short=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
+$as_echo "$ac_cv_sizeof_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5
+$as_echo_n "checking size of unsigned short... " >&6; }
+if ${ac_cv_sizeof_unsigned_short+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_unsigned_short" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned short)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_unsigned_short=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_short" >&5
+$as_echo "$ac_cv_sizeof_unsigned_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+$as_echo_n "checking size of int... " >&6; }
+if ${ac_cv_sizeof_int+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_int" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (int)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_int=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+$as_echo "$ac_cv_sizeof_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5
+$as_echo_n "checking size of unsigned int... " >&6; }
+if ${ac_cv_sizeof_unsigned_int+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_unsigned_int" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned int)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_unsigned_int=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5
+$as_echo "$ac_cv_sizeof_unsigned_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if ${ac_cv_sizeof_long+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5
+$as_echo_n "checking size of unsigned long... " >&6; }
+if ${ac_cv_sizeof_unsigned_long+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_unsigned_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned long)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_unsigned_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if ${ac_cv_sizeof_long_long+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_long_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long long)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_long_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5
+$as_echo_n "checking size of unsigned long long... " >&6; }
+if ${ac_cv_sizeof_unsigned_long_long+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_unsigned_long_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned long long)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_unsigned_long_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char *" >&5
+$as_echo_n "checking size of char *... " >&6; }
+if ${ac_cv_sizeof_char_p+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char *))" "ac_cv_sizeof_char_p"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_char_p" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (char *)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_char_p=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char_p" >&5
+$as_echo "$ac_cv_sizeof_char_p" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_CHAR_P $ac_cv_sizeof_char_p
+_ACEOF
+
+
+
+# We look for u_char, u_short, u_int, u_long -- if we can't find them,
+# we create our own.
+
+ac_fn_c_check_type "$LINENO" "u_char" "ac_cv_type_u_char" "$db_includes
+"
+if test "x$ac_cv_type_u_char" = xyes; then :
+
+else
+  u_char_decl="typedef unsigned char u_char;"
+fi
+
+
+
+ac_fn_c_check_type "$LINENO" "u_short" "ac_cv_type_u_short" "$db_includes
+"
+if test "x$ac_cv_type_u_short" = xyes; then :
+
+else
+  u_short_decl="typedef unsigned short u_short;"
+fi
+
+
+
+ac_fn_c_check_type "$LINENO" "u_int" "ac_cv_type_u_int" "$db_includes
+"
+if test "x$ac_cv_type_u_int" = xyes; then :
+
+else
+  u_int_decl="typedef unsigned int u_int;"
+fi
+
+
+
+ac_fn_c_check_type "$LINENO" "u_long" "ac_cv_type_u_long" "$db_includes
+"
+if test "x$ac_cv_type_u_long" = xyes; then :
+
+else
+  u_long_decl="typedef unsigned long u_long;"
+fi
+
+
+# We look for fixed-size variants of u_char, u_short, u_int, u_long as well.
+
+ac_fn_c_check_type "$LINENO" "u_int8_t" "ac_cv_type_u_int8_t" "$db_includes
+"
+if test "x$ac_cv_type_u_int8_t" = xyes; then :
+
+else
+
+	case "1" in
+	"$ac_cv_sizeof_unsigned_int")
+		u_int8_decl="typedef unsigned int u_int8_t;";;
+	"$ac_cv_sizeof_unsigned_char")
+		u_int8_decl="typedef unsigned char u_int8_t;";;
+	"$ac_cv_sizeof_unsigned_short")
+		u_int8_decl="typedef unsigned short u_int8_t;";;
+	"$ac_cv_sizeof_unsigned_long")
+		u_int8_decl="typedef unsigned long u_int8_t;";;
+	"$ac_cv_sizeof_unsigned_long_long")
+		u_int8_decl="typedef unsigned long long u_int8_t;";;
+	*)
+		if test "" != "notfatal"; then
+			as_fn_error $? "No unsigned 1-byte integral type" "$LINENO" 5
+		fi;;
+	esac
+fi
+
+
+
+ac_fn_c_check_type "$LINENO" "u_int16_t" "ac_cv_type_u_int16_t" "$db_includes
+"
+if test "x$ac_cv_type_u_int16_t" = xyes; then :
+
+else
+
+	case "2" in
+	"$ac_cv_sizeof_unsigned_int")
+		u_int16_decl="typedef unsigned int u_int16_t;";;
+	"$ac_cv_sizeof_unsigned_char")
+		u_int16_decl="typedef unsigned char u_int16_t;";;
+	"$ac_cv_sizeof_unsigned_short")
+		u_int16_decl="typedef unsigned short u_int16_t;";;
+	"$ac_cv_sizeof_unsigned_long")
+		u_int16_decl="typedef unsigned long u_int16_t;";;
+	"$ac_cv_sizeof_unsigned_long_long")
+		u_int16_decl="typedef unsigned long long u_int16_t;";;
+	*)
+		if test "" != "notfatal"; then
+			as_fn_error $? "No unsigned 2-byte integral type" "$LINENO" 5
+		fi;;
+	esac
+fi
+
+
+
+ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$db_includes
+"
+if test "x$ac_cv_type_int16_t" = xyes; then :
+
+else
+
+	case "2" in
+	"$ac_cv_sizeof_int")
+		int16_decl="typedef int int16_t;";;
+	"$ac_cv_sizeof_char")
+		int16_decl="typedef char int16_t;";;
+	"$ac_cv_sizeof_short")
+		int16_decl="typedef short int16_t;";;
+	"$ac_cv_sizeof_long")
+		int16_decl="typedef long int16_t;";;
+	"$ac_cv_sizeof_long_long")
+		int16_decl="typedef long long int16_t;";;
+	*)
+		if test "" != "notfatal"; then
+			as_fn_error $? "No signed 2-byte integral type" "$LINENO" 5
+		fi;;
+	esac
+fi
+
+
+
+ac_fn_c_check_type "$LINENO" "u_int32_t" "ac_cv_type_u_int32_t" "$db_includes
+"
+if test "x$ac_cv_type_u_int32_t" = xyes; then :
+
+else
+
+	case "4" in
+	"$ac_cv_sizeof_unsigned_int")
+		u_int32_decl="typedef unsigned int u_int32_t;";;
+	"$ac_cv_sizeof_unsigned_char")
+		u_int32_decl="typedef unsigned char u_int32_t;";;
+	"$ac_cv_sizeof_unsigned_short")
+		u_int32_decl="typedef unsigned short u_int32_t;";;
+	"$ac_cv_sizeof_unsigned_long")
+		u_int32_decl="typedef unsigned long u_int32_t;";;
+	"$ac_cv_sizeof_unsigned_long_long")
+		u_int32_decl="typedef unsigned long long u_int32_t;";;
+	*)
+		if test "" != "notfatal"; then
+			as_fn_error $? "No unsigned 4-byte integral type" "$LINENO" 5
+		fi;;
+	esac
+fi
+
+
+
+ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$db_includes
+"
+if test "x$ac_cv_type_int32_t" = xyes; then :
+
+else
+
+	case "4" in
+	"$ac_cv_sizeof_int")
+		int32_decl="typedef int int32_t;";;
+	"$ac_cv_sizeof_char")
+		int32_decl="typedef char int32_t;";;
+	"$ac_cv_sizeof_short")
+		int32_decl="typedef short int32_t;";;
+	"$ac_cv_sizeof_long")
+		int32_decl="typedef long int32_t;";;
+	"$ac_cv_sizeof_long_long")
+		int32_decl="typedef long long int32_t;";;
+	*)
+		if test "" != "notfatal"; then
+			as_fn_error $? "No signed 4-byte integral type" "$LINENO" 5
+		fi;;
+	esac
+fi
+
+
+
+ac_fn_c_check_type "$LINENO" "u_int64_t" "ac_cv_type_u_int64_t" "$db_includes
+"
+if test "x$ac_cv_type_u_int64_t" = xyes; then :
+
+else
+
+	case "8" in
+	"$ac_cv_sizeof_unsigned_int")
+		u_int64_decl="typedef unsigned int u_int64_t;";;
+	"$ac_cv_sizeof_unsigned_char")
+		u_int64_decl="typedef unsigned char u_int64_t;";;
+	"$ac_cv_sizeof_unsigned_short")
+		u_int64_decl="typedef unsigned short u_int64_t;";;
+	"$ac_cv_sizeof_unsigned_long")
+		u_int64_decl="typedef unsigned long u_int64_t;";;
+	"$ac_cv_sizeof_unsigned_long_long")
+		u_int64_decl="typedef unsigned long long u_int64_t;";;
+	*)
+		if test "notfatal" != "notfatal"; then
+			as_fn_error $? "No unsigned 8-byte integral type" "$LINENO" 5
+		fi;;
+	esac
+fi
+
+
+
+ac_fn_c_check_type "$LINENO" "int64_t" "ac_cv_type_int64_t" "$db_includes
+"
+if test "x$ac_cv_type_int64_t" = xyes; then :
+
+else
+
+	case "8" in
+	"$ac_cv_sizeof_int")
+		int64_decl="typedef int int64_t;";;
+	"$ac_cv_sizeof_char")
+		int64_decl="typedef char int64_t;";;
+	"$ac_cv_sizeof_short")
+		int64_decl="typedef short int64_t;";;
+	"$ac_cv_sizeof_long")
+		int64_decl="typedef long int64_t;";;
+	"$ac_cv_sizeof_long_long")
+		int64_decl="typedef long long int64_t;";;
+	*)
+		if test "notfatal" != "notfatal"; then
+			as_fn_error $? "No signed 8-byte integral type" "$LINENO" 5
+		fi;;
+	esac
+fi
+
+
+# No currently autoconf'd systems lack FILE, off_t pid_t, size_t, time_t.
+#
+# We require them, we don't try to substitute our own if we can't find them.
+
+as_ac_Type=`$as_echo "ac_cv_type_FILE *" | $as_tr_sh`
+ac_fn_c_check_type "$LINENO" "FILE *" "$as_ac_Type" "$db_includes
+"
+if eval test \"x\$"$as_ac_Type"\" = x"yes"; then :
+
+else
+  as_fn_error $? "No FILE type." "$LINENO" 5
+fi
+
+
+ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$db_includes
+"
+if test "x$ac_cv_type_off_t" = xyes; then :
+
+else
+  as_fn_error $? "No off_t type." "$LINENO" 5
+fi
+
+
+ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$db_includes
+"
+if test "x$ac_cv_type_pid_t" = xyes; then :
+
+else
+  as_fn_error $? "No pid_t type." "$LINENO" 5
+fi
+
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$db_includes
+"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+  as_fn_error $? "No size_t type." "$LINENO" 5
+fi
+
+
+ac_fn_c_check_type "$LINENO" "time_t" "ac_cv_type_time_t" "$db_includes
+"
+if test "x$ac_cv_type_time_t" = xyes; then :
+
+else
+  as_fn_error $? "No time_t type." "$LINENO" 5
+fi
+
+
+# Check for ssize_t -- if none exists, find a signed integral type that's
+# the same size as a size_t.
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5
+$as_echo_n "checking size of size_t... " >&6; }
+if ${ac_cv_sizeof_size_t+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t"        "$db_includes
+"; then :
+
+else
+  if test "$ac_cv_type_size_t" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (size_t)
+See \`config.log' for more details" "$LINENO" 5; }
+   else
+     ac_cv_sizeof_size_t=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5
+$as_echo "$ac_cv_sizeof_size_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
+_ACEOF
+
+
+
+ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$db_includes
+"
+if test "x$ac_cv_type_ssize_t" = xyes; then :
+
+else
+
+	case "$ac_cv_sizeof_size_t" in
+	"$ac_cv_sizeof_int")
+		ssize_t_decl="typedef int ssize_t;";;
+	"$ac_cv_sizeof_char")
+		ssize_t_decl="typedef char ssize_t;";;
+	"$ac_cv_sizeof_short")
+		ssize_t_decl="typedef short ssize_t;";;
+	"$ac_cv_sizeof_long")
+		ssize_t_decl="typedef long ssize_t;";;
+	"$ac_cv_sizeof_long_long")
+		ssize_t_decl="typedef long long ssize_t;";;
+	*)
+		if test "" != "notfatal"; then
+			as_fn_error $? "No signed $ac_cv_sizeof_size_t-byte integral type" "$LINENO" 5
+		fi;;
+	esac
+fi
+
+
+# Check for uintmax_t -- if none exists, find the largest unsigned integral
+# type available.
+
+ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintmax_t" = xyes; then :
+
+else
+  ac_fn_c_check_type "$LINENO" "unsigned long long" "ac_cv_type_unsigned_long_long" "$db_includes
+"
+if test "x$ac_cv_type_unsigned_long_long" = xyes; then :
+  uintmax_t_decl="typedef unsigned long long uintmax_t;"
+else
+  uintmax_t_decl="typedef unsigned long uintmax_t;"
+fi
+
+fi
+
+
+# Check for uintptr_t -- if none exists, find an integral type which is
+# the same size as a pointer.
+
+ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintptr_t" = xyes; then :
+
+else
+
+	case "$ac_cv_sizeof_char_p" in
+	"$ac_cv_sizeof_unsigned_int")
+		uintptr_t_decl="typedef unsigned int uintptr_t;";;
+	"$ac_cv_sizeof_unsigned_char")
+		uintptr_t_decl="typedef unsigned char uintptr_t;";;
+	"$ac_cv_sizeof_unsigned_short")
+		uintptr_t_decl="typedef unsigned short uintptr_t;";;
+	"$ac_cv_sizeof_unsigned_long")
+		uintptr_t_decl="typedef unsigned long uintptr_t;";;
+	"$ac_cv_sizeof_unsigned_long_long")
+		uintptr_t_decl="typedef unsigned long long uintptr_t;";;
+	*)
+		if test "" != "notfatal"; then
+			as_fn_error $? "No unsigned $ac_cv_sizeof_char_p-byte integral type" "$LINENO" 5
+		fi;;
+	esac
+fi
+
+
+
+   ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "$db_includes
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+"
+if test "x$ac_cv_type_socklen_t" = xyes; then :
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5
+$as_echo_n "checking for socklen_t equivalent... " >&6; }
+      if ${db_cv_socklen_t_equiv+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # Systems have either "struct sockaddr *" or
+	 # "void *" as the second argument to getpeername
+	 db_cv_socklen_t_equiv=
+	 for arg2 in "struct sockaddr" void; do
+	   for t in int size_t "unsigned int" "long int" "unsigned long int"; do
+	     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$db_includes
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+		int getpeername (int, $arg2 *, $t *);
+int
+main ()
+{
+$t len;
+		getpeername (0, 0, &len);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_socklen_t_equiv="$t"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+	     test "$db_cv_socklen_t_equiv" != "" && break
+	   done
+	   test "$db_cv_socklen_t_equiv" != "" && break
+	 done
+
+fi
+
+      if test "$db_cv_socklen_t_equiv" = ""; then
+	as_fn_error $? "Cannot find a type to use in place of socklen_t" "$LINENO" 5
+      fi
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_socklen_t_equiv" >&5
+$as_echo "$db_cv_socklen_t_equiv" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define socklen_t $db_cv_socklen_t_equiv
+_ACEOF
+
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C exit success/failure values" >&5
+$as_echo_n "checking for ANSI C exit success/failure values... " >&6; }
+if ${db_cv_exit_defines+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+int
+main ()
+{
+return (EXIT_SUCCESS);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_exit_defines=yes
+else
+  db_cv_exit_defines=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_exit_defines" >&5
+$as_echo "$db_cv_exit_defines" >&6; }
+if test "$db_cv_exit_defines" = "yes"; then
+	$as_echo "#define HAVE_EXIT_SUCCESS 1" >>confdefs.h
+
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getopt optreset variable" >&5
+$as_echo_n "checking for getopt optreset variable... " >&6; }
+if ${db_cv_optreset+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <unistd.h>
+int
+main ()
+{
+extern int optreset; optreset = 1;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_optreset=yes
+else
+  db_cv_optreset=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_optreset" >&5
+$as_echo "$db_cv_optreset" >&6; }
+if test "$db_cv_optreset" = "yes"; then
+	$as_echo "#define HAVE_GETOPT_OPTRESET 1" >>confdefs.h
+
+
+fi
+
+# Check for mutexes.
+# We do this first because it changes $LIBSO_LIBS.
+
+
+# Mutexes we don't test for, but want the #defines to exist for other ports.
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mutexes" >&5
+$as_echo_n "checking for mutexes... " >&6; }
+if ${db_cv_mutex+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+
+orig_libs=$LIBS
+
+db_cv_mutex=no
+
+# Mutexes can be disabled.
+if test "$db_cv_build_mutexsupport" = no; then
+	db_cv_mutex=disabled;
+fi
+
+# User-specified Win32 mutexes (MinGW build)
+if test "$db_cv_mingw" = yes; then
+	db_cv_mutex=win32/gcc
+fi
+
+if test "$db_cv_mutex" = no; then
+	# Check for the availability of POSIX or UI mutexes; also check
+	# whether the user has specified POSIX with --enable-posixmutexes.
+	#
+	# There are two different reasons to specify mutexes: First, the
+	# application is already using one type of mutex and doesn't want
+	# to mix-and-match (for example, on Solaris, which has POSIX, UI
+	# and LWP mutexes).  Second, the application's POSIX pthreads
+	# mutexes don't support inter-process locking, but the application
+	# wants to use them anyway (for example, some Linux and *BSD systems).
+	#
+	# Test for POSIX threads before testing for UI/LWP threads, they are
+	# the Sun-recommended choice on Solaris.  Also, there are Linux systems
+	# that support a UI compatibility mode, and applications are more
+	# likely to be written for POSIX threads than UI threads.
+	if test "$db_cv_posixmutexes" = yes; then
+		db_cv_mutex=posix_only;
+	fi
+	if test "$db_cv_uimutexes" = yes; then
+		db_cv_mutex=ui_only;
+	fi
+
+	# POSIX.1 pthreads: pthread_XXX
+	#
+	# If we find POSIX pthreads mutexes but not the full interface,
+	# try to configure for just intra-process support.
+	case "$host_os" in
+	    darwin*)
+		# Mac OS 10.7 Lion has broken pthread_*_setpshared() calls.
+		# Most BSD-like operating systems have pointers in their mutex
+		# and condition variables, and cannot be shared between
+		# proceses.  Earlier Mac OS releases correctly returned EINVAL
+		# from *_setpshared(PTHREAD_PROCESS_SHARED), but 10.7 returns
+		# success. Since we can't trust those calls anymore we now
+		# avoid these probes for multiprocess pthreads.
+		;;
+	    *)
+		if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then
+			LIBS="$LIBS -lpthread"
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_cond_t cond;
+	pthread_mutex_t mutex;
+	pthread_condattr_t condattr;
+	pthread_mutexattr_t mutexattr;
+	exit (
+	pthread_condattr_init(&condattr) ||
+	pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) ||
+	pthread_mutexattr_init(&mutexattr) ||
+	pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_mutex_init(&mutex, &mutexattr) ||
+	pthread_mutex_lock(&mutex) ||
+	pthread_mutex_unlock(&mutex) ||
+	pthread_mutex_destroy(&mutex) ||
+	pthread_cond_destroy(&cond) ||
+	pthread_condattr_destroy(&condattr) ||
+	pthread_mutexattr_destroy(&mutexattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex="POSIX/pthreads/library"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_cond_t cond;
+	pthread_mutex_t mutex;
+	pthread_condattr_t condattr;
+	pthread_mutexattr_t mutexattr;
+	exit (
+	pthread_condattr_init(&condattr) ||
+	pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) ||
+	pthread_mutexattr_init(&mutexattr) ||
+	pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_mutex_init(&mutex, &mutexattr) ||
+	pthread_mutex_lock(&mutex) ||
+	pthread_mutex_unlock(&mutex) ||
+	pthread_mutex_destroy(&mutex) ||
+	pthread_cond_destroy(&cond) ||
+	pthread_condattr_destroy(&condattr) ||
+	pthread_mutexattr_destroy(&mutexattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_mutex="POSIX/pthreads/library"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_cond_t cond;
+	pthread_condattr_t condattr;
+	exit(pthread_condattr_init(&condattr) ||
+	pthread_cond_init(&cond, &condattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_pthread_condinit_dupgood="yes"
+else
+  db_cv_pthread_condinit_dupgood="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_cond_t cond;
+	pthread_condattr_t condattr;
+	exit(pthread_condattr_init(&condattr) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_cond_init(&cond, &condattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_pthread_condinit_dupgood="yes"
+else
+  db_cv_pthread_condinit_dupgood="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_rwlock_t rwlock;
+	pthread_rwlockattr_t rwlockattr;
+	exit(pthread_rwlockattr_init(&rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_pthread_rwlockinit_dupgood="yes"
+else
+  db_cv_pthread_rwlockinit_dupgood="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_rwlock_t rwlock;
+	pthread_rwlockattr_t rwlockattr;
+	exit(pthread_rwlockattr_init(&rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_pthread_rwlockinit_dupgood="yes"
+else
+  db_cv_pthread_rwlockinit_dupgood="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+			LIBS="$orig_libs"
+		fi
+		if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_cond_t cond;
+	pthread_mutex_t mutex;
+	pthread_condattr_t condattr;
+	pthread_mutexattr_t mutexattr;
+	exit (
+	pthread_condattr_init(&condattr) ||
+	pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) ||
+	pthread_mutexattr_init(&mutexattr) ||
+	pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_mutex_init(&mutex, &mutexattr) ||
+	pthread_mutex_lock(&mutex) ||
+	pthread_mutex_unlock(&mutex) ||
+	pthread_mutex_destroy(&mutex) ||
+	pthread_cond_destroy(&cond) ||
+	pthread_condattr_destroy(&condattr) ||
+	pthread_mutexattr_destroy(&mutexattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex="POSIX/pthreads"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_cond_t cond;
+	pthread_mutex_t mutex;
+	pthread_condattr_t condattr;
+	pthread_mutexattr_t mutexattr;
+	exit (
+	pthread_condattr_init(&condattr) ||
+	pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) ||
+	pthread_mutexattr_init(&mutexattr) ||
+	pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_mutex_init(&mutex, &mutexattr) ||
+	pthread_mutex_lock(&mutex) ||
+	pthread_mutex_unlock(&mutex) ||
+	pthread_mutex_destroy(&mutex) ||
+	pthread_cond_destroy(&cond) ||
+	pthread_condattr_destroy(&condattr) ||
+	pthread_mutexattr_destroy(&mutexattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_mutex="POSIX/pthreads"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_cond_t cond;
+	pthread_condattr_t condattr;
+	exit(pthread_condattr_init(&condattr) ||
+	pthread_cond_init(&cond, &condattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_pthread_condinit_dupgood="yes"
+else
+  db_cv_pthread_condinit_dupgood="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_cond_t cond;
+	pthread_condattr_t condattr;
+	exit(pthread_condattr_init(&condattr) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_cond_init(&cond, &condattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_pthread_condinit_dupgood="yes"
+else
+  db_cv_pthread_condinit_dupgood="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_rwlock_t rwlock;
+	pthread_rwlockattr_t rwlockattr;
+	exit(pthread_rwlockattr_init(&rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_pthread_rwlockinit_dupgood="yes"
+else
+  db_cv_pthread_rwlockinit_dupgood="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_rwlock_t rwlock;
+	pthread_rwlockattr_t rwlockattr;
+	exit(pthread_rwlockattr_init(&rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_pthread_rwlockinit_dupgood="yes"
+else
+  db_cv_pthread_rwlockinit_dupgood="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+		fi
+		;;
+	esac
+	# We probe for private pthreads only when the user has asked for posix
+	# mutexes and we don't have a multiprocess pthreads library available.
+	if test "$db_cv_mutex" = posix_only; then
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_cond_t cond;
+	pthread_mutex_t mutex;
+	pthread_condattr_t condattr;
+	pthread_mutexattr_t mutexattr;
+	exit (
+	pthread_condattr_init(&condattr) ||
+	pthread_mutexattr_init(&mutexattr) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_mutex_init(&mutex, &mutexattr) ||
+	pthread_mutex_lock(&mutex) ||
+	pthread_mutex_unlock(&mutex) ||
+	pthread_mutex_destroy(&mutex) ||
+	pthread_cond_destroy(&cond) ||
+	pthread_condattr_destroy(&condattr) ||
+	pthread_mutexattr_destroy(&mutexattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex="POSIX/pthreads/private"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_cond_t cond;
+	pthread_mutex_t mutex;
+	pthread_condattr_t condattr;
+	pthread_mutexattr_t mutexattr;
+	exit (
+	pthread_condattr_init(&condattr) ||
+	pthread_mutexattr_init(&mutexattr) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_mutex_init(&mutex, &mutexattr) ||
+	pthread_mutex_lock(&mutex) ||
+	pthread_mutex_unlock(&mutex) ||
+	pthread_mutex_destroy(&mutex) ||
+	pthread_cond_destroy(&cond) ||
+	pthread_condattr_destroy(&condattr) ||
+	pthread_mutexattr_destroy(&mutexattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_mutex="POSIX/pthreads/private"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_cond_t cond;
+	pthread_condattr_t condattr;
+	exit(pthread_condattr_init(&condattr) ||
+	pthread_cond_init(&cond, &condattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_pthread_condinit_dupgood="yes"
+else
+  db_cv_pthread_condinit_dupgood="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_cond_t cond;
+	pthread_condattr_t condattr;
+	exit(pthread_condattr_init(&condattr) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_cond_init(&cond, &condattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_pthread_condinit_dupgood="yes"
+else
+  db_cv_pthread_condinit_dupgood="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_rwlock_t rwlock;
+	pthread_rwlockattr_t rwlockattr;
+	exit(pthread_rwlockattr_init(&rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_pthread_rwlockinit_dupgood="yes"
+else
+  db_cv_pthread_rwlockinit_dupgood="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_rwlock_t rwlock;
+	pthread_rwlockattr_t rwlockattr;
+	exit(pthread_rwlockattr_init(&rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_pthread_rwlockinit_dupgood="yes"
+else
+  db_cv_pthread_rwlockinit_dupgood="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+	fi
+	if test "$db_cv_mutex" = posix_only; then
+		LIBS="$LIBS -lpthread"
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_cond_t cond;
+	pthread_mutex_t mutex;
+	pthread_condattr_t condattr;
+	pthread_mutexattr_t mutexattr;
+	exit (
+	pthread_condattr_init(&condattr) ||
+	pthread_mutexattr_init(&mutexattr) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_mutex_init(&mutex, &mutexattr) ||
+	pthread_mutex_lock(&mutex) ||
+	pthread_mutex_unlock(&mutex) ||
+	pthread_mutex_destroy(&mutex) ||
+	pthread_cond_destroy(&cond) ||
+	pthread_condattr_destroy(&condattr) ||
+	pthread_mutexattr_destroy(&mutexattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex="POSIX/pthreads/library/private"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_cond_t cond;
+	pthread_mutex_t mutex;
+	pthread_condattr_t condattr;
+	pthread_mutexattr_t mutexattr;
+	exit (
+	pthread_condattr_init(&condattr) ||
+	pthread_mutexattr_init(&mutexattr) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_mutex_init(&mutex, &mutexattr) ||
+	pthread_mutex_lock(&mutex) ||
+	pthread_mutex_unlock(&mutex) ||
+	pthread_mutex_destroy(&mutex) ||
+	pthread_cond_destroy(&cond) ||
+	pthread_condattr_destroy(&condattr) ||
+	pthread_mutexattr_destroy(&mutexattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_mutex="POSIX/pthreads/library/private"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_cond_t cond;
+	pthread_condattr_t condattr;
+	exit(pthread_condattr_init(&condattr) ||
+	pthread_cond_init(&cond, &condattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_pthread_condinit_dupgood="yes"
+else
+  db_cv_pthread_condinit_dupgood="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_cond_t cond;
+	pthread_condattr_t condattr;
+	exit(pthread_condattr_init(&condattr) ||
+	pthread_cond_init(&cond, &condattr) ||
+	pthread_cond_init(&cond, &condattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_pthread_condinit_dupgood="yes"
+else
+  db_cv_pthread_condinit_dupgood="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+int
+main ()
+{
+
+	pthread_rwlock_t rwlock;
+	pthread_rwlockattr_t rwlockattr;
+	exit(pthread_rwlockattr_init(&rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_pthread_rwlockinit_dupgood="yes"
+else
+  db_cv_pthread_rwlockinit_dupgood="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <pthread.h>
+main() {
+	pthread_rwlock_t rwlock;
+	pthread_rwlockattr_t rwlockattr;
+	exit(pthread_rwlockattr_init(&rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr) ||
+	pthread_rwlock_init(&rwlock, &rwlockattr));
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_pthread_rwlockinit_dupgood="yes"
+else
+  db_cv_pthread_rwlockinit_dupgood="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+		LIBS="$orig_libs"
+	fi
+	if test "$db_cv_mutex" = posix_only; then
+		as_fn_error $? "unable to find POSIX 1003.1 mutex interfaces" "$LINENO" 5
+	fi
+
+	# LWP threads: _lwp_XXX
+	if test "$db_cv_mutex" = no; then
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+	#include <synch.h>
+int
+main ()
+{
+
+		static lwp_mutex_t mi = SHAREDMUTEX;
+		static lwp_cond_t ci = SHAREDCV;
+		lwp_mutex_t mutex = mi;
+		lwp_cond_t cond = ci;
+		exit (
+		_lwp_mutex_lock(&mutex) ||
+		_lwp_mutex_unlock(&mutex));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=Solaris/lwp
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	fi
+
+	# UI threads: thr_XXX
+	if test "$db_cv_mutex" = no -o "$db_cv_mutex" = ui_only; then
+	LIBS="$LIBS -lthread"
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+	#include <thread.h>
+	#include <synch.h>
+int
+main ()
+{
+
+		mutex_t mutex;
+		cond_t cond;
+		int type = USYNC_PROCESS;
+		exit (
+		mutex_init(&mutex, type, NULL) ||
+		cond_init(&cond, type, NULL) ||
+		mutex_lock(&mutex) ||
+		mutex_unlock(&mutex));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=UI/threads/library
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LIBS="$orig_libs"
+	fi
+	if test "$db_cv_mutex" = no -o "$db_cv_mutex" = ui_only; then
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+	#include <thread.h>
+	#include <synch.h>
+int
+main ()
+{
+
+		mutex_t mutex;
+		cond_t cond;
+		int type = USYNC_PROCESS;
+		exit (
+		mutex_init(&mutex, type, NULL) ||
+		cond_init(&cond, type, NULL) ||
+		mutex_lock(&mutex) ||
+		mutex_unlock(&mutex));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=UI/threads
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	fi
+	if test "$db_cv_mutex" = ui_only; then
+		as_fn_error $? "unable to find UI mutex interfaces" "$LINENO" 5
+	fi
+
+	# We're done testing for pthreads-style mutexes.  Next, check for
+	# test-and-set mutexes.  Check first for hybrid implementations,
+	# because we check for them even if we've already found a
+	# pthreads-style mutex and they're the most common architectures
+	# anyway.
+	#
+	# x86/gcc: FreeBSD, NetBSD, BSD/OS, Linux
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+	#if (defined(i386) || defined(__i386__)) && defined(__GNUC__)
+		exit(0);
+	#else
+		FAIL TO COMPILE/LINK
+	#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex="$db_cv_mutex/x86/gcc-assembly"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+	# x86_64/gcc: FreeBSD, NetBSD, BSD/OS, Linux
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+	#if (defined(x86_64) || defined(__x86_64__)) && defined(__GNUC__)
+		exit(0);
+	#else
+		FAIL TO COMPILE/LINK
+	#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex="$db_cv_mutex/x86_64/gcc-assembly"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+	# Solaris is one of the systems where we can configure hybrid mutexes.
+	# However, we require the membar_enter function for that, and only newer
+	# Solaris releases have it.  Check to see if we can configure hybrids.
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+	#include <sys/atomic.h>
+	#include <sys/machlock.h>
+int
+main ()
+{
+
+		typedef lock_t tsl_t;
+		lock_t x;
+		_lock_try(&x);
+		_lock_clear(&x);
+		membar_enter();
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex="$db_cv_mutex/Solaris/_lock_try/membar"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+	# Sparc/gcc: SunOS, Solaris, ultrasparc assembler support
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+	#if defined(__sparc__) && defined(__GNUC__)
+		asm volatile ("membar #StoreStore|#StoreLoad|#LoadStore");
+		exit(0);
+	#else
+		FAIL TO COMPILE/LINK
+	#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex="$db_cv_mutex/Sparc/gcc-assembly"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+	# We're done testing for any hybrid mutex implementations.  If we did
+	# not find a pthreads-style mutex, but did find a test-and-set mutex,
+	# we set db_cv_mutex to "no/XXX" -- clean that up.
+	db_cv_mutex=`echo $db_cv_mutex | sed 's/^no\///'`
+fi
+
+# If we still don't have a mutex implementation yet, continue testing for a
+# test-and-set mutex implementation.
+
+# _lock_try/_lock_clear: Solaris
+# On Solaris systems without other mutex interfaces, DB uses the undocumented
+# _lock_try _lock_clear function calls instead of either the sema_trywait(3T)
+# or sema_wait(3T) function calls.  This is because of problems in those
+# interfaces in some releases of the Solaris C library.
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/atomic.h>
+#include <sys/machlock.h>
+int
+main ()
+{
+
+	typedef lock_t tsl_t;
+	lock_t x;
+	_lock_try(&x);
+	_lock_clear(&x);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=Solaris/_lock_try
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+# msemaphore: HPPA only
+# Try HPPA before general msem test, it needs special alignment.
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/mman.h>
+int
+main ()
+{
+
+#if defined(__hppa)
+	typedef msemaphore tsl_t;
+	msemaphore x;
+	msem_init(&x, 0);
+	msem_lock(&x, 0);
+	msem_unlock(&x, 0);
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=HP/msem_init
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+# msemaphore: AIX, OSF/1
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+int
+main ()
+{
+
+	typedef msemaphore tsl_t;
+	msemaphore x;
+	msem_init(&x, 0);
+	msem_lock(&x, 0);
+	msem_unlock(&x, 0);
+	exit(0);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=UNIX/msem_init
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+# ReliantUNIX
+if test "$db_cv_mutex" = no; then
+LIBS="$LIBS -lmproc"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <ulocks.h>
+int
+main ()
+{
+
+	typedef spinlock_t tsl_t;
+	spinlock_t x;
+	initspin(&x, 1);
+	cspinlock(&x);
+	spinunlock(&x);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=ReliantUNIX/initspin
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS="$orig_libs"
+fi
+
+# SCO: UnixWare has threads in libthread, but OpenServer doesn't.
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if defined(__USLC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=SCO/x86/cc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# abilock_t: SGI
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <abi_mutex.h>
+int
+main ()
+{
+
+	typedef abilock_t tsl_t;
+	abilock_t x;
+	init_lock(&x);
+	acquire_lock(&x);
+	release_lock(&x);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=SGI/init_lock
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+# sema_t: Solaris
+# The sema_XXX calls do not work on Solaris 5.5.  I see no reason to ever
+# turn this test on, unless we find some other platform that uses the old
+# POSIX.1 interfaces.
+if test "$db_cv_mutex" = DOESNT_WORK; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <synch.h>
+int
+main ()
+{
+
+	typedef sema_t tsl_t;
+	sema_t x;
+	sema_init(&x, 1, USYNC_PROCESS, NULL);
+	sema_wait(&x);
+	sema_post(&x);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=UNIX/sema_init
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+# _check_lock/_clear_lock: AIX
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/atomic_op.h>
+int
+main ()
+{
+
+	int x;
+	_check_lock(&x,0,1);
+	_clear_lock(&x,0);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=AIX/_check_lock
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+# _spin_lock_try/_spin_unlock: Apple/Darwin
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+	int x;
+	_spin_lock_try(&x);
+	_spin_unlock(&x);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=Darwin/_spin_lock_try
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+# Tru64/cc
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if defined(__alpha) && defined(__DECC)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=Tru64/cc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# Alpha/gcc
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if defined(__alpha) && defined(__GNUC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=ALPHA/gcc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# ARM/gcc: Linux
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if defined(__arm__) && defined(__GNUC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=ARM/gcc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# MIPS/gcc: Linux
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if (defined(__mips) || defined(__mips__)) && defined(__GNUC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=MIPS/gcc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# PaRisc/gcc: HP/UX
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if (defined(__hppa) || defined(__hppa__)) && defined(__GNUC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=HPPA/gcc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# PPC/gcc:
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if (defined(__powerpc__) || defined(__ppc__)) && defined(__GNUC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=PPC/gcc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# 68K/gcc: SunOS
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if (defined(mc68020) || defined(sun3)) && defined(__GNUC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=68K/gcc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# S390/cc: IBM OS/390 Unix
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if defined(__MVS__) && defined(__IBMC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=S390/cc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# S390/gcc: Linux
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if defined(__s390__) && defined(__GNUC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=S390/gcc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# ia64/gcc: Linux
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if defined(__ia64) && defined(__GNUC__)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=ia64/gcc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# uts/cc: UTS
+if test "$db_cv_mutex" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#if defined(_UTS)
+	exit(0);
+#else
+	FAIL TO COMPILE/LINK
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_mutex=UTS/cc-assembly
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# UNIX fcntl system call mutexes.
+# Note that fcntl mutexes are no longer supported as of 4.8.  This code has been
+# left in place in case there is some system that we are not aware of that
+# only uses fcntl mutexes.  In that case, contact Oracle for support.
+if test "$db_cv_mutex" = no; then
+	db_cv_mutex=UNIX/fcntl
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <fcntl.h>
+int
+main ()
+{
+
+	struct flock l;
+	l.l_whence = SEEK_SET;
+	l.l_start = 10;
+	l.l_len = 1;
+	l.l_type = F_WRLCK;
+	fcntl(0, F_SETLK, &l);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_mutex=UNIX/fcntl
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_mutex" >&5
+$as_echo "$db_cv_mutex" >&6; }
+
+# Configure a pthreads-style mutex implementation.
+hybrid=pthread
+case "$db_cv_mutex" in
+POSIX/pthreads/private*)ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_PTHREADS 1" >>confdefs.h
+
+			if test "$db_cv_pthread_condinit_dupgood" = "yes"; then
+				$as_echo "#define HAVE_PTHREAD_COND_REINIT_OKAY 1" >>confdefs.h
+
+			fi
+			if test "$db_cv_pthread_rwlockinit_dupgood" = "yes"; then
+				$as_echo "#define HAVE_PTHREAD_RWLOCK_REINIT_OKAY 1" >>confdefs.h
+
+			fi
+			$as_echo "#define HAVE_MUTEX_THREAD_ONLY 1" >>confdefs.h
+
+			;;
+POSIX/pthreads/library/private*)
+			ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_PTHREADS 1" >>confdefs.h
+
+			if test "$db_cv_pthread_condinit_dupgood" = "yes"; then
+				$as_echo "#define HAVE_PTHREAD_COND_REINIT_OKAY 1" >>confdefs.h
+
+			fi
+			if test "$db_cv_pthread_rwlockinit_dupgood" = "yes"; then
+				$as_echo "#define HAVE_PTHREAD_RWLOCK_REINIT_OKAY 1" >>confdefs.h
+
+			fi
+			$as_echo "#define HAVE_MUTEX_THREAD_ONLY 1" >>confdefs.h
+;;
+POSIX/pthreads/library*)ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_PTHREADS 1" >>confdefs.h
+
+			if test "$db_cv_pthread_condinit_dupgood" = "yes"; then
+				$as_echo "#define HAVE_PTHREAD_COND_REINIT_OKAY 1" >>confdefs.h
+
+			fi
+			if test "$db_cv_pthread_rwlockinit_dupgood" = "yes"; then
+				$as_echo "#define HAVE_PTHREAD_RWLOCK_REINIT_OKAY 1" >>confdefs.h
+
+			fi;;
+POSIX/pthreads*)	ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_PTHREADS 1" >>confdefs.h
+
+
+			if test "$db_cv_pthread_condinit_dupgood" = "yes"; then
+				$as_echo "#define HAVE_PTHREAD_COND_REINIT_OKAY 1" >>confdefs.h
+
+			fi
+			if test "$db_cv_pthread_rwlockinit_dupgood" = "yes"; then
+				$as_echo "#define HAVE_PTHREAD_RWLOCK_REINIT_OKAY 1" >>confdefs.h
+
+			fi
+
+			;;
+Solaris/lwp*)		ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_SOLARIS_LWP 1" >>confdefs.h
+
+			;;
+UI/threads/library*)	ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_UI_THREADS 1" >>confdefs.h
+;;
+*)			hybrid=no;;
+UI/threads*)		ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_UI_THREADS 1" >>confdefs.h
+
+			;;
+esac
+
+# Configure a test-and-set mutex implementation.
+case "$db_cv_mutex" in
+68K/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_68K_GCC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+AIX/_check_lock)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_AIX_CHECK_LOCK 1" >>confdefs.h
+
+			;;
+Darwin/_spin_lock_try)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY 1" >>confdefs.h
+
+			;;
+ALPHA/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_ALPHA_GCC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+ARM/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_ARM_GCC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+HP/msem_init)		ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_HPPA_MSEM_INIT 1" >>confdefs.h
+
+			;;
+HPPA/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_HPPA_GCC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+ia64/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_IA64_GCC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+MIPS/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_MIPS_GCC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+PPC/gcc-assembly)
+			ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_PPC_GCC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+ReliantUNIX/initspin)	LIBSO_LIBS="$LIBSO_LIBS -lmproc"
+			ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_RELIANTUNIX_INITSPIN 1" >>confdefs.h
+
+			;;
+S390/cc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_S390_CC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+S390/gcc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_S390_GCC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+SCO/x86/cc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_SCO_X86_CC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+SGI/init_lock)		ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_SGI_INIT_LOCK 1" >>confdefs.h
+
+			;;
+Solaris/_lock_try)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_SOLARIS_LOCK_TRY 1" >>confdefs.h
+
+			;;
+*Solaris/_lock_try/membar)
+			hybrid="$hybrid/tas"
+			ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_SOLARIS_LOCK_TRY 1" >>confdefs.h
+
+			;;
+*Sparc/gcc-assembly)	hybrid="$hybrid/tas"
+			ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_SPARC_GCC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+Tru64/cc-assembly)	ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_TRU64_CC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+UNIX/msem_init)		ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_MSEM_INIT 1" >>confdefs.h
+
+			;;
+UNIX/sema_init)		ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_SEMA_INIT 1" >>confdefs.h
+
+			;;
+UTS/cc-assembly)	ADDITIONAL_OBJS="uts4.cc${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_UTS_CC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+*x86/gcc-assembly)	hybrid="$hybrid/tas"
+			ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_X86_GCC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+*x86_64/gcc-assembly)	hybrid="$hybrid/tas"
+			ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_X86_64_GCC_ASSEMBLY 1" >>confdefs.h
+
+			;;
+esac
+
+# Configure the remaining special cases.
+case "$db_cv_mutex" in
+UNIX/fcntl)		as_fn_error $? "Support for FCNTL mutexes was removed in BDB 4.8." "$LINENO" 5
+			ADDITIONAL_OBJS="mut_fcntl${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_FCNTL 1" >>confdefs.h
+
+			;;
+win32)			ADDITIONAL_OBJS="mut_win32${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_WIN32 1" >>confdefs.h
+
+			;;
+win32/gcc)		ADDITIONAL_OBJS="mut_win32${o} $ADDITIONAL_OBJS"
+			$as_echo "#define HAVE_MUTEX_WIN32_GCC 1" >>confdefs.h
+
+			;;
+esac
+
+# Mutexes may not have been found, or may have been disabled.
+case "$db_cv_mutex" in
+disabled)
+	;;
+*)
+	# Test to see if mutexes have been found by checking the list of
+	# additional objects for a mutex implementation.
+	case "$ADDITIONAL_OBJS" in
+	*mut_pthread*|*mut_tas*|*mut_win32*)
+		$as_echo "#define HAVE_MUTEX_SUPPORT 1" >>confdefs.h
+
+
+
+		# Shared latches are required in 4.8, and are implemented using
+		# mutexes if we don't have a native implementation.
+		# This macro may be removed in a future release.
+
+		$as_echo "#define HAVE_SHARED_LATCHES 1" >>confdefs.h
+;;
+	*)
+		as_fn_error $? "Unable to find a mutex implementation" "$LINENO" 5;;
+	esac
+esac
+
+# We may have found both a pthreads-style mutex implementation as well as a
+# test-and-set, in which case configure for the hybrid.
+if test "$hybrid" = pthread/tas; then
+	$as_echo "#define HAVE_MUTEX_HYBRID 1" >>confdefs.h
+
+
+fi
+
+# The mutex selection may require specific declarations -- we fill in most of
+# them above, but here are the common ones.
+#
+# The mutex selection may tell us what kind of thread package we're using,
+# which we use to figure out the thread type.
+#
+# If we're configured for the POSIX pthread API, then force the thread ID type
+# and include function, regardless of the mutex selection.  Ditto for the
+# (default) Solaris lwp mutexes, because they don't have a way to return the
+# thread ID.
+#
+# Try and link with a threads library if possible.  The problem is the Solaris
+# C library has UI/POSIX interface stubs, but they're broken, configuring them
+# for inter-process mutexes doesn't return an error, but it doesn't work either.
+# For that reason always add -lpthread if we're using pthread calls or mutexes
+# and there's a pthread library.
+#
+# We can't depend on any specific call existing (pthread_create, for example),
+# as it may be #defined in an include file -- OSF/1 (Tru64) has this problem.
+
+
+
+db_threadid_t_decl=notset
+
+case "$db_cv_mutex" in
+UI/threads*)
+	thread_h_decl="#include <thread.h>"
+	db_threadid_t_decl="typedef thread_t db_threadid_t;"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lthread" >&5
+$as_echo_n "checking for main in -lthread... " >&6; }
+if ${ac_cv_lib_thread_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lthread  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_thread_main=yes
+else
+  ac_cv_lib_thread_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_thread_main" >&5
+$as_echo "$ac_cv_lib_thread_main" >&6; }
+if test "x$ac_cv_lib_thread_main" = xyes; then :
+  LIBSO_LIBS="$LIBSO_LIBS -lthread"
+fi
+ac_cv_lib_thread=ac_cv_lib_thread_main
+;;
+*)
+	ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
+if test "x$ac_cv_header_pthread_h" = xyes; then :
+  ac_cv_header_pthread_h=yes
+fi
+
+
+	if test "$ac_cv_header_pthread_h" = "yes" ; then
+		thread_h_decl="#include <pthread.h>"
+		db_threadid_t_decl="typedef pthread_t db_threadid_t;"
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5
+$as_echo_n "checking for main in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_pthread_main=yes
+else
+  ac_cv_lib_pthread_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5
+$as_echo "$ac_cv_lib_pthread_main" >&6; }
+if test "x$ac_cv_lib_pthread_main" = xyes; then :
+  LIBSO_LIBS="$LIBSO_LIBS -lpthread"
+fi
+ac_cv_lib_pthread=ac_cv_lib_pthread_main
+;;
+esac
+
+# We need to know if the thread ID type will fit into an integral type and we
+# can compare it for equality and generally treat it like an int, or if it's a
+# non-integral type and we have to treat it like a structure or other untyped
+# block of bytes.  For example, MVS typedef's pthread_t to a structure.
+
+if test "$db_threadid_t_decl" = notset; then
+	db_threadid_t_decl="typedef uintmax_t db_threadid_t;"
+	$as_echo "#define HAVE_SIMPLE_THREAD_TYPE 1" >>confdefs.h
+
+else
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+	$thread_h_decl
+int
+main ()
+{
+
+	$db_threadid_t_decl
+	db_threadid_t a;
+	a = 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  $as_echo "#define HAVE_SIMPLE_THREAD_TYPE 1" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+# There are 3 classes of mutexes:
+#
+# 1: Mutexes requiring no cleanup, for example, test-and-set mutexes.
+# 2: Mutexes that must be destroyed, but which don't hold permanent system
+#    resources, for example, pthread mutexes on MVS aka OS/390 aka z/OS.
+# 3: Mutexes that must be destroyed, even after the process is gone, for
+#    example, pthread mutexes on QNX and binary semaphores on VxWorks.
+#
+# DB cannot currently distinguish between #2 and #3 because DB does not know
+# if the application is running environment recovery as part of startup and
+# does not need to do cleanup, or if the environment is being removed and/or
+# recovered in a loop in the application, and so does need to clean up.  If
+# we get it wrong, we're going to call the mutex destroy routine on a random
+# piece of memory, which usually works, but just might drop core.  For now,
+# we group #2 and #3 into the HAVE_MUTEX_SYSTEM_RESOURCES define, until we
+# have a better solution or reason to solve this in a general way -- so far,
+# the places we've needed to handle this are few.
+
+
+case "$host_os$db_cv_mutex" in
+*qnx*POSIX/pthread*|openedition*POSIX/pthread*)
+	$as_echo "#define HAVE_MUTEX_SYSTEM_RESOURCES 1" >>confdefs.h
+;;
+esac
+
+# Check for native (system call or instruction set) support for
+# atomic increment, decrement, and compare & exchange.
+
+# Probe for native atomic operations
+#	gcc/x86{,_64} inline asm
+#	solaris atomic_* library calls
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for atomic operations" >&5
+$as_echo_n "checking for atomic operations... " >&6; }
+if ${db_cv_atomic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+db_cv_atomic=no
+# atomic operations can be disabled via --disable-atomicsupport
+if test "$db_cv_build_atomicsupport" = no; then
+	db_cv_atomic=disabled
+fi
+
+# The MinGW build uses the Windows API for atomic operations
+if test "$db_cv_mingw" = yes; then
+	db_cv_atomic=mingw
+fi
+
+if test "$db_cv_atomic" = no; then
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+	#if ((defined(i386) || defined(__i386__)) && defined(__GNUC__))
+		exit(0);
+	#elif ((defined(x86_64) || defined(__x86_64__)) && defined(__GNUC__))
+		exit(0);
+	#else
+		FAIL TO COMPILE/LINK
+	#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  db_cv_atomic="x86/gcc-assembly"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test "$db_cv_atomic" = no; then
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/atomic.h>
+int
+main ()
+{
+
+	volatile unsigned val = 1;
+	exit (atomic_inc_uint_nv(&val) != 2 ||
+	      atomic_dec_uint_nv(&val) != 1 ||
+	      atomic_cas_32(&val, 1, 3) != 3);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_atomic="solaris/atomic"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_atomic" >&5
+$as_echo "$db_cv_atomic" >&6; }
+
+case "$db_cv_atomic" in
+	x86/gcc-assembly)
+		$as_echo "#define HAVE_ATOMIC_SUPPORT 1" >>confdefs.h
+
+		$as_echo "#define HAVE_ATOMIC_X86_GCC_ASSEMBLY 1" >>confdefs.h
+
+		;;
+
+	solaris/atomic)
+		$as_echo "#define HAVE_ATOMIC_SUPPORT 1" >>confdefs.h
+
+		$as_echo "#define HAVE_ATOMIC_SOLARIS 1" >>confdefs.h
+
+		;;
+	mingw)
+		$as_echo "#define HAVE_ATOMIC_SUPPORT 1" >>confdefs.h
+
+		;;
+esac
+
+
+# Check for os-specific event support for performance monitoring such as
+# DTrace or SystemTap.
+
+
+
+
+
+
+if test "$db_cv_systemtap" = "yes" ; then
+	if test "$DTRACE" != "dtrace"; then
+		as_fn_error $? "The dtrace program is missing; is systemtap v1.1 or better installed?" "$LINENO" 5
+	fi
+	db_cv_dtrace="yes"
+fi
+if test "$db_cv_dtrace" = "yes" ; then
+	db_cv_perfmon="yes"
+fi
+
+
+DTRACE_CPP=-C
+if test "$db_cv_perfmon" = "yes" ; then
+    if test "$DTRACE" = "dtrace" ; then
+		for ac_header in sys/sdt.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/sdt.h" "ac_cv_header_sys_sdt_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sdt_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_SDT_H 1
+_ACEOF
+
+fi
+
+done
+
+		# Generate the DTrace provider header file. This is duplicated
+		# in Makefile.in, to allow custom events to be added.
+		if test "$STAP" = "stap"; then
+		    # Linux DTrace support may have a bug with dtrace -C -h
+		    # The preprocessing isn't needed for -h on Linux,
+		    # so skip the unnecessary preprocessing.
+		    DTRACE_CPP=
+		fi
+		# The OS X version of dtrace prints a spurious line here.
+		if ! dtrace -h $DTRACE_CPP -I../util/dtrace -s ../dist/db_provider.d; then
+		    as_fn_error $? "Could not build db_provider.d: dtrace -h failed" "$LINENO" 5
+		fi
+		$RM db_provider.h.tmp
+		if ! mv db_provider.h db_provider.h.tmp ; then
+		    as_fn_error $? "Could not build db_provider.d: mv failed" "$LINENO" 5
+		elif ! sed -e \
+'/^#define[ 	]*BDB_[A-Z_]*(.*)/y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' \
+db_provider.h.tmp > db_provider.h ; then
+		    as_fn_error $? "Could not build db_provider.d: sed failed" "$LINENO" 5
+		fi
+
+		# DTrace on Solaris needs to post-process .o files to both
+		# generate an additional .o as well as resolving the
+		# __dtrace___bdb___<xxx> symbols before putting them into
+		# libraries;  Mac OS X does not. Treat a failing dtrace -G
+		# command as the indicator sign that dtrace -G is unnecessary.
+		# If it is needed then create an empty .c file to be a
+		# placeholder for the PIC & non-PIC versions of the dtrace -G
+		# output file.  The root of this .c file must be the same as
+		# the root of the .d file -- i.e. db_provider -- for the
+		# dtrace -G lines at the end of Makefile.in to work correctly.
+		$RM db_provider.o
+		if dtrace -G $DTRACE_CPP -I../util/dtrace -s ../dist/db_provider.d 2> /dev/null && \
+		    test -f db_provider.o ; then
+			FINAL_OBJS="$FINAL_OBJS db_provider${o}"
+			rm -f db_provider.c
+			echo "" > db_provider.c
+		fi
+		$as_echo "#define HAVE_DTRACE 1" >>confdefs.h
+
+	else
+		as_fn_error $? "No supported performance utility found." "$LINENO" 5
+	fi
+	$as_echo "#define HAVE_PERFMON 1" >>confdefs.h
+
+	if test "$db_cv_perfmon_statistics" != "no" ; then
+		$as_echo "#define HAVE_PERFMON_STATISTICS 1" >>confdefs.h
+
+	fi
+	# The method by which probes are listed depends on the underlying
+	# implementation; Linux's emulation of DTrace still uses the stap
+	# command at runtime.
+
+
+        if test "$STAP" = "stap"; then
+		LISTPROBES_DEPENDENCY=.libs/libdb-$DB_VERSION_MAJOR.$DB_VERSION_MINOR$SOSUFFIX
+		LISTPROBES_COMMAND="stap -l 'process(\"$LISTPROBES_DEPENDENCY\").mark(\"*\")'"
+	elif test "$DTRACE" = "dtrace" ; then
+		LISTPROBES_DEPENDENCY=db_load
+		LISTPROBES_COMMAND="	# Run a simple command which uses the library without needing any setup.
+	sleep 1 | dtrace -l -n 'bdb\$\$target:::'  -c '.libs/db_load dummy.db'"
+        fi
+elif test "$db_cv_perfmon_statistics" = "yes" ; then
+	as_fn_error $? "Enabling perfmon statistics requires --enable-dtrace" "$LINENO" 5
+fi
+
+
+# Test for various functions/libraries -- do tests that change library values
+# first.
+#
+# Update LIBS, so we're testing against the current list of libraries.
+LIBS="$LIBSO_LIBS"
+
+# The yield function on Solaris is almost certainly pthread_yield (LWP threads
+# or POSIX pthreads), or thr_yield (UI threads).  There's an outside chance it
+# is sched_yield() though, only available in -lrt on Solaris.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sched_yield" >&5
+$as_echo_n "checking for library containing sched_yield... " >&6; }
+if ${ac_cv_search_sched_yield+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sched_yield ();
+int
+main ()
+{
+return sched_yield ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' rt; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_sched_yield=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_sched_yield+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_sched_yield+:} false; then :
+
+else
+  ac_cv_search_sched_yield=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sched_yield" >&5
+$as_echo "$ac_cv_search_sched_yield" >&6; }
+ac_res=$ac_cv_search_sched_yield
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+# The Berkeley DB library calls fdatasync, only available in -lrt on Solaris.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fdatasync" >&5
+$as_echo_n "checking for library containing fdatasync... " >&6; }
+if ${ac_cv_search_fdatasync+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fdatasync ();
+int
+main ()
+{
+return fdatasync ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' rt; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_fdatasync=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_fdatasync+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_fdatasync+:} false; then :
+
+else
+  ac_cv_search_fdatasync=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fdatasync" >&5
+$as_echo "$ac_cv_search_fdatasync" >&6; }
+ac_res=$ac_cv_search_fdatasync
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getaddrinfo" >&5
+$as_echo_n "checking for library containing getaddrinfo... " >&6; }
+if ${ac_cv_search_getaddrinfo+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getaddrinfo ();
+int
+main ()
+{
+return getaddrinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' nsl socket; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_getaddrinfo=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_getaddrinfo+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_getaddrinfo+:} false; then :
+
+else
+  ac_cv_search_getaddrinfo=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getaddrinfo" >&5
+$as_echo "$ac_cv_search_getaddrinfo" >&6; }
+ac_res=$ac_cv_search_getaddrinfo
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing hstrerror" >&5
+$as_echo_n "checking for library containing hstrerror... " >&6; }
+if ${ac_cv_search_hstrerror+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char hstrerror ();
+int
+main ()
+{
+return hstrerror ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' resolv; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_hstrerror=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_hstrerror+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_hstrerror+:} false; then :
+
+else
+  ac_cv_search_hstrerror=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_hstrerror" >&5
+$as_echo "$ac_cv_search_hstrerror" >&6; }
+ac_res=$ac_cv_search_hstrerror
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+# Those tests updated LIBS, update our internal list.
+LIBSO_LIBS="$LIBS"
+
+# !!!
+# We could be more exact about whether these libraries are needed, but don't
+# bother -- if they exist, we load them, it's only the test programs anyway.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lm" >&5
+$as_echo_n "checking for main in -lm... " >&6; }
+if ${ac_cv_lib_m_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_main=yes
+else
+  ac_cv_lib_m_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_main" >&5
+$as_echo "$ac_cv_lib_m_main" >&6; }
+if test "x$ac_cv_lib_m_main" = xyes; then :
+  TEST_LIBS="$TEST_LIBS -lm"
+fi
+ac_cv_lib_m=ac_cv_lib_m_main
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lnsl" >&5
+$as_echo_n "checking for main in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_nsl_main=yes
+else
+  ac_cv_lib_nsl_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_main" >&5
+$as_echo "$ac_cv_lib_nsl_main" >&6; }
+if test "x$ac_cv_lib_nsl_main" = xyes; then :
+  TEST_LIBS="$TEST_LIBS -lnsl"
+fi
+ac_cv_lib_nsl=ac_cv_lib_nsl_main
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsocket" >&5
+$as_echo_n "checking for main in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_socket_main=yes
+else
+  ac_cv_lib_socket_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_main" >&5
+$as_echo "$ac_cv_lib_socket_main" >&6; }
+if test "x$ac_cv_lib_socket_main" = xyes; then :
+  TEST_LIBS="$TEST_LIBS -lsocket"
+fi
+ac_cv_lib_socket=ac_cv_lib_socket_main
+
+
+# Checks for system functions for which we have replacements.
+#
+# The only portable getcwd call is getcwd(char *, size_t), where the
+# buffer is non-NULL -- Solaris can't handle a NULL buffer, and they
+# deleted getwd().
+ac_fn_c_check_func "$LINENO" "abort" "ac_cv_func_abort"
+if test "x$ac_cv_func_abort" = xyes; then :
+  $as_echo "#define HAVE_ABORT 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" abort.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS abort.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "atoi" "ac_cv_func_atoi"
+if test "x$ac_cv_func_atoi" = xyes; then :
+  $as_echo "#define HAVE_ATOI 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" atoi.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS atoi.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "atol" "ac_cv_func_atol"
+if test "x$ac_cv_func_atol" = xyes; then :
+  $as_echo "#define HAVE_ATOL 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" atol.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS atol.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "bsearch" "ac_cv_func_bsearch"
+if test "x$ac_cv_func_bsearch" = xyes; then :
+  $as_echo "#define HAVE_BSEARCH 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" bsearch.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS bsearch.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd"
+if test "x$ac_cv_func_getcwd" = xyes; then :
+  $as_echo "#define HAVE_GETCWD 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" getcwd.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS getcwd.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "getenv" "ac_cv_func_getenv"
+if test "x$ac_cv_func_getenv" = xyes; then :
+  $as_echo "#define HAVE_GETENV 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" getenv.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS getenv.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "getopt" "ac_cv_func_getopt"
+if test "x$ac_cv_func_getopt" = xyes; then :
+  $as_echo "#define HAVE_GETOPT 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" getopt.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS getopt.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "isalpha" "ac_cv_func_isalpha"
+if test "x$ac_cv_func_isalpha" = xyes; then :
+  $as_echo "#define HAVE_ISALPHA 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" isalpha.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS isalpha.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "isdigit" "ac_cv_func_isdigit"
+if test "x$ac_cv_func_isdigit" = xyes; then :
+  $as_echo "#define HAVE_ISDIGIT 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" isdigit.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS isdigit.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "isprint" "ac_cv_func_isprint"
+if test "x$ac_cv_func_isprint" = xyes; then :
+  $as_echo "#define HAVE_ISPRINT 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" isprint.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS isprint.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "isspace" "ac_cv_func_isspace"
+if test "x$ac_cv_func_isspace" = xyes; then :
+  $as_echo "#define HAVE_ISSPACE 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" isspace.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS isspace.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "memcmp" "ac_cv_func_memcmp"
+if test "x$ac_cv_func_memcmp" = xyes; then :
+  $as_echo "#define HAVE_MEMCMP 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" memcmp.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS memcmp.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "memcpy" "ac_cv_func_memcpy"
+if test "x$ac_cv_func_memcpy" = xyes; then :
+  $as_echo "#define HAVE_MEMCPY 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" memcpy.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS memcpy.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove"
+if test "x$ac_cv_func_memmove" = xyes; then :
+  $as_echo "#define HAVE_MEMMOVE 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" memmove.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS memmove.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "printf" "ac_cv_func_printf"
+if test "x$ac_cv_func_printf" = xyes; then :
+  $as_echo "#define HAVE_PRINTF 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" printf.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS printf.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "qsort" "ac_cv_func_qsort"
+if test "x$ac_cv_func_qsort" = xyes; then :
+  $as_echo "#define HAVE_QSORT 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" qsort.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS qsort.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "raise" "ac_cv_func_raise"
+if test "x$ac_cv_func_raise" = xyes; then :
+  $as_echo "#define HAVE_RAISE 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" raise.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS raise.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "rand" "ac_cv_func_rand"
+if test "x$ac_cv_func_rand" = xyes; then :
+  $as_echo "#define HAVE_RAND 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" rand.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS rand.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp"
+if test "x$ac_cv_func_strcasecmp" = xyes; then :
+  $as_echo "#define HAVE_STRCASECMP 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strcasecmp.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strcasecmp.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strcat" "ac_cv_func_strcat"
+if test "x$ac_cv_func_strcat" = xyes; then :
+  $as_echo "#define HAVE_STRCAT 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strcat.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strcat.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strchr" "ac_cv_func_strchr"
+if test "x$ac_cv_func_strchr" = xyes; then :
+  $as_echo "#define HAVE_STRCHR 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strchr.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strchr.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup"
+if test "x$ac_cv_func_strdup" = xyes; then :
+  $as_echo "#define HAVE_STRDUP 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strdup.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strdup.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror"
+if test "x$ac_cv_func_strerror" = xyes; then :
+  $as_echo "#define HAVE_STRERROR 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strerror.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strerror.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strncat" "ac_cv_func_strncat"
+if test "x$ac_cv_func_strncat" = xyes; then :
+  $as_echo "#define HAVE_STRNCAT 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strncat.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strncat.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strncmp" "ac_cv_func_strncmp"
+if test "x$ac_cv_func_strncmp" = xyes; then :
+  $as_echo "#define HAVE_STRNCMP 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strncmp.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strncmp.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strrchr" "ac_cv_func_strrchr"
+if test "x$ac_cv_func_strrchr" = xyes; then :
+  $as_echo "#define HAVE_STRRCHR 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strrchr.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strrchr.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strsep" "ac_cv_func_strsep"
+if test "x$ac_cv_func_strsep" = xyes; then :
+  $as_echo "#define HAVE_STRSEP 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strsep.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strsep.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strtol" "ac_cv_func_strtol"
+if test "x$ac_cv_func_strtol" = xyes; then :
+  $as_echo "#define HAVE_STRTOL 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strtol.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strtol.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strtoul" "ac_cv_func_strtoul"
+if test "x$ac_cv_func_strtoul" = xyes; then :
+  $as_echo "#define HAVE_STRTOUL 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strtoul.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strtoul.$ac_objext"
+ ;;
+esac
+
+fi
+
+
+
+# Check for system functions we optionally use.
+for ac_func in \
+	_fstati64 backtrace backtrace_symbols directio fchmod fclose\
+	fcntl fdatasync fgetc fgets fopen fwrite getgid\
+	getrusage getuid hstrerror mprotect pstat_getdynamic\
+	pthread_self pthread_yield random sched_yield select setgid setuid\
+	sigaction snprintf stat sysconf vsnprintf yield
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+for ac_func in gettimeofday localtime time strftime
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# AIX 4.3 will link applications with calls to clock_gettime, but the
+# calls always fail.
+case "$host_os" in
+aix4.3.*)
+	;;
+*)
+	for ac_func in clock_gettime
+do :
+  ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
+if test "x$ac_cv_func_clock_gettime" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOCK_GETTIME 1
+_ACEOF
+
+fi
+done
+;;
+esac
+
+# clock_gettime -- monotonic clocks.
+#	Check to see if we can get a monotonic clock.  We actually try and
+#	run the program if possible, because we don't trust the #define's
+#	existence to mean the clock really exists.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime monotonic clock" >&5
+$as_echo_n "checking for clock_gettime monotonic clock... " >&6; }
+if ${db_cv_clock_monotonic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/time.h>
+int
+main ()
+{
+
+struct timespec t;
+clock_gettime(CLOCK_MONOTONIC, &t);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_clock_monotonic=yes
+else
+  db_cv_clock_monotonic=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/time.h>
+main() {
+	struct timespec t;
+	return (clock_gettime(CLOCK_MONOTONIC, &t) != 0);
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_clock_monotonic=yes
+else
+  db_cv_clock_monotonic=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_clock_monotonic" >&5
+$as_echo "$db_cv_clock_monotonic" >&6; }
+if test "$db_cv_clock_monotonic" = "yes"; then
+	$as_echo "#define HAVE_CLOCK_MONOTONIC 1" >>confdefs.h
+
+
+fi
+
+# ctime_r --
+#
+# There are two versions of ctime_r, one of which takes a buffer length as a
+# third argument, and one which only takes two arguments.  (There is also a
+# difference in return values and the type of the 3rd argument, but we handle
+# those problems in the code itself.)
+for ac_func in ctime_r
+do :
+  ac_fn_c_check_func "$LINENO" "ctime_r" "ac_cv_func_ctime_r"
+if test "x$ac_cv_func_ctime_r" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CTIME_R 1
+_ACEOF
+
+fi
+done
+
+if test "$ac_cv_func_ctime_r" = "yes"; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for 2 or 3 argument version of ctime_r" >&5
+$as_echo_n "checking for 2 or 3 argument version of ctime_r... " >&6; }
+if ${db_cv_ctime_r_3arg+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <time.h>
+int
+main ()
+{
+
+	ctime_r(NULL, NULL, 100);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_ctime_r_3arg="3-argument"
+else
+  db_cv_ctime_r_3arg="2-argument"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_ctime_r_3arg" >&5
+$as_echo "$db_cv_ctime_r_3arg" >&6; }
+fi
+if test "$db_cv_ctime_r_3arg" = "3-argument"; then
+	$as_echo "#define HAVE_CTIME_R_3ARG 1" >>confdefs.h
+
+
+fi
+
+
+# Ftruncate.
+# We've run into a problem with ftruncate on Alpha/Tru64, the issue is that
+# after a truncate the last page of the file mmaps as all zeros.  So just don't
+# use ftruncate.
+case "$host_os" in
+osf*)
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ftruncate ignored on $host_os-$host_vendor." >&5
+$as_echo "$as_me: WARNING: ftruncate ignored on $host_os-$host_vendor." >&2;};;
+*)
+	for ac_func in ftruncate
+do :
+  ac_fn_c_check_func "$LINENO" "ftruncate" "ac_cv_func_ftruncate"
+if test "x$ac_cv_func_ftruncate" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FTRUNCATE 1
+_ACEOF
+
+fi
+done
+;;
+esac
+
+# Pread/pwrite.
+# HP-UX has pread/pwrite, but it doesn't work with largefile support.
+# NCR's version of System V R 4.3 has pread/pwrite symbols, but no support.
+case "$host_os-$host_vendor" in
+hpux*|sysv4.3*-ncr)
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pread/pwrite interfaces ignored on $host_os-$host_vendor." >&5
+$as_echo "$as_me: WARNING: pread/pwrite interfaces ignored on $host_os-$host_vendor." >&2;};;
+*)
+	for ac_func in pread pwrite
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+;;
+esac
+
+# Check for getaddrinfo; do the test explicitly instead of using AC_CHECK_FUNCS
+# because <netdb.h> isn't a standard include file.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo" >&5
+$as_echo_n "checking for getaddrinfo... " >&6; }
+if ${db_cv_getaddrinfo+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <netdb.h>
+int
+main ()
+{
+
+	getaddrinfo(0, 0, 0, 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_getaddrinfo=yes
+else
+  db_cv_getaddrinfo=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_getaddrinfo" >&5
+$as_echo "$db_cv_getaddrinfo" >&6; }
+if test "$db_cv_getaddrinfo" = "yes"; then
+	$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h
+
+
+fi
+
+# Check for the fcntl F_SETFD flag to deny child process access to file
+# descriptors.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fcntl/F_SETFD" >&5
+$as_echo_n "checking for fcntl/F_SETFD... " >&6; }
+if ${db_cv_fcntl_f_setfd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <fcntl.h>
+int
+main ()
+{
+
+	fcntl(1, F_SETFD, 1);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_fcntl_f_setfd=yes
+else
+  db_cv_fcntl_f_setfd=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_fcntl_f_setfd" >&5
+$as_echo "$db_cv_fcntl_f_setfd" >&6; }
+if test "$db_cv_fcntl_f_setfd" = "yes"; then
+	$as_echo "#define HAVE_FCNTL_F_SETFD 1" >>confdefs.h
+
+
+fi
+
+# A/UX has a broken getopt(3).
+case "$host_os" in
+aux*)	case " $LIBOBJS " in
+  *" getopt.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS getopt.$ac_objext"
+ ;;
+esac
+;;
+esac
+
+# Linux has a broken O_DIRECT flag, but you can't detect it at configure time.
+# Linux and SGI require buffer alignment we may not match, otherwise writes
+# will fail.  Default to not using the O_DIRECT flag.
+if test "$db_cv_o_direct" = "yes"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for open/O_DIRECT" >&5
+$as_echo_n "checking for open/O_DIRECT... " >&6; }
+if ${db_cv_open_o_direct+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+	#include <sys/types.h>
+	#include <fcntl.h>
+int
+main ()
+{
+
+		open("a", O_RDONLY | O_DIRECT, 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_open_o_direct=yes
+else
+  db_cv_open_o_direct=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_open_o_direct" >&5
+$as_echo "$db_cv_open_o_direct" >&6; }
+	if test \
+	    "$db_cv_o_direct" = "yes" -a "$db_cv_open_o_direct" = "yes"; then
+		$as_echo "#define HAVE_O_DIRECT 1" >>confdefs.h
+
+
+	fi
+fi
+
+# Check for largefile support.
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+  enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_sys_largefile_CC=no
+     if test "$GCC" != yes; then
+       ac_save_CC=$CC
+       while :; do
+	 # IRIX 6.2 and later do not support large files by default,
+	 # so use the C compiler's -n32 option if that helps.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+	 if ac_fn_c_try_compile "$LINENO"; then :
+  break
+fi
+rm -f core conftest.err conftest.$ac_objext
+	 CC="$CC -n32"
+	 if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+	 break
+       done
+       CC=$ac_save_CC
+       rm -f conftest.$ac_ext
+    fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+  if test "$ac_cv_sys_largefile_CC" != no; then
+    CC=$CC$ac_cv_sys_largefile_CC
+  fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  while :; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_sys_file_offset_bits=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_sys_file_offset_bits=64; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_cv_sys_file_offset_bits=unknown
+  break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+  no | unknown) ;;
+  *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -rf conftest*
+  if test $ac_cv_sys_file_offset_bits = unknown; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if ${ac_cv_sys_large_files+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  while :; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_sys_large_files=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_sys_large_files=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_cv_sys_large_files=unknown
+  break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+  no | unknown) ;;
+  *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -rf conftest*
+  fi
+fi
+
+
+# Figure out how to create shared regions.
+#
+# First, we look for mmap.
+#
+# BSD/OS has mlock(2), but it doesn't work until the 4.1 release.
+#
+# Nextstep (version 3.3) apparently supports mmap(2) (the mmap symbol
+# is defined in the C library) but does not support munmap(2).  Don't
+# try to use mmap if we can't find munmap.
+#
+# Ultrix has mmap(2), but it doesn't work.
+mmap_ok=no
+case "$host_os" in
+bsdi3*|bsdi4.0)
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: mlock(2) interface ignored on $host_os-$host_vendor." >&5
+$as_echo "$as_me: WARNING: mlock(2) interface ignored on $host_os-$host_vendor." >&2;}
+	mmap_ok=yes
+	for ac_func in mmap munmap
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  mmap_ok=no
+fi
+done
+;;
+ultrix*)
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: mmap(2) interface ignored on $host_os-$host_vendor." >&5
+$as_echo "$as_me: WARNING: mmap(2) interface ignored on $host_os-$host_vendor." >&2;};;
+*)
+	mmap_ok=yes
+	for ac_func in mlock munlock
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+	for ac_func in mmap munmap
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  mmap_ok=no
+fi
+done
+;;
+esac
+
+# Second, we look for shmget.
+#
+# SunOS has the shmget(2) interfaces, but there appears to be a missing
+# #include <debug/debug.h> file, so we ignore them.
+shmget_ok=no
+case "$host_os" in
+sunos*)
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: shmget(2) interface ignored on $host_os-$host_vendor." >&5
+$as_echo "$as_me: WARNING: shmget(2) interface ignored on $host_os-$host_vendor." >&2;};;
+*)
+	shmget_ok=yes
+	for ac_func in shmget
+do :
+  ac_fn_c_check_func "$LINENO" "shmget" "ac_cv_func_shmget"
+if test "x$ac_cv_func_shmget" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SHMGET 1
+_ACEOF
+
+else
+  shmget_ok=no
+fi
+done
+
+
+	# Check for shmctl to lock down shared memory segments.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmctl" >&5
+$as_echo_n "checking for shmctl... " >&6; }
+if ${db_cv_shmctl_shm_lock+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <stdio.h>
+int
+main ()
+{
+
+		shmctl(0, SHM_LOCK, NULL);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  db_cv_shmctl_shm_lock=yes
+else
+  db_cv_shmctl_shm_lock=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_shmctl_shm_lock" >&5
+$as_echo "$db_cv_shmctl_shm_lock" >&6; }
+	if test "$db_cv_shmctl_shm_lock" = "yes"; then
+		$as_echo "#define HAVE_SHMCTL_SHM_LOCK 1" >>confdefs.h
+
+
+	fi;;
+esac
+
+# We require either mmap/munmap(2) or shmget(2).
+if test "$mmap_ok" = "no" -a "$shmget_ok" = "no"; then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Neither mmap/munmap(2) or shmget(2) library functions." >&5
+$as_echo "$as_me: WARNING: Neither mmap/munmap(2) or shmget(2) library functions." >&2;}
+fi
+
+# Optional Tcl support.
+if test "$db_cv_tcl" = "yes"; then
+
+
+	if ${ac_cv_c_tclconfig+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+
+	    # First check to see if --with-tclconfig was specified.
+	    if test "${with_tclconfig}" != no; then
+		if test -f "${with_tclconfig}/tclConfig.sh" ; then
+		    ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)`
+		else
+		    as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5
+		fi
+	    fi
+
+	    # check in a few common install locations
+	    if test x"${ac_cv_c_tclconfig}" = x ; then
+		for i in `ls -d /usr/local/lib 2>/dev/null` ; do
+		    if test -f "$i/tclConfig.sh" ; then
+			ac_cv_c_tclconfig=`(cd $i; pwd)`
+			break
+		    fi
+		done
+	    fi
+
+
+fi
+
+
+	if test x"${ac_cv_c_tclconfig}" = x ; then
+	    TCL_BIN_DIR="# no Tcl configs found"
+	    as_fn_error $? "can't find Tcl configuration definitions" "$LINENO" 5
+	else
+	    TCL_BIN_DIR=${ac_cv_c_tclconfig}
+	fi
+
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5
+$as_echo_n "checking for existence of $TCL_BIN_DIR/tclConfig.sh... " >&6; }
+
+	if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5
+$as_echo "loading" >&6; }
+		. $TCL_BIN_DIR/tclConfig.sh
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5
+$as_echo "file not found" >&6; }
+	fi
+
+	# DB requires at least version 8.5.
+	if test ${TCL_MAJOR_VERSION} -lt 8 \
+	    -o ${TCL_MAJOR_VERSION} -eq 8 -a ${TCL_MINOR_VERSION} -lt 5; then
+		as_fn_error $? "Berkeley DB requires Tcl version 8.5 or better." "$LINENO" 5
+	fi
+
+	# The eval is required to do substitution (for example, the TCL_DBGX
+	# substitution in the TCL_LIB_FILE variable.
+	eval "TCL_INCLUDE_SPEC=\"${TCL_INCLUDE_SPEC}\""
+	eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\""
+	eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\""
+	eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\""
+
+	#
+	# If the DB Tcl library isn't loaded with the Tcl spec and library
+	# flags on AIX, the resulting libdb_tcl-X.Y.so.0 will drop core at
+	# load time. [#4843]  Furthermore, with Tcl 8.3, the link flags
+	# given by the Tcl spec are insufficient for our use.  [#5779],[#17109]
+	#
+	case "$host_os" in
+	aix*)
+		LIBTSO_LIBS="$LIBTSO_LIBS $TCL_LIB_SPEC $TCL_LIB_FLAG"
+		LIBTSO_LIBS="$LIBTSO_LIBS -L$TCL_EXEC_PREFIX/lib -ltcl$TCL_VERSION";;
+	esac
+
+
+
+
+
+
+	TCL_TCLSH="${TCL_PREFIX}/bin/tclsh${TCL_VERSION}"
+
+
+	if test "$enable_shared" = "no"; then
+		DEFAULT_LIB_TCL="\$(libtcl_version)"
+	fi
+	if test "$enable_shared" = "yes"; then
+		DEFAULT_LIB_TCL="\$(libtso_target)"
+	fi
+	INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_TCL"
+	if test "$enable_static" = "yes"; then
+		INSTALL_LIBS="$INSTALL_LIBS \$(libtcl)"
+	fi
+	TCL_ADDITIONAL_OBJS="\$(TCL_STD_OBJS)"
+	if test "$db_cv_rdsbuild" == "yes"; then
+		# The RDS build exludes most tcl support
+		TCL_ADDITIONAL_OBJS=
+	fi
+
+fi
+
+# Optional sequence code.
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit integral type support for sequences" >&5
+$as_echo_n "checking for 64-bit integral type support for sequences... " >&6; }
+
+	db_cv_build_sequence="yes"
+
+	# Have to have found 64-bit types to support sequences.  If we don't
+	# find the native types, we try and create our own.
+	if test "$ac_cv_type_int64_t" = "no" -a -z "$int64_decl"; then
+		db_cv_build_sequence="no"
+	fi
+	if test "$ac_cv_type_uint64_t" = "no" -a -z "$u_int64_decl"; then
+		db_cv_build_sequence="no"
+	fi
+
+	# Figure out what type is the right size, and set the format.
+
+
+	db_cv_seq_type="no"
+	if test "$db_cv_build_sequence" = "yes" -a\
+	    "$ac_cv_sizeof_long" -eq "8"; then
+		db_cv_seq_type="long"
+		db_cv_seq_fmt='"%ld"'
+		db_cv_seq_ufmt='"%lu"'
+		INT64_FMT='#define	INT64_FMT	"%ld"'
+		UINT64_FMT='#define	UINT64_FMT	"%lu"'
+	else if test "$db_cv_build_sequence" = "yes" -a\
+	    "$ac_cv_sizeof_long_long" -eq "8"; then
+		db_cv_seq_type="long long"
+		db_cv_seq_fmt='"%lld"'
+		db_cv_seq_ufmt='"%llu"'
+		INT64_FMT='#define	INT64_FMT	"%lld"'
+		UINT64_FMT='#define	UINT64_FMT	"%llu"'
+	else
+		db_cv_build_sequence="no"
+	fi
+	fi
+
+	# Test to see if we can declare variables of the appropriate size
+	# and format them.  If we're cross-compiling, all we get is a link
+	# test, which won't test for the appropriate printf format strings.
+	if test "$db_cv_build_sequence" = "yes"; then
+		if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+			$db_cv_seq_type l;
+			unsigned $db_cv_seq_type u;
+			char buf[100];
+
+			buf[0] = 'a';
+			l = 9223372036854775807LL;
+			(void)snprintf(buf, sizeof(buf), $db_cv_seq_fmt, l);
+			if (strcmp(buf, "9223372036854775807"))
+				return (1);
+			u = 18446744073709551615ULL;
+			(void)snprintf(buf, sizeof(buf), $db_cv_seq_ufmt, u);
+			if (strcmp(buf, "18446744073709551615"))
+				return (1);
+			return (0);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+  db_cv_build_sequence="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+		main() {
+			$db_cv_seq_type l;
+			unsigned $db_cv_seq_type u;
+			char buf[100];
+
+			buf[0] = 'a';
+			l = 9223372036854775807LL;
+			(void)snprintf(buf, sizeof(buf), $db_cv_seq_fmt, l);
+			if (strcmp(buf, "9223372036854775807"))
+				return (1);
+			u = 18446744073709551615ULL;
+			(void)snprintf(buf, sizeof(buf), $db_cv_seq_ufmt, u);
+			if (strcmp(buf, "18446744073709551615"))
+				return (1);
+			return (0);
+		}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  db_cv_build_sequence="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+	fi
+	if test "$db_cv_build_sequence" = "yes"; then
+
+		db_seq_decl="typedef $db_cv_seq_type db_seq_t;";
+
+		$as_echo "#define HAVE_64BIT_TYPES 1" >>confdefs.h
+
+
+	else
+		# It still has to compile, but it won't run.
+		db_seq_decl="typedef int db_seq_t;";
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_build_sequence" >&5
+$as_echo "$db_cv_build_sequence" >&6; }
+
+
+# Detect whether a large mmap() supports automatically extending the accessible
+# region after growing the underlying file.
+
+
+
+
+
+if test "$mmap_ok" = "yes" ; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for growing a file under an mmap region" >&5
+$as_echo_n "checking for growing a file under an mmap region... " >&6; }
+
+    db_cv_mmap_extend="no"
+
+    if test "$cross_compiling" = yes; then :
+  db_cv_mmap_extend="no"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+    /*
+     *	Most mmap() implemenations allow you to map in a region which is much
+     *	larger than the underlying file. Only the second less than the actual
+     *	file size is accessible -- a SIGSEV typically results when attemping
+     *	a memory reference between EOF and the end of the mapped region.
+     *	One can extend the file to allow references into higher-addressed
+     *	sections of the region. However this automatic extension of the
+     *	addressible memory is beyond what POSIX requires. This function detects
+     *	whether mmap supports this automatic extension. If not (e.g. cygwin)
+     *	then the entire (hopefully sparse) file will need to be written before
+     * 	the first mmap.
+     */
+    /* Not all these includes are needed, but the minimal set varies from
+     * system to system.
+     */
+    #include <stdio.h>
+    #include <string.h>
+    #include <sys/types.h>
+    #include <sys/stat.h>
+    #include <fcntl.h>
+    #include <sys/mman.h>
+    #include <signal.h>
+
+    #define TEST_MMAP_BUFSIZE	(16 * 1024)
+    #define TEST_MMAP_EXTENDSIZE	(16 * 1024 * 1024)
+    #ifndef MAP_FAILED
+    #define MAP_FAILED (-1)
+    #endif
+
+    int catch_sig(sig)
+	    int sig;
+    {
+	    exit(1);
+    }
+
+    main() {
+	    const char *underlying;
+	    unsigned gapsize;
+	    char *base;
+	    int count, fd, i, mode, open_flags, ret, total_size;
+	    char buf[TEST_MMAP_BUFSIZE];
+
+	    gapsize = 1024;
+	    underlying = ".mmap_config";
+	    (void) unlink(underlying);
+
+	    open_flags = O_CREAT | O_TRUNC | O_RDWR;
+	    mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
+
+	    if ((fd = open(underlying, open_flags, mode)) < 0) {
+		    perror("open");
+		    return (1);
+	    }
+
+	    total_size = TEST_MMAP_EXTENDSIZE;
+
+	    memset(buf, 0, sizeof(buf));
+	    if ((count = write(fd, buf, sizeof(buf))) != sizeof(buf)) {
+		    perror("initial write");
+		    return (2);
+	    }
+
+	    if ((base = mmap(NULL, total_size,
+		PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
+		    perror("mmap");
+		    return (3);
+	    }
+
+	    /* Extend the file with just 1 byte */
+	    if (lseek(fd, total_size - 1, SEEK_SET) < 0 ||
+		(count = write(fd, buf, 1)) != 1) {
+		    perror("extending write");
+		    return (4);
+	    }
+
+	    (void) signal(SIGSEGV, catch_sig);
+	    (void) signal(SIGBUS, catch_sig);
+
+	    for (i = sizeof(buf); i < total_size; i += gapsize)
+		    base[i] = 'A';
+
+	    close(fd);
+	    (void) unlink(underlying);
+	    return (0);
+    }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  db_cv_mmap_extend="yes"
+else
+  db_cv_mmap_extend="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+
+    if test "$db_cv_mmap_extend" = yes; then
+	    $as_echo "#define HAVE_MMAP_EXTEND 1" >>confdefs.h
+
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_mmap_extend" >&5
+$as_echo "$db_cv_mmap_extend" >&6; }
+fi
+
+
+# Optional DB 1.85 compatibility API.
+if test "$db_cv_compat185" = "yes"; then
+	ADDITIONAL_INCS="db_185.h $ADDITIONAL_INCS"
+
+	ADDITIONAL_OBJS="db185${o} $ADDITIONAL_OBJS"
+fi
+
+# Optional utilities.
+if test "$db_cv_dump185" = "yes"; then
+	ADDITIONAL_PROGS="db_dump185 $ADDITIONAL_PROGS"
+fi
+
+# Log checksums can be disabled to increase performance
+if test "$db_cv_log_checksum" = "yes"; then
+	$as_echo "#define HAVE_LOG_CHECKSUM 1" >>confdefs.h
+
+
+fi
+
+# You can disable pieces of functionality to save space.
+#
+# Btree is always configured: it is the standard method, and Hash off-page
+# duplicates require it.
+
+# Compression can be disabled.
+if test "$db_cv_build_compression" = "yes"; then
+	$as_echo "#define HAVE_COMPRESSION 1" >>confdefs.h
+
+
+fi
+
+# Partitioning can be disabled.
+if test "$db_cv_build_partition" = "yes"; then
+	$as_echo "#define HAVE_PARTITION 1" >>confdefs.h
+
+
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(PARTITION_OBJS)"
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS partition_stub${o}"
+fi
+
+# Hash can be disabled.
+if test "$db_cv_build_hash" = "yes"; then
+	$as_echo "#define HAVE_HASH 1" >>confdefs.h
+
+
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HASH_OBJS)"
+	if test "$db_cv_build_verify" = "yes"; then
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HASH_VRFY_OBJS)"
+	fi
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS hash_stub${o}"
+fi
+
+# Heap can be disabled.
+if test "$db_cv_build_heap" = "yes"; then
+	$as_echo "#define HAVE_HEAP 1" >>confdefs.h
+
+
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HEAP_OBJS)"
+	if test "$db_cv_build_verify" = "yes"; then
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HEAP_VRFY_OBJS)"
+	fi
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS heap_stub${o}"
+fi
+
+# Queue can be disabled.
+if test "$db_cv_build_queue" = "yes"; then
+	$as_echo "#define HAVE_QUEUE 1" >>confdefs.h
+
+
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(QUEUE_OBJS)"
+	if test "$db_cv_build_verify" = "yes"; then
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(QUEUE_VRFY_OBJS)"
+	fi
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS qam_stub${o}"
+fi
+
+# Replication can be disabled.
+if test "$db_cv_build_replication" = "yes"; then
+	$as_echo "#define HAVE_REPLICATION 1" >>confdefs.h
+
+
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(REP_OBJS)"
+
+	# If we're building replication and detected POSIX threads, build the
+	# replication manager.
+
+
+	if test "$ac_cv_header_pthread_h" = yes -a "$db_cv_mingw" != "yes"; then
+		$as_echo "#define HAVE_REPLICATION_THREADS 1" >>confdefs.h
+
+
+		if test "$with_stacksize" != "no"; then
+
+cat >>confdefs.h <<_ACEOF
+#define DB_STACKSIZE $with_stacksize
+_ACEOF
+
+		fi
+
+		# Solaris requires the socket and nsl libraries to build the
+		# replication manager.  Don't add nsl regardless of the OS,
+		# it causes RPC to fail on AIX 4.3.3.
+		case "$host_os" in
+		solaris*)
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lnsl" >&5
+$as_echo_n "checking for main in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_nsl_main=yes
+else
+  ac_cv_lib_nsl_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_main" >&5
+$as_echo "$ac_cv_lib_nsl_main" >&6; }
+if test "x$ac_cv_lib_nsl_main" = xyes; then :
+  LIBSO_LIBS="$LIBSO_LIBS -lnsl"
+fi
+ac_cv_lib_nsl=ac_cv_lib_nsl_main
+
+			{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lsocket" >&5
+$as_echo_n "checking for main in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_main+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+return main ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_socket_main=yes
+else
+  ac_cv_lib_socket_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_main" >&5
+$as_echo "$ac_cv_lib_socket_main" >&6; }
+if test "x$ac_cv_lib_socket_main" = xyes; then :
+  LIBSO_LIBS="$LIBSO_LIBS -lsocket"
+fi
+ac_cv_lib_socket=ac_cv_lib_socket_main
+;;
+		esac
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(REPMGR_OBJS)"
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Replication manager is not supported." >&5
+$as_echo "$as_me: WARNING: Replication manager is not supported." >&2;}
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS repmgr_stub${o}"
+	fi
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS rep_stub${o} repmgr_stub${o}"
+fi
+
+# The statistics code can be disabled.
+if test "$db_cv_build_statistics" = "yes"; then
+	$as_echo "#define HAVE_STATISTICS 1" >>confdefs.h
+
+
+fi
+
+# The verification code can be disabled.
+if test "$db_cv_build_verify" = "yes"; then
+	$as_echo "#define HAVE_VERIFY 1" >>confdefs.h
+
+
+	if test "$db_cv_rdsbuild" = "no"; then
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(BTREE_VRFY_OBJS) \$(LOG_VRFY_OBJS)"
+	else
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(BTREE_VRFY_OBJS) log_verify_stub${o}"
+	fi
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS db_vrfy_stub${o} log_verify_stub${o}"
+fi
+
+# The crypto code can be disabled.
+if test -d "$topdir/src/crypto" -a "$db_cv_build_cryptography" != "no"; then
+	$as_echo "#define HAVE_CRYPTO 1" >>confdefs.h
+
+
+
+	CRYPTO_OBJS="\$(CRYPTO_OBJS)"
+
+	if test "$db_cv_build_cryptography" = "ipp"; then
+		ac_fn_c_check_header_mongrel "$LINENO" "ippcp.h" "ac_cv_header_ippcp_h" "$ac_includes_default"
+if test "x$ac_cv_header_ippcp_h" = xyes; then :
+
+else
+  as_fn_error $? "\
+The 'ippcp.h' header file required for IPP cryptography support was not found \
+in the configured include path." "$LINENO" 5
+fi
+
+
+		$as_echo "#define HAVE_CRYPTO_IPP 1" >>confdefs.h
+
+
+	fi
+else
+	CRYPTO_OBJS="crypto_stub${o}"
+fi
+
+# The mutex code can be disabled, and if there aren't any mutexes, then there's
+# no reason to include the locking code.
+if test "$db_cv_build_mutexsupport" = "yes"; then
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(MUTEX_OBJS)"
+	db_cv_locking="yes"
+else
+	db_cv_locking="no"
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS mut_stub${o}"
+fi
+
+LOCALEXAMPLES="\$(exampledir)"
+LOCALSRC="\$(srcdir)"
+LOCALUTILS="\$(utildir)"
+# The RDS build disables transactions and most features except DML and cursors.
+# They are removed by appending rds_stubs instead of STD_OBJS to ADDITIONAL_OBJS.
+if test "$db_cv_rdsbuild" = "no"; then
+	$as_echo "#define HAVE_TRANSACTIONS 1" >>confdefs.h
+
+
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(STD_OBJS)"
+	ADDITIONAL_PROGS="$ADDITIONAL_PROGS \$(STD_PROGS)"
+else
+	$as_echo "#define HAVE_RDS_BUILD 1" >>confdefs.h
+
+
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS rds_stub${o}"
+	db_cv_locking="no"
+	if test "$db_rdsbuild_default" = "no" ; then
+		# The normal db_load and db_stat utilities use non-RDS features.
+		# This modifies those source files such that they can work with
+		# with --enable-rdsbuild,
+		LOCALEXAMPLES="examples"
+		LOCALSRC="src"
+		LOCALUTILS="util"
+		# Apply all .patch files underneath the patches directory
+		# to local copies in the building directory.
+		for f in `grep -v '^#' $topdir/dist/rds/patchlist`; do
+			localdir=`dirname $f`
+			rm -f ./$f
+			test -d $localdir || mkdir -p $localdir || exit 1
+			cp $topdir/$f $f && \
+			patch $f $topdir/dist/rds/patches/$f.patch && \
+			chmod 444 $f || exit 1
+		done
+	fi
+fi
+
+# AH_TEMPLATE(HAVE_LOCKING, [Define to 1 if building in locking support.])
+if test "$db_cv_locking" = "yes"; then
+#	AC_DEFINE(HAVE_LOCKING)
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(LOCK_OBJS)"
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS lock_stub${o}"
+fi
+
+# If DIAGNOSTIC is defined (but not RDS), include the log print routines in the
+# library itself, various diagnostic modes use them.
+if test "$db_cv_diagnostic" = "yes"; then
+	if test "$db_cv_rdsbuild" = "no"; then
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(PRINT_OBJS)"
+	fi
+	PRINTLOG_OBJS=""
+else
+	PRINTLOG_OBJS="\$(PRINT_OBJS)"
+fi
+
+# If building for QNX, we need additional OS files.
+if test "$qnx_build" = "yes"; then
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS os_qnx_fsync${o} os_qnx_open${o}"
+fi
+
+# The DBM API can be disabled.
+if test "$db_cv_dbm" = "yes"; then
+	$as_echo "#define HAVE_DBM 1" >>confdefs.h
+
+
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS dbm${o} hsearch${o}"
+fi
+
+# The output and error messages can be stripped.
+if test "$db_cv_stripped_messages" = "yes"; then
+	$as_echo "#define HAVE_STRIPPED_MESSAGES 1" >>confdefs.h
+
+
+fi
+
+# The output and error messages can be localized.
+if test "$db_cv_localization" = "yes"; then
+	$as_echo "#define HAVE_LOCALIZATION 1" >>confdefs.h
+
+
+fi
+
+# We need to add the additional object files into the Makefile with the correct
+# suffix.  We can't use $LTLIBOBJS itself, because that variable has $U encoded
+# in it for automake, and that's not what we want.  See SR #7227 for additional
+# information.
+#
+# XXX: I'm not sure this is correct.
+REPLACEMENT_OBJS=`echo "$LIBOBJS" |
+		sed "s,\.[^.]* ,$o ,g;s,\.[^.]*$,$o,"`
+
+# This is necessary so that .o files in LIBOBJS are also built via
+# the ANSI2KNR-filtering rules.
+LIBOBJS=`echo "$LIBOBJS" |
+		sed 's,\.[^.]* ,$U&,g;s,\.[^.]*$,$U&,'`
+LTLIBOBJS=`echo "$LIBOBJS" |
+		sed 's,\.[^.]* ,.lo ,g;s,\.[^.]*$,.lo,'`
+
+
+# Initial output file list.
+CREATE_LIST="Makefile
+    db_cxx.h:$topdir/src/dbinc/db_cxx.in
+    db_int.h:$topdir/src/dbinc/db_int.in
+    clib_port.h:$topdir/dist/clib_port.in"
+if test "$db_cv_tcl" = "yes"; then
+CREATE_LIST="$CREATE_LIST
+    include.tcl:$topdir/test/tcl/include.tcl"
+fi
+
+# Create the db.h file from a source file, a list of global function
+# prototypes, and, if configured for unique names, a list of #defines
+# to do DB_VERSION_UNIQUE_NAME substitution.
+if test "$db_cv_uniquename" = "yes"; then
+	CREATE_LIST="$CREATE_LIST
+	db.h:$topdir/src/dbinc/db.in:$topdir/src/dbinc_auto/api_flags.in:$topdir/src/dbinc_auto/ext_def.in:$topdir/src/dbinc_auto/ext_prot.in"
+else
+	CREATE_LIST="$CREATE_LIST
+	db.h:$topdir/src/dbinc/db.in:$topdir/src/dbinc_auto/api_flags.in:$topdir/src/dbinc_auto/ext_prot.in"
+fi
+
+# If configured for unique names, create the db_int_uext.h file (which
+# does the DB_VERSION_UNIQUE_NAME substitution), which is included by
+# the db_int.h file.
+if test "$db_cv_uniquename" = "yes"; then
+	CREATE_LIST="$CREATE_LIST
+	db_int_def.h:$topdir/src/dbinc_auto/int_def.in"
+	db_int_def='#include "db_int_def.h"'
+fi
+
+# Create the db_185.h and db185_int.h files from source files, a list of
+# global function prototypes, and, if configured for unique names, a list
+# of #defines to do DB_VERSION_UNIQUE_NAME substitution.
+if test "$db_cv_compat185" = "yes"; then
+	if test "$db_cv_uniquename" = "yes"; then
+		CREATE_LIST="$CREATE_LIST
+		db_185.h:$topdir/src/dbinc/db_185.in:$topdir/src/dbinc_auto/ext_185_def.in:$topdir/src/dbinc_auto/ext_185_prot.in
+		db185_int.h:$topdir/lang/db185/db185_int.in:$topdir/src/dbinc_auto/ext_185_def.in:$topdir/src/dbinc_auto/ext_185_prot.in"
+	else
+		CREATE_LIST="$CREATE_LIST
+		db_185.h:$topdir/src/dbinc/db_185.in:$topdir/src/dbinc_auto/ext_185_prot.in
+		db185_int.h:$topdir/lang/db185/db185_int.in:$topdir/src/dbinc_auto/ext_185_prot.in"
+	fi
+fi
+
+if test "$db_cv_stl" = "yes"; then
+	CREATE_LIST="$CREATE_LIST
+	dbstl_common.h:$topdir/lang/cxx/stl/dbstl_common.in"
+fi
+
+if test "x$subdirs" != "x"; then
+	subdir_cmd="@for d in ${subdirs}; do (cd \$\$d && \${MAKE} \$@) ; done"
+fi
+
+ac_config_files="$ac_config_files $CREATE_LIST"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by Berkeley DB $as_me 5.4.0, which was
+generated by GNU Autoconf 2.68.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <Oracle Technology Network Berkeley DB forum>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+Berkeley DB config.status 5.4.0
+configured by $0, generated by GNU Autoconf 2.68,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2010 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_flag_spec_ld_CXX \
+hardcode_libdir_separator_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'
+
+
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "db_config.h") CONFIG_HEADERS="$CONFIG_HEADERS db_config.h:config.hin" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "$CREATE_LIST") CONFIG_FILES="$CONFIG_FILES $CREATE_LIST" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "libtool":C)
+
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
+#                 Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking.  This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\    # positional parameters, so assign one to ordinary parameter first.\
+\    func_stripname_result=${3}\
+\    func_stripname_result=${func_stripname_result#"${1}"}\
+\    func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+
+    cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking.  This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+if test "$db_cv_rdsbuild" = "yes" -a "$db_rdsbuild_default" = "no" ; then
+	# Patch the resulting db.h to remove unsupported functions.
+	patch "db.h" "$topdir/dist/rds/patches/src/dbinc/db.in.patch" || exit 1
+	patch "db_int.h" "$topdir/dist/rds/patches/src/dbinc/db_int.in.patch" || exit 1
+fi
+
+if test "$db_cv_sql" = "yes"; then
+	# This command runs the configure script from the SQL tree.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuring the SQL API" >&5
+$as_echo "$as_me: Configuring the SQL API" >&6;}
+
+# Setup the SQLite debug build.
+mkdir -p sql
+if test "$with_tclconfig" != "no"; then
+	db_cv_sql_config_tclconfig="--with-tcl=$with_tclconfig"
+else
+	db_cv_sql_config_tclconfig=
+fi
+
+# Whitespace in path names causes libtool to generate an invalid
+# dependency_libs line in sql/libsqlite3.la.
+# Work around this on cygwin, which commonly has spaces in path names.
+case `pwd` in
+  *\ * | *\	*)
+    if cygpath -d "$PWD" > /dev/null 2>&1 ; then
+	cd `cygpath -d "$PWD"`
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Changing current directory to $PWD to hide whitespace from libtool" >&5
+$as_echo "$as_me: WARNING: Changing current directory to $PWD to hide whitespace from libtool" >&2;}
+    else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Current bugs in libtool may prevent building the SQL API in \"$PWD\"; please use another working directory" >&5
+$as_echo "$as_me: WARNING: Current bugs in libtool may prevent building the SQL API in \"$PWD\"; please use another working directory" >&2;}
+    fi
+    ;;
+esac
+
+# It would be nice to use AC_CONFIG_SUBDIRS here, but it does not allow for
+# tweaking of command line options, so hard code things instead.
+#
+# !!! BEGIN COPIED from autoconf distribution
+# Modified to not repeat CPPFLAGS or readline settings
+
+  # Remove --cache-file, --srcdir, and --disable-option-checking arguments
+  # so they do not pile up.
+  ac_sub_configure_args=
+  ac_prev=
+  eval "set x $ac_configure_args"
+  shift
+  for ac_arg
+  do
+    if test -n "$ac_prev"; then
+      ac_prev=
+      continue
+    fi
+    case $ac_arg in
+    -cache-file | --cache-file | --cache-fil | --cache-fi \
+    | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+      ac_prev=cache_file ;;
+    -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+    | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
+    | --c=*)
+      ;;
+    --config-cache | -C)
+      ;;
+    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+      ac_prev=srcdir ;;
+    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+      ;;
+    -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+      ac_prev=prefix ;;
+    -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+      ;;
+    --disable-option-checking)
+      ;;
+    CPPFLAGS=* | *readline*)
+      ;;
+    *)
+      case $ac_arg in
+      *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+      esac
+      ac_sub_configure_args="$ac_sub_configure_args '$ac_arg'" ;;
+    esac
+  done
+
+  # Always prepend --prefix to ensure using the same prefix
+  # in subdir configurations.
+  ac_arg="--prefix=$prefix"
+  case $ac_arg in
+  *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args"
+
+  # Pass --silent
+  if test "$silent" = yes; then
+    ac_sub_configure_args="--silent $ac_sub_configure_args"
+  fi
+
+  # Always prepend --disable-option-checking to silence warnings, since
+  # different subdirs can have different --enable and --with options.
+  ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args"
+
+# !!! END COPIED from autoconf distribution
+
+sqlite_dir=$srcdir/../lang/sql/sqlite
+(cd sql && eval "\$SHELL ../$sqlite_dir/configure --disable-option-checking $ac_sub_configure_args CPPFLAGS=\"-I.. $CPPFLAGS\" --enable-amalgamation=$db_cv_sql_amalgamation --enable-readline=$with_readline" && cat build_config.h >> config.h) || exit 1
+
+# Configure JDBC if --enable-jdbc
+if test "$db_cv_jdbc" != "no"; then
+
+  # Deal with user-defined jdbc source path
+  if test "$with_jdbc" != "no"; then
+    jdbc_path="$with_jdbc"
+  else
+    jdbc_path="$srcdir/../lang/sql/jdbc"
+  fi
+
+  if test ! -d $jdbc_path; then
+    echo "Cannot find jdbc source in $jdbc_path."
+    echo "Please check that path or use --with-jdbc to specify the source directory"
+    exit 1
+  fi
+  jdbc_dir=`cd $jdbc_path && /bin/pwd`
+
+  # Transfer following setting to jdbc configure:
+  # . --prefix
+  # . --enable-shared/--disable-shared
+  # . --enable-static/--disable-static
+  # . CFLAGS, CPPFLAGS and LDFLAGS
+  jdbc_args=""
+  jdbc_flags=""
+
+  test "$prefix" != "" && jdbc_args="--prefix=$prefix --with-jardir=$prefix/jar"
+  test "$enable_shared" != "" && jdbc_args="$jdbc_args --enable-shared=$enable_shared"
+  test "$enable_static" != "" && jdbc_args="$jdbc_args --enable-static=$enable_static"
+
+  # 1. The build directory is build_unix/jdbc, so the include paths are relative
+  #    to that.
+  # 2. The JDBC driver does not accept CPPFLAGS. So we move the CPPFLAGS options
+  #    into CFLAGS for the JDBC driver.
+  jdbc_flags="$jdbc_flags CFLAGS=\"-I.. -I../../src/dbinc -I../sql \
+    -DHAVE_ERRNO_H -D_HAVE_SQLITE_CONFIG_H -DHAVE_SQLITE3_MALLOC \
+    $CFLAGS $CPPFLAGS\""
+  # Set LDFLAGS for JDBC driver
+  test "$LDFLAGS" != "" && jdbc_flags="$jdbc_flags LDFLAGS=\"$LDFLAGS\""
+
+  # Copy ../lang/sql/jdbc to build_unix/
+  test ! -d jdbc && cp -r $jdbc_dir .
+
+  # Set DBSQL LIB for Makefile.in
+  BDB_LIB="..\/libdb-$DB_VERSION_MAJOR.$DB_VERSION_MINOR.la"
+  test $enable_shared != "yes" && BDB_LIB='..\/libdb.a'
+
+  # Run the jdbc/configure
+  cd jdbc
+  test ! -e Makefile.in.tmp && mv Makefile.in Makefile.in.tmp
+  sed "s/@BDB_LIB@/$BDB_LIB/g" Makefile.in.tmp > Makefile.in
+  eval "\$SHELL ./configure --with-sqlite3=../../lang/sql/generated $jdbc_args $jdbc_flags"
+fi
+
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/configure.ac	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1210 @@
+# $Id$
+# Process this file with autoconf to produce a configure script.
+#
+# Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+
+PACKAGE=db
+AC_INIT(Berkeley DB, __EDIT_DB_VERSION__,
+	[Oracle Technology Network Berkeley DB forum],
+	db-__EDIT_DB_VERSION__)
+AC_CONFIG_SRCDIR([../src/db/db.c])
+AC_CONFIG_HEADERS([db_config.h:config.hin])
+
+AC_CONFIG_MACRO_DIR([aclocal])
+
+# We're going to pass options through to SQLite, don't check them first.
+AC_DISABLE_OPTION_CHECKING()
+
+# Configure setup.
+AC_CANONICAL_HOST()
+AC_ARG_PROGRAM()
+
+# Don't build in the dist directory.
+AC_MSG_CHECKING(if building in the top-level or dist directories)
+if [ test -f configure.ac ] ; then
+	AC_MSG_RESULT(yes)
+	AC_MSG_ERROR([\
+Berkeley DB should not be built in the "dist" directory. \
+Change directory to the build_unix directory and run ../dist/configure \
+from there.])
+fi
+AC_MSG_RESULT(no)
+
+topdir=`echo "$srcdir/.." | sed 's,/dist/\.\.,,'`
+# Substitution variables. BDB additions need to be documented.
+AC_SUBST(ADDITIONAL_INCS)
+AC_SUBST(ADDITIONAL_LANG)
+AC_SUBST(ADDITIONAL_OBJS)
+AC_SUBST(ADDITIONAL_PROGS)
+AC_SUBST(BUILD_TARGET)
+AC_SUBST(CFLAGS)
+AC_SUBST(CONFIGURATION_ARGS)
+AC_SUBST(CONFIGURATION_PATH)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(CRYPTO_OBJS)
+AC_SUBST(CXX)
+AC_SUBST(CXXFLAGS)
+AC_SUBST(DB_CONST)
+AC_SUBST(DB_PROTO1)
+AC_SUBST(DB_PROTO2)
+AC_SUBST(DB_STRUCT_ALIGN8)
+AC_SUBST(DEFAULT_LIB)
+AC_SUBST(DEFAULT_LIB_CXX)
+AC_SUBST(DEFAULT_LIB_SQL)
+AC_SUBST(DEFAULT_LIB_SQLITE)
+AC_SUBST(DEFAULT_LIB_STL)
+AC_SUBST(DEFAULT_LIB_TCL)
+AC_SUBST(DTRACE)
+AC_SUBST(FINAL_OBJS)
+AC_SUBST(INSTALLER)
+AC_SUBST(INSTALL_LIBS)
+AC_SUBST(INSTALL_LIBS_EXTRA)
+AC_SUBST(INSTALL_TARGET)
+AC_SUBST(JAR)
+AC_SUBST(JAVACFLAGS)
+AC_SUBST(LDFLAGS)
+AC_SUBST(LIBCSO_LIBS)
+AC_SUBST(LIBJSO_LIBS)
+AC_SUBST(LIBS)
+AC_SUBST(LIBSO_LIBS)
+AC_SUBST(LIBTOOL)
+AC_SUBST(LIBTSO_LIBS)
+AC_SUBST(LIBTSO_MODSUFFIX)
+AC_SUBST(LIBTSO_MODULE)
+AC_SUBST(LIBXSO_LIBS)
+AC_SUBST(LOCALEXAMPLES)
+AC_SUBST(LOCALSRC)
+AC_SUBST(LOCALUTILS)
+AC_SUBST(MAKEFILE_CC)
+AC_SUBST(MAKEFILE_CCLINK)
+AC_SUBST(MAKEFILE_CXX)
+AC_SUBST(MAKEFILE_CXXLINK)
+AC_SUBST(MAKEFILE_SOLINK)
+AC_SUBST(MAKEFILE_XSOLINK)
+AC_SUBST(OSDIR)
+AC_SUBST(PATH_SEPARATOR)
+AC_SUBST(POSTLINK)
+AC_SUBST(PRINTLOG_OBJS)
+AC_SUBST(REPLACEMENT_OBJS)
+AC_SUBST(SOFLAGS)
+AC_SUBST(SQL_FLAGS)
+AC_SUBST(SQL_LIBS)
+AC_SUBST(SWIGCFLAGS)
+AC_SUBST(TCL_ADDITIONAL_OBJS)
+AC_SUBST(TEST_LIBS)
+AC_SUBST(db_int_def)
+AC_SUBST(o)
+AC_SUBST(subdir_cmd)
+AC_SUBST(topdir)
+
+# The Windows public header has two extra symbols we need to remove.
+AC_SUBST(platform_header)
+AC_SUBST(platform_footer)
+
+# Set the default installation location.
+AC_PREFIX_DEFAULT(/usr/local/BerkeleyDB.__EDIT_DB_VERSION_MAJOR__.__EDIT_DB_VERSION_MINOR__)
+
+# Configure the version information.
+AC_SUBST(DB_VERSION_FAMILY)
+DB_VERSION_FAMILY="__EDIT_DB_VERSION_FAMILY__"
+AC_SUBST(DB_VERSION_RELEASE)
+DB_VERSION_RELEASE="__EDIT_DB_VERSION_RELEASE__"
+AC_SUBST(DB_VERSION_MAJOR)
+DB_VERSION_MAJOR="__EDIT_DB_VERSION_MAJOR__"
+AC_SUBST(DB_VERSION_MINOR)
+DB_VERSION_MINOR="__EDIT_DB_VERSION_MINOR__"
+AC_SUBST(DB_VERSION_PATCH)
+DB_VERSION_PATCH="__EDIT_DB_VERSION_PATCH__"
+AC_SUBST(DB_VERSION_STRING)
+DB_VERSION_STRING='"__EDIT_DB_VERSION_STRING__"'
+AC_SUBST(DB_VERSION_FULL_STRING)
+DB_VERSION_FULL_STRING='"__EDIT_DB_VERSION_FULL_STRING__"'
+AC_SUBST(DB_VERSION_UNIQUE_NAME)
+
+# Process all options before using them.
+AM_OPTIONS_SET
+
+# Set some #defines based on configuration options.
+if test "$db_cv_diagnostic" = "yes"; then
+	AC_DEFINE(DIAGNOSTIC)
+	AH_TEMPLATE(DIAGNOSTIC,
+    [Define to 1 if you want a version with run-time diagnostic checking.])
+fi
+if test "$db_cv_debug_rop" = "yes"; then
+	AC_DEFINE(DEBUG_ROP)
+	AH_TEMPLATE(DEBUG_ROP,
+    [Define to 1 if you want a version that logs read operations.])
+fi
+if test "$db_cv_debug_wop" = "yes"; then
+	AC_DEFINE(DEBUG_WOP)
+	AH_TEMPLATE(DEBUG_WOP,
+    [Define to 1 if you want a version that logs write operations.])
+fi
+if test "$db_cv_umrw" = "yes"; then
+	AC_DEFINE(UMRW)
+	AH_TEMPLATE(UMRW,
+    [Define to 1 to mask harmless uninitialized memory read/writes.])
+
+fi
+if test "$db_cv_test" = "yes"; then
+	AC_DEFINE(CONFIG_TEST)
+	AH_TEMPLATE(CONFIG_TEST,
+    [Define to 1 if you want to build a version for running the test suite.])
+fi
+
+AH_TEMPLATE(HAVE_UPGRADE_SUPPORT,
+    [Define to 1 if port includes historic database upgrade support.])
+AC_DEFINE(HAVE_UPGRADE_SUPPORT)
+
+# Check for programs used in building and installation.
+AM_PROGRAMS_SET
+AC_PROG_INSTALL
+
+BUILD_TARGET="library_build"
+INSTALL_TARGET="library_install"
+
+# Respect the environment LIBS settings
+LIBSO_LIBS="$LIBS"
+
+# This is where we handle stuff that autoconf can't handle: compiler,
+# preprocessor and load flags, libraries that the standard tests don't
+# look for.
+#
+# There are additional libraries we need for some compiler/architecture
+# combinations.
+#
+# Some architectures require DB to be compiled with special flags and/or
+# libraries for threaded applications
+#
+# The makefile CC may be different than the CC used in config testing,
+# because the makefile CC may be set to use $(LIBTOOL).
+#
+# Don't override anything if it's already set from the environment.
+optimize_flag="-O"
+extra_cflags=""
+
+case "$host_os" in
+aix4.3.*|aix[[56]]*)
+	case "$host_os" in
+	aix4.3.*)
+		CPPFLAGS="$CPPFLAGS -D_LINUX_SOURCE_COMPAT";;
+	esac
+	# IBM's XLC compilers (at least versions 7/8/9) generate incorrect code
+	# when ordinary optimization is enabled because they make strong
+	# assumptions about the types held at each memory location, and some
+	# Berkeley DB code violates those assumptions.  [#16141]
+	extra_cflags=" -qalias=noansi"
+	optimize_flag="-O2"
+	CC=${CC-"xlc_r"}
+	CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"
+	LDFLAGS="$LDFLAGS -Wl,-brtl";;
+bsdi3*)	CC=${CC-"shlicc2"}
+	LIBSO_LIBS="$LIBSO_LIBS -lipc";;
+cygwin*)
+	CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";;
+freebsd*)
+	CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE"
+	LDFLAGS="$LDFLAGS -pthread";;
+gnu*|k*bsd*-gnu|linux*)
+	CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";;
+hpux*)	CPPFLAGS="$CPPFLAGS -D_REENTRANT";;
+irix*)	optimize_flag="-O2"
+	CPPFLAGS="$CPPFLAGS -D_SGI_MP_SOURCE";;
+mpeix*)	CPPFLAGS="$CPPFLAGS -D_POSIX_SOURCE -D_SOCKET_SOURCE"
+	LIBSO_LIBS="$LIBSO_LIBS -lsocket -lsvipc";;
+osf*)	CPPFLAGS="$CPPFLAGS -pthread";;
+*qnx*)	qnx_build="yes"
+	AC_DEFINE(HAVE_QNX)
+	AH_TEMPLATE(HAVE_QNX, [Define to 1 if building on QNX.]);;
+solaris*)
+	CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS ";;
+esac
+
+# Set CFLAGS/CXXFLAGS.  We MUST set the flags before we call autoconf
+# compiler configuration macros, because if we don't, they set CFLAGS
+# to no optimization and -g, which isn't what we want.
+#
+# If the user wants a debugging environment, add -g the their compiler flags
+# and don't automatically optimize.  If you want to compile with a different
+# set of flags, specify CFLAGS in the environment before configuring.
+if test "$db_cv_debug" = "yes"; then
+	AC_DEFINE(DEBUG)
+	AH_TEMPLATE(DEBUG, [Define to 1 if you want a debugging version.])
+
+	CFLAGS="-g $CFLAGS"
+else
+	CFLAGS=${CFLAGS-$optimize_flag}
+fi
+
+CFLAGS="$CFLAGS$extra_cflags"
+CXXFLAGS=${CXXFLAGS-"$CFLAGS"}
+
+# The default compiler is cc (NOT gcc), the default CFLAGS is as specified
+# above, NOT what is set by AC_PROG_CC, as it won't set optimization flags
+# for any compiler other than gcc.
+AC_PROG_CC(cc gcc)
+
+# We know what compiler we're going to use, now.  Set per-compiler flags.
+if test "$GCC" = "yes"; then
+	# Use -O3 if we're using gcc, unless we're doing a small build, in
+	# which case we use -Os alone.  The code size for -O3 is quite a
+	# bit larger than -O2: a compromise is "-Os -finline-functions",
+	# it's smaller and explicitly inlining the functions helps Berkeley
+	# DB.
+	CFLAGS="$CFLAGS "
+	if test "$db_cv_smallbuild" = "yes" -o "$db_cv_rdsbuild" = "yes" ; then
+		CFLAGS=`echo "$CFLAGS" | sed 's/-O /-Os /g'`
+	else
+		CFLAGS=`echo "$CFLAGS" | sed 's/-O /-O3 /g'`
+	fi
+else
+	case "$host_os" in
+	hpux11.0*)	;;
+	hpux11*)	CPPFLAGS="$CPPFLAGS -mt"
+			test "$host_cpu" = "ia64" &&
+			    CFLAGS="$CFLAGS +u1";;
+	esac
+fi
+
+# Check for "const" and "inline" keywords.
+AC_C_CONST
+AC_C_INLINE
+
+# We use prototypes and the keyword "const" in db.h which doesn't include
+# db_config.h, so we have to figure out what to do there.
+#
+# There is an autoconf AC_C_PROTOTYPES macro, but as all it does is define
+# db_config.h variables, it doesn't help us.
+#
+# We don't have much choice, we look at internal autoconf variables.
+if test "$ac_cv_c_const" != "yes"; then
+	DB_CONST="#define const"
+fi
+
+# We use alignment attributes in db.h - figure out if the compiler supports
+# them.
+AC_CACHE_CHECK([for GCC aligned attribute], db_cv_aligned_attribute, [
+AC_TRY_COMPILE(, __attribute__ ((aligned (8))) int i;,
+    [db_cv_aligned_attribute=yes], [db_cv_aligned_attribute=no])])
+if test "$db_cv_aligned_attribute" = "yes"; then
+	DB_STRUCT_ALIGN8="__attribute__ ((aligned (8)))"
+fi
+
+# Clear __P, some other systems use it too.
+DB_PROTO1="#undef __P"
+if test "$ac_cv_prog_cc_c89" = "no"; then
+	DB_PROTO2="#define	__P(protos)	()"
+else
+	DB_PROTO2="#define	__P(protos)	protos"
+fi
+
+# Because of shared library building, the ${CC} used for config tests
+# may be different than the ${CC} we want to put in the Makefile.
+# The latter is known as ${MAKEFILE_CC} in this script.
+MAKEFILE_CC="${CC}"
+MAKEFILE_CCLINK="${CC}"
+MAKEFILE_CXX="nocxx"
+MAKEFILE_CXXLINK="nocxx"
+
+# See if we need the C++ compiler at all.  If so, we'd like to find one that
+# interoperates with the C compiler we chose.  Since we prefered cc over gcc,
+# we'll also prefer the vendor's compiler over g++/gcc.  If we're wrong, the
+# user can set CC and CXX in their environment before running configure.
+#
+# AC_PROG_CXX sets CXX, but it uses $CXX and $CCC (in that order) as its
+# first choices.
+if test "$db_cv_cxx" = "yes"; then
+	if test "$GCC" != "yes"; then
+		case "$host_os" in
+		aix*)		AC_CHECK_TOOL(CCC, xlC_r)
+				LIBXSO_LIBS="-lC_r $LIBXSO_LIBS"
+				LIBSO_LIBS="-lC_r $LIBSO_LIBS";;
+		hpux*)		AC_CHECK_TOOL(CCC, aCC);;
+		irix*)		AC_CHECK_TOOL(CCC, CC);;
+		osf*)		AC_CHECK_TOOL(CCC, cxx)
+				CXXFLAGS="$CXXFLAGS -D__USE_STD_IOSTREAM"
+				test -d /usr/include.dtk &&
+				    CXXFLAGS="$CXXFLAGS -I/usr/include.dtk";;
+		solaris*)	AC_CHECK_TOOL(CCC, CC);;
+		esac
+	fi
+	AC_PROG_CXX
+	###### WORKAROUND: SEE SR #7938
+	AC_PROG_CXXCPP
+	###############################
+	AC_CXX_STDHEADERS
+	MAKEFILE_CXX="${CXX}"
+	MAKEFILE_CXXLINK="${CXX}"
+fi
+
+# Do some gcc specific configuration.
+AC_GCC_CONFIG1
+
+# We need the -Kthread/-pthread flag when compiling on SCO/Caldera's UnixWare
+# and OpenUNIX releases.  We can't make the test until we know which compiler
+# we're using.
+case "$host_os" in
+sysv5UnixWare*|sysv5OpenUNIX8*)
+	if test "$GCC" == "yes"; then
+		CPPFLAGS="$CPPFLAGS -pthread"
+		LDFLAGS="$LDFLAGS -pthread"
+	else
+		CPPFLAGS="$CPPFLAGS -Kthread"
+		LDFLAGS="$LDFLAGS -Kthread"
+	fi;;
+esac
+
+# Export our compiler preferences for the libtool configuration.
+export CC CCC
+CCC=$CXX
+
+# Libtool configuration.
+AC_PROG_LIBTOOL
+
+SOFLAGS="-rpath \$(libdir)"
+
+# Set SOSUFFIX and friends
+SOSUFFIX_CONFIG
+MODSUFFIX_CONFIG
+JMODSUFFIX_CONFIG
+
+LIBTOOL="./libtool"
+
+INSTALLER="\$(LIBTOOL) --mode=install cp -p"
+
+MAKEFILE_CC="\$(LIBTOOL) --mode=compile ${MAKEFILE_CC}"
+MAKEFILE_SOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK} -avoid-version"
+MAKEFILE_CCLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK}"
+MAKEFILE_CXX="\$(LIBTOOL) --mode=compile ${MAKEFILE_CXX}"
+MAKEFILE_XSOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK} -avoid-version"
+MAKEFILE_CXXLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK}"
+
+
+case "$host_os" in
+cygwin* | mingw*)
+	MAKEFILE_SOLINK="$MAKEFILE_SOLINK -no-undefined"
+	MAKEFILE_XSOLINK="$MAKEFILE_XSOLINK -no-undefined";;
+esac
+
+case "$host_os" in
+    darwin*)
+        LIBTSO_MODULE=""
+        LIBTSO_MODSUFFIX=".dylib";;
+    *qnx*)
+        LIBTSO_MODULE=""
+        LIBTSO_MODSUFFIX=$MODSUFFIX;;
+    *)
+        LIBTSO_MODULE="-module"
+        LIBTSO_MODSUFFIX=$MODSUFFIX;;
+esac
+
+if test "$enable_static" = "yes"; then
+	test "$AR" = "false" && AC_MSG_ERROR([No ar utility found.])
+fi
+
+# C API.
+if test "$enable_shared" = "no"; then
+	DEFAULT_LIB="\$(libdb_version)"
+	POSTLINK=": "
+	o=".o"
+else
+	DEFAULT_LIB="\$(libso_target)"
+	POSTLINK="\$(LIBTOOL) --mode=execute true"
+	o=".lo"
+fi
+INSTALL_LIBS="$DEFAULT_LIB"
+if test "$enable_static" = "yes"; then
+	INSTALL_LIBS="$INSTALL_LIBS \$(libdb)"
+fi
+
+# Optional C++ API.
+if test "$db_cv_cxx" = "yes"; then
+	if test "$enable_shared" = "no"; then
+		DEFAULT_LIB_CXX="\$(libcxx_version)"
+	fi
+	if test "$enable_shared" = "yes"; then
+		DEFAULT_LIB_CXX="\$(libxso_target)"
+	fi
+	INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_CXX"
+	if test "$enable_static" = "yes"; then
+		INSTALL_LIBS="$INSTALL_LIBS \$(libcxx)"
+	fi
+fi
+
+# Optional Java API / JDBC.
+if test "$db_cv_java" = "yes" -o "$db_cv_jdbc" = "yes"; then
+	# BDB Java API requires shared libraries.
+	if test "$db_cv_java" = "yes" -a "$enable_shared" = "no"; then
+		AC_MSG_ERROR([Java requires shared libraries])
+	fi
+
+        # A classpath that includes . is needed to check for Java
+	# Since Cygwin uses Windows' javac, we need Windows path separators
+	case "$host_os" in 
+	cygwin*)	CLASSPATH=".;$CLASSPATH";;
+	*)		CLASSPATH=".:$CLASSPATH";;
+	esac
+	export CLASSPATH
+	AC_PROG_JAVAC
+	AC_PROG_JAR
+	AC_PROG_JAVA
+	AC_JNI_INCLUDE_DIR
+
+	AC_MSG_CHECKING(java version)
+        case "$JAVA" in
+	*kaffe* )
+		JAVA_VERSION=`$JAVA -version 2>&1 |
+			sed -e '/Java Version:/!d' -e 's/.*Java Version: \([[^ 	]]*\)[[ 	]]*/\1/'` ;;
+	* )	JAVA_VERSION=`$JAVA -version 2>&1 |
+        	       	sed -e '/ version /!d' -e 's/.*"\(.*\)".*/\1/'` ;;
+	esac
+	AC_MSG_RESULT($JAVA_VERSION)
+	case "$JAVA_VERSION" in
+	1.[[3456789]]* | 1.[[1-9]][[0-9]]* | [[23456789]]* ) ;;
+	* )
+		AC_MSG_ERROR([Java version 1.3 or higher required, got $JAVA_VERSION]) ;;
+	esac
+
+	# Because of the code that SWIG generates to cast between pointers and
+	# integers, we need to add the flag "-fno-strict-aliasing" to the gcc
+	# command line when compiling the JNI code.  This is documented in
+	# [#14953] and at http://www.swig.org/Doc1.3/Java.html
+	if test "${GCC}" = "yes"; then
+		SWIGCFLAGS="-fno-strict-aliasing"
+	fi
+
+	for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS
+	do
+		CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR"
+	done
+
+	if test "$db_cv_java" = "yes"; then
+		ADDITIONAL_LANG="$ADDITIONAL_LANG java"
+		INSTALL_LIBS="$INSTALL_LIBS \$(libjso_target)"
+	fi
+else
+	JAVAC=nojavac
+fi
+
+# MinGW support.
+if test "$db_cv_mingw" = "yes"; then
+	OSDIR=os_windows
+	PATH_SEPARATOR="\\\\/:"
+
+	AC_DEFINE(DB_WIN32)
+	AC_DEFINE(STDC_HEADERS)
+else
+	OSDIR=os
+	PATH_SEPARATOR="/"
+	AC_DEFINE(HAVE_SYSTEM_INCLUDE_FILES)
+fi
+
+# Optional SQL API.
+if test "$db_cv_sql" = "yes"; then
+	ADDITIONAL_INCS="$ADDITIONAL_INCS dbsql.h"
+	ADDITIONAL_PROGS="$ADDITIONAL_PROGS dbsql"
+
+	# Link against libdl, if found. It is only needed for the load
+	# extension, but shouldn't hurt.
+	AC_HAVE_LIBRARY(dl, SQL_LIBS="$SQL_LIBS -ldl")
+
+	# Link against libedit or readline for command-line editing.
+	if test x"$with_readline" != xno; then
+		header=readline.h
+		for rl_lib in edit readline; do
+			found="yes"
+			save_LIBS=""
+			LIBS=""
+			AS_UNSET(ac_cv_search_tgetent)
+			AC_SEARCH_LIBS(tgetent,
+			    [$rl_lib ncurses curses termcap],
+			    [term_LIBS="$LIBS"], [term_LIBS=""])
+			AC_CHECK_LIB([$rl_lib], [readline],
+			    [SQL_LIBS="$SQL_LIBS -l$rl_lib $term_LIBS"],
+			    [found="no"])
+			LIBS="$save_LIBS"
+			test "$found" = "yes" && break
+		done
+
+		if test x"$rl_lib" = xedit; then
+			header="editline/readline.h"
+		fi
+
+		if test "$found" = "yes"; then
+			AC_CHECK_HEADER($header, [found="yes"], [
+				found="no"
+				if test "$cross_compiling" != yes; then
+					for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do
+						for subdir in include include/readline; do
+							AC_CHECK_FILE($dir/$subdir/$header, found=yes)
+							if test "$found" = "yes"; then
+								SQL_FLAGS="$SQL_FLAGS -I$dir/$subdir"
+								break
+							fi
+						done
+						test "$found" = "yes" && break
+					done
+				fi])
+		fi
+	fi
+
+	if test "$enable_shared" = "no"; then
+		DEFAULT_LIB_SQL="\$(libsql_version)"
+	else
+		DEFAULT_LIB_SQL="\$(libsqlso_target)"
+	fi
+	INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_SQL"
+	if test "$enable_static" = "yes"; then
+		INSTALL_LIBS="$INSTALL_LIBS \$(libsql)"
+	fi
+
+	if test "$db_cv_test" = "yes"; then
+		subdirs="$subdirs sql"
+		ADDITIONAL_LANG="$ADDITIONAL_LANG sql-test"
+	fi
+
+	if test "$db_cv_jdbc" = "yes"; then
+		subdirs="$subdirs jdbc"
+		ADDITIONAL_LANG="$ADDITIONAL_LANG jdbc"
+	fi
+
+	if test "$db_cv_debug" = "yes"; then
+		SQL_FLAGS="$SQL_FLAGS -DSQLITE_DEBUG=1"
+	fi
+
+	if test "$db_cv_build_cryptography" = "yes"; then
+		SQL_FLAGS="$SQL_FLAGS -DSQLITE_HAS_CODEC=1"
+	fi
+fi
+
+if test "$db_cv_sql_compat" = "yes"; then
+	if test "$enable_shared" = "no"; then
+		DEFAULT_LIB_SQLITE="\$(libsqlite)"
+	else
+		DEFAULT_LIB_SQLITE="\$(libsqliteso_target)"
+	fi
+
+	ADDITIONAL_INCS="$ADDITIONAL_INCS \$(langdir)/sql/generated/sqlite3.h"
+	ADDITIONAL_PROGS="$ADDITIONAL_PROGS sqlite3"
+	INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_SQLITE"
+
+	# This is different to the other libraries: we need to be very
+	# careful not to delete an existing installation of SQLite unless
+	# we are installing over it.
+	if test "$enable_shared" = "yes"; then
+		INSTALL_LIBS_EXTRA="$INSTALL_LIBS_EXTRA \$(libsqliteso)"
+	fi
+	if test "$enable_static" = "yes"; then
+		INSTALL_LIBS="$INSTALL_LIBS \$(libsqlite)"
+	fi
+fi
+
+# Optional SQL code generation tool.
+if test "$db_cv_sql_codegen" = "yes"; then
+	ADDITIONAL_PROGS="$ADDITIONAL_PROGS db_sql_codegen"
+fi
+
+# Optional STL API.
+if test "$db_cv_stl" = "yes"; then
+	AC_CXX_SUPPORTS_TEMPLATES
+	AC_CXX_WSTRING
+	AX_TLS
+	if test "$enable_shared" = "no"; then
+		DEFAULT_LIB_STL="\$(libstl_version)"
+	fi
+	if test "$enable_shared" = "yes"; then
+		DEFAULT_LIB_STL="\$(libstlso_target)"
+	fi
+	ADDITIONAL_INCS="$ADDITIONAL_INCS dbstl_common.h"
+	for f in dbstl_set.h dbstl_vector.h dbstl_exception.h dbstl_map.h dbstl_utility.h dbstl_dbc.h dbstl_dbt.h dbstl_base_iterator.h dbstl_container.h dbstl_element_ref.h dbstl_inner_utility.h dbstl_resource_manager.h ; do
+		ADDITIONAL_INCS="$ADDITIONAL_INCS \$(topdir)/lang/cxx/stl/$f"
+	done
+	INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_STL"
+	if test "$enable_static" = "yes"; then
+		INSTALL_LIBS="$INSTALL_LIBS \$(libstl)"
+	fi
+fi
+
+# Checks for include files, structures, C types.
+AC_HEADER_STAT
+AC_HEADER_TIME
+AC_HEADER_DIRENT
+AC_CHECK_HEADERS(execinfo.h sys/select.h sys/socket.h sys/time.h)
+AC_CHECK_MEMBERS([struct stat.st_blksize])
+AM_TYPES
+
+AC_CACHE_CHECK([for ANSI C exit success/failure values], db_cv_exit_defines, [
+AC_TRY_COMPILE([#include <stdlib.h>], return (EXIT_SUCCESS);,
+    [db_cv_exit_defines=yes], [db_cv_exit_defines=no])])
+if test "$db_cv_exit_defines" = "yes"; then
+	AC_DEFINE(HAVE_EXIT_SUCCESS)
+	AH_TEMPLATE(HAVE_EXIT_SUCCESS,
+	    [Define to 1 if platform has EXIT_SUCCESS/EXIT_FAILURE #defines.])
+fi
+
+AC_CACHE_CHECK([for getopt optreset variable], db_cv_optreset, [
+AC_TRY_LINK([#include <unistd.h>], extern int optreset; optreset = 1;,
+    [db_cv_optreset=yes], [db_cv_optreset=no])])
+if test "$db_cv_optreset" = "yes"; then
+	AC_DEFINE(HAVE_GETOPT_OPTRESET)
+	AH_TEMPLATE(HAVE_GETOPT_OPTRESET,
+	    [Define to 1 if getopt supports the optreset variable.])
+fi
+
+# Check for mutexes.
+# We do this first because it changes $LIBSO_LIBS.
+AM_DEFINE_MUTEXES
+
+# Check for native (system call or instruction set) support for
+# atomic increment, decrement, and compare & exchange.
+AM_DEFINE_ATOMIC
+
+# Check for os-specific event support for performance monitoring such as
+# DTrace or SystemTap.
+AM_DEFINE_PERFMON
+
+# Test for various functions/libraries -- do tests that change library values
+# first.
+#
+# Update LIBS, so we're testing against the current list of libraries.
+LIBS="$LIBSO_LIBS"
+
+# The yield function on Solaris is almost certainly pthread_yield (LWP threads
+# or POSIX pthreads), or thr_yield (UI threads).  There's an outside chance it
+# is sched_yield() though, only available in -lrt on Solaris.
+AC_SEARCH_LIBS(sched_yield, rt)
+
+# The Berkeley DB library calls fdatasync, only available in -lrt on Solaris.
+AC_SEARCH_LIBS(fdatasync, rt)
+
+AC_SEARCH_LIBS(getaddrinfo, nsl socket)
+AC_SEARCH_LIBS(hstrerror, resolv)
+
+# Those tests updated LIBS, update our internal list.
+LIBSO_LIBS="$LIBS"
+
+# !!!
+# We could be more exact about whether these libraries are needed, but don't
+# bother -- if they exist, we load them, it's only the test programs anyway.
+AC_HAVE_LIBRARY(m, TEST_LIBS="$TEST_LIBS -lm")
+AC_HAVE_LIBRARY(nsl, TEST_LIBS="$TEST_LIBS -lnsl")
+AC_HAVE_LIBRARY(socket, TEST_LIBS="$TEST_LIBS -lsocket")
+
+# Checks for system functions for which we have replacements.
+#
+# The only portable getcwd call is getcwd(char *, size_t), where the
+# buffer is non-NULL -- Solaris can't handle a NULL buffer, and they
+# deleted getwd().
+AC_REPLACE_FUNCS(\
+	abort atoi atol bsearch getcwd getenv getopt isalpha isdigit isprint\
+	isspace memcmp memcpy memmove printf qsort raise rand strcasecmp\
+	strcat strchr strdup strerror strncat strncmp strrchr strsep\
+	strtol strtoul)
+
+# Check for system functions we optionally use.
+AC_CHECK_FUNCS(\
+	_fstati64 backtrace backtrace_symbols directio fchmod fclose\
+	fcntl fdatasync fgetc fgets fopen fwrite getgid\
+	getrusage getuid hstrerror mprotect pstat_getdynamic\
+	pthread_self pthread_yield random sched_yield select setgid setuid\
+	sigaction snprintf stat sysconf vsnprintf yield)
+
+AC_TIMERS
+
+# Ftruncate.
+# We've run into a problem with ftruncate on Alpha/Tru64, the issue is that
+# after a truncate the last page of the file mmaps as all zeros.  So just don't
+# use ftruncate.
+case "$host_os" in
+osf*)
+	AC_MSG_WARN(
+	    [ftruncate ignored on $host_os-$host_vendor.]);;
+*)
+	AC_CHECK_FUNCS(ftruncate);;
+esac
+
+# Pread/pwrite.
+# HP-UX has pread/pwrite, but it doesn't work with largefile support.
+# NCR's version of System V R 4.3 has pread/pwrite symbols, but no support.
+case "$host_os-$host_vendor" in
+hpux*|sysv4.3*-ncr)
+	AC_MSG_WARN(
+	    [pread/pwrite interfaces ignored on $host_os-$host_vendor.]);;
+*)
+	AC_CHECK_FUNCS(pread pwrite);;
+esac
+
+# Check for getaddrinfo; do the test explicitly instead of using AC_CHECK_FUNCS
+# because <netdb.h> isn't a standard include file.
+AC_CACHE_CHECK([for getaddrinfo], db_cv_getaddrinfo, [
+AC_TRY_LINK([
+#include <sys/types.h>
+#include <netdb.h>], [
+	getaddrinfo(0, 0, 0, 0);
+], [db_cv_getaddrinfo=yes], [db_cv_getaddrinfo=no])])
+if test "$db_cv_getaddrinfo" = "yes"; then
+	AC_DEFINE(HAVE_GETADDRINFO)
+	AH_TEMPLATE(HAVE_GETADDRINFO,
+	    [Define to 1 if you have the `getaddrinfo' function.])
+fi
+
+# Check for the fcntl F_SETFD flag to deny child process access to file
+# descriptors.
+AC_CACHE_CHECK([for fcntl/F_SETFD], db_cv_fcntl_f_setfd, [
+AC_TRY_LINK([
+#include <sys/types.h>
+#include <fcntl.h>], [
+	fcntl(1, F_SETFD, 1);
+], [db_cv_fcntl_f_setfd=yes], [db_cv_fcntl_f_setfd=no])])
+if test "$db_cv_fcntl_f_setfd" = "yes"; then
+	AC_DEFINE(HAVE_FCNTL_F_SETFD)
+	AH_TEMPLATE(HAVE_FCNTL_F_SETFD,
+    [Define to 1 if fcntl/F_SETFD denies child access to file descriptors.])
+fi
+
+# A/UX has a broken getopt(3).
+case "$host_os" in
+aux*)	AC_LIBOBJ([getopt]);;
+esac
+
+# Linux has a broken O_DIRECT flag, but you can't detect it at configure time.
+# Linux and SGI require buffer alignment we may not match, otherwise writes
+# will fail.  Default to not using the O_DIRECT flag.
+if test "$db_cv_o_direct" = "yes"; then
+	AC_CACHE_CHECK([for open/O_DIRECT], db_cv_open_o_direct, [
+	AC_TRY_LINK([
+	#include <sys/types.h>
+	#include <fcntl.h>], [
+		open("a", O_RDONLY | O_DIRECT, 0);
+	], [db_cv_open_o_direct=yes], [db_cv_open_o_direct=no])])
+	if test \
+	    "$db_cv_o_direct" = "yes" -a "$db_cv_open_o_direct" = "yes"; then
+		AC_DEFINE(HAVE_O_DIRECT)
+		AH_TEMPLATE(HAVE_O_DIRECT,
+		    [Define to 1 if you have the O_DIRECT flag.])
+	fi
+fi
+
+# Check for largefile support.
+AC_SYS_LARGEFILE
+
+# Figure out how to create shared regions.
+#
+# First, we look for mmap.
+#
+# BSD/OS has mlock(2), but it doesn't work until the 4.1 release.
+#
+# Nextstep (version 3.3) apparently supports mmap(2) (the mmap symbol
+# is defined in the C library) but does not support munmap(2).  Don't
+# try to use mmap if we can't find munmap.
+#
+# Ultrix has mmap(2), but it doesn't work.
+mmap_ok=no
+case "$host_os" in
+bsdi3*|bsdi4.0)
+	AC_MSG_WARN([mlock(2) interface ignored on $host_os-$host_vendor.])
+	mmap_ok=yes
+	AC_CHECK_FUNCS(mmap munmap, , mmap_ok=no);;
+ultrix*)
+	AC_MSG_WARN([mmap(2) interface ignored on $host_os-$host_vendor.]);;
+*)
+	mmap_ok=yes
+	AC_CHECK_FUNCS(mlock munlock)
+	AC_CHECK_FUNCS(mmap munmap, , mmap_ok=no);;
+esac
+
+# Second, we look for shmget.
+#
+# SunOS has the shmget(2) interfaces, but there appears to be a missing
+# #include <debug/debug.h> file, so we ignore them.
+shmget_ok=no
+case "$host_os" in
+sunos*)
+	AC_MSG_WARN([shmget(2) interface ignored on $host_os-$host_vendor.]);;
+*)
+	shmget_ok=yes
+	AC_CHECK_FUNCS(shmget, , shmget_ok=no)
+
+	# Check for shmctl to lock down shared memory segments.
+	AC_CACHE_CHECK([for shmctl], db_cv_shmctl_shm_lock, [
+	AC_TRY_LINK([
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <stdio.h>], [
+		shmctl(0, SHM_LOCK, NULL);
+	], [db_cv_shmctl_shm_lock=yes], [db_cv_shmctl_shm_lock=no])])
+	if test "$db_cv_shmctl_shm_lock" = "yes"; then
+		AC_DEFINE(HAVE_SHMCTL_SHM_LOCK)
+		AH_TEMPLATE(HAVE_SHMCTL_SHM_LOCK,
+	    [Define to 1 if shmctl/SHM_LOCK locks down shared memory segments.])
+	fi;;
+esac
+
+# We require either mmap/munmap(2) or shmget(2).
+if test "$mmap_ok" = "no" -a "$shmget_ok" = "no"; then
+	AC_MSG_WARN([Neither mmap/munmap(2) or shmget(2) library functions.])
+fi
+
+# Optional Tcl support.
+if test "$db_cv_tcl" = "yes"; then
+	AM_TCL_LOAD
+fi
+
+# Optional sequence code.
+AM_SEQUENCE_CONFIGURE
+
+# Detect whether a large mmap() supports automatically extending the accessible
+# region after growing the underlying file.
+AM_MMAP_EXTEND
+
+# Optional DB 1.85 compatibility API.
+if test "$db_cv_compat185" = "yes"; then
+	ADDITIONAL_INCS="db_185.h $ADDITIONAL_INCS"
+
+	ADDITIONAL_OBJS="db185${o} $ADDITIONAL_OBJS"
+fi
+
+# Optional utilities.
+if test "$db_cv_dump185" = "yes"; then
+	ADDITIONAL_PROGS="db_dump185 $ADDITIONAL_PROGS"
+fi
+
+# Log checksums can be disabled to increase performance
+if test "$db_cv_log_checksum" = "yes"; then
+	AC_DEFINE(HAVE_LOG_CHECKSUM)
+	AH_TEMPLATE(HAVE_LOG_CHECKSUM, [Define to 1 if enabling checksums in log records.])
+fi
+
+# You can disable pieces of functionality to save space.
+#
+# Btree is always configured: it is the standard method, and Hash off-page
+# duplicates require it.
+
+# Compression can be disabled.
+if test "$db_cv_build_compression" = "yes"; then
+	AC_DEFINE(HAVE_COMPRESSION)
+	AH_TEMPLATE(HAVE_COMPRESSION, [Define to 1 if building compression support.])
+fi
+
+# Partitioning can be disabled.
+if test "$db_cv_build_partition" = "yes"; then
+	AC_DEFINE(HAVE_PARTITION)
+	AH_TEMPLATE(HAVE_PARTITION, [Define to 1 if building partitioned database support.])
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(PARTITION_OBJS)"
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS partition_stub${o}"
+fi
+
+# Hash can be disabled.
+if test "$db_cv_build_hash" = "yes"; then
+	AC_DEFINE(HAVE_HASH)
+	AH_TEMPLATE(HAVE_HASH, [Define to 1 if building Hash access method.])
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HASH_OBJS)"
+	if test "$db_cv_build_verify" = "yes"; then
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HASH_VRFY_OBJS)"
+	fi
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS hash_stub${o}"
+fi
+
+# Heap can be disabled.
+if test "$db_cv_build_heap" = "yes"; then
+	AC_DEFINE(HAVE_HEAP)
+	AH_TEMPLATE(HAVE_HEAP, [Define to 1 if building Heap access method.])
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HEAP_OBJS)"
+	if test "$db_cv_build_verify" = "yes"; then
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HEAP_VRFY_OBJS)"
+	fi
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS heap_stub${o}"
+fi
+
+# Queue can be disabled.
+if test "$db_cv_build_queue" = "yes"; then
+	AC_DEFINE(HAVE_QUEUE)
+	AH_TEMPLATE(HAVE_QUEUE, [Define to 1 if building Queue access method.])
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(QUEUE_OBJS)"
+	if test "$db_cv_build_verify" = "yes"; then
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(QUEUE_VRFY_OBJS)"
+	fi
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS qam_stub${o}"
+fi
+
+# Replication can be disabled.
+if test "$db_cv_build_replication" = "yes"; then
+	AC_DEFINE(HAVE_REPLICATION)
+	AH_TEMPLATE(HAVE_REPLICATION,
+	    [Define to 1 if building replication support.])
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(REP_OBJS)"
+
+	# If we're building replication and detected POSIX threads, build the
+	# replication manager.
+	AH_TEMPLATE(HAVE_REPLICATION_THREADS,
+	    [Define to 1 if building the Berkeley DB replication framework.])
+
+	if test "$ac_cv_header_pthread_h" = yes -a "$db_cv_mingw" != "yes"; then
+		AC_DEFINE(HAVE_REPLICATION_THREADS)
+
+		if test "$with_stacksize" != "no"; then
+			AC_DEFINE_UNQUOTED(DB_STACKSIZE, $with_stacksize,
+	    [Defined to a size to limit the stack size of Berkeley DB threads.])
+		fi
+
+		# Solaris requires the socket and nsl libraries to build the
+		# replication manager.  Don't add nsl regardless of the OS,
+		# it causes RPC to fail on AIX 4.3.3.
+		case "$host_os" in
+		solaris*)
+			AC_HAVE_LIBRARY(nsl, LIBSO_LIBS="$LIBSO_LIBS -lnsl")
+			AC_HAVE_LIBRARY(socket,
+			    LIBSO_LIBS="$LIBSO_LIBS -lsocket");;
+		esac
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(REPMGR_OBJS)"
+	else
+		AC_MSG_WARN([Replication manager is not supported.])
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS repmgr_stub${o}"
+	fi
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS rep_stub${o} repmgr_stub${o}"
+fi
+
+# The statistics code can be disabled.
+if test "$db_cv_build_statistics" = "yes"; then
+	AC_DEFINE(HAVE_STATISTICS)
+	AH_TEMPLATE(HAVE_STATISTICS,
+	    [Define to 1 if building statistics support.])
+fi
+
+# The verification code can be disabled.
+if test "$db_cv_build_verify" = "yes"; then
+	AC_DEFINE(HAVE_VERIFY)
+	AH_TEMPLATE(HAVE_VERIFY,
+	    [Define to 1 if building access method verification support.])
+	if test "$db_cv_rdsbuild" = "no"; then
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(BTREE_VRFY_OBJS) \$(LOG_VRFY_OBJS)"
+	else
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(BTREE_VRFY_OBJS) log_verify_stub${o}"
+	fi
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS db_vrfy_stub${o} log_verify_stub${o}"
+fi
+
+# The crypto code can be disabled.
+if test -d "$topdir/src/crypto" -a "$db_cv_build_cryptography" != "no"; then
+	AC_DEFINE(HAVE_CRYPTO)
+	AH_TEMPLATE(HAVE_CRYPTO,
+	    [Define to 1 if building cryptography support.])
+
+	CRYPTO_OBJS="\$(CRYPTO_OBJS)"
+
+	if test "$db_cv_build_cryptography" = "ipp"; then
+		AC_CHECK_HEADER([ippcp.h], [], AC_MSG_ERROR([\
+The 'ippcp.h' header file required for IPP cryptography support was not found \
+in the configured include path.]))
+		AC_DEFINE(HAVE_CRYPTO_IPP)
+		AH_TEMPLATE(HAVE_CRYPTO_IPP,
+		    [Define to 1 if using Intel IPP for cryptography.])
+	fi
+else
+	CRYPTO_OBJS="crypto_stub${o}"
+fi
+
+# The mutex code can be disabled, and if there aren't any mutexes, then there's
+# no reason to include the locking code.
+if test "$db_cv_build_mutexsupport" = "yes"; then
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(MUTEX_OBJS)"
+	db_cv_locking="yes"
+else
+	db_cv_locking="no"
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS mut_stub${o}"
+fi
+
+LOCALEXAMPLES="\$(exampledir)"
+LOCALSRC="\$(srcdir)"
+LOCALUTILS="\$(utildir)"
+# The RDS build disables transactions and most features except DML and cursors.
+# They are removed by appending rds_stubs instead of STD_OBJS to ADDITIONAL_OBJS.
+if test "$db_cv_rdsbuild" = "no"; then
+	AC_DEFINE(HAVE_TRANSACTIONS)
+	AH_TEMPLATE(HAVE_TRANSACTIONS, [Define to 1 if building in transaction support.])
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(STD_OBJS)"
+	ADDITIONAL_PROGS="$ADDITIONAL_PROGS \$(STD_PROGS)"
+else
+	AC_DEFINE(HAVE_RDS_BUILD)
+	AH_TEMPLATE(HAVE_RDS_BUILD, [Define to 1 if building only the most basic features.])
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS rds_stub${o}"
+	db_cv_locking="no"
+	if test "$db_rdsbuild_default" = "no" ; then
+		# The normal db_load and db_stat utilities use non-RDS features.
+		# This modifies those source files such that they can work with
+		# with --enable-rdsbuild,
+		LOCALEXAMPLES="examples"
+		LOCALSRC="src"
+		LOCALUTILS="util"
+		# Apply all .patch files underneath the patches directory
+		# to local copies in the building directory.
+		for f in `grep -v '^#' $topdir/dist/rds/patchlist`; do
+			localdir=`dirname $f`
+			rm -f ./$f
+			test -d $localdir || mkdir -p $localdir || exit 1
+			cp $topdir/$f $f && \
+			patch $f $topdir/dist/rds/patches/$f.patch && \
+			chmod 444 $f || exit 1
+		done
+	fi
+fi
+
+# AH_TEMPLATE(HAVE_LOCKING, [Define to 1 if building in locking support.])
+if test "$db_cv_locking" = "yes"; then
+#	AC_DEFINE(HAVE_LOCKING)
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(LOCK_OBJS)"
+else
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS lock_stub${o}"
+fi
+
+# If DIAGNOSTIC is defined (but not RDS), include the log print routines in the
+# library itself, various diagnostic modes use them.
+if test "$db_cv_diagnostic" = "yes"; then
+	if test "$db_cv_rdsbuild" = "no"; then
+		ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(PRINT_OBJS)"
+	fi
+	PRINTLOG_OBJS=""
+else
+	PRINTLOG_OBJS="\$(PRINT_OBJS)"
+fi
+
+# If building for QNX, we need additional OS files.
+if test "$qnx_build" = "yes"; then
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS os_qnx_fsync${o} os_qnx_open${o}"
+fi
+
+# The DBM API can be disabled.
+if test "$db_cv_dbm" = "yes"; then
+	AC_DEFINE(HAVE_DBM)
+	AH_TEMPLATE(HAVE_DBM, [Define to 1 if building the DBM API.])
+	ADDITIONAL_OBJS="$ADDITIONAL_OBJS dbm${o} hsearch${o}"
+fi
+
+# The output and error messages can be stripped.
+if test "$db_cv_stripped_messages" = "yes"; then
+	AC_DEFINE(HAVE_STRIPPED_MESSAGES)
+	AH_TEMPLATE(HAVE_STRIPPED_MESSAGES,
+	    [Define to 1 if building without output message content.])
+fi
+
+# The output and error messages can be localized.
+if test "$db_cv_localization" = "yes"; then
+	AC_DEFINE(HAVE_LOCALIZATION)
+	AH_TEMPLATE(HAVE_LOCALIZATION,
+[Define to 1 if you have localization function to support globalization.])
+fi
+
+# We need to add the additional object files into the Makefile with the correct
+# suffix.  We can't use $LTLIBOBJS itself, because that variable has $U encoded
+# in it for automake, and that's not what we want.  See SR #7227 for additional
+# information.
+#
+# XXX: I'm not sure this is correct.
+REPLACEMENT_OBJS=`echo "$LIB@&t@OBJS" |
+		sed "s,\.[[^.]]* ,$o ,g;s,\.[[^.]]*$,$o,"`
+
+# This is necessary so that .o files in LIBOBJS are also built via
+# the ANSI2KNR-filtering rules.
+LIB@&t@OBJS=`echo "$LIB@&t@OBJS" |
+		sed 's,\.[[^.]]* ,$U&,g;s,\.[[^.]]*$,$U&,'`
+LTLIBOBJS=`echo "$LIB@&t@OBJS" |
+		sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'`
+AC_SUBST(LTLIBOBJS)
+
+# Initial output file list.
+CREATE_LIST="Makefile
+    db_cxx.h:$topdir/src/dbinc/db_cxx.in
+    db_int.h:$topdir/src/dbinc/db_int.in
+    clib_port.h:$topdir/dist/clib_port.in"
+if test "$db_cv_tcl" = "yes"; then
+CREATE_LIST="$CREATE_LIST
+    include.tcl:$topdir/test/tcl/include.tcl"
+fi
+
+# Create the db.h file from a source file, a list of global function
+# prototypes, and, if configured for unique names, a list of #defines
+# to do DB_VERSION_UNIQUE_NAME substitution.
+if test "$db_cv_uniquename" = "yes"; then
+	CREATE_LIST="$CREATE_LIST
+	db.h:$topdir/src/dbinc/db.in:$topdir/src/dbinc_auto/api_flags.in:$topdir/src/dbinc_auto/ext_def.in:$topdir/src/dbinc_auto/ext_prot.in"
+else
+	CREATE_LIST="$CREATE_LIST
+	db.h:$topdir/src/dbinc/db.in:$topdir/src/dbinc_auto/api_flags.in:$topdir/src/dbinc_auto/ext_prot.in"
+fi
+
+# If configured for unique names, create the db_int_uext.h file (which
+# does the DB_VERSION_UNIQUE_NAME substitution), which is included by
+# the db_int.h file.
+if test "$db_cv_uniquename" = "yes"; then
+	CREATE_LIST="$CREATE_LIST
+	db_int_def.h:$topdir/src/dbinc_auto/int_def.in"
+	db_int_def='#include "db_int_def.h"'
+fi
+
+# Create the db_185.h and db185_int.h files from source files, a list of
+# global function prototypes, and, if configured for unique names, a list
+# of #defines to do DB_VERSION_UNIQUE_NAME substitution.
+if test "$db_cv_compat185" = "yes"; then
+	if test "$db_cv_uniquename" = "yes"; then
+		CREATE_LIST="$CREATE_LIST
+		db_185.h:$topdir/src/dbinc/db_185.in:$topdir/src/dbinc_auto/ext_185_def.in:$topdir/src/dbinc_auto/ext_185_prot.in
+		db185_int.h:$topdir/lang/db185/db185_int.in:$topdir/src/dbinc_auto/ext_185_def.in:$topdir/src/dbinc_auto/ext_185_prot.in"
+	else
+		CREATE_LIST="$CREATE_LIST
+		db_185.h:$topdir/src/dbinc/db_185.in:$topdir/src/dbinc_auto/ext_185_prot.in
+		db185_int.h:$topdir/lang/db185/db185_int.in:$topdir/src/dbinc_auto/ext_185_prot.in"
+	fi
+fi
+
+if test "$db_cv_stl" = "yes"; then
+	CREATE_LIST="$CREATE_LIST
+	dbstl_common.h:$topdir/lang/cxx/stl/dbstl_common.in"
+fi
+
+if test "x$subdirs" != "x"; then
+	subdir_cmd="@for d in ${subdirs}; do (cd \$\$d && \${MAKE} \$@) ; done"
+fi
+
+AC_CONFIG_FILES($CREATE_LIST)
+AC_OUTPUT
+
+if test "$db_cv_rdsbuild" = "yes" -a "$db_rdsbuild_default" = "no" ; then
+	# Patch the resulting db.h to remove unsupported functions.
+	patch "db.h" "$topdir/dist/rds/patches/src/dbinc/db.in.patch" || exit 1
+	patch "db_int.h" "$topdir/dist/rds/patches/src/dbinc/db_int.in.patch" || exit 1
+fi
+
+if test "$db_cv_sql" = "yes"; then
+	# This command runs the configure script from the SQL tree.
+	AC_MSG_NOTICE([Configuring the SQL API])
+	AC_SQL_CONFIG
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/errno.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,213 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)errno.h	8.5 (Berkeley) 1/21/94
+ * FreeBSD: /repoman/r/ncvs/src/sys/sys/errno.h,v 1.28 2005/04/02 12:33:28 das Exp $
+ *
+ * $Id$
+ */
+
+#ifndef _SYS_ERRNO_H_
+#define	_SYS_ERRNO_H_
+
+#undef	errno
+#define	errno	DB_GLOBAL(db_errno)
+
+#define	EPERM		1		/* Operation not permitted */
+#define	ENOENT		2		/* No such file or directory */
+#define	ESRCH		3		/* No such process */
+#define	EINTR		4		/* Interrupted system call */
+#define	EIO		5		/* Input/output error */
+#define	ENXIO		6		/* Device not configured */
+#define	E2BIG		7		/* Argument list too long */
+#define	ENOEXEC		8		/* Exec format error */
+#define	EBADF		9		/* Bad file descriptor */
+#define	ECHILD		10		/* No child processes */
+#define	EDEADLK		11		/* Resource deadlock avoided */
+					/* 11 was EAGAIN */
+#define	ENOMEM		12		/* Cannot allocate memory */
+#define	EACCES		13		/* Permission denied */
+#define	EFAULT		14		/* Bad address */
+#ifndef _POSIX_SOURCE
+#define	ENOTBLK		15		/* Block device required */
+#endif
+#define	EBUSY		16		/* Device busy */
+#define	EEXIST		17		/* File exists */
+#define	EXDEV		18		/* Cross-device link */
+#define	ENODEV		19		/* Operation not supported by device */
+#define	ENOTDIR		20		/* Not a directory */
+#define	EISDIR		21		/* Is a directory */
+#define	EINVAL		22		/* Invalid argument */
+#define	ENFILE		23		/* Too many open files in system */
+#define	EMFILE		24		/* Too many open files */
+#define	ENOTTY		25		/* Inappropriate ioctl for device */
+#ifndef _POSIX_SOURCE
+#define	ETXTBSY		26		/* Text file busy */
+#endif
+#define	EFBIG		27		/* File too large */
+#define	ENOSPC		28		/* No space left on device */
+#define	ESPIPE		29		/* Illegal seek */
+#define	EROFS		30		/* Read-only filesystem */
+#define	EMLINK		31		/* Too many links */
+#define	EPIPE		32		/* Broken pipe */
+
+/* math software */
+#define	EDOM		33		/* Numerical argument out of domain */
+#define	ERANGE		34		/* Result too large */
+
+/* non-blocking and interrupt i/o */
+#define	EAGAIN		35		/* Resource temporarily unavailable */
+#ifndef _POSIX_SOURCE
+#define	EWOULDBLOCK	EAGAIN		/* Operation would block */
+#define	EINPROGRESS	36		/* Operation now in progress */
+
+#define	EALREADY	37		/* Operation already in progress */
+
+/* ipc/network software -- argument errors */
+#define	ENOTSOCK	38		/* Socket operation on non-socket */
+#define	EDESTADDRREQ	39		/* Destination address required */
+#define	EMSGSIZE	40		/* Message too long */
+#define	EPROTOTYPE	41		/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	42		/* Protocol not available */
+#define	EPROTONOSUPPORT	43		/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	44		/* Socket type not supported */
+#define	EOPNOTSUPP	45		/* Operation not supported */
+#define	ENOTSUP		EOPNOTSUPP	/* Operation not supported */
+#define	EPFNOSUPPORT	46		/* Protocol family not supported */
+#define	EAFNOSUPPORT	47		/* Address family not supported by protocol family */
+#define	EADDRINUSE	48		/* Address already in use */
+#define	EADDRNOTAVAIL	49		/* Can't assign requested address */
+
+/* ipc/network software -- operational errors */
+#define	ENETDOWN	50		/* Network is down */
+#define	ENETUNREACH	51		/* Network is unreachable */
+#define	ENETRESET	52		/* Network dropped connection on reset */
+#define	ECONNABORTED	53		/* Software caused connection abort */
+#define	ECONNRESET	54		/* Connection reset by peer */
+#define	ENOBUFS		55		/* No buffer space available */
+#define	EISCONN		56		/* Socket is already connected */
+#define	ENOTCONN	57		/* Socket is not connected */
+#define	ESHUTDOWN	58		/* Can't send after socket shutdown */
+#define	ETOOMANYREFS	59		/* Too many references: can't splice */
+#define	ETIMEDOUT	60		/* Operation timed out */
+#define	ECONNREFUSED	61		/* Connection refused */
+
+#define	ELOOP		62		/* Too many levels of symbolic links */
+#endif /* _POSIX_SOURCE */
+#define	ENAMETOOLONG	63		/* File name too long */
+
+/* should be rearranged */
+#ifndef _POSIX_SOURCE
+#define	EHOSTDOWN	64		/* Host is down */
+#define	EHOSTUNREACH	65		/* No route to host */
+#endif /* _POSIX_SOURCE */
+#define	ENOTEMPTY	66		/* Directory not empty */
+
+/* quotas & mush */
+#ifndef _POSIX_SOURCE
+#define	EPROCLIM	67		/* Too many processes */
+#define	EUSERS		68		/* Too many users */
+#define	EDQUOT		69		/* Disc quota exceeded */
+
+/* Network File System */
+#define	ESTALE		70		/* Stale NFS file handle */
+#define	EREMOTE		71		/* Too many levels of remote in path */
+#define	EBADRPC		72		/* RPC struct is bad */
+#define	ERPCMISMATCH	73		/* RPC version wrong */
+#define	EPROGUNAVAIL	74		/* RPC prog. not avail */
+#define	EPROGMISMATCH	75		/* Program version wrong */
+#define	EPROCUNAVAIL	76		/* Bad procedure for program */
+#endif /* _POSIX_SOURCE */
+
+#define	ENOLCK		77		/* No locks available */
+#define	ENOSYS		78		/* Function not implemented */
+
+#ifndef _POSIX_SOURCE
+#define	EFTYPE		79		/* Inappropriate file type or format */
+#define	EAUTH		80		/* Authentication error */
+#define	ENEEDAUTH	81		/* Need authenticator */
+#define	EIDRM		82		/* Identifier removed */
+#define	ENOMSG		83		/* No message of desired type */
+#define	EOVERFLOW	84		/* Value too large to be stored in data type */
+#define	ECANCELED	85		/* Operation canceled */
+#define	EILSEQ		86		/* Illegal byte sequence */
+#define	ENOATTR		87		/* Attribute not found */
+
+#define	EDOOFUS		88		/* Programming error */
+#endif /* _POSIX_SOURCE */
+
+#define	EBADMSG		89		/* Bad message */
+#define	EMULTIHOP	90		/* Multihop attempted */
+#define	ENOLINK		91		/* Link has been severed */
+#define	EPROTO		92		/* Protocol error */
+
+#ifndef _POSIX_SOURCE
+#define	ELAST		92		/* Must be equal largest errno */
+#endif /* _POSIX_SOURCE */
+
+#ifdef _KERNEL
+/* pseudo-errors returned inside kernel to modify return to process */
+#define	ERESTART	(-1)		/* restart syscall */
+#define	EJUSTRETURN	(-2)		/* don't modify regs, just return */
+#define	ENOIOCTL	(-3)		/* ioctl not handled by this layer */
+#define	EDIRIOCTL	(-4)		/* do direct ioctl in GEOM */
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/gen_inc.awk	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,94 @@
+# This awk script parses C input files looking for lines marked "PUBLIC:"
+# "EXTERN:", and "DB_LOG_RECSPEC".  (PUBLIC lines are DB internal function
+# prototypes and #defines, EXTERN lines are DB external function prototypes
+# and #defines, and DB_LOG_RECSPEC lines are the definition of log record
+# templates.)
+#
+# PUBLIC lines are put into two versions of per-directory include files:
+# one file that contains the prototypes, and one file that contains a
+# #define for the name to be processed during configuration when creating
+# unique names for every global C-language symbol in the DB library.
+#
+# The EXTERN lines are put into two files: one of which contains prototypes
+# which are always appended to the db.h file, and one of which contains a
+# #define list for use when creating unique symbol names.
+#
+# DB_LOG_RECSPEC lines are put into PUBLIC's internal #define file.
+#
+# Four arguments:
+#	e_dfile		list of EXTERN #defines
+#	e_pfile		include file that contains EXTERN prototypes
+#	i_dfile		list of internal (PUBLIC) #defines
+#	i_pfile		include file that contains internal (PUBLIC) prototypes
+#
+# Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+/PUBLIC:/ {
+	sub(/^.*PUBLIC:[	 ][	 ]*/, "")
+	if ($0 ~ /^#if|^#ifdef|^#ifndef|^#else|^#endif/) {
+		print $0 >> i_pfile
+		print $0 >> i_dfile
+		next
+	}
+	pline = sprintf("%s %s", pline, $0)
+	if (pline ~ /\)\);/) {
+		sub(/^[	 ]*/, "", pline)
+		print pline >> i_pfile
+		if (pline !~ db_version_unique_name) {
+			gsub(/[	 ][	 ]*__P.*/, "", pline)
+			sub(/^.*[	 ][*]*/, "", pline)
+			printf("#define	%s %s@DB_VERSION_UNIQUE_NAME@\n",
+			    pline, pline) >> i_dfile
+		}
+		pline = ""
+	}
+}
+
+/EXTERN:/ {
+	sub(/^.*EXTERN:[	 ][	 ]*/, "")
+	if ($0 ~ /^#if|^#ifdef|^#ifndef|^#else|^#endif/) {
+		print $0 >> e_pfile
+		print $0 >> e_dfile
+		next
+	}
+	eline = sprintf("%s %s", eline, $0)
+	if (eline ~ /\)\);/) {
+		sub(/^[	 ]*/, "", eline)
+		print eline >> e_pfile
+		if (eline !~ db_version_unique_name) {
+			gsub(/[	 ][	 ]*__P.*/, "", eline)
+			sub(/^.*[	 ][*]*/, "", eline)
+			printf("#define	%s %s@DB_VERSION_UNIQUE_NAME@\n",
+			    eline, eline) >> e_dfile
+		}
+		eline = ""
+	}
+}
+
+/^DB_LOG_RECSPEC.*_desc\[\]/ {
+    sub(/DB_LOG_RECSPEC[ 	]*/, "");
+    sub(/\[][ 	]*=[ 	]*{.*$/, "");
+    printf("#define\t%s %s@DB_VERSION_UNIQUE_NAME@\n", $0, $0) >> i_dfile
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/gen_msg.awk	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,496 @@
+#
+# See the file LICENSE for redistribution information.
+#
+# Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+# $Id$
+#
+
+BEGIN {
+	if (source_file == "" || header_file == "") {
+	    print "Usage: gen_msg.awk requires these variables to be set:";
+	    print "\theader_file\t-- the message #include file being created";
+	    print "\tsource_file\t-- the message source file being created";
+	    exit;
+	}
+	CFILE=source_file;
+	HFILE=header_file;
+	maxmsg = 0;
+}
+/^[	]*PREFIX/ {
+	prefix = $2;
+
+	# Start .c files.
+	printf("/* Do not edit: automatically built by gen_msg.awk.\n *\n") \
+	    > CFILE
+ 	printf(" * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.")\
+	    >> CFILE
+ 	printf(" *\n */\n\n") >> CFILE
+	printf("#include \"db_config.h\"\n\n") >> CFILE
+
+	# Start .h file, make the entire file conditional.
+	printf("/* Do not edit: automatically built by gen_msg.awk.\n *\n") \
+	    > HFILE
+ 	printf(" * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.")\
+	    >> HFILE
+ 	printf(" *\n */\n\n") >> HFILE
+	printf("#ifndef\t%s_AUTOMSG_H\n#define\t%s_AUTOMSG_H\n\n", prefix, prefix) \
+	    >> HFILE;
+	printf("/*\n") >> HFILE;
+	printf(" * Message sizes are simply the sum of field sizes (not\n") \
+	    >> HFILE;
+	printf(" * counting variable size parts, when DBTs are present),\n") \
+	    >> HFILE;
+	printf(" * and may be different from struct sizes due to padding.\n") \
+	    >> HFILE;
+	printf(" */\n") >> HFILE;
+}
+/^[	]*INCLUDE/ {
+	for (i = 2; i < NF; i++)
+		printf("%s ", $i) >> CFILE;
+	printf("%s\n", $i) >> CFILE;
+}
+/^[	]*BEGIN_MSG/ {
+	if (in_begin) {
+		print "Invalid format: missing END statement";
+		exit;
+	}
+	in_begin = 1;
+	nvars = 0;
+	thismsg = $2;
+	for (i = 2; i<= NF; i++) {
+		if ($i == "alloc")
+			alloc = 1;
+		else if ($i == "check_length")
+			check_length = 1;
+		else if ($i == "version")
+			version = 1;
+	}
+
+	base_name = sprintf("%s_%s", prefix, thismsg);
+	typedef_name = sprintf("%s_args", base_name);
+	msg_size_name = toupper(sprintf("%s_SIZE", base_name));
+	max_name = toupper(sprintf("%s_MAXMSG_SIZE", prefix));
+}
+/^[	]*ARG/ {
+	vars[nvars] = $2;
+	types[nvars] = $3;
+	if (types[nvars] == "DBT")
+		has_dbt = 1;
+	nvars++;
+}
+/^[	]*END/ {
+	if (!in_begin) {
+		print "Invalid format: missing BEGIN statement";
+		exit;
+	}
+	if (nvars == 0) {
+		printf("%s needs at least one field\n", thismsg);
+		exit;
+	}
+
+	sum = 0;
+	for (i = 0; i < nvars; i++)
+		sum += type_length(types[i]);
+	printf("#define\t%s\t%d\n", msg_size_name, sum) >> HFILE;
+	if (sum > maxmsg)
+		maxmsg = sum;
+
+	printf("typedef struct _%s {\n", typedef_name) >> HFILE;
+	for (i = 0; i < nvars; i++) {
+		if (types[i] == "DB_LSN" || types[i] == "DBT")
+			printf("\t%s\t\t%s;\n", types[i], vars[i]) >> HFILE;
+		else
+			printf("\t%s\t%s;\n", types[i], vars[i]) >> HFILE;
+	}
+	printf("} %s;\n\n", typedef_name) >> HFILE;
+
+	emit_marshal();
+	emit_unmarshal();
+ 
+	# Reinitialize variables for next time.
+	in_begin = 0;
+	alloc = 0;
+	check_length = 0;
+	version = 0;
+	has_dbt = 0;
+}
+END {
+	# End the conditional for the HFILE
+	printf("#define\t%s\t%d\n", max_name, maxmsg) >> HFILE;
+	printf("#endif\n") >> HFILE;
+}
+
+# Length of fixed part of message.  Does not count variable-length data portion
+# of DBT.
+#
+function type_length(type)
+{
+	if (type == "DB_LSN")
+		return (8);
+	if (type == "DBT" || type == "u_int32_t" || type == "db_pgno_t")
+		return (4);
+	if (type == "u_int16_t")
+		return (2);
+	if (type == "u_int8_t")
+		return (1);
+	printf("unknown field type: %s", type);
+	exit(1);
+}
+
+function emit_marshal()
+{
+	pi = 1;
+	if (check_length)
+		p[pi++] = "int ";
+	else
+		p[pi++] = "void ";
+	function_name = sprintf("%s_marshal", base_name);
+	p[pi++] = function_name;
+	p[pi++] = " __P((ENV *, ";
+	if (version)
+		p[pi++] = "u_int32_t, ";
+	p[pi++] = sprintf("%s *, u_int8_t *", typedef_name);
+	if (check_length)
+		p[pi++] = ", size_t, size_t *";
+	p[pi++] = "));";
+	proto_format(p, CFILE);
+
+	if (check_length)
+		printf("int\n") >> CFILE;
+	else
+		printf("void\n") >> CFILE;
+	printf("%s(env", function_name) >> CFILE;
+	if (version)
+		printf(", version") >> CFILE;
+	printf(", argp, bp") >> CFILE;
+	if (check_length)
+		printf(", max, lenp") >> CFILE;
+	printf(")\n") >> CFILE;
+
+	printf("\tENV *env;\n") >> CFILE;
+	if (version)
+		printf("\tu_int32_t version;\n") >> CFILE;
+	printf("\t%s *argp;\n", typedef_name) >> CFILE;
+	printf("\tu_int8_t *bp;\n") >> CFILE;
+	if (check_length)
+		printf("\tsize_t *lenp, max;\n") >> CFILE;
+	printf("{\n") >> CFILE;
+
+	if (version)
+		printf("\tint copy_only;\n") >> CFILE;
+	if (check_length) {
+		printf("\tu_int8_t *start;\n\n") >> CFILE;
+		printf("\tif (max < %s", msg_size_name) >> CFILE;
+		for (i = 0; i < nvars; i++)
+			if (types[i] == "DBT")
+				printf("\n\t    + (size_t)argp->%s.size", \
+                                    vars[i]) >> CFILE;
+		# add in dbt sizes
+		printf(")\n") >> CFILE;
+		printf("\t\treturn (ENOMEM);\n") >> CFILE;
+		printf("\tstart = bp;\n\n") >> CFILE;
+	}
+
+	if (version) {
+		printf("\tcopy_only = 0;\n") >> CFILE;
+		printf("\tif (version < DB_REPVERSION_47)\n") >> CFILE;
+		printf("\t\tcopy_only = 1;\n") >> CFILE;
+	}
+	for (i = 0; i < nvars; i++) {
+		if (types[i] == "u_int32_t" || types[i] == "db_pgno_t") {
+			if (version) {
+				printf("\tif (copy_only) {\n") >> CFILE;
+				printf(\
+    "\t\tmemcpy(bp, &argp->%s, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
+				printf(\
+    "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
+				printf("\t} else\n\t") >> CFILE;
+			}
+			printf("\tDB_HTONL_COPYOUT(env, bp, argp->%s);\n", \
+                            vars[i]) >> CFILE;
+		} else if (types[i] == "u_int16_t") {
+			if (version) {
+				printf("\tif (copy_only) {\n") >> CFILE;
+				printf(\
+    "\t\tmemcpy(bp, &argp->%s, sizeof(u_int16_t));\n", vars[i]) >> CFILE;
+				printf(\
+    "\t\tbp += sizeof(u_int16_t);\n") >> CFILE;
+				printf("\t} else\n\t") >> CFILE;
+			}
+			printf("\tDB_HTONS_COPYOUT(env, bp, argp->%s);\n", \
+                            vars[i]) >> CFILE;
+		} else if (types[i] == "u_int8_t") {
+				printf(\
+    "\t*bp++ = argp->%s;\n", vars[i]) >> CFILE;
+		} else if (types[i] == "DB_LSN") {
+			if (version) {
+				printf("\tif (copy_only) {\n") >> CFILE;
+				printf(\
+    "\t\tmemcpy(bp, &argp->%s.file, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
+				printf(\
+    "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
+				printf(\
+    "\t\tmemcpy(bp, &argp->%s.offset, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
+				printf(\
+    "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
+				printf("\t} else {\n\t") >> CFILE;
+			}
+			printf("\tDB_HTONL_COPYOUT(env, bp, argp->%s.file);\n",\
+                            vars[i]) >> CFILE;
+			if (version)
+				printf("\t") >> CFILE;
+			printf( \
+                            "\tDB_HTONL_COPYOUT(env, bp, argp->%s.offset);\n", \
+                            vars[i]) >> CFILE;
+			if (version)
+				printf("\t}\n") >> CFILE;
+		} else if (types[i] == "DBT") {
+			if (version) {
+				printf("\tif (copy_only) {\n") >> CFILE;
+				printf(\
+    "\t\tmemcpy(bp, &argp->%s.size, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
+				printf(\
+    "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
+				printf("\t} else\n\t") >> CFILE;
+			}
+			printf("\tDB_HTONL_COPYOUT(env, bp, argp->%s.size);\n",\
+                            vars[i]) >> CFILE;
+			printf("\tif (argp->%s.size > 0) {\n", vars[i]) \
+                            >> CFILE;
+			printf( \
+                            "\t\tmemcpy(bp, argp->%s.data, argp->%s.size);\n", \
+                            vars[i], vars[i]) >> CFILE;
+			printf("\t\tbp += argp->%s.size;\n", vars[i]) >> CFILE;
+			printf("\t}\n") >> CFILE;
+		} else {
+			printf("unknown field type: %s", types[i]);
+			exit(1);
+		}
+	}
+
+	if (check_length) {
+		printf("\n\t*lenp = (size_t)(bp - start);\n") >> CFILE;
+		printf("\treturn (0);\n") >> CFILE;
+	}
+	printf("}\n\n") >> CFILE;
+}
+
+function emit_unmarshal()
+{
+	pi = 1;
+	p[pi++] = "int ";
+	function_name = sprintf("%s_unmarshal", base_name);
+	p[pi++] = function_name;
+	p[pi++] = " __P((ENV *, ";
+	if (version)
+		p[pi++] = sprintf("u_int32_t, ");
+	if (alloc)
+		p[pi++] = sprintf("%s **, u_int8_t *, ", typedef_name);
+	else
+		p[pi++] = sprintf("%s *, u_int8_t *, ", typedef_name);
+	p[pi++] = sprintf("size_t, u_int8_t **));");
+	proto_format(p, CFILE);
+
+	printf("int\n") >> CFILE;
+	if (alloc)
+		arg_name = "argpp";
+	else
+		arg_name = "argp";
+	printf("%s(env, ", function_name) >> CFILE;
+	if (version)
+		printf("version, ") >> CFILE;
+	printf("%s, bp, ", arg_name) >> CFILE;
+	printf("max, nextp)\n") >> CFILE;
+	printf("\tENV *env;\n") >> CFILE;
+	if (version)
+		printf("\tu_int32_t version;\n") >> CFILE;
+	if (alloc)
+		printf("\t%s **argpp;\n", typedef_name) >> CFILE;
+	else
+		printf("\t%s *argp;\n", typedef_name) >> CFILE;
+	printf("\tu_int8_t *bp;\n") >> CFILE;
+	printf("\tsize_t max;\n") >> CFILE;
+	printf("\tu_int8_t **nextp;\n") >> CFILE;
+	printf("{\n") >> CFILE;
+	has_locals = 0;
+	if (has_dbt) {
+		printf("\tsize_t needed;\n") >> CFILE;
+		has_locals = 1;
+	}
+	if (alloc) {
+		printf("\t%s *argp;\n", typedef_name) >> CFILE;
+		printf("\tint ret;\n") >> CFILE;
+		has_locals = 1;
+	}
+	if (version) {
+		printf("\tint copy_only;\n") >> CFILE;
+		has_locals = 1;
+	}
+	if (has_locals)
+		printf("\n") >> CFILE;
+
+	# Check that input byte buffer is long enough.
+	#
+	if (has_dbt) {
+		printf("\tneeded = %s;\n", msg_size_name) >> CFILE;
+		printf("\tif (max < needed)\n") >> CFILE;
+	} else 
+		printf("\tif (max < %s)\n", msg_size_name) >> CFILE;
+	printf("\t\tgoto too_few;\n") >> CFILE;
+
+	if (alloc) {
+		printf( \
+              "\tif ((ret = __os_malloc(env, sizeof(*argp), &argp)) != 0)\n") \
+		    >> CFILE;
+		printf("\t\treturn (ret);\n\n") >> CFILE;
+	}
+	if (version) {
+		printf("\tcopy_only = 0;\n") >> CFILE;
+		printf("\tif (version < DB_REPVERSION_47)\n") >> CFILE;
+		printf("\t\tcopy_only = 1;\n") >> CFILE;
+	}
+	
+	for (i = 0; i < nvars; i++) {
+		if (types[i] == "u_int32_t" || types[i] == "db_pgno_t") {
+			if (version) {
+				printf("\tif (copy_only) {\n") >> CFILE;
+				printf(\
+    "\t\tmemcpy(&argp->%s, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
+				printf(\
+    "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
+				printf("\t} else\n\t") >> CFILE;
+			}
+			printf("\tDB_NTOHL_COPYIN(env, argp->%s, bp);\n", \
+                            vars[i]) >> CFILE;
+		} else if (types[i] == "u_int16_t") {
+			if (version) {
+				printf("\tif (copy_only) {\n") >> CFILE;
+				printf(\
+    "\t\tmemcpy(&argp->%s, bp, sizeof(u_int16_t));\n", vars[i]) >> CFILE;
+				printf(\
+    "\t\tbp += sizeof(u_int16_t);\n") >> CFILE;
+				printf("\t} else\n\t") >> CFILE;
+			}
+			printf("\tDB_NTOHS_COPYIN(env, argp->%s, bp);\n", \
+                            vars[i]) >> CFILE;
+		} else if (types[i] == "u_int8_t") {
+				printf(\
+    "\targp->%s = *bp++;\n", vars[i]) >> CFILE;
+		} else if (types[i] == "DB_LSN") {
+			if (version) {
+				printf("\tif (copy_only) {\n") >> CFILE;
+				printf(\
+    "\t\tmemcpy(&argp->%s.file, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
+				printf(\
+    "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
+				printf(\
+    "\t\tmemcpy(&argp->%s.offset, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
+				printf(\
+    "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
+				printf("\t} else {\n\t") >> CFILE;
+			}
+			printf("\tDB_NTOHL_COPYIN(env, argp->%s.file, bp);\n", \
+                            vars[i]) >> CFILE;
+			if (version)
+				printf("\t") >> CFILE;
+			printf( \
+                            "\tDB_NTOHL_COPYIN(env, argp->%s.offset, bp);\n", \
+                            vars[i]) >> CFILE;
+			if (version)
+				printf("\t}\n") >> CFILE;
+		} else if (types[i] == "DBT") {
+			if (version) {
+				printf("\tif (copy_only) {\n") >> CFILE;
+				printf(\
+    "\t\tmemcpy(&argp->%s.size, bp, sizeof(u_int32_t));\n", vars[i]) >> CFILE;
+				printf(\
+    "\t\tbp += sizeof(u_int32_t);\n") >> CFILE;
+				printf("\t} else\n\t") >> CFILE;
+			}
+			printf("\tDB_NTOHL_COPYIN(env, argp->%s.size, bp);\n", \
+                            vars[i]) >> CFILE;
+			printf("\tif (argp->%s.size == 0)\n", vars[i]) >> CFILE;
+			printf("\t\targp->%s.data = NULL;\n", vars[i]) >> CFILE;
+			printf("\telse\n") >> CFILE;
+			printf("\t\targp->%s.data = bp;\n", vars[i]) >> CFILE;
+			printf("\tneeded += (size_t)argp->%s.size;\n", \
+                            vars[i]) >> CFILE;
+			printf("\tif (max < needed)\n") >> CFILE;
+			printf("\t\tgoto too_few;\n") >> CFILE;
+			printf("\tbp += argp->%s.size;\n", vars[i]) >> CFILE;
+		} else {
+			printf("unknown field type: %s", types[i]);
+			exit(1);
+		}
+	}
+
+	printf("\n\tif (nextp != NULL)\n") >> CFILE;
+	printf("\t\t*nextp = bp;\n") >> CFILE;
+	if (alloc) {
+		printf("\t*argpp = argp;\n") >> CFILE;
+	}
+	printf("\treturn (0);\n\n") >> CFILE;
+
+	printf("too_few:\n") >> CFILE;
+	printf("\t__db_errx(env, DB_STR(\"3675\",\n") >> CFILE;
+	printf("\t    \"Not enough input bytes to fill a %s message\"));\n", \
+	    base_name) >> CFILE;
+	printf("\treturn (EINVAL);\n") >> CFILE;
+	printf("}\n\n") >> CFILE;
+}	
+
+# proto_format --
+#	Pretty-print a function prototype.
+function proto_format(p, fp)
+{
+	printf("/*\n") >> fp;
+
+	s = "";
+	for (i = 1; i in p; ++i)
+		s = s p[i];
+
+	t = " * PUBLIC: "
+	if (length(s) + length(t) < 80)
+		printf("%s%s", t, s) >> fp;
+	else {
+		split(s, p, "__P");
+		len = length(t) + length(p[1]);
+		printf("%s%s", t, p[1]) >> fp
+
+		n = split(p[2], comma, ",");
+		comma[1] = "__P" comma[1];
+		for (i = 1; i <= n; i++) {
+			if (len + length(comma[i]) > 70) {
+				printf("\n * PUBLIC:	") >> fp;
+				len = 0;
+			}
+			printf("%s%s", comma[i], i == n ? "" : ",") >> fp;
+			len += length(comma[i]) + 2;
+		}
+	}
+	printf("\n */\n") >> fp;
+	delete p;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/install.sh	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,26 @@
+#!/bin/sh 
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+echo >&2 "No suitable 'install' command found.'" 
+exit 1 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/ltmain.sh	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,9636 @@
+
+# libtool (GNU libtool) 2.4
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+#       --config             show all configuration variables
+#       --debug              enable verbose shell tracing
+#   -n, --dry-run            display commands without modifying any files
+#       --features           display basic configuration information and exit
+#       --mode=MODE          use operation mode MODE
+#       --preserve-dup-deps  don't remove duplicate dependency libraries
+#       --quiet, --silent    don't print informational messages
+#       --no-quiet, --no-silent
+#                            print informational messages (default)
+#       --tag=TAG            use configuration variables from tag TAG
+#   -v, --verbose            print more informational messages than default
+#       --no-verbose         don't print the extra informational messages
+#       --version            print version information
+#   -h, --help, --help-all   print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+#         clean              remove files from the build directory
+#         compile            compile a source file into a libtool object
+#         execute            automatically set library path, then run a program
+#         finish             complete the installation of libtool libraries
+#         install            install libraries or executables
+#         link               create a library or an executable
+#         uninstall          remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.  When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#         host-triplet:	$host
+#         shell:		$SHELL
+#         compiler:		$LTCC
+#         compiler flags:		$LTCFLAGS
+#         linker:		$LD (gnu? $with_gnu_ld)
+#         $progname:	(GNU libtool) 2.4
+#         automake:	$automake_version
+#         autoconf:	$autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4
+TIMESTAMP=""
+package_revision=1.3293
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test \"\${$lt_var+set}\" = set; then
+          save_$lt_var=\$$lt_var
+          $lt_var=C
+	  export $lt_var
+	  lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+	fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${EGREP="grep -E"}
+: ${FGREP="grep -F"}
+: ${GREP="grep"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SED="sed"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+    # Extract subdirectory from the argument.
+    func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+    func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+    case ${2} in
+      .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+    esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+		s@/\./@/@g
+		t dotsl
+		s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+#             value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+  # Start from root dir and reassemble the path.
+  func_normal_abspath_result=
+  func_normal_abspath_tpath=$1
+  func_normal_abspath_altnamespace=
+  case $func_normal_abspath_tpath in
+    "")
+      # Empty path, that just means $cwd.
+      func_stripname '' '/' "`pwd`"
+      func_normal_abspath_result=$func_stripname_result
+      return
+    ;;
+    # The next three entries are used to spot a run of precisely
+    # two leading slashes without using negated character classes;
+    # we take advantage of case's first-match behaviour.
+    ///*)
+      # Unusual form of absolute path, do nothing.
+    ;;
+    //*)
+      # Not necessarily an ordinary path; POSIX reserves leading '//'
+      # and for example Cygwin uses it to access remote file shares
+      # over CIFS/SMB, so we conserve a leading double slash if found.
+      func_normal_abspath_altnamespace=/
+    ;;
+    /*)
+      # Absolute path, do nothing.
+    ;;
+    *)
+      # Relative path, prepend $cwd.
+      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+    ;;
+  esac
+  # Cancel out all the simple stuff to save iterations.  We also want
+  # the path to end with a slash for ease of parsing, so make sure
+  # there is one (and only one) here.
+  func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+  while :; do
+    # Processed it all yet?
+    if test "$func_normal_abspath_tpath" = / ; then
+      # If we ascended to the root using ".." the result may be empty now.
+      if test -z "$func_normal_abspath_result" ; then
+        func_normal_abspath_result=/
+      fi
+      break
+    fi
+    func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcar"`
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcdr"`
+    # Figure out what to do with it
+    case $func_normal_abspath_tcomponent in
+      "")
+        # Trailing empty path component, ignore it.
+      ;;
+      ..)
+        # Parent dir; strip last assembled component from result.
+        func_dirname "$func_normal_abspath_result"
+        func_normal_abspath_result=$func_dirname_result
+      ;;
+      *)
+        # Actual path component, append it.
+        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+      ;;
+    esac
+  done
+  # Restore leading double-slash if one was found on entry.
+  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+#             value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+  func_relative_path_result=
+  func_normal_abspath "$1"
+  func_relative_path_tlibdir=$func_normal_abspath_result
+  func_normal_abspath "$2"
+  func_relative_path_tbindir=$func_normal_abspath_result
+
+  # Ascend the tree starting from libdir
+  while :; do
+    # check if we have found a prefix of bindir
+    case $func_relative_path_tbindir in
+      $func_relative_path_tlibdir)
+        # found an exact match
+        func_relative_path_tcancelled=
+        break
+        ;;
+      $func_relative_path_tlibdir*)
+        # found a matching prefix
+        func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+        func_relative_path_tcancelled=$func_stripname_result
+        if test -z "$func_relative_path_result"; then
+          func_relative_path_result=.
+        fi
+        break
+        ;;
+      *)
+        func_dirname $func_relative_path_tlibdir
+        func_relative_path_tlibdir=${func_dirname_result}
+        if test "x$func_relative_path_tlibdir" = x ; then
+          # Have to descend all the way to the root!
+          func_relative_path_result=../$func_relative_path_result
+          func_relative_path_tcancelled=$func_relative_path_tbindir
+          break
+        fi
+        func_relative_path_result=../$func_relative_path_result
+        ;;
+    esac
+  done
+
+  # Now calculate path; take care to avoid doubling-up slashes.
+  func_stripname '' '/' "$func_relative_path_result"
+  func_relative_path_result=$func_stripname_result
+  func_stripname '/' '/' "$func_relative_path_tcancelled"
+  if test "x$func_stripname_result" != x ; then
+    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+  fi
+
+  # Normalisation. If bindir is libdir, return empty string,
+  # else relative path ending with a slash; either way, target
+  # file name can be directly appended.
+  if test ! -z "$func_relative_path_result"; then
+    func_stripname './' '' "$func_relative_path_result/"
+    func_relative_path_result=$func_stripname_result
+  fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=$func_dirname_result
+     progdir=`cd "$progdir" && pwd`
+     progpath="$progdir/$progname"
+     ;;
+  *)
+     save_IFS="$IFS"
+     IFS=:
+     for progdir in $PATH; do
+       IFS="$save_IFS"
+       test -x "$progdir/$progname" && break
+     done
+     IFS="$save_IFS"
+     test -n "$progdir" || progdir=`pwd`
+     progpath="$progdir/$progname"
+     ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+    # bash bug again:
+    :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information."  ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    my_directory_path="$1"
+    my_dir_list=
+
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$my_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+	# list incase some portion of path contains whitespace.
+        my_dir_list="$my_directory_path:$my_dir_list"
+
+        # If the last portion added has no slash in it, the list is done
+        case $my_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+      done
+      my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+	IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$my_dir" 2>/dev/null || :
+      done
+      IFS="$save_mkdir_p_IFS"
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
+    fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$opt_dry_run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+        # Failing that, at least try and use $RANDOM to avoid a race
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+        save_mktempdir_umask=`umask`
+        umask 0077
+        $MKDIR "$my_tmpdir"
+        umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+    fi
+
+    $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+    case $1 in
+      *[\\\`\"\$]*)
+	func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
+
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    case $1 in
+      *[\\\`\"]*)
+	my_arg=`$ECHO "$1" | $SED \
+	    -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
+
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
+
+    func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+	    $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case $1 in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+    ;;
+  * )
+    func_tr_sh_result=$1
+    ;;
+  esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $opt_debug
+
+    $SED -n '/(C)/!b go
+	:more
+	/\./!{
+	  N
+	  s/\n# / /
+	  b more
+	}
+	:go
+	/^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+	s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/^#  *.*--help/ {
+        s/^# //
+	s/^# *$//
+	s/\$progname/'$progname'/
+	p
+    }' < "$progpath"
+    echo
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+	:print
+        s/^# //
+	s/^# *$//
+	s*\$progname*'$progname'*
+	s*\$host*'"$host"'*
+	s*\$SHELL*'"$SHELL"'*
+	s*\$LTCC*'"$LTCC"'*
+	s*\$LTCFLAGS*'"$LTCFLAGS"'*
+	s*\$LD*'"$LD"'*
+	s/\$with_gnu_ld/'"$with_gnu_ld"'/
+	s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
+	s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+	p
+	d
+     }
+     /^# .* home page:/b print
+     /^# General help using/b print
+     ' < "$progpath"
+    ret=$?
+    if test -z "$1"; then
+      exit $ret
+    fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    $opt_debug
+
+    func_error "missing argument for $1."
+    exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+    my_sed_long_arg='1s/^--[^=]*=//'
+
+    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+    eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+    func_quote_for_eval "${2}"
+    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+    func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
+
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+    done
+
+    exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+
+    exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+  # Global variable:
+  tagname="$1"
+
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
+
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
+    *)
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	taglist="$taglist $tagname"
+
+	# Evaluate the configuration.  Be careful to quote the path
+	# and the sed script, to avoid splitting on whitespace, but
+	# also don't use non-portable quotes within backquotes within
+	# quotes we have to do it in 2 steps:
+	extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	eval "$extractedcf"
+      else
+	func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+    fi
+
+    exit $EXIT_MISMATCH
+  fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+  shift; set dummy --mode clean ${1+"$@"}; shift
+  ;;
+compile|compil|compi|comp|com|co|c)
+  shift; set dummy --mode compile ${1+"$@"}; shift
+  ;;
+execute|execut|execu|exec|exe|ex|e)
+  shift; set dummy --mode execute ${1+"$@"}; shift
+  ;;
+finish|finis|fini|fin|fi|f)
+  shift; set dummy --mode finish ${1+"$@"}; shift
+  ;;
+install|instal|insta|inst|ins|in|i)
+  shift; set dummy --mode install ${1+"$@"}; shift
+  ;;
+link|lin|li|l)
+  shift; set dummy --mode link ${1+"$@"}; shift
+  ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+  shift; set dummy --mode uninstall ${1+"$@"}; shift
+  ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly.  This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+  # this just eases exit handling
+  while test $# -gt 0; do
+    opt="$1"
+    shift
+    case $opt in
+      --debug|-x)	opt_debug='set -x'
+			func_echo "enabling shell trace mode"
+			$opt_debug
+			;;
+      --dry-run|--dryrun|-n)
+			opt_dry_run=:
+			;;
+      --config)
+			opt_config=:
+func_config
+			;;
+      --dlopen|-dlopen)
+			optarg="$1"
+			opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+			shift
+			;;
+      --preserve-dup-deps)
+			opt_preserve_dup_deps=:
+			;;
+      --features)
+			opt_features=:
+func_features
+			;;
+      --finish)
+			opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+			;;
+      --help)
+			opt_help=:
+			;;
+      --help-all)
+			opt_help_all=:
+opt_help=': help-all'
+			;;
+      --mode)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_mode="$optarg"
+case $optarg in
+  # Valid mode arguments:
+  clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+  # Catch anything else as an error
+  *) func_error "invalid argument for $opt"
+     exit_cmd=exit
+     break
+     ;;
+esac
+			shift
+			;;
+      --no-silent|--no-quiet)
+			opt_silent=false
+func_append preserve_args " $opt"
+			;;
+      --no-verbose)
+			opt_verbose=false
+func_append preserve_args " $opt"
+			;;
+      --silent|--quiet)
+			opt_silent=:
+func_append preserve_args " $opt"
+        opt_verbose=false
+			;;
+      --verbose|-v)
+			opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+			;;
+      --tag)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+			shift
+			;;
+
+      -\?|-h)		func_usage				;;
+      --help)		func_help				;;
+      --version)	func_version				;;
+
+      # Separate optargs to long options:
+      --*=*)
+			func_split_long_opt "$opt"
+			set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      # Separate non-argument short options:
+      -\?*|-h*|-n*|-v*)
+			func_split_short_opt "$opt"
+			set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      --)		break					;;
+      -*)		func_fatal_help "unrecognized option \`$opt'" ;;
+      *)		set dummy "$opt" ${1+"$@"};	shift; break  ;;
+    esac
+  done
+
+  # Validate options:
+
+  # save first non-option argument
+  if test "$#" -gt 0; then
+    nonopt="$opt"
+    shift
+  fi
+
+  # preserve --debug
+  test "$opt_debug" = : || func_append preserve_args " --debug"
+
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+      ;;
+  esac
+
+  $opt_help || {
+    # Sanity checks first:
+    func_check_version_match
+
+    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+      func_fatal_configuration "not configured to build any kind of library"
+    fi
+
+    # Darwin sucks
+    eval std_shrext=\"$shrext_cmds\"
+
+    # Only execute mode is allowed to have -dlopen flags.
+    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+      func_error "unrecognized option \`-dlopen'"
+      $ECHO "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Change the help message to a mode-specific one.
+    generic_help="$help"
+    help="Try \`$progname --help --mode=$opt_mode' for more information."
+  }
+
+
+  # Bail if the options were screwed
+  $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+##    Main.    ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+	for lalib_p_l in 1 2 3 4
+	do
+	    read lalib_p_line
+	    case "$lalib_p_line" in
+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+	    esac
+	done
+	exec 0<&5 5<&-
+    fi
+    test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
+    esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_dirname_and_basename "$1" "" "."
+    func_stripname '' '.exe' "$func_basename_result"
+    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $opt_debug
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$save_ifs
+      eval cmd=\"$cmd\"
+      func_show_eval "$cmd" "${2-:}"
+    done
+    IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+    $opt_debug
+    case $1 in
+    */* | *\\*)	. "$1" ;;
+    *)		. "./$1" ;;
+    esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot.  Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+  func_resolve_sysroot_result=$1
+  case $func_resolve_sysroot_result in
+  =*)
+    func_stripname '=' '' "$func_resolve_sysroot_result"
+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+    ;;
+  esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+  case "$lt_sysroot:$1" in
+  ?*:"$lt_sysroot"*)
+    func_stripname "$lt_sysroot" '' "$1"
+    func_replace_sysroot_result="=$func_stripname_result"
+    ;;
+  *)
+    # Including no sysroot.
+    func_replace_sysroot_result=$1
+    ;;
+  esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    $opt_debug
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	func_append_quoted CC_quoted "$arg"
+      done
+      CC_expanded=`func_echo_all $CC`
+      CC_quoted_expanded=`func_echo_all $CC_quoted`
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	      # Double-quote args containing other shell metacharacters.
+	      func_append_quoted CC_quoted "$arg"
+	    done
+	    CC_expanded=`func_echo_all $CC`
+	    CC_quoted_expanded=`func_echo_all $CC_quoted`
+	    case "$@ " in
+	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  func_echo "unable to infer tagged configuration"
+	  func_fatal_error "specify a tag with \`--tag'"
+#	else
+#	  func_verbose "using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
+    else
+      write_lobj=none
+    fi
+
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
+    else
+      write_oldobj=none
+    fi
+
+    $opt_dry_run || {
+      cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+      $MV "${write_libobj}T" "${write_libobj}"
+    }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+  $opt_debug
+  func_convert_core_file_wine_to_w32_result="$1"
+  if test -n "$1"; then
+    # Unfortunately, winepath does not exit with a non-zero error code, so we
+    # are forced to check the contents of stdout. On the other hand, if the
+    # command is not found, the shell will set an exit code of 127 and print
+    # *an error message* to stdout. So we must check for both error code of
+    # zero AND non-empty stdout, which explains the odd construction:
+    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+        $SED -e "$lt_sed_naive_backslashify"`
+    else
+      func_convert_core_file_wine_to_w32_result=
+    fi
+  fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+  $opt_debug
+  # unfortunately, winepath doesn't convert paths, only file names
+  func_convert_core_path_wine_to_w32_result=""
+  if test -n "$1"; then
+    oldIFS=$IFS
+    IFS=:
+    for func_convert_core_path_wine_to_w32_f in $1; do
+      IFS=$oldIFS
+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+        if test -z "$func_convert_core_path_wine_to_w32_result"; then
+          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+        else
+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+        fi
+      fi
+    done
+    IFS=$oldIFS
+  fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+  $opt_debug
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format.  Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+  $opt_debug
+  # awkward: cmd appends spaces to result
+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
+    func_error "Could not determine host file name corresponding to"
+    func_error "  \`$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_file_result="$1"
+  fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+  $opt_debug
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path corresponding to"
+    func_error "  \`$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback.  This is a deliberately simplistic "conversion" and
+    # should not be "improved".  See libtool.info.
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_path_result=`echo "$3" |
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_path_result="$3"
+    fi
+  fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+  $opt_debug
+  case $4 in
+  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+    ;;
+  esac
+  case $4 in
+  $2 ) func_append func_to_host_path_result "$3"
+    ;;
+  esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+  $opt_debug
+  $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result.  If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+  $opt_debug
+  case ,$2, in
+    *,"$to_tool_file_cmd",*)
+      func_to_tool_file_result=$1
+      ;;
+    *)
+      $to_tool_file_cmd "$1"
+      func_to_tool_file_result=$func_to_host_file_result
+      ;;
+  esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+  func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+    # LT_CYGPATH in this case.
+    func_to_host_file_result=`cygpath -m "$1"`
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format.  Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_file_wine_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_msys_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+    func_convert_core_file_wine_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format.  If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+#   file name conversion function    : func_convert_file_X_to_Y ()
+#   path conversion function         : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same.  If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+  $opt_debug
+  if test -z "$to_host_path_cmd"; then
+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+    to_host_path_cmd="func_convert_path_${func_stripname_result}"
+  fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+  $opt_debug
+  func_init_to_host_path_cmd
+  $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+  func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from ARG.  MSYS
+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+    # and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format.  Requires a wine environment and
+# a working winepath.  Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $opt_debug
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+    pie_flag=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg="$arg"
+	arg_mode=normal
+	;;
+
+      target )
+	libobj="$arg"
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  test -n "$libobj" && \
+	    func_fatal_error "you cannot specify \`-o' more than once"
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-pie | -fpie | -fPIE)
+          func_append pie_flag " $arg"
+	  continue
+	  ;;
+
+	-shared | -static | -prefer-pic | -prefer-non-pic)
+	  func_append later " $arg"
+	  continue
+	  ;;
+
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  func_stripname '-Wc,' '' "$arg"
+	  args=$func_stripname_result
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+	  for arg in $args; do
+	    IFS="$save_ifs"
+	    func_append_quoted lastarg "$arg"
+	  done
+	  IFS="$save_ifs"
+	  func_stripname ' ' '' "$lastarg"
+	  lastarg=$func_stripname_result
+
+	  # Add the arguments to base_compile.
+	  func_append base_compile " $lastarg"
+	  continue
+	  ;;
+
+	*)
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg="$srcfile"
+	  srcfile="$arg"
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      func_append_quoted base_compile "$lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with \`-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+	func_basename "$srcfile"
+	libobj="$func_basename_result"
+      }
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
+
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	continue
+	;;
+
+      -static)
+	build_libtool_libs=no
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
+
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	$ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+      func_append removelist " $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
+
+    $opt_dry_run || $RM $removelist
+    func_append removelist " $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+    srcfile=$func_to_tool_file_result
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
+
+      func_mkdir_p "$xdir$objdir"
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	func_append command " -o $lobj"
+      fi
+
+      func_show_eval_locale "$command"	\
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	func_show_eval '$MV "$output_obj" "$lobj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+	suppress_output=' >/dev/null 2>&1'
+      fi
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile$pie_flag"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	func_append command " -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      func_append command "$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	func_show_eval '$MV "$output_obj" "$obj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
+
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+      # Unlock the critical section if it was locked
+      if test "$need_locks" != no; then
+	removelist=$lockfile
+        $RM "$lockfile"
+      fi
+    }
+
+    exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+    # We need to display help for each of the modes.
+    case $opt_mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
+
+      clean)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      compile)
+      $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to build PIC objects only
+  -prefer-non-pic   try to build non-PIC objects only
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
+  -Wc,FLAG          pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+        ;;
+
+      execute)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+        ;;
+
+      finish)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+        ;;
+
+      install)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -bindir BINDIR    specify path to binaries directory (for systems where
+                    libraries must be found in the PATH setting at runtime)
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+  -Wc,FLAG
+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
+  -Wl,FLAG
+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+        ;;
+
+      uninstall)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode \`$opt_mode'"
+        ;;
+    esac
+
+    echo
+    $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+  if test "$opt_help" = :; then
+    func_mode_help
+  else
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	func_mode_help
+      done
+    } | sed -n '1p; 2,$s/^Usage:/  or: /p'
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	echo
+	func_mode_help
+      done
+    } |
+    sed '1d
+      /^When reporting/,/^Report/{
+	H
+	d
+      }
+      $x
+      /information about other modes/d
+      /more detailed .*MODE/d
+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+  fi
+  exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $opt_debug
+    # The first argument is the command name.
+    cmd="$nonopt"
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
+
+    # Handle -dlopen flags immediately.
+    for file in $opt_dlopen; do
+      test -f "$file" \
+	|| func_fatal_help "\`$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+	func_source "$file"
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && \
+	    func_warning "\`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  func_append dir "/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+	;;
+
+      *)
+	func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -* | *.la | *.lo ) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if func_ltwrapper_script_p "$file"; then
+	  func_source "$file"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	elif func_ltwrapper_executable_p "$file"; then
+	  func_ltwrapper_scriptname "$file"
+	  func_source "$func_ltwrapper_scriptname_result"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_append_quoted args "$file"
+    done
+
+    if test "X$opt_dry_run" = Xfalse; then
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+	eval "if test \"\${save_$lt_var+set}\" = set; then
+                $lt_var=\$save_$lt_var; export $lt_var
+	      else
+		$lt_unset $lt_var
+	      fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	echo "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $opt_debug
+    libs=
+    libdirs=
+    admincmds=
+
+    for opt in "$nonopt" ${1+"$@"}
+    do
+      if test -d "$opt"; then
+	func_append libdirs " $opt"
+
+      elif test -f "$opt"; then
+	if func_lalib_unsafe_p "$opt"; then
+	  func_append libs " $opt"
+	else
+	  func_warning "\`$opt' is not a valid libtool archive"
+	fi
+
+      else
+	func_fatal_error "invalid argument \`$opt'"
+      fi
+    done
+
+    if test -n "$libs"; then
+      if test -n "$lt_sysroot"; then
+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+      else
+        sysroot_cmd=
+      fi
+
+      # Remove sysroot references
+      if $opt_dry_run; then
+        for lib in $libs; do
+          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+        done
+      else
+        tmpdir=`func_mktempdir`
+        for lib in $libs; do
+	  sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	    > $tmpdir/tmp-la
+	  mv -f $tmpdir/tmp-la $lib
+	done
+        ${RM}r "$tmpdir"
+      fi
+    fi
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $opt_dry_run || eval "$cmds" || func_append admincmds "
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    $opt_silent && exit $EXIT_SUCCESS
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      echo "----------------------------------------------------------------------"
+      echo "Libraries have been installed in:"
+      for libdir in $libdirs; do
+	$ECHO "   $libdir"
+      done
+      echo
+      echo "If you ever happen to want to link against installed libraries"
+      echo "in a given directory, LIBDIR, you must either use libtool, and"
+      echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+      echo "flag during linking and do at least one of the following:"
+      if test -n "$shlibpath_var"; then
+	echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+	echo "     during execution"
+      fi
+      if test -n "$runpath_var"; then
+	echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+	echo "     during linking"
+      fi
+      if test -n "$hardcode_libdir_flag_spec"; then
+	libdir=LIBDIR
+	eval flag=\"$hardcode_libdir_flag_spec\"
+
+	$ECHO "   - use the \`$flag' linker flag"
+      fi
+      if test -n "$admincmds"; then
+	$ECHO "   - have your system administrator run these commands:$admincmds"
+      fi
+      if test -f /etc/ld.so.conf; then
+	echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+      fi
+      echo
+
+      echo "See any operating system documentation about shared libraries for"
+      case $host in
+	solaris2.[6789]|solaris2.1[0-9])
+	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+	  echo "pages."
+	  ;;
+	*)
+	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
+	  ;;
+      esac
+      echo "----------------------------------------------------------------------"
+    fi
+    exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $opt_debug
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       case $nonopt in *shtool*) :;; *) false;; esac; then
+      # Aesthetically quote it.
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
+      arg=$1
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_for_eval "$arg"
+    func_append install_prog "$func_quote_for_eval_result"
+    install_shared_prog=$install_prog
+    case " $install_prog " in
+      *[\\\ /]cp\ *) install_cp=: ;;
+      *) install_cp=false ;;
+    esac
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    no_mode=:
+    for arg
+    do
+      arg2=
+      if test -n "$dest"; then
+	func_append files " $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f)
+	if $install_cp; then :; else
+	  prev=$arg
+	fi
+	;;
+      -g | -m | -o)
+	prev=$arg
+	;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  if test "x$prev" = x-m && test -n "$install_override_mode"; then
+	    arg2=$install_override_mode
+	    no_mode=false
+	  fi
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      func_quote_for_eval "$arg"
+      func_append install_prog " $func_quote_for_eval_result"
+      if test -n "$arg2"; then
+	func_quote_for_eval "$arg2"
+      fi
+      func_append install_shared_prog " $func_quote_for_eval_result"
+    done
+
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prev' option requires an argument"
+
+    if test -n "$install_override_mode" && $no_mode; then
+      if $install_cp; then :; else
+	func_quote_for_eval "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_for_eval_result"
+      fi
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	func_fatal_help "no file or destination specified"
+      else
+	func_fatal_help "you must specify a destination"
+      fi
+    fi
+
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+	func_fatal_help "\`$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  func_fatal_help "\`$destdir' must be an absolute directory name"
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	func_append staticlibs " $file"
+	;;
+
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$file' is not a valid libtool archive"
+
+	library_names=
+	old_library=
+	relink_command=
+	func_source "$file"
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append current_libdirs " $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append future_libdirs " $libdir" ;;
+	  esac
+	fi
+
+	func_dirname "$file" "/" ""
+	dir="$func_dirname_result"
+	func_append dir "$objdir"
+
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  test "$inst_prefix_dir" = "$destdir" && \
+	    func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  func_warning "relinking \`$file'"
+	  func_show_eval "$relink_command" \
+	    'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names; shift
+	if test -n "$1"; then
+	  realname="$1"
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+	      'exit $?'
+	  tstripme="$stripme"
+	  case $host_os in
+	  cygwin* | mingw* | pw32* | cegcc*)
+	    case $realname in
+	    *.dll.a)
+	      tstripme=""
+	      ;;
+	    esac
+	    ;;
+	  esac
+	  if test -n "$tstripme" && test -n "$striplib"; then
+	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try `ln -sf' first, because the `ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      test "$linkname" != "$realname" \
+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  func_execute_cmds "$postinstall_cmds" 'exit $?'
+	fi
+
+	# Install the pseudo-library for information purposes.
+	func_basename "$file"
+	name="$func_basename_result"
+	instname="$dir/$name"i
+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  func_lo2o "$destfile"
+	  staticdest=$func_lo2o_result
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  func_fatal_help "cannot copy a libtool object to \`$destfile'"
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	test -n "$destfile" && \
+	  func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  func_lo2o "$file"
+	  staticobj=$func_lo2o_result
+	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+	fi
+	exit $EXIT_SUCCESS
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=""
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      func_stripname '' '.exe' "$file"
+	      file=$func_stripname_result
+	      stripped_ext=".exe"
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin* | *mingw*)
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      wrapper=$func_ltwrapper_scriptname_result
+	    else
+	      func_stripname '' '.exe' "$file"
+	      wrapper=$func_stripname_result
+	    fi
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if func_ltwrapper_script_p "$wrapper"; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  func_source "$wrapper"
+
+	  # Check the variables that should have been set.
+	  test -z "$generated_by_libtool_version" && \
+	    func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      func_source "$lib"
+	    fi
+	    libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      func_warning "\`$lib' has not been installed in \`$libdir'"
+	      finalize=no
+	    fi
+	  done
+
+	  relink_command=
+	  func_source "$wrapper"
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    $opt_dry_run || {
+	      if test "$finalize" = yes; then
+	        tmpdir=`func_mktempdir`
+		func_basename "$file$stripped_ext"
+		file="$func_basename_result"
+	        outputname="$tmpdir/$file"
+	        # Replace the output file specification.
+	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+	        $opt_silent || {
+	          func_quote_for_expand "$relink_command"
+		  eval "func_echo $func_quote_for_expand_result"
+	        }
+	        if eval "$relink_command"; then :
+	          else
+		  func_error "error: relink \`$file' with the above command before installing it"
+		  $opt_dry_run || ${RM}r "$tmpdir"
+		  continue
+	        fi
+	        file="$outputname"
+	      else
+	        func_warning "cannot relink \`$file'"
+	      fi
+	    }
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    func_stripname '' '.exe' "$destfile"
+	    destfile=$func_stripname_result
+	    ;;
+	  esac
+	  ;;
+	esac
+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+	$opt_dry_run || if test -n "$outputname"; then
+	  ${RM}r "$tmpdir"
+	fi
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      func_basename "$file"
+      name="$func_basename_result"
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	func_show_eval "$old_striplib $oldlib" 'exit $?'
+      fi
+
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
+
+    test -n "$future_libdirs" && \
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	my_dlsyms="${my_outputname}S.c"
+      else
+	func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
+
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+	# Discover the nlist of each of the dlfiles.
+	nlist="$output_objdir/${my_outputname}.nm"
+
+	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+	# Parse the name list into a source file.
+	func_verbose "creating $output_objdir/$my_dlsyms"
+
+	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+	if test "$dlself" = yes; then
+	  func_verbose "generating symbol list for \`$output'"
+
+	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+	  # Add our own program objects to the symbol list.
+	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	  for progfile in $progfiles; do
+	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+	    func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -n "$exclude_expsyms"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  if test -n "$export_symbols_regex"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  # Prepare the list of exported symbols
+	  if test -z "$export_symbols"; then
+	    export_symbols="$output_objdir/$outputname.exp"
+	    $opt_dry_run || {
+	      $RM $export_symbols
+	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      case $host in
+	      *cygwin* | *mingw* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+	        ;;
+	      esac
+	    }
+	  else
+	    $opt_dry_run || {
+	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	      case $host in
+	        *cygwin* | *mingw* | *cegcc* )
+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+	          ;;
+	      esac
+	    }
+	  fi
+	fi
+
+	for dlprefile in $dlprefiles; do
+	  func_verbose "extracting global C symbols from \`$dlprefile'"
+	  func_basename "$dlprefile"
+	  name="$func_basename_result"
+          case $host in
+	    *cygwin* | *mingw* | *cegcc* )
+	      # if an import library, we need to obtain dlname
+	      if func_win32_import_lib_p "$dlprefile"; then
+	        func_tr_sh "$dlprefile"
+	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
+	        dlprefile_dlbasename=""
+	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+	          # Use subshell, to avoid clobbering current variable values
+	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+	          if test -n "$dlprefile_dlname" ; then
+	            func_basename "$dlprefile_dlname"
+	            dlprefile_dlbasename="$func_basename_result"
+	          else
+	            # no lafile. user explicitly requested -dlpreopen <import library>.
+	            $sharedlib_from_linklib_cmd "$dlprefile"
+	            dlprefile_dlbasename=$sharedlib_from_linklib_result
+	          fi
+	        fi
+	        $opt_dry_run || {
+	          if test -n "$dlprefile_dlbasename" ; then
+	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+	          else
+	            func_warning "Could not compute DLL name from $name"
+	            eval '$ECHO ": $name " >> "$nlist"'
+	          fi
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+	        }
+	      else # not an import lib
+	        $opt_dry_run || {
+	          eval '$ECHO ": $name " >> "$nlist"'
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	        }
+	      fi
+	    ;;
+	    *)
+	      $opt_dry_run || {
+	        eval '$ECHO ": $name " >> "$nlist"'
+	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	      }
+	    ;;
+          esac
+	done
+
+	$opt_dry_run || {
+	  # Make sure we have at least an empty file.
+	  test -f "$nlist" || : > "$nlist"
+
+	  if test -n "$exclude_expsyms"; then
+	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	    $MV "$nlist"T "$nlist"
+	  fi
+
+	  # Try sorting and uniquifying the output.
+	  if $GREP -v "^: " < "$nlist" |
+	      if sort -k 3 </dev/null >/dev/null 2>&1; then
+		sort -k 3
+	      else
+		sort +2
+	      fi |
+	      uniq > "$nlist"S; then
+	    :
+	  else
+	    $GREP -v "^: " < "$nlist" > "$nlist"S
+	  fi
+
+	  if test -f "$nlist"S; then
+	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+	  else
+	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+	  fi
+
+	  echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+  { \"$my_originator\", (void *) 0 },"
+
+	  case $need_lib_prefix in
+	  no)
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  *)
+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  esac
+	  echo >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	} # !$opt_dry_run
+
+	pic_flag_for_symtable=
+	case "$compile_command " in
+	*" -static "*) ;;
+	*)
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+	  *-*-hpux*)
+	    pic_flag_for_symtable=" $pic_flag"  ;;
+	  *)
+	    if test "X$my_pic_p" != Xno; then
+	      pic_flag_for_symtable=" $pic_flag"
+	    fi
+	    ;;
+	  esac
+	  ;;
+	esac
+	symtab_cflags=
+	for arg in $LTCFLAGS; do
+	  case $arg in
+	  -pie | -fpie | -fPIE) ;;
+	  *) func_append symtab_cflags " $arg" ;;
+	  esac
+	done
+
+	# Now compile the dynamic symbol file.
+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+	# Clean up the generated files.
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+	# Transform the symbol file into the correct name.
+	symfileobj="$output_objdir/${my_outputname}S.$objext"
+	case $host in
+	*cygwin* | *mingw* | *cegcc* )
+	  if test -f "$output_objdir/$my_outputname.def"; then
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	  else
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  fi
+	  ;;
+	*)
+	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  ;;
+	esac
+	;;
+      *)
+	func_fatal_error "unknown suffix for \`$my_dlsyms'"
+	;;
+      esac
+    else
+      # We keep going just in case the user didn't refer to
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+      # really was required.
+
+      # Nullify the symbol file.
+      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+    fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+  $opt_debug
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+      func_to_tool_file "$1" func_convert_file_msys_to_w32
+      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	$SED -n -e '
+	    1,100{
+		/ I /{
+		    s,.*,import,
+		    p
+		    q
+		}
+	    }'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+  $opt_debug
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  $opt_debug
+  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+    $SED '/^Contents of section '"$match_literal"':/{
+      # Place marker at beginning of archive member dllname section
+      s/.*/====MARK====/
+      p
+      d
+    }
+    # These lines can sometimes be longer than 43 characters, but
+    # are always uninteresting
+    /:[	 ]*file format pe[i]\{,1\}-/d
+    /^In archive [^:]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining lines, remove first 43 characters
+    s/^.\{43\}//' |
+    $SED -n '
+      # Join marker and all lines until next marker into a single line
+      /^====MARK====/ b para
+      H
+      $ b para
+      b
+      :para
+      x
+      s/\n//g
+      # Remove the marker
+      s/^====MARK====//
+      # Remove trailing dots and whitespace
+      s/[\. \t]*$//
+      # Print
+      /./p' |
+    # we now have a list, one entry per line, of the stringified
+    # contents of the appropriate section of all members of the
+    # archive which possess that section. Heuristic: eliminate
+    # all those which have a first or second character that is
+    # a '.' (that is, objdump's representation of an unprintable
+    # character.) This should work for all archives with less than
+    # 0x302f exports -- but will fail for DLLs whose name actually
+    # begins with a literal '.' or a single character followed by
+    # a '.'.
+    #
+    # Of those that remain, print the first one.
+    $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+  $opt_debug
+  if func_cygming_gnu_implib_p "$1" ; then
+    # binutils import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+  elif func_cygming_ms_implib_p "$1" ; then
+    # ms-generated import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+  else
+    # unknown
+    sharedlib_from_linklib_result=""
+  fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    if test "$lock_old_archive_extraction" = yes; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+		   'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test "$lock_old_archive_extraction" = yes; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $opt_debug
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      func_basename "$my_xlib"
+      my_xlib="$func_basename_result"
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  func_arith $extracted_serial + 1
+	  extracted_serial=$func_arith_result
+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
+	*) break ;;
+	esac
+      done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir="$my_gentop/$my_xlib_u"
+
+      func_mkdir_p "$my_xdir"
+
+      case $host in
+      *-darwin*)
+	func_verbose "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	$opt_dry_run || {
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  darwin_base_archive=`basename "$darwin_archive"`
+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+	  if test -n "$darwin_arches"; then
+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches ; do
+	      func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+	      cd "$darwin_curdir"
+	      $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+	    done # $darwin_arches
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+	      $LIPO -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    $RM -rf unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd $darwin_orig_dir
+	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	} # !$opt_dry_run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+	;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+    done
+
+    func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+	func_emit_wrapper_arg1=${1-no}
+
+	$ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='$macro_version'
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    file=\"\$0\""
+
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+    ECHO=\"$qECHO\"
+  fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=\$0
+  shift
+  for lt_opt
+  do
+    case \"\$lt_opt\" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+        cat \"\$lt_dump_D/\$lt_dump_F\"
+        exit 0
+      ;;
+    --lt-*)
+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+        exit 1
+      ;;
+    esac
+  done
+
+  # Print the debug banner immediately:
+  if test -n \"\$lt_option_debug\"; then
+    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+  fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+  done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+  case $host in
+  # Backslashes separate directories on plain windows
+  *-*-mingw | *-*-os2* | *-cegcc*)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+    ;;
+
+  *)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+    ;;
+  esac
+  $ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  for lt_wr_arg
+  do
+    case \$lt_wr_arg in
+    --lt-*) ;;
+    *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+    esac
+    shift
+  done
+  func_exec_program_core \${1+\"\$@\"}
+}
+
+  # Parse options
+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+  done
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  $ECHO "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" ||
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $MKDIR \"\$progdir\"
+    else
+      $RM \"\$progdir/\$file\"
+    fi"
+
+	  $ECHO "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	$ECHO \"\$relink_command_output\" >&2
+	$RM \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+	else
+	  $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$ECHO "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# fixup the dll searchpath if we need to.
+	#
+	# Fix the DLL searchpath if we need to.  Do this before prepending
+	# to shlibpath, because on Windows, both are PATH and uninstalled
+	# libraries must come first.
+	if test -n "$dllsearchpath"; then
+	  $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $ECHO "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	$ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+      func_exec_program \${1+\"\$@\"}
+    fi
+  else
+    # The program doesn't exist.
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+	cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+*/
+EOF
+	    cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+#  include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+#  define _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+	    cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+              func_to_host_path "$temp_rpath"
+	      cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test -n "$dllsearchpath"; then
+              func_to_host_path "$dllsearchpath:"
+	      cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test "$fast_install" = yes; then
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+	    else
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+	    fi
+
+
+	    cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int  newargc;
+  char *tmp_pathspec;
+  char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
+  char *target_name;
+  char *lt_argv_zero;
+  intptr_t rval = 127;
+
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  newargz = XMALLOC (char *, argc + 1);
+
+  /* very simple arg parsing; don't want to rely on getopt
+   * also, copy all non cwrapper options to newargz, except
+   * argz[0], which is handled differently
+   */
+  newargc=0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], dumpscript_opt) == 0)
+	{
+EOF
+	    case "$host" in
+	      *mingw* | *cygwin* )
+		# make stdout use "unix" line endings
+		echo "          setmode(1,_O_BINARY);"
+		;;
+	      esac
+
+	    cat <<"EOF"
+	  lt_dump_script (stdout);
+	  return 0;
+	}
+      if (strcmp (argv[i], debug_opt) == 0)
+	{
+          lt_debug = 1;
+          continue;
+	}
+      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal (__FILE__, __LINE__,
+		    "unrecognized %s option: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
+
+EOF
+	    cat <<EOF
+  /* The GNU banner must be the first non-error debug message */
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+	    cat <<"EOF"
+  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+  tmp_pathspec = find_executable (argv[0]);
+  if (tmp_pathspec == NULL)
+    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (before symlink chase) at: %s\n",
+		  tmp_pathspec);
+
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (after symlink chase) at: %s\n",
+		  actual_cwrapper_path);
+  XFREE (tmp_pathspec);
+
+  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+  strendzap (target_name, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+  XFREE (target_name);
+  target_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(main) libtool target name: %s\n",
+		  target_name);
+EOF
+
+	    cat <<EOF
+  newargz[0] =
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
+		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+EOF
+
+	    cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
+
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
+
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = NULL;
+EOF
+
+	    case $host_os in
+	      mingw*)
+	    cat <<"EOF"
+  {
+    char* p;
+    while ((p = strchr (newargz[0], '\\')) != NULL)
+      {
+	*p = '/';
+      }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+	*p = '/';
+      }
+  }
+EOF
+	    ;;
+	    esac
+
+	    cat <<"EOF"
+  XFREE (target_name);
+  XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
+
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
+     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+     because on Windows, both *_VARNAMEs are PATH but uninstalled
+     libraries must come first. */
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+		  nonnull (lt_argv_zero));
+  for (i = 0; i < newargc; i++)
+    {
+      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+		      i, nonnull (newargz[i]));
+    }
+
+EOF
+
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+  /* execv doesn't actually work on mingw as expected on unix */
+  newargz = prepare_spawn (newargz);
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  if (rval == -1)
+    {
+      /* failed to start process */
+      lt_debugprintf (__FILE__, __LINE__,
+		      "(main) failed to launch target \"%s\": %s\n",
+		      lt_argv_zero, nonnull (strerror (errno)));
+      return 127;
+    }
+  return rval;
+EOF
+		;;
+	      *)
+		cat <<"EOF"
+  execv (lt_argv_zero, newargz);
+  return rval; /* =127, but avoids unused variable warning */
+EOF
+		;;
+	    esac
+
+	    cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void *p = (void *) malloc (num);
+  if (!p)
+    lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+			  string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable (const char *path)
+{
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
+
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+  int has_slash = 0;
+  const char *p;
+  const char *p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char *concat_name;
+
+  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+                  nonempty (wrapper));
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable (concat_name))
+	return concat_name;
+      XFREE (concat_name);
+    }
+  else
+    {
+#endif
+      if (IS_DIR_SEPARATOR (wrapper[0]))
+	{
+	  concat_name = xstrdup (wrapper);
+	  if (check_executable (concat_name))
+	    return concat_name;
+	  XFREE (concat_name);
+	}
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+    }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+      {
+	has_slash = 1;
+	break;
+      }
+  if (!has_slash)
+    {
+      /* no slashes; search PATH */
+      const char *path = getenv ("PATH");
+      if (path != NULL)
+	{
+	  for (p = path; *p; p = p_next)
+	    {
+	      const char *q;
+	      size_t p_len;
+	      for (q = p; *q; q++)
+		if (IS_PATH_SEPARATOR (*q))
+		  break;
+	      p_len = q - p;
+	      p_next = (*q == '\0' ? q : q + 1);
+	      if (p_len == 0)
+		{
+		  /* empty path: current directory */
+		  if (getcwd (tmp, LT_PATHMAX) == NULL)
+		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+                              nonnull (strerror (errno)));
+		  tmp_len = strlen (tmp);
+		  concat_name =
+		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, tmp, tmp_len);
+		  concat_name[tmp_len] = '/';
+		  strcpy (concat_name + tmp_len + 1, wrapper);
+		}
+	      else
+		{
+		  concat_name =
+		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, p, p_len);
+		  concat_name[p_len] = '/';
+		  strcpy (concat_name + p_len + 1, wrapper);
+		}
+	      if (check_executable (concat_name))
+		return concat_name;
+	      XFREE (concat_name);
+	    }
+	}
+      /* not found in PATH; assume curdir */
+    }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+              nonnull (strerror (errno)));
+  tmp_len = strlen (tmp);
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable (concat_name))
+    return concat_name;
+  XFREE (concat_name);
+  return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      lt_debugprintf (__FILE__, __LINE__,
+		      "checking path component for symlinks: %s\n",
+		      tmp_pathspec);
+      if (lstat (tmp_pathspec, &s) == 0)
+	{
+	  if (S_ISLNK (s.st_mode) != 0)
+	    {
+	      has_symlinks = 1;
+	      break;
+	    }
+
+	  /* search backwards for last DIR_SEPARATOR */
+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    p--;
+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    {
+	      /* no more DIR_SEPARATORS left */
+	      break;
+	    }
+	  *p = '\0';
+	}
+      else
+	{
+	  lt_fatal (__FILE__, __LINE__,
+		    "error accessing file \"%s\": %s",
+		    tmp_pathspec, nonnull (strerror (errno)));
+	}
+    }
+  XFREE (tmp_pathspec);
+
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
+
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal (__FILE__, __LINE__,
+		"could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert (str != NULL);
+  assert (pat != NULL);
+
+  len = strlen (str);
+  patlen = strlen (pat);
+
+  if (patlen <= len)
+    {
+      str += len - patlen;
+      if (strcmp (str, pat) == 0)
+	*str = '\0';
+    }
+  return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  if (lt_debug)
+    {
+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+      va_start (args, fmt);
+      (void) vfprintf (stderr, fmt, args);
+      va_end (args);
+    }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+	       int line, const char *mode,
+	       const char *message, va_list ap)
+{
+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+  va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+  return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+  return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_setenv) setting '%s' to '%s'\n",
+                  nonnull (name), nonnull (value));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    int len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[len-1] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+EOF
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
+
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+	new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+	{
+	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+	  size_t length;
+	  unsigned int backslashes;
+	  const char *s;
+	  char *quoted_string;
+	  char *p;
+
+	  length = 0;
+	  backslashes = 0;
+	  if (quote_around)
+	    length++;
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		length += backslashes + 1;
+	      length++;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    length += backslashes + 1;
+
+	  quoted_string = XMALLOC (char, length + 1);
+
+	  p = quoted_string;
+	  backslashes = 0;
+	  if (quote_around)
+	    *p++ = '"';
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		{
+		  unsigned int j;
+		  for (j = backslashes + 1; j > 0; j--)
+		    *p++ = '\\';
+		}
+	      *p++ = c;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    {
+	      unsigned int j;
+	      for (j = backslashes; j > 0; j--)
+		*p++ = '\\';
+	      *p++ = '"';
+	    }
+	  *p = '\0';
+
+	  new_argv[i] = quoted_string;
+	}
+      else
+	new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
+
+  return new_argv;
+}
+EOF
+		;;
+	    esac
+
+            cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+	    func_emit_wrapper yes |
+              $SED -e 's/\([\\"]\)/\\\1/g' \
+	           -e 's/^/  fputs ("/' -e 's/$/\\n", f);/'
+
+            cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+    $opt_debug
+    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+    *import*) : ;;
+    *) false ;;
+    esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+    $opt_debug
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args=$nonopt
+    base_compile="$nonopt $@"
+    compile_command=$nonopt
+    finalize_command=$nonopt
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+    new_inherited_linker_flags=
+
+    avoid_version=no
+    bindir=
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    weak_libs=
+    single_module="${wl}-single_module"
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	break
+	;;
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    func_warning "complete static linking is impossible in this configuration"
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	-static)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	  ;;
+	-static-libtool-libs)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	esac
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  func_append compile_command " @OUTPUT@"
+	  func_append finalize_command " @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	bindir)
+	  bindir="$arg"
+	  prev=
+	  continue
+	  ;;
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    func_append compile_command " @SYMFILE@"
+	    func_append finalize_command " @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      func_append dlfiles " $arg"
+	    else
+	      func_append dlprefiles " $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  test -f "$arg" \
+	    || func_fatal_error "symbol file \`$arg' does not exist"
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	framework)
+	  case $host in
+	    *-*-darwin*)
+	      case "$deplibs " in
+		*" $qarg.ltframework "*) ;;
+		*) func_append deplibs " $qarg.ltframework" # this is fixed later
+		   ;;
+	      esac
+	      ;;
+	  esac
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat "$save_arg"`
+	    do
+#	      func_append moreargs " $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if func_lalib_unsafe_p "$arg"; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		func_source "$arg"
+
+		if test -z "$pic_object" ||
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none &&
+		   test "$non_pic_object" = none; then
+		  func_fatal_error "cannot find name of object for \`$arg'"
+		fi
+
+		# Extract subdirectory from the argument.
+		func_dirname "$arg" "/" ""
+		xdir="$func_dirname_result"
+
+		if test "$pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object="$xdir$pic_object"
+
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		      func_append dlfiles " $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test "$prev" = dlprefiles; then
+		    # Preload the old-style object.
+		    func_append dlprefiles " $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  func_append libobjs " $pic_object"
+		  arg="$pic_object"
+		fi
+
+		# Non-PIC object.
+		if test "$non_pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object="$xdir$non_pic_object"
+
+		  # A standard non-PIC object
+		  func_append non_pic_objects " $non_pic_object"
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object="$pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if $opt_dry_run; then
+		  # Extract subdirectory from the argument.
+		  func_dirname "$arg" "/" ""
+		  xdir="$func_dirname_result"
+
+		  func_lo2o "$arg"
+		  pic_object=$xdir$objdir/$func_lo2o_result
+		  non_pic_object=$xdir$func_lo2o_result
+		  func_append libobjs " $pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+	        else
+		  func_fatal_error "\`$arg' is not a valid libtool object"
+		fi
+	      fi
+	    done
+	  else
+	    func_fatal_error "link input file \`$arg' does not exist"
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    func_fatal_error "only absolute run-paths are allowed"
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) func_append rpath " $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) func_append xrpath " $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	shrext)
+	  shrext_cmds="$arg"
+	  prev=
+	  continue
+	  ;;
+	weak)
+	  func_append weak_libs " $arg"
+	  prev=
+	  continue
+	  ;;
+	xcclinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xcompiler)
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $wl$qarg"
+	  prev=
+	  func_append compile_command " $wl$qarg"
+	  func_append finalize_command " $wl$qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  # See comment for -static flag below, for more details.
+	  func_append compile_command " $link_static_flag"
+	  func_append finalize_command " $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -bindir)
+	prev=bindir
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  func_fatal_error "more than one -exported-symbols argument is not allowed"
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework)
+	prev=framework
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	func_stripname "-L" '' "$arg"
+	if test -z "$func_stripname_result"; then
+	  if test "$#" -gt 0; then
+	    func_fatal_error "require no space between \`-L' and \`$1'"
+	  else
+	    func_fatal_error "need path for \`-L' option"
+	  fi
+	fi
+	func_resolve_sysroot "$func_stripname_result"
+	dir=$func_resolve_sysroot_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  test -z "$absdir" && \
+	    func_fatal_error "cannot determine absolute directory name of \`$dir'"
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "* | *" $arg "*)
+	  # Will only happen for absolute or sysroot arguments
+	  ;;
+	*)
+	  # Preserve sysroot, but never include relative directories
+	  case $dir in
+	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+	    *) func_append deplibs " -L$dir" ;;
+	  esac
+	  func_append lib_search_path " $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  ::) dllsearchpath=$dir;;
+	  *) func_append dllsearchpath ":$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    func_append deplibs " System.ltframework"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  esac
+	elif test "X$arg" = "X-lc_r"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	func_append deplibs " $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      -model|-arch|-isysroot|--sysroot)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	prev=xcompiler
+	continue
+	;;
+
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	case "$new_inherited_linker_flags " in
+	    *" $arg "*) ;;
+	    * ) func_append new_inherited_linker_flags " $arg" ;;
+	esac
+	continue
+	;;
+
+      -multi_module)
+	single_module="${wl}-multi_module"
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # and Darwin in order for the loader to find any dlls it needs.
+	  func_warning "\`-no-install' is ignored for $host"
+	  func_warning "assuming \`-no-fast-install' instead"
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	func_stripname '-R' '' "$arg"
+	dir=$func_stripname_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	=*)
+	  func_stripname '=' '' "$dir"
+	  dir=$lt_sysroot$func_stripname_result
+	  ;;
+	*)
+	  func_fatal_error "only absolute run-paths are allowed"
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) func_append xrpath " $dir" ;;
+	esac
+	continue
+	;;
+
+      -shared)
+	# The effects of -shared are defined in a previous loop.
+	continue
+	;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -static | -static-libtool-libs)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -weak)
+        prev=weak
+	continue
+	;;
+
+      -Wc,*)
+	func_stripname '-Wc,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $func_quote_for_eval_result"
+	  func_append compiler_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Wl,*)
+	func_stripname '-Wl,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $wl$func_quote_for_eval_result"
+	  func_append compiler_flags " $wl$func_quote_for_eval_result"
+	  func_append linker_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # -msg_* for osf cc
+      -msg_*)
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      # Flags to be passed through unchanged, with rationale:
+      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
+      # -r[0-9][0-9]*        specify processor for the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+      # +DA*, +DD*           enable 64-bit mode for the HP compiler
+      # -q*                  compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+      # -F/path              path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
+      # @file                GCC response files
+      # -tp=*                Portland pgcc target processor selection
+      # --sysroot=*          for sysroot support
+      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+        func_append compile_command " $arg"
+        func_append finalize_command " $arg"
+        func_append compiler_flags " $arg"
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      *.$objext)
+	# A standard object.
+	func_append objs " $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if func_lalib_unsafe_p "$arg"; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  func_source "$arg"
+
+	  if test -z "$pic_object" ||
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none &&
+	     test "$non_pic_object" = none; then
+	    func_fatal_error "cannot find name of object for \`$arg'"
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  func_dirname "$arg" "/" ""
+	  xdir="$func_dirname_result"
+
+	  if test "$pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    pic_object="$xdir$pic_object"
+
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		func_append dlfiles " $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test "$prev" = dlprefiles; then
+	      # Preload the old-style object.
+	      func_append dlprefiles " $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    func_append libobjs " $pic_object"
+	    arg="$pic_object"
+	  fi
+
+	  # Non-PIC object.
+	  if test "$non_pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object="$xdir$non_pic_object"
+
+	    # A standard non-PIC object
+	    func_append non_pic_objects " $non_pic_object"
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object="$pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if $opt_dry_run; then
+	    # Extract subdirectory from the argument.
+	    func_dirname "$arg" "/" ""
+	    xdir="$func_dirname_result"
+
+	    func_lo2o "$arg"
+	    pic_object=$xdir$objdir/$func_lo2o_result
+	    non_pic_object=$xdir$func_lo2o_result
+	    func_append libobjs " $pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  else
+	    func_fatal_error "\`$arg' is not a valid libtool object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	func_append deplibs " $arg"
+	func_append old_deplibs " $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	func_resolve_sysroot "$arg"
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  func_append dlfiles " $func_resolve_sysroot_result"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  func_append dlprefiles " $func_resolve_sysroot_result"
+	  prev=
+	else
+	  func_append deplibs " $func_resolve_sysroot_result"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+      fi
+    done # argument parsing loop
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prevarg' option requires an argument"
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      func_append compile_command " $arg"
+      func_append finalize_command " $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    func_basename "$output"
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    func_dirname "$output" "/" ""
+    output_objdir="$func_dirname_result$objdir"
+    func_to_tool_file "$output_objdir/"
+    tool_output_objdir=$func_to_tool_file_result
+    # Create the object directory.
+    func_mkdir_p "$output_objdir"
+
+    # Determine the type of output
+    case $output in
+    "")
+      func_fatal_help "you must specify an output file"
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if $opt_preserve_dup_deps ; then
+	case "$libs " in
+	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	esac
+      fi
+      func_append libs " $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if $opt_duplicate_compiler_generated_deps; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+	  esac
+	  func_append pre_post_deps " $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+
+    case $linkmode in
+    lib)
+	passes="conv dlpreopen link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+
+    for pass in $passes; do
+      # The preopen pass in lib mode reverses $deplibs; put it back here
+      # so that -L comes before libs that need it for instance...
+      if test "$linkmode,$pass" = "lib,link"; then
+	## FIXME: Find the place where the list is rebuilt in the wrong
+	##        order, and fix it there properly
+        tmp_deplibs=
+	for deplib in $deplibs; do
+	  tmp_deplibs="$deplib $tmp_deplibs"
+	done
+	deplibs="$tmp_deplibs"
+      fi
+
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
+	deplibs=
+      fi
+      if test "$linkmode" = prog; then
+	case $pass in
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+	esac
+      fi
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
+	# Collect and forward deplibs of preopened libtool libs
+	for lib in $dlprefiles; do
+	  # Ignore non-libtool-libs
+	  dependency_libs=
+	  func_resolve_sysroot "$lib"
+	  case $lib in
+	  *.la)	func_source "$func_resolve_sysroot_result" ;;
+	  esac
+
+	  # Collect preopened libtool deplibs, except any this library
+	  # has declared as weak libs
+	  for deplib in $dependency_libs; do
+	    func_basename "$deplib"
+            deplib_base=$func_basename_result
+	    case " $weak_libs " in
+	    *" $deplib_base "*) ;;
+	    *) func_append deplibs " $deplib" ;;
+	    esac
+	  done
+	done
+	libs="$dlprefiles"
+      fi
+      if test "$pass" = dlopen; then
+	# Collect dlpreopened libraries
+	save_deplibs="$deplibs"
+	deplibs=
+      fi
+
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    func_append compiler_flags " $deplib"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    func_warning "\`-l' is ignored for archives/objects"
+	    continue
+	  fi
+	  func_stripname '-l' '' "$deplib"
+	  name=$func_stripname_result
+	  if test "$linkmode" = lib; then
+	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+	  else
+	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+	  fi
+	  for searchdir in $searchdirs; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib="$searchdir/lib${name}${search_ext}"
+	      if test -f "$lib"; then
+		if test "$search_ext" = ".la"; then
+		  found=yes
+		else
+		  found=no
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if func_lalib_p "$lib"; then
+		  library_names=
+		  old_library=
+		  func_source "$lib"
+		  for l in $old_library $library_names; do
+		    ll="$l"
+		  done
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
+		    func_dirname "$lib" "" "."
+		    ladir="$func_dirname_result"
+		    lib=$ladir/$old_library
+		    if test "$linkmode,$pass" = "prog,link"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+		;;
+	      *) ;;
+	      esac
+	    fi
+	  fi
+	  ;; # -l
+	*.ltframework)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    deplibs="$deplib $deplibs"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  prog)
+	    if test "$pass" = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test "$pass" = scan; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  *)
+	    func_warning "\`-L' is ignored for archives/objects"
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    func_stripname '-R' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    dir=$func_resolve_sysroot_result
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) func_append xrpath " $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la)
+	  func_resolve_sysroot "$deplib"
+	  lib=$func_resolve_sysroot_result
+	  ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    # Linking convenience modules into shared libraries is allowed,
+	    # but linking other static libraries is non-portable.
+	    case " $dlpreconveniencelibs " in
+	    *" $deplib "*) ;;
+	    *)
+	      valid_a_lib=no
+	      case $deplibs_check_method in
+		match_pattern*)
+		  set dummy $deplibs_check_method; shift
+		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		    valid_a_lib=yes
+		  fi
+		;;
+		pass_all)
+		  valid_a_lib=yes
+		;;
+	      esac
+	      if test "$valid_a_lib" != yes; then
+		echo
+		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because the file extensions .$libext of this argument makes me believe"
+		echo "*** that it is just a static archive that I should not use here."
+	      else
+		echo
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
+	      fi
+	      ;;
+	    esac
+	    continue
+	    ;;
+	  prog)
+	    if test "$pass" != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      func_append newdlprefiles " $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      func_append newdlfiles " $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+	fi
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$lib" \
+	  || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+	func_dirname "$lib" "" "."
+	ladir="$func_dirname_result"
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	inherited_linker_flags=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	func_source "$lib"
+
+	# Convert "-framework foo" to "foo.ltframework"
+	if test -n "$inherited_linker_flags"; then
+	  tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+	    case " $new_inherited_linker_flags " in
+	      *" $tmp_inherited_linker_flag "*) ;;
+	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+	    esac
+	  done
+	fi
+	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && func_append dlfiles " $dlopen"
+	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+	fi
+
+	if test "$pass" = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      func_fatal_error "cannot find name of link library for \`$lib'"
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    func_append convenience " $ladir/$objdir/$old_library"
+	    func_append old_convenience " $ladir/$objdir/$old_library"
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    func_fatal_error "\`$lib' is not a convenience library"
+	  fi
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    deplibs="$deplib $deplibs"
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	if test -n "$old_library" &&
+	   { test "$prefer_static_libs" = yes ||
+	     test "$prefer_static_libs,$installed" = "built,no"; }; then
+	  linklib=$old_library
+	else
+	  for l in $old_library $library_names; do
+	    linklib="$l"
+	  done
+	fi
+	if test -z "$linklib"; then
+	  func_fatal_error "cannot find name of link library for \`$lib'"
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+	  fi
+	  if test -z "$dlname" ||
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    func_append dlprefiles " $lib $dependency_libs"
+	  else
+	    func_append newdlfiles " $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    func_warning "cannot determine absolute directory name of \`$ladir'"
+	    func_warning "passing it literally to the linker, although it might fail"
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	func_basename "$lib"
+	laname="$func_basename_result"
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    func_warning "library \`$lib' was moved."
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$lt_sysroot$libdir"
+	    absdir="$lt_sysroot$libdir"
+	  fi
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  else
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  fi
+	fi # $installed = yes
+	func_stripname 'lib' '.la' "$laname"
+	name=$func_stripname_result
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir" && test "$linkmode" = prog; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+	  fi
+	  case "$host" in
+	    # special handling for platforms with PE-DLLs.
+	    *cygwin* | *mingw* | *cegcc* )
+	      # Linker will automatically link against shared library if both
+	      # static and shared are present.  Therefore, ensure we extract
+	      # symbols from the import library if a shared library is present
+	      # (otherwise, the dlopen module name will be incorrect).  We do
+	      # this by putting the import library name into $newdlprefiles.
+	      # We recover the dlopen module name by 'saving' the la file
+	      # name in a special purpose variable, and (later) extracting the
+	      # dlname from the la file.
+	      if test -n "$dlname"; then
+	        func_tr_sh "$dir/$linklib"
+	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+	        func_append newdlprefiles " $dir/$linklib"
+	      else
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      fi
+	    ;;
+	    * )
+	      # Prefer using a static library (so that no silly _DYNAMIC symbols
+	      # are required to link).
+	      if test -n "$old_library"; then
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      # Otherwise, use the dlname, so that lt_dlopen finds it.
+	      elif test -n "$dlname"; then
+	        func_append newdlprefiles " $dir/$dlname"
+	      else
+	        func_append newdlprefiles " $dir/$linklib"
+	      fi
+	    ;;
+	  esac
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test "$linkmode" = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test "$linkmode" = prog && test "$pass" != link; then
+	  func_append newlib_search_path " $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) func_stripname '-L' '' "$deplib"
+	         func_resolve_sysroot "$func_stripname_result"
+	         func_append newlib_search_path " $func_resolve_sysroot_result"
+		 ;;
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test "$linkalldeplibs" = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test "$linkmode,$pass" = "prog,link"; then
+	  if test -n "$library_names" &&
+	     { { test "$prefer_static_libs" = no ||
+	         test "$prefer_static_libs,$installed" = "built,yes"; } ||
+	       test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+	      # Make sure the rpath contains only unique directories.
+	      case "$temp_rpath:" in
+	      *"$absdir:"*) ;;
+	      *) func_append temp_rpath "$absdir:" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test "$use_static_libs" = built && test "$installed" = yes; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc*)
+	      # No point in relinking DLLs because paths are not encoded
+	      func_append notinst_deplibs " $lib"
+	      need_relink=no
+	    ;;
+	  *)
+	    if test "$installed" = no; then
+	      func_append notinst_deplibs " $lib"
+	      need_relink=yes
+	    fi
+	    ;;
+	  esac
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on some
+	  # systems (darwin).  Don't bleat about dlopened modules though!
+	  dlopenmodule=""
+	  for dlpremoduletest in $dlprefiles; do
+	    if test "X$dlpremoduletest" = "X$lib"; then
+	      dlopenmodule="$dlpremoduletest"
+	      break
+	    fi
+	  done
+	  if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+	    echo
+	    if test "$linkmode" = prog; then
+	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $ECHO "*** $linklib is not portable!"
+	  fi
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    shift
+	    realname="$1"
+	    shift
+	    libname=`eval "\\$ECHO \"$libname_spec\""`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw* | *cegcc*)
+	        func_arith $current - $age
+		major=$func_arith_result
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    func_basename "$soroot"
+	    soname="$func_basename_result"
+	    func_stripname 'lib' '.dll' "$soname"
+	    newlib=libimp-$func_stripname_result.a
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      func_verbose "extracting exported symbol list from \`$soname'"
+	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      func_verbose "generating import library for \`$soname'"
+	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test "$linkmode" = prog || test "$opt_mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir="-L$dir" ;;
+		  *-*-darwin* )
+		    # if the lib is a (non-dlopened) module then we can not
+		    # link against it, someone is ignoring the earlier warnings
+		    if /usr/bin/file -L $add 2> /dev/null |
+			 $GREP ": [^:]* bundle" >/dev/null ; then
+		      if test "X$dlopenmodule" != "X$lib"; then
+			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
+			if test -z "$old_library" ; then
+			  echo
+			  echo "*** And there doesn't seem to be a static archive available"
+			  echo "*** The link will probably fail, sorry"
+			else
+			  add="$dir/$old_library"
+			fi
+		      elif test -n "$old_library"; then
+			add="$dir/$old_library"
+		      fi
+		    fi
+		esac
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes &&
+	         test "$hardcode_direct_absolute" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$dir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      func_append add_dir " -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      func_fatal_configuration "unsupported hardcode properties"
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes &&
+		 test "$hardcode_minus_L" != yes &&
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) func_append finalize_shlibpath "$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$opt_mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes &&
+	       test "$hardcode_direct_absolute" = no; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) func_append finalize_shlibpath "$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+		add="$inst_prefix_dir$libdir/$linklib"
+	      else
+		add="$libdir/$linklib"
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    func_append add_dir " -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add="-l$name"
+	    fi
+
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test "$linkmode" = prog; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    echo
+	    $ECHO "*** Warning: This system can not link to static lib archive $lib."
+	    echo "*** I have the capability to make that library automatically link in when"
+	    echo "*** you link to this library.  But I can only do this if you have a"
+	    echo "*** shared version of the library, which you do not appear to have."
+	    if test "$module" = yes; then
+	      echo "*** But as you try to build a module library, libtool will still create "
+	      echo "*** a static module, that should work as long as the dlopening application"
+	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		echo
+		echo "*** However, this would only work if libtool was able to extract symbol"
+		echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+		echo "*** not find such a program.  So, this module is probably useless."
+		echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test "$build_old_libs" = no; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test "$linkmode" = lib; then
+	  if test -n "$dependency_libs" &&
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) func_stripname '-R' '' "$libdir"
+	           temp_xrpath=$func_stripname_result
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) func_append xrpath " $temp_xrpath";;
+		   esac;;
+	      *) func_append temp_deplibs " $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  fi
+
+	  func_append newlib_search_path " $absdir"
+	  # Link against this library
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    case $deplib in
+              -L*) func_stripname '-L' '' "$deplib"
+                   func_resolve_sysroot "$func_stripname_result";;
+              *) func_resolve_sysroot "$deplib" ;;
+            esac
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $func_resolve_sysroot_result "*)
+                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $func_resolve_sysroot_result"
+	  done
+
+	  if test "$link_all_deplibs" != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      path=
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+	        func_resolve_sysroot "$deplib"
+	        deplib=$func_resolve_sysroot_result
+	        func_dirname "$deplib" "" "."
+		dir=$func_dirname_result
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    func_warning "cannot determine absolute directory name of \`$dir'"
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if $GREP "^installed=no" $deplib > /dev/null; then
+		case $host in
+		*-*-darwin*)
+		  depdepl=
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$absdir/$objdir/$depdepl" ; then
+		      depdepl="$absdir/$objdir/$depdepl"
+		      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+                      if test -z "$darwin_install_name"; then
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                      fi
+		      func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+		      func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+		      path=
+		    fi
+		  fi
+		  ;;
+		*)
+		  path="-L$absdir/$objdir"
+		  ;;
+		esac
+		else
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  test -z "$libdir" && \
+		    func_fatal_error "\`$deplib' is not a valid libtool archive"
+		  test "$absdir" != "$libdir" && \
+		    func_warning "\`$deplib' seems to be moved"
+
+		  path="-L$absdir"
+		fi
+		;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      if test "$pass" = link; then
+	if test "$linkmode" = "prog"; then
+	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+	else
+	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	fi
+      fi
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) func_append lib_search_path " $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	fi
+
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
+	else
+	  vars="compile_deplibs finalize_deplibs"
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) func_append tmp_libs " $deplib" ;;
+	      esac
+	      ;;
+	    *) func_append tmp_libs " $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=""
+	  ;;
+	esac
+	if test -n "$i" ; then
+	  func_append tmp_libs " $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+    fi
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for archives"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for archives" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for archives"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for archives"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info/-version-number' is ignored for archives"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for archives"
+
+      test -n "$export_symbols$export_symbols_regex" && \
+	func_warning "\`-export-symbols' is ignored for archives"
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      func_append objs "$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	func_stripname 'lib' '.la' "$outputname"
+	name=$func_stripname_result
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	test "$module" = no && \
+	  func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  func_stripname '' '.la' "$outputname"
+	  name=$func_stripname_result
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  func_stripname '' '.la' "$outputname"
+	  libname=$func_stripname_result
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+	else
+	  echo
+	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+	  $ECHO "*** objects $objs is not portable!"
+	  func_append libobjs " $objs"
+	fi
+      fi
+
+      test "$dlself" != no && \
+	func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+      set dummy $rpath
+      shift
+      test "$#" -gt 1 && \
+	func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+      install_libdir="$1"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a `.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	test -n "$vinfo" && \
+	  func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+	test -n "$release" && \
+	  func_warning "\`-release' is ignored for convenience libraries"
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	shift
+	IFS="$save_ifs"
+
+	test -n "$7" && \
+	  func_fatal_help "too many parameters to \`-version-info'"
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+
+	case $vinfo_number in
+	yes)
+	  number_major="$1"
+	  number_minor="$2"
+	  number_revision="$3"
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # which has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  darwin|linux|osf|windows|none)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_revision"
+	    ;;
+	  freebsd-aout|freebsd-elf|qnx|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
+	    ;;
+	  irix|nonstopux)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_minor"
+	    lt_irix_increment=no
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current="$1"
+	  revision="$2"
+	  age="$3"
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "CURRENT \`$current' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $revision in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "REVISION \`$revision' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $age in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "AGE \`$age' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  func_error "AGE \`$age' is greater than the current interface number \`$current'"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  func_arith $current + 1
+	  minor_current=$func_arith_result
+	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	irix | nonstopux)
+	  if test "X$lt_irix_increment" = "Xno"; then
+	    func_arith $current - $age
+	  else
+	    func_arith $current - $age + 1
+	  fi
+	  major=$func_arith_result
+
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring="$verstring_prefix$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test "$loop" -ne 0; do
+	    func_arith $revision - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring_prefix$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test "$loop" -ne 0; do
+	    func_arith $current - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  func_append verstring ":${current}.0"
+	  ;;
+
+	qnx)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  func_arith $current - $age
+	  major=$func_arith_result
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  func_fatal_configuration "unknown library version type \`$version_type'"
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring="0.0"
+	    ;;
+	  esac
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    func_warning "undefined symbols not allowed in $host shared libraries"
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+
+      fi
+
+      func_generate_dlsyms "$libname" "$libname" "yes"
+      func_append libobjs " $symfileobj"
+      test "X$libobjs" = "X " && libobjs=
+
+      if test "$opt_mode" != relink; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$ECHO "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext | *.gcno)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
+		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+		 then
+		   continue
+		 fi
+	       fi
+	       func_append removelist " $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	test -n "$removelist" && \
+	  func_show_eval "${RM}r \$removelist"
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	func_append oldlibs " $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #	lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+      #	deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+      #	dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+      #done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  func_replace_sysroot "$libdir"
+	  func_append temp_xrpath " -R$func_replace_sysroot_result"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) func_append dlfiles " $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) func_append dlprefiles " $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    func_append deplibs " System.ltframework"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
+	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test "$build_libtool_need_lc" = "yes"; then
+	      func_append deplibs " -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $opt_dry_run || $RM conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $opt_dry_run || $RM conftest
+	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    func_append newdeplibs " $i"
+		    i=""
+		    ;;
+		  esac
+		fi
+		if test -n "$i" ; then
+		  libname=`eval "\\$ECHO \"$libname_spec\""`
+		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		  set dummy $deplib_matches; shift
+		  deplib_match=$1
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    func_append newdeplibs " $i"
+		  else
+		    droppeddeps=yes
+		    echo
+		    $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		    echo "*** I have the capability to make that library automatically link in when"
+		    echo "*** you link to this library.  But I can only do this if you have a"
+		    echo "*** shared version of the library, which I believe you do not have"
+		    echo "*** because a test_compile did reveal that the linker did not use it for"
+		    echo "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		$opt_dry_run || $RM conftest
+		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+		  ldd_output=`ldd conftest`
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      func_append newdeplibs " $i"
+		      i=""
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i" ; then
+		    libname=`eval "\\$ECHO \"$libname_spec\""`
+		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		    set dummy $deplib_matches; shift
+		    deplib_match=$1
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		      func_append newdeplibs " $i"
+		    else
+		      droppeddeps=yes
+		      echo
+		      $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		      echo "*** I have the capability to make that library automatically link in when"
+		      echo "*** you link to this library.  But I can only do this if you have a"
+		      echo "*** shared version of the library, which you do not appear to have"
+		      echo "*** because a test_compile did reveal that the linker did not use this one"
+		      echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  echo
+		  $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
+		  echo "*** make it link in!  You will probably need to install it or some"
+		  echo "*** library that it depends on before this library will be fully"
+		  echo "*** functional.  Installing it before continuing would be even better."
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method; shift
+	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		if test -n "$file_magic_glob"; then
+		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+		else
+		  libnameglob=$libname
+		fi
+		test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  if test "$want_nocaseglob" = yes; then
+		    shopt -s nocaseglob
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		    $nocaseglob
+		  else
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		  fi
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null |
+			 $GREP " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+			 $SED -e 10q |
+			 $EGREP "$file_magic_regex" > /dev/null; then
+			func_append newdeplibs " $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method; shift
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
+		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+		       $EGREP "$match_pattern_regex" > /dev/null; then
+		      func_append newdeplibs " $a_deplib"
+		      a_deplib=""
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+	    done
+	  fi
+	  case $tmp_deplibs in
+	  *[!\	\ ]*)
+	    echo
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	    ;;
+	  esac
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library with the System framework
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+	  ;;
+	esac
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    echo
+	    echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
+	    echo "*** a static module, that should work as long as the dlopening"
+	    echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      echo
+	      echo "*** However, this would only work if libtool was able to extract symbol"
+	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      echo "*** not find such a program.  So, this module is probably useless."
+	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    echo "*** The inter-library dependencies that have been dropped here will be"
+	    echo "*** automatically added whenever a program is linked with this library"
+	    echo "*** or is declared to -dlopen it."
+
+	    if test "$allow_undefined" = no; then
+	      echo
+	      echo "*** Since this library must not contain undefined symbols,"
+	      echo "*** because either the platform does not support them or"
+	      echo "*** it was explicitly requested with -no-undefined,"
+	      echo "*** libtool will only create a static version of it."
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+      case $host in
+	*-*-darwin*)
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  ;;
+      esac
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      deplibs="$new_libs"
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	if test "$hardcode_into_libs" = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		func_replace_sysroot "$libdir"
+		libdir=$func_replace_sysroot_result
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs="$libdir"
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		func_append dep_rpath " $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_apped perm_rpath " $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir="$hardcode_libdirs"
+	    if test -n "$hardcode_libdir_flag_spec_ld"; then
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+	    else
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+	    fi
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      func_append rpath "$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath="$finalize_shlibpath"
+	test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext_cmds\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	shift
+	realname="$1"
+	shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
+	fi
+
+	lib="$output_objdir/$realname"
+	linknames=
+	for link
+	do
+	  func_append linknames " $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	test "X$libobjs" = "X " && libobjs=
+
+	delfiles=
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+	  export_symbols="$output_objdir/$libname.uexp"
+	  func_append delfiles " $export_symbols"
+	fi
+
+	orig_export_symbols=
+	case $host_os in
+	cygwin* | mingw* | cegcc*)
+	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+	    # exporting using user supplied symfile
+	    if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+	      # and it's NOT already a .def file. Must figure out
+	      # which of the given symbols are data symbols and tag
+	      # them as such. So, trigger use of export_symbols_cmds.
+	      # export_symbols gets reassigned inside the "prepare
+	      # the list of exported symbols" if statement, so the
+	      # include_expsyms logic still works.
+	      orig_export_symbols="$export_symbols"
+	      export_symbols=
+	      always_export_symbols=yes
+	    fi
+	  fi
+	  ;;
+	esac
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $opt_dry_run || $RM $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd1 in $cmds; do
+	      IFS="$save_ifs"
+	      # Take the normal branch if the nm_file_list_spec branch
+	      # doesn't work or if tool conversion is not needed.
+	      case $nm_file_list_spec~$to_tool_file_cmd in
+		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+		  try_normal_branch=yes
+		  eval cmd=\"$cmd1\"
+		  func_len " $cmd"
+		  len=$func_len_result
+		  ;;
+		*)
+		  try_normal_branch=no
+		  ;;
+	      esac
+	      if test "$try_normal_branch" = yes \
+		 && { test "$len" -lt "$max_cmd_len" \
+		      || test "$max_cmd_len" -le -1; }
+	      then
+		func_show_eval "$cmd" 'exit $?'
+		skipped_export=false
+	      elif test -n "$nm_file_list_spec"; then
+		func_basename "$output"
+		output_la=$func_basename_result
+		save_libobjs=$libobjs
+		save_output=$output
+		output=${output_objdir}/${output_la}.nm
+		func_to_tool_file "$output"
+		libobjs=$nm_file_list_spec$func_to_tool_file_result
+		func_append delfiles " $output"
+		func_verbose "creating $NM input file list: $output"
+		for obj in $save_libobjs; do
+		  func_to_tool_file "$obj"
+		  $ECHO "$func_to_tool_file_result"
+		done > "$output"
+		eval cmd=\"$cmd1\"
+		func_show_eval "$cmd" 'exit $?'
+		output=$save_output
+		libobjs=$save_libobjs
+		skipped_export=false
+	      else
+		# The command line is too long to execute in one step.
+		func_verbose "using reloadable object file for export list..."
+		skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
+	      fi
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  tmp_export_symbols="$export_symbols"
+	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	fi
+
+	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+	  # The given exports_symbols file has to be filtered, so filter it.
+	  func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	  # 's' commands which not all seds can handle. GNU sed should be fine
+	  # though. Also, the filter scales superlinearly with the number of
+	  # global variables. join(1) would be nice here, but unfortunately
+	  # isn't a blessed tool.
+	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	  export_symbols=$output_objdir/$libname.def
+	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+	  case " $convenience " in
+	  *" $test_deplib "*) ;;
+	  *)
+	    func_append tmp_deplibs " $test_deplib"
+	    ;;
+	  esac
+	done
+	deplibs="$tmp_deplibs"
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec" &&
+	    test "$compiler_needs_object" = yes &&
+	    test -z "$libobjs"; then
+	    # extract the archives, so we have objects to list.
+	    # TODO: could optimize this to just extract one archive.
+	    whole_archive_flag_spec=
+	  fi
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    func_append generated " $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    func_append libobjs " $func_extract_archives_result"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	fi
+
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  func_append linker_flags " $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test "$opt_mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+	fi
+
+	# Do each of the archive commands.
+	if test "$module" = yes && test -n "$module_cmds" ; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval test_cmds=\"$module_expsym_cmds\"
+	    cmds=$module_expsym_cmds
+	  else
+	    eval test_cmds=\"$module_cmds\"
+	    cmds=$module_cmds
+	  fi
+	else
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    eval test_cmds=\"$archive_expsym_cmds\"
+	    cmds=$archive_expsym_cmds
+	  else
+	    eval test_cmds=\"$archive_cmds\"
+	    cmds=$archive_cmds
+	  fi
+	fi
+
+	if test "X$skipped_export" != "X:" &&
+	   func_len " $test_cmds" &&
+	   len=$func_len_result &&
+	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise
+	  # or, if using GNU ld and skipped_export is not :, use a linker
+	  # script.
+
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+	  func_basename "$output"
+	  output_la=$func_basename_result
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  last_robj=
+	  k=1
+
+	  if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+	    output=${output_objdir}/${output_la}.lnkscript
+	    func_verbose "creating GNU ld script: $output"
+	    echo 'INPUT (' > $output
+	    for obj in $save_libobjs
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    echo ')' >> $output
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$func_to_tool_file_result
+	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+	    output=${output_objdir}/${output_la}.lnk
+	    func_verbose "creating linker input file list: $output"
+	    : > $output
+	    set x $save_libobjs
+	    shift
+	    firstobj=
+	    if test "$compiler_needs_object" = yes; then
+	      firstobj="$1 "
+	      shift
+	    fi
+	    for obj
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+	  else
+	    if test -n "$save_libobjs"; then
+	      func_verbose "creating reloadable object files..."
+	      output=$output_objdir/$output_la-${k}.$objext
+	      eval test_cmds=\"$reload_cmds\"
+	      func_len " $test_cmds"
+	      len0=$func_len_result
+	      len=$len0
+
+	      # Loop over the list of objects to be linked.
+	      for obj in $save_libobjs
+	      do
+		func_len " $obj"
+		func_arith $len + $func_len_result
+		len=$func_arith_result
+		if test "X$objlist" = X ||
+		   test "$len" -lt "$max_cmd_len"; then
+		  func_append objlist " $obj"
+		else
+		  # The command $test_cmds is almost too long, add a
+		  # command to the queue.
+		  if test "$k" -eq 1 ; then
+		    # The first file doesn't have a previous command to add.
+		    reload_objs=$objlist
+		    eval concat_cmds=\"$reload_cmds\"
+		  else
+		    # All subsequent reloadable object files will link in
+		    # the last one created.
+		    reload_objs="$objlist $last_robj"
+		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+		  fi
+		  last_robj=$output_objdir/$output_la-${k}.$objext
+		  func_arith $k + 1
+		  k=$func_arith_result
+		  output=$output_objdir/$output_la-${k}.$objext
+		  objlist=" $obj"
+		  func_len " $last_robj"
+		  func_arith $len0 + $func_len_result
+		  len=$func_arith_result
+		fi
+	      done
+	      # Handle the remaining objects by creating one last
+	      # reloadable object file.  All subsequent reloadable object
+	      # files will link in the last one created.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      reload_objs="$objlist $last_robj"
+	      eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+	      if test -n "$last_robj"; then
+	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+	      fi
+	      func_append delfiles " $output"
+
+	    else
+	      output=
+	    fi
+
+	    if ${skipped_export-false}; then
+	      func_verbose "generating symbol list for \`$libname.la'"
+	      export_symbols="$output_objdir/$libname.exp"
+	      $opt_dry_run || $RM $export_symbols
+	      libobjs=$output
+	      # Append the command to create the export file.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+	      if test -n "$last_robj"; then
+		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	      fi
+	    fi
+
+	    test -n "$save_libobjs" &&
+	      func_verbose "creating a temporary reloadable object file: $output"
+
+	    # Loop through the commands generated above and execute them.
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $concat_cmds; do
+	      IFS="$save_ifs"
+	      $opt_silent || {
+		  func_quote_for_expand "$cmd"
+		  eval "func_echo $func_quote_for_expand_result"
+	      }
+	      $opt_dry_run || eval "$cmd" || {
+		lt_exit=$?
+
+		# Restore the uninstalled library and exit
+		if test "$opt_mode" = relink; then
+		  ( cd "$output_objdir" && \
+		    $RM "${realname}T" && \
+		    $MV "${realname}U" "$realname" )
+		fi
+
+		exit $lt_exit
+	      }
+	    done
+	    IFS="$save_ifs"
+
+	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+
+          if ${skipped_export-false}; then
+	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	      tmp_export_symbols="$export_symbols"
+	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	    fi
+
+	    if test -n "$orig_export_symbols"; then
+	      # The given exports_symbols file has to be filtered, so filter it.
+	      func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	      # 's' commands which not all seds can handle. GNU sed should be fine
+	      # though. Also, the filter scales superlinearly with the number of
+	      # global variables. join(1) would be nice here, but unfortunately
+	      # isn't a blessed tool.
+	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	      export_symbols=$output_objdir/$libname.def
+	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	    fi
+	  fi
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test "$module" = yes && test -n "$module_cmds" ; then
+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	      cmds=$module_expsym_cmds
+	    else
+	      cmds=$module_cmds
+	    fi
+	  else
+	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	      cmds=$archive_expsym_cmds
+	    else
+	      cmds=$archive_cmds
+	    fi
+	  fi
+	fi
+
+	if test -n "$delfiles"; then
+	  # Append the command to remove temporary files to $cmds.
+	  eval cmds=\"\$cmds~\$RM $delfiles\"
+	fi
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append libobjs " $func_extract_archives_result"
+	  test "X$libobjs" = "X " && libobjs=
+	fi
+
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $opt_silent || {
+	    func_quote_for_expand "$cmd"
+	    eval "func_echo $func_quote_for_expand_result"
+	  }
+	  $opt_dry_run || eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test "$opt_mode" = relink; then
+	      ( cd "$output_objdir" && \
+	        $RM "${realname}T" && \
+		$MV "${realname}U" "$realname" )
+	    fi
+
+	    exit $lt_exit
+	  }
+	done
+	IFS="$save_ifs"
+
+	# Restore the uninstalled library and exit
+	if test "$opt_mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      func_show_eval '${RM}r "$gentop"'
+	    fi
+	  fi
+
+	  exit $EXIT_SUCCESS
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for objects"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for objects" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for objects"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for objects"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for objects"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for objects"
+
+      case $output in
+      *.lo)
+	test -n "$objs$old_deplibs" && \
+	  func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+	libobj=$output
+	func_lo2o "$libobj"
+	obj=$func_lo2o_result
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $opt_dry_run || $RM $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
+
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+	  reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+	else
+	  gentop="$output_objdir/${obj}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
+      fi
+
+      # If we're not building shared, we need to use non_pic_objs
+      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      func_execute_cmds "$reload_cmds" 'exit $?'
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+	exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	func_execute_cmds "$reload_cmds" 'exit $?'
+      fi
+
+      if test -n "$gentop"; then
+	func_show_eval '${RM}r "$gentop"'
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) func_stripname '' '.exe' "$output"
+	          output=$func_stripname_result.exe;;
+      esac
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for programs"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for programs"
+
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+	&& test "$dlopen_self" = unknown \
+	&& test "$dlopen_self_static" = unknown && \
+	  func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	;;
+      esac
+
+      case $host in
+      *-*-darwin*)
+	# Don't allow lazy linking, it breaks C++ global constructors
+	# But is supposedly fixed on 10.4 or later (yay!).
+	if test "$tagname" = CXX ; then
+	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+	    10.[0123])
+	      func_append compile_command " ${wl}-bind_at_load"
+	      func_append finalize_command " ${wl}-bind_at_load"
+	    ;;
+	  esac
+	fi
+	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      func_append compile_command " $compile_deplibs"
+      func_append finalize_command " $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append perm_rpath " $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  ::) dllsearchpath=$libdir;;
+	  *) func_append dllsearchpath ":$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_perm_rpath " $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+      fi
+
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+	func_execute_cmds "$prelink_cmds" 'exit $?'
+      fi
+
+      wrappers_required=yes
+      case $host in
+      *cegcc* | *mingw32ce*)
+        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+        wrappers_required=no
+        ;;
+      *cygwin* | *mingw* )
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      *)
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      esac
+      if test "$wrappers_required" = no; then
+	# Replace the output file specification.
+	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	exit_status=0
+	func_show_eval "$link_command" 'exit_status=$?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	# Delete the generated files.
+	if test -f "$output_objdir/${outputname}S.${objext}"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+	fi
+
+	exit $exit_status
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$no_install" = yes; then
+	# We don't need to create a wrapper script.
+	link_command="$compile_var$compile_command$compile_rpath"
+	# Replace the output file specification.
+	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$opt_dry_run || $RM $output
+	# Link the executable and exit
+	func_show_eval "$link_command" 'exit $?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+	func_warning "this platform does not like uninstalled shared libraries"
+	func_warning "\`$output' will be relinked during installation"
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      func_show_eval "$link_command" 'exit $?'
+
+      if test -n "$postlink_cmds"; then
+	func_to_tool_file "$output_objdir/$outputname"
+	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	func_execute_cmds "$postlink_cmds" 'exit $?'
+      fi
+
+      # Now create the wrapper script.
+      func_verbose "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    func_quote_for_eval "$var_value"
+	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if not in dry run mode.
+      $opt_dry_run || {
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) func_stripname '' '.exe' "$output"
+	         output=$func_stripname_result ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    func_stripname '' '.exe' "$outputname"
+	    outputname=$func_stripname_result ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+	    func_dirname_and_basename "$output" "" "."
+	    output_name=$func_basename_result
+	    output_path=$func_dirname_result
+	    cwrappersource="$output_path/$objdir/lt-$output_name.c"
+	    cwrapper="$output_path/$output_name.exe"
+	    $RM $cwrappersource $cwrapper
+	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_cwrapperexe_src > $cwrappersource
+
+	    # The wrapper executable is built using the $host compiler,
+	    # because it contains $host paths and files. If cross-
+	    # compiling, it, like the target executable, must be
+	    # executed on the $host or under an emulation environment.
+	    $opt_dry_run || {
+	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+	      $STRIP $cwrapper
+	    }
+
+	    # Now, create the wrapper script for func_source use:
+	    func_ltwrapper_scriptname $cwrapper
+	    $RM $func_ltwrapper_scriptname_result
+	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+	    $opt_dry_run || {
+	      # note: this script will not be executed, so do not chmod.
+	      if test "x$build" = "x$host" ; then
+		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+	      else
+		func_emit_wrapper no > $func_ltwrapper_scriptname_result
+	      fi
+	    }
+	  ;;
+	  * )
+	    $RM $output
+	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_wrapper no > $output
+	    chmod +x $output
+	  ;;
+	esac
+      }
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save $symfileobj"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$old_deplibs $non_pic_objects"
+	  if test "$preload" = yes && test -f "$symfileobj"; then
+	    func_append oldobjs " $symfileobj"
+	  fi
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	func_append generated " $gentop"
+
+	func_extract_archives $gentop $addlibs
+	func_append oldobjs " $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	cmds=$old_archive_from_new_cmds
+      else
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append oldobjs " $func_extract_archives_result"
+	fi
+
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+	if (for obj in $oldobjs
+	    do
+	      func_basename "$obj"
+	      $ECHO "$func_basename_result"
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  echo "copying selected object files to avoid basename conflicts..."
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+	  func_mkdir_p "$gentop"
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    func_basename "$obj"
+	    objbase="$func_basename_result"
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		func_arith $counter + 1
+		counter=$func_arith_result
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      func_append oldobjs " $gentop/$newobj"
+	      ;;
+	    *) func_append oldobjs " $obj" ;;
+	    esac
+	  done
+	fi
+	eval cmds=\"$old_archive_cmds\"
+
+	func_len " $cmds"
+	len=$func_len_result
+	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	elif test -n "$archiver_list_spec"; then
+	  func_verbose "using command file archive linking..."
+	  for obj in $oldobjs
+	  do
+	    func_to_tool_file "$obj"
+	    $ECHO "$func_to_tool_file_result"
+	  done > $output_objdir/$libname.libcmd
+	  func_to_tool_file "$output_objdir/$libname.libcmd"
+	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  func_verbose "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done
+	  eval test_cmds=\"$old_archive_cmds\"
+	  func_len " $test_cmds"
+	  len0=$func_len_result
+	  len=$len0
+	  for obj in $save_oldobjs
+	  do
+	    func_len " $obj"
+	    func_arith $len + $func_len_result
+	    len=$func_arith_result
+	    func_append objlist " $obj"
+	    if test "$len" -lt "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj" ; then
+		RANLIB=$save_RANLIB
+	      fi
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+	      objlist=
+	      len=$len0
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test "X$oldobjs" = "X" ; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      func_execute_cmds "$cmds" 'exit $?'
+    done
+
+    test -n "$generated" && \
+      func_show_eval "${RM}r$generated"
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      func_verbose "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  func_quote_for_eval "$var_value"
+	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+	relink_command=
+      fi
+
+      # Only create the output if not a dry run.
+      $opt_dry_run || {
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		func_basename "$deplib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$deplib' is not a valid libtool archive"
+		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      -L*)
+		func_stripname -L '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -L$func_replace_sysroot_result"
+		;;
+	      -R*)
+		func_stripname -R '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -R$func_replace_sysroot_result"
+		;;
+	      *) func_append newdependency_libs " $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+
+	    for lib in $dlfiles; do
+	      case $lib in
+	      *.la)
+	        func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      *) func_append newdlfiles " $lib" ;;
+	      esac
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+	      *.la)
+		# Only pass preopened files to the pseudo-archive (for
+		# eventual linking with the app. that links it) if we
+		# didn't already link the preopened objects directly into
+		# the library:
+		func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      esac
+	    done
+	    dlprefiles="$newdlprefiles"
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlfiles " $abs"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlprefiles " $abs"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $RM $output
+	  # place dlname in correct position for cygwin
+	  # In fact, it would be nice if we could use this code for all target
+	  # systems that can't hard-code library paths into their executables
+	  # and that have no shared library path variable independent of PATH,
+	  # but it turns out we can't easily determine that from inspecting
+	  # libtool variables, so we have to hard-code the OSs to which it
+	  # applies here; at the moment, that means platforms that use the PE
+	  # object format with DLL files.  See the long comment at the top of
+	  # tests/bindir.at for full details.
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+	      # If a -bindir argument was supplied, place the dll there.
+	      if test "x$bindir" != x ;
+	      then
+		func_relative_path "$install_libdir" "$bindir"
+		tdlname=$func_relative_path_result$dlname
+	      else
+		# Otherwise fall back on heuristic.
+		tdlname=../bin/$dlname
+	      fi
+	      ;;
+	  esac
+	  $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test "$installed" = no && test "$need_relink" = yes; then
+	    $ECHO >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      }
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+    func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+    $opt_debug
+    RM="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) func_append RM " $arg"; rmforce=yes ;;
+      -*) func_append RM " $arg" ;;
+      *) func_append files " $arg" ;;
+      esac
+    done
+
+    test -z "$RM" && \
+      func_fatal_help "you must specify an RM program"
+
+    rmdirs=
+
+    for file in $files; do
+      func_dirname "$file" "" "."
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+	odir="$objdir"
+      else
+	odir="$dir/$objdir"
+      fi
+      func_basename "$file"
+      name="$func_basename_result"
+      test "$opt_mode" = uninstall && odir="$dir"
+
+      # Remember odir for removal later, being careful to avoid duplicates
+      if test "$opt_mode" = clean; then
+	case " $rmdirs " in
+	  *" $odir "*) ;;
+	  *) func_append rmdirs " $odir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if { test -L "$file"; } >/dev/null 2>&1 ||
+	 { test -h "$file"; } >/dev/null 2>&1 ||
+	 test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif test "$rmforce" = yes; then
+	continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if func_lalib_p "$file"; then
+	  func_source $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    func_append rmfiles " $odir/$n"
+	  done
+	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+	  case "$opt_mode" in
+	  clean)
+	    case " $library_names " in
+	    *" $dlname "*) ;;
+	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+	    esac
+	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+	    ;;
+	  uninstall)
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	    ;;
+	  esac
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if func_lalib_p "$file"; then
+
+	  # Read the .lo file
+	  func_source $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" &&
+	     test "$pic_object" != none; then
+	    func_append rmfiles " $dir/$pic_object"
+	  fi
+
+	  # Add non-PIC object to the list of files to remove.
+	  if test -n "$non_pic_object" &&
+	     test "$non_pic_object" != none; then
+	    func_append rmfiles " $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test "$opt_mode" = clean ; then
+	  noexename=$name
+	  case $file in
+	  *.exe)
+	    func_stripname '' '.exe' "$file"
+	    file=$func_stripname_result
+	    func_stripname '' '.exe' "$name"
+	    noexename=$func_stripname_result
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    func_append rmfiles " $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if func_ltwrapper_p "$file"; then
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      relink_command=
+	      func_source $func_ltwrapper_scriptname_result
+	      func_append rmfiles " $func_ltwrapper_scriptname_result"
+	    else
+	      relink_command=
+	      func_source $dir/$noexename
+	    fi
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
+	      func_append rmfiles " $odir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name" ; then
+	      func_append rmfiles " $odir/lt-${noexename}.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
+    done
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	func_show_eval "rmdir $dir >/dev/null 2>&1"
+      fi
+    done
+
+    exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+  help="$generic_help"
+  func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+  func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+  eval exec "$exec_cmd"
+  exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/pubdef.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,585 @@
+# $Id: pubdef.in,v 4d4a04145f28 2010/07/28 15:20:45 ben $
+#
+# Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+# Name
+# D == documentation
+# I == include file
+# J == Java constant
+# N == wrapped by the Java native layer
+# C == C# constant
+DB_AFTER			D I J C
+DB_AGGRESSIVE			D I J C
+DB_ALIGN8			* I * *
+DB_ALREADY_ABORTED		* I * *
+DB_AM_CHKSUM			* I * *
+DB_AM_COMPENSATE		* I * *
+DB_AM_COMPRESS			* I * *
+DB_AM_CREATED			* I * *
+DB_AM_CREATED_MSTR		* I * *
+DB_AM_DBM_ERROR			* I * *
+DB_AM_DELIMITER			* I * *
+DB_AM_DISCARD			* I * *
+DB_AM_DUP			* I * *
+DB_AM_DUPSORT			* I * *
+DB_AM_ENCRYPT			* I * *
+DB_AM_FIXEDLEN			* I * *
+DB_AM_INMEM			* I * *
+DB_AM_INORDER			* I * *
+DB_AM_IN_RENAME			* I * *
+DB_AM_NOT_DURABLE		* I * *
+DB_AM_OPEN_CALLED		* I * *
+DB_AM_PAD			* I * *
+DB_AM_PARTDB			* I * *
+DB_AM_PGDEF			* I * *
+DB_AM_RDONLY			* I * *
+DB_AM_READ_UNCOMMITTED		* I * *
+DB_AM_RECNUM			* I * *
+DB_AM_RECOVER			* I * *
+DB_AM_RENUMBER			* I * *
+DB_AM_REVSPLITOFF		* I * *
+DB_AM_SECONDARY			* I * *
+DB_AM_SNAPSHOT			* I * *
+DB_AM_SUBDB			* I * *
+DB_AM_SWAP			* I * *
+DB_AM_TXN			* I * *
+DB_AM_VERIFYING			* I * *
+DB_APPEND			D I J C
+DB_ARCH_ABS			D I J C
+DB_ARCH_DATA			D I J C
+DB_ARCH_LOG			D I J C
+DB_ARCH_REMOVE			D I J C
+DB_ASSOC_IMMUTABLE_KEY		* I J C
+DB_ASSOC_CREATE       		* I J C
+DB_AUTO_COMMIT			D I J C
+DB_BACKUP_CLEAN			D I J C
+DB_BACKUP_FILES			D I J C
+DB_BACKUP_NO_LOGS		D I J C
+DB_BACKUP_READ_COUNT		D I J C
+DB_BACKUP_READ_SLEEP		D I J C
+DB_BACKUP_SINGLE_DIR		D I J C
+DB_BACKUP_SIZE			D I J C
+DB_BACKUP_UPDATE		D I J C
+DB_BACKUP_WRITE_DIRECT		D I J C
+DB_BEFORE			D I J C
+DB_BOOTSTRAP_HELPER		D I J C
+DB_BTREE			D I J C
+DB_BTREEMAGIC			* I * *
+DB_BTREEOLDVER			* I * *
+DB_BTREEVERSION			* I * *
+DB_BUFFER_SMALL			D I J C
+DB_CDB_ALLDB			D I J C
+DB_CHKSUM			D I J C
+DB_CKP_INTERNAL			* I * *
+DB_CONFIG			D * * *
+DB_CONSUME			D I J C
+DB_CONSUME_WAIT			D I J C
+DB_CREATE			D I J C
+DB_CURRENT			D I J C
+DB_CURSOR_BULK			D I J C
+DB_CURSOR_TRANSIENT		* I * *
+DB_CXX_NO_EXCEPTIONS		D I * *
+DB_DATABASE_LOCK		* I * *
+DB_DATABASE_LOCKING		* I * *
+DB_DBM_HSEARCH			* I * *
+DB_DBT_APPMALLOC		D I N C
+DB_DBT_BULK			D I J C
+DB_DBT_DUPOK			* I * *
+DB_DBT_ISSET			* I * *
+DB_DBT_MALLOC			D I J C
+DB_DBT_MULTIPLE			D I N C
+DB_DBT_PARTIAL			D I J C
+DB_DBT_READONLY			D I J C
+DB_DBT_REALLOC			D I N C
+DB_DBT_STREAMING		D I * *
+DB_DBT_USERCOPY			* I N C
+DB_DBT_USERMEM			D I J C
+DB_DEGREE_2			* I * *
+DB_DELETED			* I * *
+DB_DIRECT			D I * *
+DB_DIRECT_DB			D I J C
+DB_DIRTY_READ			* I * *
+DB_DONOTINDEX			D I N C
+DB_DSYNC_DB			D I J C
+DB_DUP				D I J C
+DB_DUPSORT			D I J C
+DB_DURABLE_UNKNOWN		* I * *
+DB_EID_BROADCAST		D I J C
+DB_EID_INVALID			D I J C
+DB_EID_MASTER			D I J C
+DB_ENCRYPT			D I J C
+DB_ENCRYPT_AES			D I J C
+DB_ENV_AUTO_COMMIT		* I * *
+DB_ENV_CDB_ALLDB		* I * *
+DB_ENV_DATABASE_LOCKING		* I * *
+DB_ENV_DIRECT_DB		* I * *
+DB_ENV_DSYNC_DB			* I * *
+DB_ENV_FAILCHK 			* I * *
+DB_ENV_MULTIVERSION		* I * *
+DB_ENV_NOLOCKING		* I * *
+DB_ENV_NOMMAP			* I * *
+DB_ENV_NOPANIC			* I * *
+DB_ENV_OVERWRITE		* I * *
+DB_ENV_REGION_INIT		* I * *
+DB_ENV_TIME_NOTGRANTED		* I * *
+DB_ENV_TXN_NOSYNC		* I * *
+DB_ENV_TXN_NOWAIT		* I * *
+DB_ENV_TXN_SNAPSHOT		* I * *
+DB_ENV_TXN_WRITE_NOSYNC		* I * *
+DB_ENV_YIELDCPU			* I * *
+DB_EVENT_NOT_HANDLED		* I * *
+DB_EVENT_NO_SUCH_EVENT		* I * *
+DB_EVENT_PANIC			D I N C
+DB_EVENT_REG_ALIVE		D I * *
+DB_EVENT_REG_PANIC		D I * *
+DB_EVENT_REP_CLIENT		D I N C
+DB_EVENT_REP_CONNECT_BROKEN	D I N C
+DB_EVENT_REP_CONNECT_ESTD	D I N C
+DB_EVENT_REP_CONNECT_TRY_FAILED	D I N C
+DB_EVENT_REP_DUPMASTER		D I N C
+DB_EVENT_REP_ELECTED		D I N C
+DB_EVENT_REP_ELECTION_FAILED	D I N C
+DB_EVENT_REP_INIT_DONE		D I N C
+DB_EVENT_REP_JOIN_FAILURE	D I N C
+DB_EVENT_REP_LOCAL_SITE_REMOVED	D I N C
+DB_EVENT_REP_MASTER		D I N C
+DB_EVENT_REP_MASTER_FAILURE	D I N C
+DB_EVENT_REP_NEWMASTER		D I N C
+DB_EVENT_REP_PERM_FAILED	D I N C
+DB_EVENT_REP_SITE_ADDED		D I N C
+DB_EVENT_REP_SITE_REMOVED	D I N C
+DB_EVENT_REP_STARTUPDONE	D I N C
+DB_EVENT_REP_WOULD_ROLLBACK	* I * *
+DB_EVENT_WRITE_FAILED		D I N C
+DB_EXCL				D I J C
+DB_EXTENT			* I * *
+DB_FAILCHK			D I * *
+DB_FAILCHK_ISALIVE		* I * *
+DB_FAST_STAT			D I J C
+DB_FCNTL_LOCKING		* I * *
+DB_FILE_ID_LEN			* I * *
+DB_FIRST			D I J C
+DB_FLUSH			D I J C
+DB_FORCE			D I J C
+DB_FORCESYNC			D I J C
+DB_FOREIGN_ABORT                * I J C
+DB_FOREIGN_CASCADE              * I J C
+DB_FOREIGN_CONFLICT             * I * C
+DB_FOREIGN_NULLIFY    		* I J C
+DB_FREELIST_ONLY		D I J C
+DB_FREE_SPACE			D I J C
+DB_GET_BOTH			D I J C
+DB_GET_BOTHC			* I * *
+DB_GET_BOTH_LTE			D I * *
+DB_GET_BOTH_RANGE		D I J C
+DB_GET_RECNO			D I J C
+DB_GID_SIZE			* I N C
+DB_GROUP_CREATOR		D I J C
+DB_HANDLE_LOCK			* I * *
+DB_HASH				D I J C
+DB_HASHMAGIC			* I * *
+DB_HASHOLDVER			* I * *
+DB_HASHVERSION			* I * *
+DB_HEAP				D I J C
+DB_HEAPMAGIC			* I * *
+DB_HEAPOLDVER                   * I * *
+DB_HEAPVERSION			* I * *
+DB_HEAP_FULL			D I J C
+DB_HEAP_RID_SZ			D I * *
+DB_HOME				D * * *
+DB_HOTBACKUP_IN_PROGRESS	D I J C
+DB_IGNORE_LEASE			D I J C
+DB_IMMUTABLE_KEY		D I J C
+DB_INIT_CDB			D I J C
+DB_INIT_LOCK			D I J C
+DB_INIT_LOG			D I J C
+DB_INIT_MPOOL			D I J C
+DB_INIT_MUTEX			* I * *
+DB_INIT_REP			D I J C
+DB_INIT_TXN			D I J C
+DB_INORDER			D I J C
+DB_INTERNAL_PERSISTENT_DB	* I * *
+DB_INTERNAL_TEMPORARY_DB	* I * *
+DB_JOINENV			* I J C
+DB_JOIN_ITEM			D I J C
+DB_JOIN_NOSORT			D I J C
+DB_KEYEMPTY			D I J C
+DB_KEYEXIST			D I J C
+DB_KEYFIRST			D I J C
+DB_KEYLAST			D I J C
+DB_LAST				D I J C
+DB_LEGACY			D I J C
+DB_LOCAL_SITE			D I J C
+DB_LOCKDOWN			D I J C
+DB_LOCKVERSION			* I * *
+DB_LOCK_CHECK			* I * *
+DB_LOCK_DEADLOCK		D I N C
+DB_LOCK_DEFAULT			D I J C
+DB_LOCK_DUMP			* I * *
+DB_LOCK_EXPIRE			D I J C
+DB_LOCK_GET			D I J C
+DB_LOCK_GET_TIMEOUT		D I J C
+DB_LOCK_IGNORE_REC		* I * *
+DB_LOCK_INHERIT			* I * *
+DB_LOCK_IREAD			D I J C
+DB_LOCK_IWR			D I J C
+DB_LOCK_IWRITE			D I J C
+DB_LOCK_MAXLOCKS		D I J C
+DB_LOCK_MAXWRITE		D I J C
+DB_LOCK_MINLOCKS		D I J C
+DB_LOCK_MINWRITE		D I J C
+DB_LOCK_NG			* I * *
+DB_LOCK_NORUN			* I * *
+DB_LOCK_NOTGRANTED		D I J C
+DB_LOCK_NOWAIT			D I J C
+DB_LOCK_OLDEST			D I J C
+DB_LOCK_PUT			D I J C
+DB_LOCK_PUT_ALL			D I J C
+DB_LOCK_PUT_OBJ			D I J C
+DB_LOCK_PUT_READ		* I * *
+DB_LOCK_RANDOM			D I J C
+DB_LOCK_READ			D I J C
+DB_LOCK_READ_UNCOMMITTED	* I * *
+DB_LOCK_RECORD			* I * *
+DB_LOCK_SET_TIMEOUT		* I * *
+DB_LOCK_SWITCH			* I * *
+DB_LOCK_TIMEOUT			D I J C
+DB_LOCK_TRADE			* I * *
+DB_LOCK_UPGRADE			* I * *
+DB_LOCK_UPGRADE_WRITE		* I * *
+DB_LOCK_WAIT			* I * *
+DB_LOCK_WRITE			D I J C
+DB_LOCK_WWRITE			* I * *
+DB_LOCK_YOUNGEST		D I J C
+DB_LOGCHKSUM			D I * *
+DB_LOGFILEID_INVALID		* I * *
+DB_LOGMAGIC			* I * *
+DB_LOGOLDVER			* I * *
+DB_LOGVERSION			* I * *
+DB_LOGVERSION_LATCHING		D I * *
+DB_LOG_AUTO_REMOVE		D I J C
+DB_LOG_BUFFER_FULL		D I * C
+DB_LOG_CHKPNT			* I * *
+DB_LOG_COMMIT			* I * *
+DB_LOG_DIRECT			D I J C
+DB_LOG_DISK			* I * *
+DB_LOG_DSYNC			D I J C
+DB_LOG_IN_MEMORY		D I J C
+DB_LOG_LOCKED			* I * *
+DB_LOG_NOCOPY			* I * *
+DB_LOG_NO_DATA			* I * *
+DB_LOG_NOT_DURABLE		* I * *
+DB_LOG_SILENT_ERR		* I * *
+DB_LOG_WRNOSYNC			* I * *
+DB_LOG_VERIFY_BAD		D I * *
+DB_LOG_VERIFY_CAF		D I * *
+DB_LOG_VERIFY_ERR		D I * *
+DB_LOG_VERIFY_PARTIAL		* I * *
+DB_LOG_VERIFY_DBFILE		* I * *
+DB_LOG_VERIFY_FORWARD		* I * *
+DB_LOG_VERIFY_INTERR		D I * *
+DB_LOG_VERIFY_WARNING		D I * *
+DB_LOG_VERIFY_VERBOSE		D I * *
+DB_LOG_ZERO			D I J C
+DB_LSTAT_ABORTED		* I * *
+DB_LSTAT_EXPIRED		* I * *
+DB_LSTAT_FREE			* I * *
+DB_LSTAT_HELD			* I * *
+DB_LSTAT_PENDING		* I * *
+DB_LSTAT_WAITING		* I * *
+DB_MAX_PAGES			* I * *
+DB_MAX_RECORDS			* I * *
+DB_MEM_LOCK			D I J C
+DB_MEM_LOCKOBJECT		D I J C
+DB_MEM_LOCKER			D I J C
+DB_MEM_LOGID			D I J C
+DB_MEM_TRANSACTION		D I J C
+DB_MEM_THREAD			D I J C
+DB_MPOOL_CREATE			D I * *
+DB_MPOOL_DIRTY			D I * *
+DB_MPOOL_TRY			D I * *
+DB_MPOOL_DISCARD		* I * *
+DB_MPOOL_EDIT			D I * *
+DB_MPOOL_FREE			* I * *
+DB_MPOOL_LAST			D I * *
+DB_MPOOL_NEW			D I * *
+DB_MPOOL_NOFILE			D I J C
+DB_MPOOL_NOLOCK			* I * *
+DB_MPOOL_UNLINK			D I J C
+DB_MULTIPLE			D I J C
+DB_MULTIPLE_INIT		D I * *
+DB_MULTIPLE_KEY			D I J C
+DB_MULTIPLE_KEY_NEXT		D I * *
+DB_MULTIPLE_KEY_RESERVE_NEXT	D I * *
+DB_MULTIPLE_KEY_WRITE_NEXT	D I * *
+DB_MULTIPLE_NEXT		D I * *
+DB_MULTIPLE_RECNO_NEXT		D I * *
+DB_MULTIPLE_RECNO_RESERVE_NEXT	D I * *
+DB_MULTIPLE_RECNO_WRITE_INIT	D I * *
+DB_MULTIPLE_RECNO_WRITE_NEXT 	D I * *
+DB_MULTIPLE_RESERVE_NEXT	D I * *
+DB_MULTIPLE_WRITE_INIT 		D I * *
+DB_MULTIPLE_WRITE_NEXT		D I * *
+DB_MULTIVERSION			D I J C
+DB_MUTEX_ALLOCATED		* I * *
+DB_MUTEX_LOCKED			* I * *
+DB_MUTEX_LOGICAL_LOCK		* I * *
+DB_MUTEX_PROCESS_ONLY		D I * C
+DB_MUTEX_SELF_BLOCK		D I * C
+DB_MUTEX_SHARED			D I * *
+DB_NEEDSPLIT			* I * *
+DB_NEXT				D I J C
+DB_NEXT_DUP			D I J C
+DB_NEXT_NODUP			D I J C
+DB_NODUPDATA			D I J C
+DB_NOERROR			* I * *
+DB_NOFLUSH			* I * *
+DB_NOLOCKING			D I J C
+DB_NOMMAP			D I J C
+DB_NOORDERCHK			D I J C
+DB_NOOVERWRITE			D I J C
+DB_NOPANIC			D I J C
+DB_NOSERVER			D I * C
+DB_NOSYNC			D I J C
+DB_NOTFOUND			D I J C
+DB_NO_AUTO_COMMIT		* I * *
+DB_NO_CHECKPOINT		* I * *
+DB_ODDFILESIZE			D I * *
+DB_OK_BTREE			* I * *
+DB_OK_HASH			* I * *
+DB_OK_HEAP			* I * *
+DB_OK_QUEUE			* I * *
+DB_OK_RECNO			* I * *
+DB_OLD_VERSION			D I * C
+DB_OPFLAGS_MASK			* I * *
+DB_ORDERCHKONLY			D I J C
+DB_OVERWRITE			D I J C
+DB_OVERWRITE_DUP		D I * *
+DB_PAGE_LOCK			* I * *
+DB_PAGE_NOTFOUND		D I * C
+DB_PANIC_ENVIRONMENT		D I J C
+DB_POSITION			D I J C
+DB_PREV				D I J C
+DB_PREV_DUP			D I J C
+DB_PREV_NODUP			D I J C
+DB_PRINTABLE			D I J C
+DB_PRIORITY_DEFAULT		D I J C
+DB_PRIORITY_HIGH		D I J C
+DB_PRIORITY_LOW			D I J C
+DB_PRIORITY_UNCHANGED		D I * *
+DB_PRIORITY_VERY_HIGH		D I J C
+DB_PRIORITY_VERY_LOW		D I J C
+DB_PRIVATE			D I J C
+DB_PR_PAGE			* I * *
+DB_PR_RECOVERYTEST		* I * *
+DB_QAMMAGIC			* I * *
+DB_QAMOLDVER			* I * *
+DB_QAMVERSION			* I * *
+DB_QUEUE			D I J C
+DB_RDONLY			D I J C
+DB_RDWRMASTER			* I * *
+DB_READ_COMMITTED		D I J C
+DB_READ_UNCOMMITTED		D I J C
+DB_RECNO			D I J C
+DB_RECNUM			D I J C
+DB_RECORD_LOCK			* I * *
+DB_RECOVER			D I J C
+DB_RECOVER_FATAL		D I J C
+DB_REDO				* I * *
+DB_REGION_INIT			D I J C
+DB_REGION_MAGIC			* I * *
+DB_REGISTER			D I J C
+DB_RENAMEMAGIC			* I * *
+DB_RENUMBER			D I J C
+DB_REP_CONF_AUTOROLLBACK	* I * *
+DB_REP_WOULDROLLBACK		* I * *
+DB_REPMGR_ACKS_ALL		D I J C
+DB_REPMGR_ACKS_ALL_AVAILABLE	D I J C
+DB_REPMGR_ACKS_ALL_PEERS	D I J C
+DB_REPMGR_ACKS_NONE		D I J C
+DB_REPMGR_ACKS_ONE		D I J C
+DB_REPMGR_ACKS_ONE_PEER		D I J C
+DB_REPMGR_ACKS_QUORUM		D I J C
+DB_REPMGR_CONF_2SITE_STRICT	D I J C
+DB_REPMGR_CONF_ELECTIONS	D I J C
+DB_REPMGR_CONNECTED		D I J C
+DB_REPMGR_DISCONNECTED		D I J C
+DB_REPMGR_NEED_RESPONSE		D I J C
+DB_REPMGR_ISPEER		D I J *
+DB_REPMGR_PEER			D I J C
+DB_REP_ACK_TIMEOUT		D I J C
+DB_REP_ANYWHERE			D I J C
+DB_REP_BULKOVF			* I * *
+DB_REP_CHECKPOINT_DELAY		D I J C
+DB_REP_CLIENT			D I J C
+DB_REP_CONF_AUTOINIT		D I J C
+DB_REP_CONF_BULK		D I J C
+DB_REP_CONF_DELAYCLIENT		D I J C
+DB_REP_CONF_INMEM		D I J C
+DB_REP_CONF_LEASE		D I J C
+DB_REP_CONF_NOWAIT		D I J C
+DB_REP_CONNECTION_RETRY		D I J C
+DB_REP_DEFAULT_PRIORITY		* I J C
+DB_REP_DUPMASTER		D I N C
+DB_REP_ELECTION			D I J C
+DB_REP_ELECTION_RETRY		D I J C
+DB_REP_ELECTION_TIMEOUT		D I J C
+DB_REP_FULL_ELECTION_TIMEOUT	D I J C
+DB_REP_HANDLE_DEAD		D I N C
+DB_REP_HEARTBEAT_MONITOR	D I J C
+DB_REP_HEARTBEAT_SEND		D I J C
+DB_REP_HOLDELECTION		D I N C
+DB_REP_IGNORE			D I J C
+DB_REP_ISPERM			D I J C
+DB_REP_JOIN_FAILURE		D I N C
+DB_REP_LEASE_EXPIRED		D I N C
+DB_REP_LEASE_TIMEOUT		D I J C
+DB_REP_LOCKOUT			D I N C
+DB_REP_LOGREADY			* I * *
+DB_REP_MASTER			D I J C
+DB_REP_NEWMASTER		* I * *
+DB_REP_NEWSITE			D I J C
+DB_REP_NOBUFFER			D I J C
+DB_REP_NOTPERM			D I J C
+DB_REP_PAGEDONE			* I * *
+DB_REP_PERMANENT		D I J C
+DB_REP_REREQUEST		D I J C
+DB_REP_UNAVAIL			D I N C
+DB_REVSPLITOFF			D I J C
+DB_RMW				D I J C
+DB_RUNRECOVERY			D I N C
+DB_SALVAGE			D I J C
+DB_SA_SKIPFIRSTKEY		* I * *
+DB_SA_UNKNOWNKEY		* I * *
+DB_SECONDARY_BAD		D I * C
+DB_SEQUENCE_OLDVER		* I * *
+DB_SEQUENCE_VERSION		* I * *
+DB_SEQ_DEC			D I J C
+DB_SEQ_INC			D I J C
+DB_SEQ_RANGE_SET		* I * *
+DB_SEQ_WRAP			D I J C
+DB_SEQ_WRAPPED			* I * *
+DB_SET				D I J C
+DB_SET_LTE			D I * *
+DB_SET_LOCK_TIMEOUT		D I J C
+DB_SET_RANGE			D I J C
+DB_SET_REG_TIMEOUT		D I * *
+DB_SET_RECNO			D I J C
+DB_SET_TXN_LSNP			* I * *
+DB_SET_TXN_NOW			* I * *
+DB_SET_TXN_TIMEOUT		D I J C
+DB_SHALLOW_DUP			* I * *
+DB_SNAPSHOT			D I J C
+DB_STAT_ALL			D I * C
+DB_STAT_ALLOC			* I * *
+DB_STAT_CLEAR			D I J C
+DB_STAT_LOCK_CONF		D I * C
+DB_STAT_LOCK_LOCKERS		D I * C
+DB_STAT_LOCK_OBJECTS		D I * C
+DB_STAT_LOCK_PARAMS		D I * C
+DB_STAT_MEMP_HASH		D I * C
+DB_STAT_MEMP_NOERROR		* I * *
+DB_STAT_SUBSYSTEM		D I * C
+DB_STAT_SUMMARY			* I * *
+DB_ST_DUPOK			* I * *
+DB_ST_DUPSET			* I * *
+DB_ST_DUPSORT			* I * *
+DB_ST_IS_RECNO			* I * *
+DB_ST_OVFL_LEAF			* I * *
+DB_ST_RECNUM			* I * *
+DB_ST_RELEN			* I * *
+DB_ST_TOPLEVEL			* I * *
+DB_SURPRISE_KID			* I * *
+DB_SWAPBYTES			* I * *
+DB_SYSTEM_MEM			D I J C
+DB_THREAD			D I J C
+DB_THREADID_STRLEN		D I * *
+DB_TIMEOUT			D I J C
+DB_TIME_NOTGRANTED		D I J C
+DB_TRUNCATE			D I J C
+DB_TXNVERSION			* I * *
+DB_TXN_ABORT			D I J C
+DB_TXN_APPLY			D I J C
+DB_TXN_BACKWARD_ROLL		D I J C
+DB_TXN_BULK			D I J C
+DB_TXN_CKP			* I * *
+DB_TXN_FAMILY			* I * *
+DB_TXN_FORWARD_ROLL		D I J C
+DB_TXN_LOG_VERIFY		D I * *
+DB_TXN_NOSYNC			D I J C
+DB_TXN_NOT_DURABLE		D I J C
+DB_TXN_NOWAIT			D I J C
+DB_TXN_OPENFILES		* I * *
+DB_TXN_POPENFILES		* I * *
+DB_TXN_PRINT			D I J C
+DB_TXN_SNAPSHOT			D I J C
+DB_TXN_SYNC			D I J C
+DB_TXN_TOKEN_SIZE		* I J C
+DB_TXN_WAIT			D I J C
+DB_TXN_WRITE_NOSYNC		D I J C
+DB_UNDO				* I * *
+DB_UNKNOWN			D I J C
+DB_UNREF			* I * *
+DB_UPDATE_SECONDARY		* I * *
+DB_UPGRADE			D I J C
+DB_USE_ENVIRON			D I J C
+DB_USE_ENVIRON_ROOT		D I J C
+DB_VERB_BACKUP			D I J C
+DB_VERB_DEADLOCK		D I J C
+DB_VERB_FILEOPS			D I J C
+DB_VERB_FILEOPS_ALL		D I J C
+DB_VERB_RECOVERY		D I J C
+DB_VERB_REGISTER		D I J C
+DB_VERB_REPLICATION		D I J C
+DB_VERB_REPMGR_CONNFAIL		D I J C
+DB_VERB_REPMGR_MISC		D I J C
+DB_VERB_REP_ELECT		D I J C
+DB_VERB_REP_LEASE		D I J C
+DB_VERB_REP_MISC		D I J C
+DB_VERB_REP_MSGS		D I J C
+DB_VERB_REP_SYNC		D I J C
+DB_VERB_REP_SYSTEM		D I J C
+DB_VERB_REP_TEST		D I J C
+DB_VERB_WAITSFOR		D I J C
+DB_VERIFY			D I J C
+DB_VERIFY_BAD			D I N C
+DB_VERIFY_FATAL			* I * *
+DB_VERIFY_PARTITION		D I * *
+DB_VERSION_FAMILY		* I N C
+DB_VERSION_RELEASE		* I N C
+DB_VERSION_MAJOR		* I J C
+DB_VERSION_MINOR		* I J C
+DB_VERSION_MISMATCH		D I N C
+DB_VERSION_PATCH		* I J C
+DB_VERSION_STRING		* I N C
+DB_VERSION_FULL_STRING		* I N C
+DB_WRITECURSOR			D I J C
+DB_WRITELOCK			* I * *
+DB_WRITEOPEN			* I * *
+DB_XA_CREATE			D I * *
+DB_YIELDCPU			D I J C
+DB2_AM_EXCL			* I * *
+DB2_AM_INTEXCL			* I * *
+DB2_AM_NOWAIT			* I * *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_all	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,67 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+
+LC_ALL=C
+export LC_ALL
+
+sh s_readme		# distribution README file.
+
+sh s_config		# autoconf.
+sh s_apiflags		# API flags.
+sh s_sig		# Structure signature.
+sh s_recover		# logging/recovery files.
+sh s_message		# replication and repmgr message files.
+sh s_message_id		# generate message id.
+sh s_sql		# regenerate sqlite3.c
+sh s_php                # PHP config files
+
+#############################################################
+# The following order is important, s_include must run after
+# the other source files have been created.
+#############################################################
+sh s_include		# standard include files.
+
+sh s_java		# Java support.
+sh s_csharp		# Csharp support.
+sh s_test		# Test suite support.
+#sh s_tags		# Tags files.
+
+#############################################################
+# We only build the Cscope file for releases, it's too big to
+# commit into the CVS tree.
+#############################################################
+#sh s_cscope		# Cscope files.
+
+#############################################################
+# Create the build environments last, they use files created
+# by previous steps.
+#############################################################
+sh s_vxworks		# VxWorks support.
+sh s_windows		# Windows support.
+sh s_windows_dsp	# Windows support: build environment.
+sh s_android            # Android support: drop-in build environment.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_apiflags	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,77 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Build the automatically generated API flag #defines.
+
+msgc=`cat << EOMSG
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+EOMSG`
+
+b=/tmp/api_flags_binary
+t=/tmp/__db_a
+
+trap 'rm -f $b $t; exit 0' 0
+trap 'rm -f $b $t; exit 1' 1 2 3 13 15
+
+cc api_flags.c -o $b || {
+	echo 's_apiflags: unable to compile api_flags.c'
+	exit 1
+}
+
+(echo "$msgc"
+ $b < api_flags) > $t
+
+f=../src/dbinc_auto/api_flags.in
+cmp $f $t > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_config	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,62 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Build the autoconfiguration files.
+
+trap 'rm -f aclocal.m4 ; exit 0' 0 1 2 3 13 15
+
+. ./RELEASE
+
+echo "autoconf: building aclocal.m4..."
+cat aclocal/*.m4 aclocal_java/*.m4 > aclocal.m4
+
+echo "autoconf: running autoheader to build config.hin..."
+rm -f config.hin
+autoheader
+chmod 644 config.hin
+
+echo "autoconf: running autoconf to build configure"
+rm -f configure
+autoconf
+
+# Edit version information we couldn't pre-compute.
+sed -e "s/__EDIT_DB_VERSION_FAMILY__/$DB_VERSION_FAMILY/g" \
+    -e "s/__EDIT_DB_VERSION_RELEASE__/$DB_VERSION_RELEASE/g" \
+    -e "s/__EDIT_DB_VERSION_MAJOR__/$DB_VERSION_MAJOR/g" \
+    -e "s/__EDIT_DB_VERSION_MINOR__/$DB_VERSION_MINOR/g" \
+    -e "s/__EDIT_DB_VERSION_PATCH__/$DB_VERSION_PATCH/g" \
+    -e "s/__EDIT_DB_VERSION_STRING__/$DB_VERSION_STRING/g" \
+    -e "s/__EDIT_DB_VERSION_FULL_STRING__/$DB_VERSION_FULL_STRING/g" \
+    -e "s/__EDIT_DB_VERSION_UNIQUE_NAME__/$DB_VERSION_UNIQUE_NAME/g" \
+    -e "s/__EDIT_DB_VERSION__/$DB_VERSION/g" configure > configure.version
+mv configure.version configure
+
+rm -rf autom4te.cache
+chmod 755 configure
+
+chmod 755 config.guess config.sub install-sh
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_docs	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,144 @@
+#! /bin/sh
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Build the documentation from a docs_books repository.
+#
+# Optional input is a release tag number to be built.
+
+distdir=`pwd`
+if [ `basename $distdir` != "dist" ]; then
+	echo "The s_docs script must be run from the dist dir."
+	exit 1
+fi
+
+tag=$1
+docs_dir=$2
+
+rootdir=`(cd $distdir/../.. ; pwd)`
+
+# Create temporary space.
+tmp_dir=$distdir/s_docs.tmp
+
+rm -rf $tmp_dir && mkdir $tmp_dir && mkdir $tmp_dir/logs
+
+if [ "$docs_dir" = "" ]; then
+	docs_dir=$rootdir/docs_books
+fi
+
+# Verify that the docs_books repository is where we expect it.
+if [ ! -d "$docs_dir" ]; then
+	echo "Script requires a doc repository at: $docs_dir"
+	exit 1
+fi
+
+# If a release tag is specified, ensure the docs_books is up to date.
+if [ "$tag" != "" ]; then
+	cd $docs_dir
+	hg up -r $tag > /dev/null
+	if [ $? != 0 ]; then
+		echo "Failed to update docs_books repo to requested tag." >&2
+		exit 1
+	fi
+	cd $distdir
+else
+	echo "No release tag specified, assuming docs_books repo already in required state."
+fi
+
+# Set up env variables.
+system=`uname | grep -i cygwin`
+if [ "$system"x != x ]; then
+	DOCS_REPOSITORY=`cygpath -m $docs_dir`; export DOCS_REPOSITORY
+	DOCS_OUTPUT_DIR=`cygpath -m $tmp_dir`; export DOCS_OUTPUT_DIR
+	DOCS_TARGET_REPOSITORY=`cygpath -m $distdir/../docs`; export DOCS_TARGET_REPOSITORY
+else
+	DOCS_REPOSITORY=$docs_dir; export DOCS_REPOSITORY
+	DOCS_OUTPUT_DIR=$tmp_dir; export DOCS_OUTPUT_DIR
+	DOCS_TARGET_REPOSITORY=$distdir/../docs; export DOCS_TARGET_REPOSITORY
+fi
+
+if [ "$DOCS_PDF_BUILDER" = "" ]; then
+	fop_cmd=`which fop`
+	if [ "$fop_cmd" = "" ]; then
+		echo "Could not find a FOP install. Add it to your path, or 
+set DOCS_PDF_BUILDER environment directory. The FOP install package can be
+found at s.o.c:/b/htdocs/documentation/sleepycat-fop095.zip"
+		exit 1;
+	fi
+	DOCS_PDF_BUILDER=$fop_cmd; export DOCS_PDF_BUILDER
+	echo "Found a fop command in the path. Using it's base dir as the FOP install."
+fi
+if [ "$DOCS_PARSER" = "" ]; then
+	xslt_cmd=`which xsltproc`
+	if [ "$xslt_cmd" = "" ]; then
+		echo "No xsltproc found. Install libxml2."
+		exit 1
+	fi
+	DOCS_PARSER=$xslt_cmd; export DOCS_PARSER
+fi
+
+###################################################################
+
+(`cd $distdir/../docs ; mkdir -p installation ; mkdir -p bdb-sql`)
+
+cd $docs_dir/tools/misc_doc_scripts
+
+./make_db_landing_page.py
+./make_db_changelog.py
+
+cd $docs_dir/tools/buildBooks
+
+for book in DB_PROG_REF DB_REF_C DB_REF_CXX DB_REF_STL DB_REF_TCL \
+	    DB_GSG_C DB_GSG_CXX DB_GSG_JAVA DB_REP_C DB_REP_CXX \
+	    DB_REP_JAVA DB_COLLECTIONS DB_TXN_C DB_TXN_CXX DB_TXN_JAVA \
+	    DB_PORT DB_INSTALL DB_UPGRADE DB_SQL DB_SQL_ADO \
+	    core_inmem_app core_mssgtxt; do
+
+	    case $book in
+	    DB_PROG_REF)
+	    	HTML_OPTS="-x"
+		PDF_OPTS=
+		;;
+	    core_*)
+	    	HTML_OPTS="-a"
+		PDF_OPTS="-a"
+		;;
+	    *)
+	    	HTML_OPTS=
+		PDF_OPTS=
+		;;
+	    esac
+
+	    DOCS_ERROR_FILE=$tmp_dir/${book}_err_htm.txt; export DOCS_ERROR_FILE
+	    ./buildBooks.py $HTML_OPTS -t $book -h
+	    DOCS_ERROR_FILE=$tmp_dir/${book}_err_pdf.txt; export DOCS_ERROR_FILE
+	    ./buildBooks.py $PDF_OPTS -t $book -p
+done
+
+# Cleanup after ourselves
+rm -rf $tmp_dir
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_include	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,228 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Build the automatically generated function prototype files.
+
+msgc=`cat << EOMSG
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+EOMSG`
+
+. ./RELEASE
+
+AWK=${AWK:-awk}
+head()
+{
+	defonly=0
+	while :
+		do case "$1" in
+		space)
+			echo ""; shift;;
+		defonly)
+			defonly=1; shift;;
+		*)
+			name="$1"; break;;
+		esac
+	done
+
+	echo "$msgc"
+	echo "#ifndef	$name"
+	echo "#define	$name"
+	echo ""
+	if [ $defonly -eq 0 ]; then
+		echo "#if defined(__cplusplus)"
+		echo "extern \"C\" {"
+		echo "#endif"
+		echo ""
+	fi
+}
+
+tail()
+{
+	defonly=0
+	while :
+		do case "$1" in
+		defonly)
+			defonly=1; shift;;
+		*)
+			name="$1"; break;;
+		esac
+	done
+
+	echo ""
+	if [ $defonly -eq 0 ]; then
+		echo "#if defined(__cplusplus)"
+		echo "}"
+		echo "#endif"
+	fi
+	echo "#endif /* !$name */"
+}
+
+# This script is run on a variety of systems.  To avoid spurious changes, fix
+# some variables that affect sort order of ls(1).
+unset LANG
+export LANG
+LC_ALL="C"
+export LC_ALL
+
+# We are building several files:
+#	1 external #define file
+#	1 external prototype file
+#	1 internal #define file
+#	N internal prototype files
+e_dfile=/tmp/__db_c.$$
+e_pfile=/tmp/__db_a.$$
+i_dfile=/tmp/__db_d.$$
+i_pfile=/tmp/__db_b.$$
+trap 'rm -f $e_dfile $e_pfile $i_dfile $i_pfile; exit 0' 0 1 2 3 13 15
+
+head defonly space _DB_EXT_DEF_IN_ > $e_dfile
+head space _DB_EXT_PROT_IN_ > $e_pfile
+head defonly _DB_INT_DEF_IN_ > $i_dfile
+
+# Process the standard directories, creating per-directory prototype
+# files and adding to the external prototype and #define files.
+for i in db btree clib common crypto dbreg env fileops hash heap \
+    hmac lock log mp mutex os qam rep repmgr sequence tcl txn xa; do
+	head "_${i}_ext_h_" > $i_pfile
+
+	if [ $i = os ] ; then
+		f=`ls ../src/$i/*.c \
+	    ../src/os_qnx/*.c ../src/os_vxworks/*.c ../src/os_windows/*.c`
+	elif [ $i = crypto ] ; then
+		f=`ls ../src/$i/*.c ../src/$i/*/*.c`
+	elif [ $i = env ] ; then
+		f=`ls ../src/$i/*.c ../src/repmgr/repmgr_stub.c`
+	elif [ $i = tcl ] ; then
+		f=`ls ../lang/$i/*.c`
+	else
+		f=`ls ../src/$i/*.c`
+	fi
+	$AWK -f gen_inc.awk \
+	    -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \
+	    -v e_dfile=$e_dfile \
+	    -v e_pfile=$e_pfile \
+	    -v i_dfile=$i_dfile \
+	    -v i_pfile=$i_pfile $f
+
+	tail "_${i}_ext_h_" >> $i_pfile
+
+	f=../src/dbinc_auto/${i}_ext.h
+	cmp $i_pfile $f > /dev/null 2>&1 ||
+	    (echo "Building $f" && rm -f $f && cp $i_pfile $f)
+done
+
+# Process directories which only add to the external prototype and #define
+# files.
+for i in dbm hsearch; do
+	f=`ls ../lang/$i/*.c`
+	$AWK -f gen_inc.awk \
+	    -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \
+	    -v e_dfile=$e_dfile \
+	    -v e_pfile=$e_pfile \
+	    -v i_dfile="" \
+	    -v i_pfile="" $f
+done
+
+# There are a few global variables in DB -- add them to the external/internal
+# #define files.
+(echo "#define	__db_global_values __db_global_values@DB_VERSION_UNIQUE_NAME@";
+ echo "#define	__repmgr_guesstimated_max __repmgr_guesstimated_max@DB_VERSION_UNIQUE_NAME@";
+ echo "#define	db_xa_switch db_xa_switch@DB_VERSION_UNIQUE_NAME@"
+ ) >> $i_dfile
+
+# Wrap up the external #defines/prototypes, and internal #defines.
+tail defonly _DB_EXT_DEF_IN_ >> $e_dfile
+f=../src/dbinc_auto/ext_def.in
+cmp $e_dfile $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $e_dfile $f)
+
+tail _DB_EXT_PROT_IN_ >> $e_pfile
+f=../src/dbinc_auto/ext_prot.in
+cmp $e_pfile $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $e_pfile $f)
+
+tail defonly _DB_INT_DEF_IN_ >> $i_dfile
+f=../src/dbinc_auto/int_def.in
+cmp $i_dfile $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $i_dfile $f)
+
+# DB185 compatibility support.
+head space defonly _DB_EXT_185_DEF_IN_ > $e_dfile
+head space _DB_EXT_185_PROT_IN_ > $e_pfile
+
+f=`ls ../lang/db185/*.c`
+$AWK -f gen_inc.awk \
+    -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \
+    -v e_dfile=$e_dfile \
+    -v e_pfile=$e_pfile \
+    -v i_dfile="" \
+    -v i_pfile="" $f
+
+tail defonly _DB_EXT_185_DEF_IN_ >> $e_dfile
+f=../src/dbinc_auto/ext_185_def.in
+cmp $e_dfile $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $e_dfile $f)
+
+tail _DB_EXT_185_PROT_IN_ >> $e_pfile
+f=../src/dbinc_auto/ext_185_prot.in
+cmp $e_pfile $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $e_pfile $f)
+
+# Make the DTrace provider description file from events.in
+rm -f db_provider.d
+(echo "/*"; \
+ echo " * DO NOT EDIT: automatically built by dist/s_include."; \
+ echo " * Oracle Berkeley DB DTrace Provider"; \
+ echo " */"; \
+perl gen_provider.pl events.in)  > db_provider.d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_message	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,56 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Build the automatically generated rep & repmgr message files.
+
+header=/tmp/__db_a
+source=/tmp/__db_b
+
+trap 'rm -f /tmp/__db_[ab]; exit 1' 1 2 3 13 15
+trap 'rm -f /tmp/__db_[ab]; exit 0' 0
+
+DIR="rep repmgr"
+
+# Build DB's message marshaling/unmarshaling routines.
+for i in $DIR; do
+	for f in ../src/$i/*.msg; do
+		subsystem=`basename $f .msg`
+		awk -f gen_msg.awk \
+		    -v header_file=$header \
+		    -v source_file=$source < $f
+
+		f=../src/dbinc_auto/${subsystem}_automsg.h
+		cmp $header $f > /dev/null 2>&1 ||
+		    (echo "Building $f" &&
+		    rm -f $f && cp $header $f)
+		f=../src/$i/${subsystem}_automsg.c
+		cmp $source $f > /dev/null 2>&1 ||
+		    (echo "Building $f" &&
+		    rm -f $f && cp $source $f)
+	done
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_message_id	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,212 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Automatically generate message id.
+
+# Usage: A BDB#### would be replaced with an unused message id in:
+# 1) DB_STR(BDB####
+# 2) DB_STR_A(BDB####
+# NOTE: Do not add whitespace between DB_STR( or DB_STR_A( and the message ID.
+
+# NOTE: Please update the MSG_DIRS if there is any new source dir.
+MSG_DIRS="../src/ ../util/ ../lang/dbm/ ../dist/gen_msg.awk"
+
+# Environment Configuration
+GREP_CMDS="grep ggrep"
+for i in $GREP_CMDS; do
+	if [ "`which $i`" = "" ]; then
+		continue
+	fi
+	echo "s_message_id test" > s_message_id.tmp
+	$i "s_message_id test"  s_message_id.tmp -o --include=*.tmp | \
+	    $i -v "s_message_id.txt" > s_message_id.tmp.out 2>&1
+	if [ `$i "unrecognized option" s_message_id.tmp.out | wc -l` \
+	    -eq 0 ] && [ `$i "invalid option" s_message_id.tmp.out | \
+	    wc -l` -eq 0 ] && [ `$i "can't open" s_message_id.tmp.out | \
+	    wc -l` -eq 0 ]; then
+		GREP_CMD=$i
+		break
+	fi
+done
+rm -f s_message_id.tmp s_message_id.tmp.out
+if [ "$GREP_CMD" = "" ]; then
+	echo "UNSUPPORTED COMMAND: (g)grep -o --include"
+	echo "Please try other platform"
+	exit 
+fi
+
+pref=MSG_INDX
+
+get_value() {
+	value=${1}${2}
+	eval "echo $`echo $value`"
+}
+
+get_max() {
+	if [ ${1} -gt ${2} ] ; then
+		eval "echo ${1}"
+	else
+		eval "echo ${2}"
+	fi
+}
+
+# Iterate source files and replace "BDB####" with the real message id.
+for i in $MSG_DIRS; do
+	for f in `$GREP_CMD BDB#### -r $i -wl --include=*.c --include=*.h \
+ 	    --include=*.in --include=*.awk | \
+	    $GREP_CMD -v "../util/db_dump185.c" | \
+	    $GREP_CMD -v "../util/db_sql_codegen"`; do
+		IFS='/'
+		set $f
+		# There are 11 categories in the MSG_DIRS:
+		# 1) COMMON; 2) DB; 3) AM; 4) ENV; 5) LOCK; 6) LOG;
+		# 7) MPOOL; 8) REP; 9) SEQUENCE; 10) TXN; 11) UTIL.
+		#
+		# NOTE: Please add a new block (see below) and assign the values
+		# of cat_indx and cat_dirs if there is new group, or update the
+		# existing block if there is new source tree under the existing
+		# group.
+		if [ "$i" = "../util/" ] || [ "$i" = "../lang/dbm/" ]; then
+			cat_indx=10
+			cat_dirs="../util/ ../lang/dbm/"
+		elif [ "$3" = "common" ] || [ "$3" = "crypto" ] || \
+		    [ "$3" = "fileops" ] || [ "$3" = "hmac" ] || \
+		    [ "$3" = "os" ] || [ "$3" = "os_qnx" ] || \
+		    [ "$3" = "os_vxworks" ] || [ "$3" = "os_windows" ]; then 
+			cat_indx=0
+			cat_dirs=$i"common "$i"crypto "$i"fileops "
+			cat_dirs=$cat_dirs$i"hmac "$i"os "$i"os_qnx "
+			cat_dirs=$cat_dirs$i"os_vxworks "$i"os_windows"
+		elif [ "$3" = "db" ] || [ "$3" = "dbinc" ] || \
+		    [ "$3" = "dbinc_auto" ]; then
+			cat_indx=1
+			cat_dirs=$i"db "$i"dbinc "$i"dbinc_auto"
+		elif [ "$3" = "btree" ] || [ "$3" = "hash" ] || \
+		    [ "$3" = "heap" ] || [ "$3" = "qam" ]; then
+			cat_indx=2
+			cat_dirs=$i"btree "$i"hash "$i"heap "$i"qam"
+		elif [ "$3" = "dbreg" ] || [ "$3" = "env" ] ; then
+			cat_indx=3
+			cat_dirs=$i"dbreg "$i"env"
+		elif [ "$3" = "lock" ] || [ "$3" = "mutex" ]; then
+			cat_indx=4
+			cat_dirs=$i"lock "$i"mutex"
+		elif [ "$3" = "log" ]; then
+			cat_indx=5
+			cat_dirs=$i"log"
+		elif [ "$3" = "mp" ]; then
+			cat_indx=6
+			cat_dirs=$i"mp"
+		elif [ "$3" = "rep" ] || [ "$3" = "repmgr" ] || \
+			[ "$3" = "gen_msg.awk" ] ; then
+			cat_indx=7
+			cat_dirs="../src/rep ../src/repmgr ../dist/gen_msg.awk"
+		elif [ "$3" = "sequence" ]; then
+			cat_indx=8
+			cat_dirs=$i"sequence"
+		elif [ "$3" = "txn" ] || [ "$3" = "xa" ]; then
+			cat_indx=9
+			cat_dirs=$i"txn "$i"xa"
+		else
+			echo "ERROR UNKNOWN PATH:" "$i""$3"
+			exit
+		fi
+
+		unset IFS
+
+		# Initialize MSG_INDX for each group if it is never initialized.
+		if [ "`get_value $pref $cat_indx`" = "" ]; then
+			# Get the start index, that is the next available number
+			# for the current group. If there is no existing message
+			# marked by DB_STR or DB_STR_A, the start index is the
+			# first available integer in its range. Unless, it is
+			# the next available integer in its range.
+			MSG_START_NUM=`expr $cat_indx \* 500 + 1`
+			DB_STR_NUM=`$GREP_CMD -E "DB_STR\(\"[0-9]{4}\"" -r \
+			    $cat_dirs | wc -l`
+			if [ $DB_STR_NUM -eq 0 ]; then
+				DB_STR_NUM=`expr 0 + $MSG_START_NUM`
+			else
+				DB_STR_NUM=`$GREP_CMD -E "DB_STR\(\"[0-9]{4}\"" -oh \
+				    -r $cat_dirs | sort | tail -n 1 | \
+				    sed -e "s/DB_STR(//g" | sed -e "s/\"//g"`
+				DB_STR_NUM=`expr 1 + $DB_STR_NUM`
+			fi
+
+			DB_STR_A_NUM=`$GREP_CMD -E "DB_STR_A\(\"[0-9]{4}\"" -r \
+			    $cat_dirs | wc -l`
+			if [ $DB_STR_A_NUM -eq 0 ]; then
+				DB_STR_A_NUM=`expr 0 + $MSG_START_NUM`
+			else
+				DB_STR_A_NUM=`$GREP_CMD -E \
+				    "DB_STR_A\(\"[0-9]{4}\"" -oh -r $cat_dirs | \
+				    sort | tail -n 1 | \
+				    sed -e "s/DB_STR_A(//g" | sed -e "s/\"//g"`
+				DB_STR_A_NUM=`expr 1 + $DB_STR_A_NUM`
+			fi
+
+			MSG_START_INDX=`get_max $DB_STR_NUM $DB_STR_A_NUM`
+			eval "$pref$cat_indx=$MSG_START_INDX"
+		fi
+
+		cat $f | awk '{
+			if(num<max && sub(/BDB####/, fill(num))==1) num++;
+			print $0>"tmp.tmp"
+		}END{
+			printf("%s", num)>"tmp.num"} 
+			function fill(i) {
+				s=""
+				j=4-length(i)
+				while(j) {
+				s=0""s
+				j--
+			}
+			return "\""s""i"\""
+		}' num=`get_value $pref $cat_indx` \
+		max=`expr \( $cat_indx + 1 \) \* 500`
+		cp tmp.tmp $f
+		eval "$pref$cat_indx=`sed 'q' tmp.num`"
+		if [ "$cat_indx" -lt 11 ]; then
+			if [ `get_value $pref $cat_indx` -ge \
+			    `expr \( $cat_indx + 1 \) \* 500` ]; then
+				echo "RANGE FULL"
+			fi
+		else
+			echo "ERROR CATEGORY NUMBER: " $cat_indx
+		fi
+		rm tmp.tmp tmp.num
+	done
+done
+
+# Check if there is any remaining "BDB####". 
+# NOTE: If "BDB####" is not .c, .h, .in files, they won't be updated with the 
+# real message id.
+if [ `$GREP_CMD "BDB####" -r $MSG_DIRS | wc -l` -gt 0 ]; then
+	echo "WARNING: There is remaining BDB####. Please check:"
+	$GREP_CMD "BDB####" -r $MSG_DIRS
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_perm	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,74 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# This script is designed to be run while packaging up releases, not during
+# other s_all processing.
+
+d=..
+echo 'Updating Berkeley DB source tree permissions for a release package'
+
+run()
+{
+	if [ -f "$d/$1" ]; then
+		chmod "$2" "$d/$1"
+	else
+		echo "$d/$1: no such file or directory"
+		exit 1
+	fi
+}
+
+# Ensure all files in the package have consistent permissions.
+find $d -type d | xargs chmod 775
+find $d -type f | xargs chmod 644
+
+# Assign execute permissions where necessary.
+# ODBC and JDBC are only present in release packages.
+if [ -d $d/lang/sql/odbc ]; then
+	chmod 755 $d/lang/sql/odbc/conf*
+fi
+if [ -d $d/lang/sql/jdbc ]; then
+	chmod 755 $d/lang/sql/jdbc/conf*
+fi
+chmod 755 $d/dist/s_*
+
+run dist/config.guess 755
+run dist/config.sub 755
+run dist/configure 755
+run dist/install-sh 755
+run dist/vx_buildcd 755
+run lang/perl/BerkeleyDB/dbinfo 755
+run lang/perl/BerkeleyDB/mkpod 755
+run lang/sql/sqlite/configure 755
+
+for i in `cd $d && find build_vxworks \
+    -name '*.wsp' -o -name '*.cdf' -o -name '*.wpj'`; do
+	chmod 775 $d/$i
+done
+
+chmod 555 $d/util/dtrace/*.d
+chmod 555 $d/util/systemtap/*.stp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_readme	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,50 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Build the README.
+
+echo 'Updating Berkeley DB README file...'
+
+d=..
+
+t=/tmp/__t
+trap 'rm -f $t; exit 0' 0 1 2 3 13 15
+
+. ./RELEASE
+
+cat << END_OF_README>$t
+$DB_VERSION_FULL_STRING
+
+This is Berkeley DB $DB_VERSION_FAMILY$DB_VERSION_LETTER Release $DB_VERSION_RELEASE from Oracle.  To view release and
+installation documentation, load the distribution file docs/index.html
+into your web browser.
+END_OF_README
+
+f=../README
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_sig	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,168 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Build structure signature code.
+
+a=/tmp/__db_a.$$
+b=/tmp/__db_b.$$
+c=/tmp/__db_c.$$
+trap 'rm -f $a $b $c; exit 0' 0 1 2 3 13 15
+
+cat ../src/dbinc/db.in ../src/dbinc/db_int.in ../src/dbinc/*.h | 
+sed -e '/.*struct.*mutex.*{[	 ]*\/\* SHARED \*\/.*/i\
+#ifdef	HAVE_MUTEX_SUPPORT' \
+    -e '/.*struct.*mutex.*{[	 ]*\/\* SHARED \*\/.*/a\
+#endif' \
+    -e 's/.*[	 ]*\(__[a-z_]*\)[	 ]*{[	 ]*\/\* SHARED \*\/.*/	__ADD(\1);/p' \
+    -e d > $a
+
+cat ../src/dbinc/db.in ../src/dbinc/db_int.in ../src/dbinc/*.h | 
+sed -e '/__addrinfo/d' \
+    -e '/__aes_cipher/d' \
+    -e '/__cipher/d' \
+    -e '/__channel/d' \
+    -e '/__queued_output/d' \
+    -e '/__repmgr_connection/d' \
+    -e '/__repmgr_message/d' \
+    -e '/__repmgr_response/d' \
+    -e '/__repmgr_retry/d' \
+    -e '/__repmgr_runnable/d' \
+    -e '/__repmgr_site/d' \
+    -e '/.*[	 ]*\(__[a-z_]*\)[	 ]*{[	 ]*\/\* SHARED \*\/.*/d' \
+    -e '/struct.*mutex.*{/i\
+#ifdef	HAVE_MUTEX_SUPPORT' \
+    -e '/struct.*mutex.*{/a\
+#endif' \
+    -e 's/.*[	 ]*struct[	 ]*\(__[a-z_]*\)[	 ]*{.*/	__ADD(\1);/p' \
+    -e d > $c
+
+cnt1=`sed -e '$=' -e d $a`
+cnt2=`sed -e '$=' -e d $c`
+
+cat << END_OF_TEXT > $b
+/*-
+ * DO NOT EDIT: automatically built by dist/s_sig.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * \$Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/crypto.h"
+#include "dbinc/db_join.h"
+#include "dbinc/db_verify.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/lock.h"
+#include "dbinc/log_verify.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+#include "dbinc/qam.h"
+#include "dbinc/txn.h"
+
+END_OF_TEXT
+cat << END_OF_TEXT >> $b
+/* 
+ * For a pure 32bit/64bit environment, we check all structures and calculate a
+ * signature. For compatible environment, we only check the structures in
+ * shared memory.
+ */
+END_OF_TEXT
+echo "#ifdef HAVE_MIXED_SIZE_ADDRESSING" >> $b
+echo "#define	__STRUCTURE_COUNT	$cnt1" >> $b
+echo "#else" >> $b
+echo "#define	__STRUCTURE_COUNT	($cnt1 + $cnt2)" >> $b
+echo "#endif" >> $b
+
+cat << END_OF_TEXT >> $b
+
+/*
+ * __env_struct_sig --
+ *	Compute signature of structures.
+ *
+ * PUBLIC: u_int32_t __env_struct_sig __P((void));
+ */
+u_int32_t
+__env_struct_sig()
+{
+	u_short t[__STRUCTURE_COUNT + 5];
+	u_int i;
+
+	i = 0;
+#define	__ADD(s)	(t[i++] = sizeof(struct s))
+
+END_OF_TEXT
+
+cat $a >> $b
+
+cat << END_OF_TEXT >> $b
+
+#ifndef HAVE_MIXED_SIZE_ADDRESSING
+END_OF_TEXT
+
+cat $c >> $b
+
+echo "#endif" >> $b
+
+cat << END_OF_TEXT >> $b
+
+	return (__ham_func5(NULL, t, i * sizeof(t[0])));
+}
+END_OF_TEXT
+
+f=../src/env/env_sig.c
+cmp $b $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $b $f)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_tags	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,90 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Build tags files.
+
+cd tagdir
+files=`echo ../../src/dbinc/*.h \
+	../../src/dbinc/*.in \
+	../../src/btree/*.[ch] \
+	../../src/clib/*.[ch] \
+	../../src/common/*.[ch] \
+	../../src/crypto/*.[ch] \
+	../../src/crypto/mersenne/*.[ch] \
+	../../src/crypto/rijndael/*.[ch] \
+	../../src/db/*.[ch] \
+	../../lang/db185/*.[ch] \
+	../../lang/dbm/*.[ch] \
+	../../src/dbreg/*.[ch] \
+	../../src/env/*.[ch] \
+	../../src/fileops/*.[ch] \
+	../../src/hash/*.[ch] \
+	../../src/heap/*.[ch] \
+	../../src/hmac/*.[ch] \
+	../../src/hsearch/*.[ch] \
+	../../src/lock/*.[ch] \
+	../../src/log/*.[ch] \
+	../../src/mp/*.[ch] \
+	../../src/mutex/*.[ch] \
+	../../src/os/*.[ch] \
+	../../src/os_qnx/*.[ch] \
+	../../src/qam/*.[ch] \
+	../../src/rep/*.[ch] \
+	../../src/repmgr/*.[ch] \
+	../../src/sequence/*.[ch] \
+	../../lang/tcl/*.[ch] \
+	../../src/txn/*.[ch] \
+	../../src/xa/*.[ch] \
+	../../lang/cxx/*.cpp \
+	../../lang/java/libdb_java/*.[ch] | sed 's/[^ ]*stub.c//g'`
+
+f=tags
+echo "Building $f"
+rm -f $f
+
+# Figure out what flags this ctags accepts.
+flags=""
+if ctags -d ../../src/db/db.c 2>/dev/null; then
+	flags="-d $flags"
+fi
+if ctags -t ../../src/db/db.c 2>/dev/null; then
+	flags="-t $flags"
+fi
+if ctags -w ../../src/db/db.c 2>/dev/null; then
+	flags="-w $flags"
+fi
+
+ctags $flags $files 2>/dev/null
+
+for i in test/perf testrrepmgr testrserver; do
+	test -d ../../$i || continue
+
+	f=../../$i/tags
+	echo "Building $f"
+	(cd ../../$i && ctags $flags *.[ch] 2>/dev/null)
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_test	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,136 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Build the Tcl test files.
+
+msg1="# Automatically built by dist/s_test; may require local editing."
+msg2="# Automatically built by dist/s_test; may require local editing."
+
+t=/tmp/__t
+trap 'rm -f $t; exit 0' 0 1 2 3 13 15
+
+. ./RELEASE
+
+(echo "$msg1"					&& \
+ echo ""					&& \
+ echo "set tclsh_path @TCL_TCLSH@"		&& \
+ echo "set tcllib .libs/libdb_tcl-@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@@LIBTSO_MODSUFFIX@" && \
+ echo ""					&& \
+ echo "set src_root @srcdir@/.."		&& \
+ echo "set test_path @srcdir@/../test/tcl"	&& \
+ echo "set je_root @srcdir@/../../je"		&& \
+ echo "set tcl_utils @srcdir@/../test/tcl_utils"	&& \
+ echo ""					&& \
+ echo "global testdir"				&& \
+ echo "set testdir ./TESTDIR"			&& \
+ echo ""					&& \
+ echo "global dict"				&& \
+ echo "global util_path"			&& \
+ echo ""					&& \
+ echo "global is_freebsd_test"			&& \
+ echo "global is_hp_test"			&& \
+ echo "global is_linux_test"			&& \
+ echo "global is_osx_test"			&& \
+ echo "global is_qnx_test"			&& \
+ echo "global is_sunos_test"			&& \
+ echo "global is_windows_test"			&& \
+ echo "global is_windows9x_test"		&& \
+ echo ""					&& \
+ echo "global valid_methods"			&& \
+ echo "global checking_valid_methods"		&& \
+ echo "global test_recopts"			&& \
+ echo ""					&& \
+ echo "set KILL \"@KILL@\"") > $t
+
+f=../test/tcl/include.tcl
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+
+(echo "$msg1"					&& \
+ echo ""					&& \
+ echo "set tclsh_path SET_YOUR_TCLSH_PATH"	&& \
+ echo "set buildpath Win32/Debug"	&& \
+ echo "set tcllib libdb_tcl${DB_VERSION_MAJOR}${DB_VERSION_MINOR}d.dll" && \
+ echo ""					&& \
+ echo "set src_root .."				&& \
+ echo "set test_path ../test/tcl"		&& \
+ echo "set je_root ../../je"			&& \
+ echo "set tcl_utils ../test/tcl_utils"		&& \
+ echo ""					&& \
+ echo "global testdir"				&& \
+ echo "set testdir ./TESTDIR"			&& \
+ echo ""					&& \
+ echo "global dict"				&& \
+ echo "global util_path"			&& \
+ echo ""					&& \
+ echo "global is_freebsd_test"			&& \
+ echo "global is_hp_test"			&& \
+ echo "global is_linux_test"			&& \
+ echo "global is_osx_test"			&& \
+ echo "global is_qnx_test"			&& \
+ echo "global is_sunos_test"			&& \
+ echo "global is_windows_test"			&& \
+ echo "global is_windows9x_test"		&& \
+ echo ""					&& \
+ echo "global valid_methods"			&& \
+ echo "global checking_valid_methods"		&& \
+ echo "global test_recopts"			&& \
+ echo ""					&& \
+ echo "set KILL dbkill.exe") > $t
+
+f=../build_windows/include.tcl
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+
+# Build the test directory TESTS file.
+(echo $msg2;
+cat `egrep -l '^#[	 ][	 ]*TEST' ../test/tcl/*.tcl` |
+sed -e '/^#[	 ][	 ]*TEST/!{' \
+    -e 's/.*//' \
+    -e '}' |
+cat -s |
+sed -e '/TEST/{' \
+    -e 's/^#[	 ][	 ]*TEST[	 ]*//' \
+    -e 's/^	//' \
+    -e 'H' \
+    -e 'd' \
+    -e '}' \
+    -e 's/.*//' \
+    -e x \
+    -e 's/\n/__LINEBREAK__/g' |
+LANG=C sort |
+sed -e 's/__LINEBREAK__/\
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\
+/' \
+    -e 's/__LINEBREAK__/\
+	/g' |
+sed -e 's/^[	 ][	 ]*$//') > $t
+
+f=../test/tcl/TESTS
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_validate	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,104 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# This script runs the various validation tests in the validate directory.
+
+# Run everything, even those known to be invalid or useless.
+all_tests=1
+# Run all tests, even those that require odd env setup or a long time.
+full=0
+ignore_failures=0
+nocleanup=0
+verbose=1
+while [ $# -gt 0 ]
+do 
+	case "$1" in
+	-a*) # all
+		all_tests=1; full=1; shift;;
+	-c*) # continue
+		ignore_failures=1; shift;;
+	-f*) # full
+		full=1; shift;;
+	-nocleanup)
+		nocleanup=1; shift;;
+	-q*)
+		verbose=0; shift;;
+	*)
+		echo "Unrecognized option: $1, ignoring"
+		shift;;
+	esac
+done
+
+# The set of full tests are those that have special env setup requirements
+# or take a long time to run. They should be run at release time.
+FULL_TESTS="s_chk_build_configs s_chk_vxworks"
+EXCLUDE_TESTS="s_chk_logverify s_chk_srcfiles s_chk_java_samples"
+
+# Run all s_chk scripts, files with extensions are used by the script with
+# the shorter name, they shouldn't be run directly.
+for t in `(cd validate && ls s_chk_* | grep -v "\.")`
+do
+	excluded=0
+	for skip in $FULL_TESTS; do
+		if [ $full = 0 -a "$t" = "$skip" ]; then
+			echo "===!! Skipping $t ==="
+			echo "=== Add -full to the command line to enable ==="
+			excluded=1
+			break;
+		fi
+	done
+	for skip in $EXCLUDE_TESTS; do
+		if [ $all_tests != 0 -a "$t" = "$skip" ]; then
+			echo "===!! Skipping $t ==="
+			echo "=== Add -all to the command line to enable ==="
+			excluded=1
+			break;
+		fi
+	done
+	if [ $excluded != 0 ]; then
+		continue
+	fi
+
+	echo "=== Running $t ==="
+	if [ "$verbose" = 1 ]; then
+		(cd validate && sh $t)
+	else
+		(cd validate && sh $t > /dev/null)
+	fi
+	ret_val=$?
+	if [ "$ret_val" != 0 ]; then
+		echo "=== Test $t reported a failure $ret_val." >&2
+		if [ $ignore_failures = 0 ]; then
+			exit $ret_val
+		fi
+	else
+		echo "=== Test $t passed, $ret_val"
+	fi
+	rm -f validate/__?
+done
+echo "Finished running validate tests."
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_windows	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,304 @@
+#!/bin/sh -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Build Windows include files.
+
+msgc="/* DO NOT EDIT: automatically built by dist/s_windows. */"
+msgw="; DO NOT EDIT: automatically built by dist/s_windows."
+
+. ./RELEASE
+
+s=/tmp/__db_a$$
+t=/tmp/__db_b$$
+rm -f $s $t
+
+trap 'rm -f $s $t ; exit 1' 1 2 3 13 15
+
+# Build the Windows db.h
+cat <<ENDOFSEDTEXT > $s
+/@inttypes_h_decl@/d
+/@stdint_h_decl@/d
+s/@stddef_h_decl@/#include <stddef.h>/
+/@unistd_h_decl@/d
+/@thread_h_decl@/d
+s/@u_int8_decl@/typedef unsigned char u_int8_t;/
+s/@int16_decl@/typedef short int16_t;/
+s/@u_int16_decl@/typedef unsigned short u_int16_t;/
+s/@int32_decl@/typedef int int32_t;/
+s/@u_int32_decl@/typedef unsigned int u_int32_t;/
+s/@int64_decl@/typedef __int64 int64_t;/
+s/@u_int64_decl@/typedef unsigned __int64 u_int64_t;/
+s/@db_seq_decl@/typedef int64_t db_seq_t;/
+s/@db_threadid_t_decl@/typedef u_int32_t db_threadid_t;/
+s/@pid_t_decl@/typedef int32_t pid_t;/
+/@u_char_decl@/{
+	i\\
+#ifndef _WINSOCKAPI_
+	s/@u_char_decl@/typedef unsigned char u_char;/
+}
+s/@u_short_decl@/typedef unsigned short u_short;/
+s/@u_int_decl@/typedef unsigned int u_int;/
+/@u_long_decl@/{
+	s/@u_long_decl@/typedef unsigned long u_long;/
+	a\\
+#endif
+}
+/@FILE_t_decl@/d
+/@size_t_decl@/d
+/@ssize_t_decl@/{
+ 	i\\
+#ifdef _WIN64\\
+typedef int64_t ssize_t;\\
+#else\\
+typedef int32_t ssize_t;\\
+#endif
+ 	d
+ }
+
+/@time_t_decl@/d
+/@uintmax_t_decl@/{
+	i\\
+#if defined(_MSC_VER) && _MSC_VER < 1300\\
+typedef u_int32_t uintmax_t;\\
+#else\\
+typedef u_int64_t uintmax_t;\\
+#endif
+	d
+}
+/@uintptr_t_decl@/{
+	i\\
+#ifdef _WIN64\\
+typedef u_int64_t uintptr_t;\\
+#else\\
+typedef u_int32_t uintptr_t;\\
+#endif
+	d
+}
+/@off_t_decl@/{
+	i\\
+/*\\
+\ * Windows defines off_t to long (i.e., 32 bits).  We need to pass 64-bit\\
+\ * file offsets, so we declare our own.\\
+\ */\\
+#define	off_t	__db_off_t\\
+typedef int64_t off_t;
+	d
+}
+/@platform_header@/{
+	i\\
+/*\\
+\ * Turn off inappropriate compiler warnings\\
+\ */\\
+#ifdef _MSC_VER\\
+/*\\
+\ * This warning is explicitly disabled in Visual C++ by default.\\
+\ * It is necessary to explicitly enable the /Wall flag to generate this\\
+\ * warning.\\
+\ * Since this is a shared include file it should compile without warnings\\
+\ * at the highest warning level, so third party applications can use\\
+\ * higher warning levels cleanly.\\
+\ *\\
+\ * 4820: 'bytes' bytes padding added after member 'member'\\
+\ *       The type and order of elements caused the compiler to\\
+\ *       add padding to the end of a struct.\\
+\ */\\
+#pragma warning(push)\\
+#pragma warning(disable: 4820)\\
+#endif /* _MSC_VER */
+	d
+}
+/@platform_footer@/{
+	i\\
+/* Restore default compiler warnings */\\
+#ifdef _MSC_VER\\
+#pragma warning(pop)\\
+#endif
+	d
+}
+s/@DB_VERSION_FAMILY@/$DB_VERSION_FAMILY/
+s/@DB_VERSION_RELEASE@/$DB_VERSION_RELEASE/
+s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/
+s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/
+s/@DB_VERSION_PATCH@/$DB_VERSION_PATCH/
+s/@DB_VERSION_STRING@/"$DB_VERSION_STRING"/
+s/@DB_VERSION_FULL_STRING@/"$DB_VERSION_FULL_STRING"/
+s/@DB_VERSION_UNIQUE_NAME@//
+s/@DB_CONST@//
+s/@DB_PROTO1@/#undef __P/
+s/@DB_PROTO2@/#define	__P(protos)	protos/
+ENDOFSEDTEXT
+# The db.h, db_int.h files are identical between Windows and WinCE.
+# This may change in the future, for now have the script copy
+# the headers into the build_wince directory.
+# WinCE does not support the C++ API, so don't need to copy db_cxx.h
+
+(echo "$msgc" &&
+    sed -f $s ../src/dbinc/db.in &&
+    cat ../src/dbinc_auto/api_flags.in &&
+    cat ../src/dbinc_auto/ext_prot.in) > $t
+test `egrep '@.*@' $t` && {
+	egrep '@.*@' $t
+	echo 'Unexpanded autoconf variables found in Windows db.h.'
+	exit 1
+}
+f=../build_windows/db.h
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+f=../build_wince/db.h
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+
+# Build the Windows db_cxx.h.
+cat <<ENDOFSEDTEXT > $s
+s/@cxx_have_stdheaders@/#define	HAVE_CXX_STDHEADERS 1/
+ENDOFSEDTEXT
+(echo "$msgc" && sed -f $s ../src/dbinc/db_cxx.in) > $t
+test `egrep '@.*@' $t` && {
+	egrep '@.*@' $t
+	echo 'Unexpanded autoconf variables found in Windows db_cxx.h.'
+	exit 1
+}
+f=../build_windows/db_cxx.h
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+
+# Build the Windows db_int.h.
+cat <<ENDOFSEDTEXT > $s
+s/@DB_STRUCT_ALIGN8@/__declspec(align(8))/
+s/@PATH_SEPARATOR@/\\\\\\\\\/:/
+s/@db_int_def@//
+ENDOFSEDTEXT
+(echo "$msgc" && sed -f $s ../src/dbinc/db_int.in) > $t
+test `egrep '@.*@' $t` && {
+	egrep '@.*@' $t
+	echo 'Unexpanded autoconf variables found in Windows db_int.h.'
+	exit 1
+}
+f=../build_windows/db_int.h
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+f=../build_wince/db_int.h
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+
+# Build the Windows and WinCE db_config.h.
+# We don't fail, but we complain if the win_config.in file isn't up-to-date.
+check_config()
+{
+	egrep '^#undef' config.hin | awk '{print $2}' | sort -u > $s
+	(egrep '#undef' $1 | awk '{print $3}'
+	 egrep '^#define' $1 | awk '{print $2}') | sed '/__STDC__/d' | sort -u > $t
+	cmp $s $t > /dev/null || {
+		echo "config.hin and $1 differ"
+		echo "<<< config.hin >>> $1"
+		diff $s $t
+	}
+}
+check_config win_config.in
+f=../build_windows/db_config.h
+(echo "$msgc" && sed "s/__EDIT_DB_VERSION__/$DB_VERSION/" win_config.in) > $t
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+check_config wince_config.in
+f=../build_wince/db_config.h
+(echo "$msgc" && sed "s/__EDIT_DB_VERSION__/$DB_VERSION/" wince_config.in) > $t
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+
+# Build the Windows libdb.rc, libdb.def and libdb_small.def.
+f=../build_windows/libdb.rc
+cat <<ENDOFSEDTEXT > $s
+s/%MAJOR%/$DB_VERSION_MAJOR/
+s/%MINOR%/$DB_VERSION_MINOR/
+s/%PATCH%/$DB_VERSION_PATCH/
+ENDOFSEDTEXT
+sed -f $s ../build_windows/libdbrc.src > $t
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+f=../build_windows/libdb.def
+(echo $msgw &&
+ echo &&
+ echo EXPORTS;
+a=1
+for i in `sed -e '/^$/d' -e '/^#/d' win_exports.in | 
+	egrep -w rds |
+        sed -e 's/[	 ].*//'`; do
+	echo "	$i	@$a"
+	a=`expr $a + 1`
+done) > $t
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+f=../build_windows/libdb_small.def
+(echo $msgw &&
+ echo &&
+ echo EXPORTS;
+a=1
+for i in `sed -e '/^$/d' -e '/^#/d' win_exports.in |
+          egrep -w db_small |
+          sed -e 's/[	 ].*//'`; do
+	echo "	$i	@$a"
+	a=`expr $a + 1`
+done) > $t
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+
+# Build the Windows clib_port.h.
+cat <<ENDOFSEDTEXT > $s
+s/@INT64_FMT@/#define	INT64_FMT	"%I64d"/
+s/@UINT64_FMT@/#define	UINT64_FMT	"%I64u"/
+ENDOFSEDTEXT
+sed -f $s clib_port.in > $t
+test `egrep '@.*@' $t` && {
+	egrep '@.*@' $t
+	echo 'Unexpanded autoconf variables found in Windows clib_port.h.'
+	exit 1
+}
+f=../build_windows/clib_port.h
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+f=../build_wince/clib_port.h
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+
+# Build the Windows dbstl_common.h.
+cat <<ENDOFSEDTEXT > $s
+s/@WSTRING_decl@/#define	HAVE_WSTRING	1/
+s/@TLS_decl@/#define	TLS_DECL_MODIFIER	__declspec(thread)/
+s/@TLS_defn@/#define	TLS_DEFN_MODIFIER	__declspec(thread)/
+ENDOFSEDTEXT
+sed -f $s ../lang/cxx/stl/dbstl_common.in > $t
+f=../build_windows/dbstl_common.h
+cmp $t $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp $t $f)
+
+# Copy in errno.h.
+f=../build_wince/errno.h
+cmp errno.h $f > /dev/null 2>&1 ||
+    (echo "Building $f" && rm -f $f && cp errno.h $f)
+
+rm -f $s $t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/s_windows_dsp	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,216 @@
+#!/bin/bash -
+#
+# Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+#	$Id$
+#
+# Build Windows CE .vcproj files
+# Build Windows .vcproj files.
+
+. ./RELEASE
+
+create_projects()
+{
+    # project name list
+    PROJECTS=$1
+
+    # xquery script template
+    TEMPLATE=genproject.template
+    TEMPLATE_VS2010=vs2010.template
+
+    # vs2010 common properties template
+    LIBTEMPLATE=library.props.template
+    APPTEMPLATE=application.props.template
+
+    # temporary script, post-sed-replacement
+    TEMP_SCRIPT=genproject.script
+
+    # temporary common properties for vs2010
+    TEMP_LIB=library.props
+    TEMP_APP=application.props
+
+    # xml document input template
+    CONFIG_INPUT=$2
+
+    # temporary xml document, post-sed-replacement
+    CONFIG_OUTPUT=projects.xml
+
+    # location for output project files
+    PROJECT_OUTPUT_PARENT_DIR=$3
+
+    # judge Windows or Win CE for vs2010
+    WinVersion=$4
+
+    if [ $WinVersion = "WinCE" ]; then
+      VLoop=VS8
+    else 
+      VLoop="VS8 VS10"
+    fi
+
+    # for each project, substitute 2 variables in the XQuery script, then run it
+    # temporarily use only VS10 here to omit the generation of VS8
+    for v in $VLoop
+    do
+
+        if [ $v = "VS71" ]; then
+            VERSION="7.10"
+        elif [ $v = "VS8" ]; then
+    	    VERSION="8.00"
+ 	elif [ $v = "VS10" ]; then
+	    VERSION="10.0"
+        fi
+
+	PROJECT_OUTPUT_DIR="$PROJECT_OUTPUT_PARENT_DIR/$v"
+
+    	# substitute some variables in the XML document template
+        if [ $v = "VS10" ]; then
+    	    sed -e "s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/g" \
+                -e "s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/g" \
+                -e "s/$/
/" \
+                < $LIBTEMPLATE > $TEMP_LIB
+
+            sed -e "s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/g" \
+                -e "s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/g" \
+                -e "s/$/
/" \
+                < $APPTEMPLATE > $TEMP_APP
+
+	    mv $TEMP_LIB $PROJECT_OUTPUT_DIR/$TEMP_LIB
+            mv $TEMP_APP $PROJECT_OUTPUT_DIR/$TEMP_APP
+	fi
+    	sed -e "s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/g" \
+            -e "s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/g" \
+            < $CONFIG_INPUT > $CONFIG_OUTPUT
+	
+	
+	
+        echo "Building for Visual Studio version $VERSION"
+
+        for i in `cat $PROJECTS`
+        do
+	    if [ $v = "VS10" ]; then
+            	sed -e "s!@PROJECT_NAME@!$i!g" -e "s!@PROJECT_INPUT@!$CONFIG_OUTPUT!g" -e "s!@VISUAL_STUDIO_VERSION@!$VERSION!g" < $TEMPLATE_VS2010 > $TEMP_SCRIPT
+            else 
+            	sed -e "s!@PROJECT_NAME@!$i!g" -e "s!@PROJECT_INPUT@!$CONFIG_OUTPUT!g" -e "s!@VISUAL_STUDIO_VERSION@!$VERSION!g" < $TEMPLATE > $TEMP_SCRIPT
+	    fi 	
+            if [ $v = "VS7.1" ]; then
+            	TMP=$PROJECT_OUTPUT_DIR/$i.tmp.vcproj
+                TARG=$PROJECT_OUTPUT_DIR/${i}_vs71.vcproj
+            elif [ $v = "VS8" ]; then
+            	TMP=$PROJECT_OUTPUT_DIR/$i.tmp.vcproj
+		TARG=$PROJECT_OUTPUT_DIR/${i}.vcproj
+	    else
+            	TMP=$PROJECT_OUTPUT_DIR/$i.tmp.vcxproj
+                TARG=$PROJECT_OUTPUT_DIR/${i}.vcxproj
+            fi
+            xqilla -o $TMP $TEMP_SCRIPT
+            rm -f $TEMP_SCRIPT
+            chmod 644 $TMP
+            cmp $TMP $TARG > /dev/null 2>&1 ||
+            (echo "Building $TARG" && rm -f $TARG &&
+            cp $TMP $TARG)
+            rm -f $TMP
+        done
+    done
+
+    # Cleanup.
+    rm -f $CONFIG_OUTPUT
+}
+
+create_projects_csharp()
+{
+    # project name list
+    PROJECTS=$1
+
+    # xquery script template
+    TEMPLATE=genproject_csharp.template
+
+    # temporary script, post-sed-replacement
+    TEMP_SCRIPT=genproject.script
+
+    # xml document input template
+    CONFIG_INPUT=$2
+
+    # temporary xml document, post-sed-replacement
+    CONFIG_OUTPUT=projects.xml
+
+    # substitute some variables in the XML document template
+    sed -e "s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/g" \
+        -e "s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/g" \
+        < $CONFIG_INPUT > $CONFIG_OUTPUT
+
+    # for each project, substitute 2 variables in the XQuery script, then run it
+    for i in `cat $PROJECTS`
+    do
+        # Split project path into dir + basename
+        PROJECT_OUTPUT_DIR=`dirname $i`
+        i=`basename $i`
+
+        sed -e "s!@PROJECT_NAME@!$i!g" -e "s!@PROJECT_INPUT@!$CONFIG_OUTPUT!g" -e "s!@VISUAL_STUDIO_VERSION@!$VERSION!g" < $TEMPLATE > $TEMP_SCRIPT
+        TMP=$PROJECT_OUTPUT_DIR/$i.tmp.csproj
+        TARG=$PROJECT_OUTPUT_DIR/${i}.csproj
+        xqilla -o $TMP $TEMP_SCRIPT
+        rm -f $TEMP_SCRIPT
+        chmod 644 $TMP
+        cmp $TMP $TARG > /dev/null 2>&1 ||
+        (echo "Building $TARG" && rm -f $TARG &&
+        cp $TMP $TARG)
+        rm -f $TMP
+    done
+
+    # Cleanup.
+    rm -f $CONFIG_OUTPUT
+}
+
+# Detect XQilla
+which xqilla  > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+ 	echo "Can not find xqilla command."
+    	exit 1
+fi
+
+cd win_projects
+
+# Create/Update Windows project files
+echo "Building Visual Studio project files for Windows -- "
+echo "   output only for modified projects (this can take a while)"
+create_projects db.projects projects.template.xml ../../build_windows Win
+
+echo "Building Visual Studio project files for Windows DB-RDS --"
+echo "   output only for modified projects (this can take a while)"
+create_projects ../rds/db_rds.projects ../rds/projects_rds.template.xml ../rds/build_windows Win
+ls -ltR ../rds/build_windows
+
+# Create/Update Windows CE project files
+echo "Building Visual Studio project files for Windows CE -- "
+echo "   output only for modified projects (this can take a while)"
+create_projects db_wince.projects projects_wince.template.xml ../../build_wince WinCE
+
+# Create/Update C Sharp project files
+echo "Building C Sharp project files -- "
+echo "   output only for modified projects (this can take a while)"
+create_projects_csharp db_csharp.projects projects_csharp.template.xml
+
+cd ..
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist/srcfiles.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,374 @@
+#	$Id$
+#
+# Copyright (c) 2000, 2012 Oracle and/or its affiliates.  All rights reserved.
+# 
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.  Oracle designates this
+#  particular file as subject to the "Classpath" exception as provided
+#  by Oracle in the LICENSE file that accompanied this code.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+#
+# This is an input file for the s_vxworks, s_android, and buildrds scripts.  It
+# lists the source files in the Berkeley DB tree and notes which are used to
+# build the Android, VxWorks libraries.
+#
+# If you are adding a new file, putting the filename here in srcfiles.in and
+# indicate which modules require the file. Also make sure to add the file to
+# dist/win_projects/projects.template.xml for Windows, and
+# dist/win_projects/projects_wince.template.xml for Windows CE.
+#
+# Please keep this list sorted alphabetically!
+#
+# Each non-blank, non-comment line is of the form
+#   filename		module [ module ...]
+
+src/btree/bt_compact.c						android vx vxsmall
+src/btree/bt_compare.c						android vx vxsmall rds
+src/btree/bt_compress.c						android vx vxsmall
+src/btree/bt_conv.c						android vx vxsmall rds
+src/btree/bt_curadj.c						android vx vxsmall rds
+src/btree/bt_cursor.c						android vx vxsmall rds
+src/btree/bt_delete.c						android vx vxsmall rds
+src/btree/bt_method.c						android vx vxsmall rds
+src/btree/bt_open.c						android vx vxsmall rds
+src/btree/bt_put.c						android vx vxsmall rds
+src/btree/bt_rec.c						android vx vxsmall
+src/btree/bt_reclaim.c						android vx vxsmall rds
+src/btree/bt_recno.c						android vx vxsmall rds
+src/btree/bt_rsearch.c						android vx vxsmall rds
+src/btree/bt_search.c						android vx vxsmall rds
+src/btree/bt_split.c						android vx vxsmall rds
+src/btree/bt_stat.c						android vx vxsmall rds
+src/btree/bt_upgrade.c						android vx vxsmall
+src/btree/bt_verify.c						vx rds
+src/btree/btree_auto.c						android vx vxsmall
+src/btree/btree_autop.c						vx6
+build_vxworks/util/db_archive.c					vx6
+build_vxworks/util/db_checkpoint.c				vx6
+build_vxworks/util/db_deadlock.c				vx6
+build_vxworks/util/db_dump.c					vx6 rds
+build_vxworks/util/db_hotbackup.c				vx6
+build_vxworks/util/db_load.c					vx6 rds
+build_vxworks/util/db_log_verify.c				vx6
+build_vxworks/util/db_printlog.c				vx6
+build_vxworks/util/db_recover.c					vx6
+build_vxworks/util/db_stat.c					vx6 rds
+build_vxworks/util/db_tuner.c					vx6
+build_vxworks/util/db_upgrade.c					vx6
+build_vxworks/util/db_verify.c					vx6 rds
+build_vxworks/dbdemo/dbdemo.c					vx6
+build_vxworks/test/micro/b_curalloc.c				vx6
+build_vxworks/test/micro/b_curwalk.c				vx6
+build_vxworks/test/micro/b_del.c				vx6
+build_vxworks/test/micro/b_get.c				vx6
+build_vxworks/test/micro/b_inmem.c				vx6
+build_vxworks/test/micro/b_latch.c				vx6
+build_vxworks/test/micro/b_load.c				vx6
+build_vxworks/test/micro/b_open.c				vx6
+build_vxworks/test/micro/b_put.c				vx6
+build_vxworks/test/micro/b_recover.c				vx6
+build_vxworks/test/micro/b_txn.c				vx6
+build_vxworks/test/micro/b_txn_write.c				vx6
+build_vxworks/test/micro/b_uname.c				vx6
+build_vxworks/test/micro/b_util.c				vx6
+build_vxworks/test/micro/b_workload.c				vx6
+build_vxworks/test/micro/test_micro.c				vx6
+src/clib/isalpha.c						rds
+src/clib/getopt.c						vx vxsmall rds
+src/clib/rand.c							android 
+src/clib/snprintf.c						android vx vxsmall rds
+src/clib/strcasecmp.c						vx vxsmall
+src/clib/strdup.c						vx vxsmall
+src/clib/strsep.c						vx vxsmall rds
+src/common/clock.c						android vx vxsmall rds
+src/common/crypto_stub.c					vxsmall rds
+src/common/db_byteorder.c					android vx vxsmall rds
+src/common/db_compint.c						android vx vxsmall 
+src/common/db_err.c						android vx vxsmall rds
+src/common/db_getlong.c						android vx vxsmall rds
+src/common/db_idspace.c						android vx vxsmall rds
+src/common/db_log2.c						android vx vxsmall rds
+src/common/db_shash.c						android vx vxsmall rds
+src/common/dbt.c						android vx vxsmall rds
+src/common/mkpath.c						android vx vxsmall rds
+src/common/os_method.c						android vx vxsmall rds
+src/common/rds_stub.c						rds
+src/common/util_arg.c						vx vxsmall
+src/common/util_cache.c						vx vxsmall rds
+src/common/util_log.c						vx vxsmall rds
+src/common/util_sig.c						vx vxsmall rds
+src/common/zerofill.c						android vx vxsmall rds
+src/crypto/aes_method.c						vx
+src/crypto/crypto.c						vx
+src/crypto/mersenne/mt19937db.c					vx
+src/crypto/rijndael/rijndael-alg-fst.c				vx
+src/crypto/rijndael/rijndael-api-fst.c				vx
+lang/cxx/cxx_channel.cpp					vx6
+lang/cxx/cxx_db.cpp						vx6
+lang/cxx/cxx_dbc.cpp						vx6
+lang/cxx/cxx_dbt.cpp						vx6
+lang/cxx/cxx_env.cpp						vx6
+lang/cxx/cxx_except.cpp						vx6
+lang/cxx/cxx_lock.cpp						vx6
+lang/cxx/cxx_logc.cpp						vx6
+lang/cxx/cxx_mpool.cpp						vx6
+lang/cxx/cxx_multi.cpp						vx6
+lang/cxx/cxx_seq.cpp						vx6
+lang/cxx/cxx_site.cpp						vx6
+lang/cxx/cxx_txn.cpp						vx6
+src/db/crdel_auto.c						android vx vxsmall
+src/db/crdel_autop.c						vx6
+src/db/crdel_rec.c						android vx vxsmall
+src/db/db.c							android vx vxsmall rds
+src/db/db_am.c							android vx vxsmall rds
+src/db/db_auto.c						android vx vxsmall
+src/db/db_autop.c						vx6
+src/db/db_backup.c						android vx vxsmall rds
+src/db/db_cam.c							android vx vxsmall rds
+src/db/db_cds.c							android vx vxsmall
+src/db/db_compact.c						android vx vxsmall
+src/db/db_conv.c						android vx vxsmall rds
+src/db/db_copy.c						android vx vxsmall rds
+src/db/db_dispatch.c						android vx vxsmall
+src/db/db_dup.c							android vx vxsmall rds
+src/db/db_iface.c						android vx vxsmall rds
+src/db/db_join.c						android vx vxsmall
+src/db/db_meta.c						android vx vxsmall rds
+src/db/db_method.c						android vx vxsmall rds
+src/db/db_open.c						android vx vxsmall rds
+src/db/db_overflow.c						android vx vxsmall rds
+src/db/db_ovfl_vrfy.c						vx rds
+src/db/db_pr.c							android vx vxsmall rds
+src/db/db_rec.c							android vx vxsmall
+src/db/db_reclaim.c						android vx vxsmall rds
+src/db/db_remove.c						android vx vxsmall rds
+src/db/db_rename.c						android vx vxsmall rds
+src/db/db_ret.c							android vx vxsmall rds
+src/db/db_setid.c						android vx vxsmall rds
+src/db/db_setlsn.c						android vx vxsmall rds
+src/db/db_sort_multiple.c					android vx vxsmall rds
+src/db/db_stati.c						android vx vxsmall rds
+src/db/db_truncate.c						android vx vxsmall rds
+src/db/db_upg.c							android vx vxsmall
+src/db/db_upg_opd.c						android vx vxsmall
+src/db/db_vrfy.c						vx rds
+src/db/db_vrfy_stub.c						android vxsmall  rds
+src/db/db_vrfyutil.c						vx rds
+src/db/partition.c						android vx
+src/db/partition_stub.c						android vx rds
+lang/db185/db185.c
+src/dbreg/dbreg.c						android vx vxsmall
+src/dbreg/dbreg_auto.c						android vx vxsmall
+src/dbreg/dbreg_autop.c						vx6
+src/dbreg/dbreg_rec.c						android vx vxsmall
+src/dbreg/dbreg_stat.c						android vx vxsmall
+src/dbreg/dbreg_util.c						android vx vxsmall
+src/env/env_alloc.c						android vx vxsmall rds
+src/env/env_backup.c						android vx vxsmall
+src/env/env_config.c						android vx vxsmall rds
+src/env/env_failchk.c						android vx vxsmall
+src/env/env_file.c						android vx vxsmall rds
+src/env/env_globals.c						android vx vxsmall rds
+src/env/env_method.c						android vx vxsmall rds
+src/env/env_name.c						android vx vxsmall rds
+src/env/env_open.c						android vx vxsmall rds
+src/env/env_recover.c						android vx vxsmall
+src/env/env_region.c						android vx vxsmall rds
+src/env/env_register.c						android vx vxsmall
+src/env/env_sig.c						android vx vxsmall rds
+src/env/env_stat.c						android vx vxsmall rds
+src/fileops/fileops_auto.c					android vx vxsmall
+src/fileops/fileops_autop.c					vx6
+src/fileops/fop_basic.c						android vx vxsmall rds
+src/fileops/fop_rec.c						android vx vxsmall
+src/fileops/fop_util.c						android vx vxsmall rds
+src/hash/hash.c							vx
+src/hash/hash_auto.c						vx
+src/hash/hash_autop.c						vx6
+src/hash/hash_compact.c						vx
+src/hash/hash_conv.c						vx
+src/hash/hash_dup.c						vx
+src/hash/hash_func.c						android vx vxsmall rds
+src/hash/hash_meta.c						vx
+src/hash/hash_method.c						vx
+src/hash/hash_open.c						vx
+src/hash/hash_page.c						vx
+src/hash/hash_rec.c						vx
+src/hash/hash_reclaim.c						vx
+src/hash/hash_stat.c						vx
+src/hash/hash_stub.c						android vxsmall rds
+src/hash/hash_upgrade.c						vx
+src/hash/hash_verify.c						vx
+src/heap/heap_auto.c						vx
+src/heap/heap_autop.c						vx
+src/heap/heap_backup.c						vx
+src/heap/heap.c							vx
+src/heap/heap_conv.c						vx
+src/heap/heap_method.c						vx
+src/heap/heap_open.c						vx
+src/heap/heap_rec.c						vx
+src/heap/heap_reclaim.c						vx
+src/heap/heap_stat.c						vx
+src/heap/heap_stub.c						android vxsmall rds
+src/heap/heap_verify.c						vx
+src/hmac/hmac.c							android vx vxsmall
+src/hmac/sha1.c							android vx vxsmall
+src/lock/db_lock.c						android vx vxsmall
+src/lock/lock.c							android vx vxsmall 
+src/lock/lock_deadlock.c					android vx vxsmall 
+src/lock/lock_failchk.c						android vx vxsmall 
+src/lock/lock_id.c						android vx vxsmall 
+src/lock/lock_list.c						android vx vxsmall 
+src/lock/lock_method.c						android vx vxsmall 
+src/lock/lock_region.c						android vx vxsmall 
+src/lock/lock_stat.c						android vx vxsmall 
+src/lock/lock_timer.c						android vx vxsmall 
+src/lock/lock_util.c						android vx vxsmall 
+src/lock/lock_stub.c						rds
+src/log/log.c							android vx vxsmall 
+src/log/log_archive.c						android vx vxsmall 
+src/log/log_compare.c						android vx vxsmall 
+src/log/log_debug.c						android vx vxsmall 
+src/log/log_get.c						android vx vxsmall 
+src/log/log_method.c						android vx vxsmall 
+src/log/log_print.c						android vx vxsmall 
+src/log/log_put.c						android vx vxsmall 
+src/log/log_stat.c						android vx vxsmall 
+src/log/log_verify.c						vx 
+src/log/log_verify_util.c					vx 
+src/log/log_verify_auto.c					vx 
+src/log/log_verify_int.c					vx 
+src/log/log_verify_stub.c					android vxsmall rds
+src/mp/mp_alloc.c						android vx vxsmall rds
+src/mp/mp_backup.c						android vx vxsmall 
+src/mp/mp_bh.c							android vx vxsmall rds
+src/mp/mp_fget.c						android vx vxsmall rds
+src/mp/mp_fmethod.c						android vx vxsmall rds
+src/mp/mp_fopen.c						android vx vxsmall rds
+src/mp/mp_fput.c						android vx vxsmall rds
+src/mp/mp_fset.c						android vx vxsmall rds
+src/mp/mp_method.c						android vx vxsmall rds
+src/mp/mp_mvcc.c						android vx vxsmall 
+src/mp/mp_region.c						android vx vxsmall rds
+src/mp/mp_register.c						android vx vxsmall rds
+src/mp/mp_resize.c						android vx vxsmall rds
+src/mp/mp_stat.c						android vx vxsmall rds
+src/mp/mp_sync.c						android vx vxsmall rds
+src/mp/mp_trickle.c						android vx vxsmall rds
+src/mutex/mut_alloc.c						android vx vxsmall rds
+src/mutex/mut_failchk.c						android vx vxsmall 
+src/mutex/mut_fcntl.c
+src/mutex/mut_method.c						android vx vxsmall rds
+src/mutex/mut_pthread.c						android vx vxsmall rds
+src/mutex/mut_region.c						android vx vxsmall rds
+src/mutex/mut_stat.c						android vx vxsmall rds
+src/mutex/mut_tas.c						android vx vxsmall rds
+src/mutex/mut_win32.c						ce_small rds
+src/os/os_abort.c						android vx vxsmall rds
+src/os/os_abs.c							android rds
+src/os/os_addrinfo.c						vx rds
+src/os/os_alloc.c						android vx vxsmall  rds
+src/os/os_clock.c						android vx vxsmall  rds
+src/os/os_config.c						android rds
+src/os/os_cpu.c							android vx vxsmall  rds
+src/os/os_ctime.c						android vx vxsmall rds
+src/os/os_dir.c							android vx vxsmall rds
+src/os/os_errno.c						android vx vxsmall rds
+src/os/os_fid.c							android vx vxsmall rds
+src/os/os_flock.c						android vx vxsmall rds
+src/os/os_fsync.c						android vx vxsmall rds
+src/os/os_getenv.c						android vx vxsmall rds
+src/os/os_handle.c						android vx vxsmall rds
+src/os/os_map.c							android rds
+src/os/os_mkdir.c						android vx vxsmall rds
+src/os/os_open.c						android vx vxsmall rds
+src/os/os_path.c						android vx vxsmall rds
+src/os/os_pid.c							android vx vxsmall rds
+src/os/os_rename.c						android vx vxsmall rds
+src/os/os_root.c						android vx vxsmall rds
+src/os/os_rpath.c						android rds
+src/os/os_rw.c							android vx vxsmall rds
+src/os/os_seek.c						android vx vxsmall rds
+src/os/os_stack.c						android vx vxsmall rds
+src/os/os_stat.c						android vx vxsmall rds
+src/os/os_tmpdir.c						android vx vxsmall rds
+src/os/os_truncate.c						android vx vxsmall rds
+src/os/os_uid.c							android vx vxsmall rds
+src/os/os_unlink.c						android vx vxsmall rds
+src/os/os_yield.c						android rds
+src/os_qnx/os_qnx_fsync.c
+src/os_qnx/os_qnx_open.c
+src/os_vxworks/os_vx_abs.c					vx vxsmall
+src/os_vxworks/os_vx_config.c					vx vxsmall
+src/os_vxworks/os_vx_map.c					vx vxsmall
+src/os_vxworks/os_vx_rpath.c					vx vxsmall
+src/os_vxworks/os_vx_yield.c					vx vxsmall
+src/qam/qam.c							vx
+src/qam/qam_auto.c						vx
+src/qam/qam_autop.c						vx6
+src/qam/qam_conv.c						vx
+src/qam/qam_files.c						vx
+src/qam/qam_method.c						vx
+src/qam/qam_open.c						vx
+src/qam/qam_rec.c						vx
+src/qam/qam_stat.c						vx
+src/qam/qam_stub.c						android vxsmall rds
+src/qam/qam_upgrade.c						vx
+src/qam/qam_verify.c						vx
+src/rep/rep_automsg.c						vx
+src/rep/rep_backup.c						vx
+src/rep/rep_elect.c						vx
+src/rep/rep_lease.c						vx
+src/rep/rep_log.c						vx
+src/rep/rep_method.c						vx
+src/rep/rep_record.c						vx
+src/rep/rep_region.c						vx
+src/rep/rep_stat.c						vx
+src/rep/rep_stub.c						android vxsmall rds
+src/rep/rep_util.c						vx
+src/rep/rep_verify.c						vx
+src/repmgr/repmgr_auto.c					vx
+src/repmgr/repmgr_autop.c					vx6
+src/repmgr/repmgr_automsg.c					vx
+src/repmgr/repmgr_elect.c					vx
+src/repmgr/repmgr_method.c					vx
+src/repmgr/repmgr_msg.c						vx
+src/repmgr/repmgr_net.c						vx
+src/repmgr/repmgr_posix.c					vx
+src/repmgr/repmgr_queue.c					vx
+src/repmgr/repmgr_rec.c						vx
+src/repmgr/repmgr_sel.c						vx
+src/repmgr/repmgr_stat.c					vx
+src/repmgr/repmgr_stub.c					android vxsmall rds
+src/repmgr/repmgr_util.c					vx
+src/sequence/seq_stat.c						android vx6
+src/sequence/sequence.c						android vx6
+src/txn/txn.c							android vx vxsmall
+src/txn/txn_auto.c						android vx vxsmall
+src/txn/txn_autop.c						vx6
+src/txn/txn_chkpt.c						android vx vxsmall
+src/txn/txn_failchk.c						android vx vxsmall
+src/txn/txn_method.c						android vx vxsmall
+src/txn/txn_rec.c						android vx vxsmall
+src/txn/txn_recover.c						android vx vxsmall
+src/txn/txn_region.c						android vx vxsmall
+src/txn/txn_stat.c						android vx vxsmall
+src/txn/txn_util.c						android vx vxsmall
+src/xa/xa.c							vx
+src/xa/xa_map.c							vx
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/FILES_c.gmk	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,170 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+FILES_c = \
+        btree/bt_compare.c \
+        btree/bt_conv.c \
+        btree/bt_curadj.c \
+        btree/bt_cursor.c \
+        btree/bt_delete.c \
+        btree/bt_method.c \
+        btree/bt_open.c \
+        btree/bt_put.c \
+        btree/bt_reclaim.c \
+        btree/bt_recno.c \
+        btree/bt_rsearch.c \
+        btree/bt_search.c \
+        btree/bt_split.c \
+        btree/bt_stat.c \
+        btree/bt_verify.c \
+\
+        clib/isalpha.c \
+        clib/strsep.c \
+\
+        common/clock.c \
+        common/crypto_stub.c \
+        common/db_byteorder.c \
+        common/db_err.c \
+        common/db_getlong.c \
+        common/db_idspace.c \
+        common/db_log2.c \
+        common/db_shash.c \
+        common/dbt.c \
+        common/mkpath.c \
+        common/os_method.c \
+        common/util_cache.c \
+        common/util_sig.c \
+        common/zerofill.c \
+\
+	db/db_am.c \
+        db/db_backup.c \
+	db/db_cam.c \
+	db/db_conv.c \
+        db/db_copy.c \
+	db/db_dup.c \
+	db/db_iface.c \
+	db/db_meta.c \
+	db/db_method.c \
+	db/db_open.c \
+	db/db_overflow.c \
+        db/db_ovfl_vrfy.c \
+	db/db_pr.c \
+	db/db_reclaim.c \
+	db/db_remove.c \
+	db/db_rename.c \
+	db/db_ret.c \
+	db/db_setid.c \
+	db/db_setlsn.c \
+	db/db_sort_multiple.c \
+	db/db_stati.c \
+	db/db_truncate.c \
+	db/db_vrfy.c \
+        db/db_vrfyutil.c \
+	db/db.c \
+	db/partition_stub.c \
+	db/rds_stub.c \
+\
+	env/env_alloc.c \
+	env/env_config.c \
+	env/env_file.c \
+	env/env_globals.c \
+	env/env_method.c \
+	env/env_name.c \
+	env/env_open.c \
+	env/env_region.c \
+	env/env_sig.c \
+	env/env_stat.c \
+\
+        fileops/fop_basic.c \
+        fileops/fop_util.c \
+\
+        hash/hash_func.c \
+        hash/hash_stub.c \
+\
+        heap/heap_stub.c \
+\
+        lock/lock_stub.c \
+\
+        log/log_verify_stub.c \
+\
+        mp/mp_alloc.c \
+        mp/mp_bh.c \
+        mp/mp_fget.c \
+        mp/mp_fmethod.c \
+        mp/mp_fopen.c \
+        mp/mp_fput.c \
+        mp/mp_fset.c \
+        mp/mp_method.c \
+        mp/mp_region.c \
+        mp/mp_register.c \
+        mp/mp_resize.c \
+        mp/mp_stat.c \
+        mp/mp_sync.c \
+        mp/mp_trickle.c \
+\
+        mutex/mut_alloc.c \
+        mutex/mut_method.c \
+        mutex/mut_region.c \
+        mutex/mut_stat.c \
+        mutex/mut_win32.c \
+\
+        os_abort.c \
+        os_abs.c \
+        os_addrinfo.c \
+        os_alloc.c \
+        os_clock.c \
+        os_config.c \
+        os_cpu.c \
+        os_ctime.c \
+        os_dir.c \
+        os_errno.c \
+        os_fid.c \
+        os_flock.c \
+        os_fsync.c \
+        os_getenv.c \
+        os_handle.c \
+        os_map.c \
+        os_mkdir.c \
+        os_open.c \
+        os_path.c \
+        os_pid.c \
+        os_rename.c \
+        os_root.c \
+        os_rpath.c \
+        os_rw.c \
+        os_seek.c \
+        os_stack.c \
+        os_stat.c \
+        os_tmpdir.c \
+        os_truncate.c \
+        os_uid.c \
+        os_unlink.c \
+        os_yield.c \
+\
+        qam/qam_stub.c \
+\
+        rep/rep_stub.c \
+\
+        repmgr/repmgr_stub.c \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/Makefile	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,165 @@
+#
+# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Makefile for building Berkeley DB-RDS ( Restricted Data Store ),
+# a.k.a Ultrasmall build
+#
+# This library is currently used by org.openjdk.pmap.PersistentTreeMap.
+
+# For now dependency on JDK shared makefiles
+BUILDDIR = .
+PACKAGE = bdb
+
+ifndef BDB_TOPDIR
+  BDB_TOPDIR = $(BUILDDIR)/..
+endif
+ifndef JDK_TOPDIR
+  JDK_TOPDIR=$(BDB_TOPDIR)/../jdk
+endif
+ifndef JDK_MAKE_SHARED_DIR
+  JDK_MAKE_SHARED_DIR=$(JDK_TOPDIR)/make/common/shared
+endif
+ifndef ALT_EXPORT_PATH
+  ALT_EXPORT_PATH = $(BDB_TOPDIR)/import
+endif
+
+include $(JDK_MAKE_SHARED_DIR)/../Defs.gmk
+
+SRCDIR = $(BUILDDIR)/../src
+DISTDIR = $(BUILDDIR)/../dist
+EXPORTDIR = $(ALT_EXPORT_PATH)
+
+# Careful not to conflict with LIBRARY definition for Library.gmk
+_LIBRARY = $(LIB_PREFIX)db-rds.$(LIBRARY_SUFFIX)
+
+GEN_HEADERS_DIR=$(GENNATIVESRCDIR)/bdb
+
+all: build
+
+ifeq ($(PLATFORM), windows)
+  LIBRARY = db-rds
+  VERSIONINFO_RESOURCE = libdb.rc
+
+  include FILES_c.gmk
+  include $(JDK_MAKE_SHARED_DIR)/../Library.gmk
+
+  # Find C source files
+  vpath %.c $(SRCDIR)
+  vpath %.c $(SRCDIR)/btree
+  vpath %.c $(SRCDIR)/db
+  vpath %.c $(SRCDIR)/dbreg
+  vpath %.c $(SRCDIR)/common
+  vpath %.c $(SRCDIR)/fileops
+  vpath %.c $(SRCDIR)/clib
+  vpath %.c $(SRCDIR)/hash
+  vpath %.c $(SRCDIR)/heap
+  vpath %.c $(SRCDIR)/log
+  vpath %.c $(SRCDIR)/mutex
+  vpath %.c $(SRCDIR)/qam
+  vpath %.c $(SRCDIR)/rep
+  vpath %.c $(SRCDIR)/repmgr
+  vpath %.c $(SRCDIR)/env
+  vpath %.c $(SRCDIR)/lock
+  vpath %.c $(SRCDIR)/mp
+  vpath %.c $(SRCDIR)/txn
+  vpath %.c $(SRCDIR)/hmac
+  vpath %.c $(SRCDIR)/os_windows
+  # search os after os_windows so any commonly named files
+  # will be found in os_windows first
+  vpath %.c $(SRCDIR)/os
+
+  CFLAGS += -D_WINDOWS -DDB_CREATE_DLL -DHAVE_RDS_BUILD \
+            -D_USRDLL -D_WINDLL -D_UNICODE -DUNICODE -D_MBCS
+  EXTRA_LFLAGS += /DEF:"libdb.def"
+  OTHER_LDLIBS += kernel32.lib user32.lib ws2_32.lib
+
+  # do not link against libjava
+  JAVALIB =
+
+  OTHER_INCLUDES += -I$(SRCDIR)
+  OTHER_INCLUDES += -I$(SRCDIR)/windows_incl
+
+  $(EXPORTDIR)/header/db.h: $(SRCDIR)/windows_incl/db.h
+	$(install-file)
+
+else # NOT WINDOWS
+  SRCDIR_ABS:=$(call FullPath,$(SRCDIR))
+  DISTDIR_ABS:=$(call FullPath,$(DISTDIR))
+  BDB_OUTPUT_LIB=$(TEMPDIR)/.libs/libdb-5.4.$(LIBRARY_SUFFIX)
+  BDB_OUTPUT_HEADER=$(TEMPDIR)/db.h
+  BDB_CONFIG_OPTIONS=--disable-static CC=$(CC) LD=$(LD)
+
+  # 64-bit Solaris compile needs to specify appropriate addressing model
+  ifeq ($(PLATFORM), solaris)
+    ifeq ($(ARCH_DATA_MODEL), 64)
+      BDB_CONFIG_OPTIONS+=CFLAGS=-m64
+    endif
+  endif
+
+  ifeq ($(CROSS_COMPILE_ARCH), arm)
+    BDB_CONFIG_OPTIONS+=--build=i686-pc-linux-gnu --host=arm-none-linux-gnueabi \
+                        cross_compiling=yes
+  endif
+
+  define configure-bdb
+    $(CD) $(TEMPDIR) && \
+    $(SH) $(DISTDIR_ABS)/configure $(BDB_CONFIG_OPTIONS)
+  endef
+
+  define make-bdb
+    $(CD) $(TEMPDIR) && \
+    $(MAKE)
+  endef
+
+  $(BDB_OUTPUT_HEADER):
+	$(configure-bdb)
+	$(MKDIR) -p $(GEN_HEADERS_DIR)
+	$(CP) $(BDB_OUTPUT_HEADER) $(GEN_HEADERS_DIR)
+
+  $(BDB_OUTPUT_LIB): $(BDB_OUTPUT_HEADER)
+	$(make-bdb)
+
+  $(LIB_LOCATION)/$(_LIBRARY): $(BDB_OUTPUT_LIB)
+	$(install-file)
+
+  $(EXPORTDIR)/header/db.h: $(GEN_HEADERS_DIR)/db.h
+	$(install-file)
+
+endif  # NOT WINDOWS
+
+EXPORT_LIST = $(EXPORTDIR)/lib/$(LIBARCH)/$(_LIBRARY)
+EXPORT_LIST += $(EXPORTDIR)/header/db.h
+
+build: $(LIB_LOCATION)/$(_LIBRARY) export
+
+export: $(EXPORT_LIST)
+
+$(EXPORTDIR)/lib/$(LIBARCH)/$(_LIBRARY): $(LIB_LOCATION)/$(_LIBRARY)
+	$(install-file)
+
+clobber::
+	$(RM) -rf $(TEMPDIR) $(EXPORTDIR)
+
+.PHONY: clobber clean build all export $(EXPORTDIR)/lib/$(LIBARCH)/$(_LIBRARY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/libdb.def	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,28 @@
+;
+; Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+;
+; This code is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License version 2 only, as
+; published by the Free Software Foundation.  Oracle designates this
+; particular file as subject to the "Classpath" exception as provided
+; by Oracle in the LICENSE file that accompanied this code.
+;
+; This code is distributed in the hope that it will be useful, but WITHOUT
+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; version 2 for more details (a copy is included in the LICENSE file that
+; accompanied this code).
+;
+; You should have received a copy of the GNU General Public License version
+; 2 along with this work; if not, write to the Free Software Foundation,
+; Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+;
+; Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+; or visit www.oracle.com if you need additional information or have any
+; questions.
+;
+
+EXPORTS
+	db_create	@1
+	db_strerror	@2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/libdb.rc	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,56 @@
+//
+// Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+// or visit www.oracle.com if you need additional information or have any
+// questions.
+//  
+
+1 VERSIONINFO
+ FILEVERSION 5,0,4,0
+ PRODUCTVERSION 5,0,4,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", "Oracle\0"
+            VALUE "FileDescription", "Berkeley DB 5.4 DLL\0"
+            VALUE "FileVersion", "5.4.0\0"
+            VALUE "InternalName", "libdb54.dll\0"
+            VALUE "LegalCopyright", "Copyright © Oracle 1997-2009\0"
+            VALUE "OriginalFilename", "libdb54.dll\0"
+            VALUE "ProductName", "Oracle libdb\0"
+            VALUE "ProductVersion", "5.4.0\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_compare.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,235 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+
+/*
+ * __bam_cmp --
+ *	Compare a key to a given record.
+ *
+ * PUBLIC: int __bam_cmp __P((DBC *, const DBT *, PAGE *, u_int32_t,
+ * PUBLIC:    int (*)(DB *, const DBT *, const DBT *), int *));
+ */
+int
+__bam_cmp(dbc, dbt, h, indx, func, cmpp)
+	DBC *dbc;
+	const DBT *dbt;
+	PAGE *h;
+	u_int32_t indx;
+	int (*func)__P((DB *, const DBT *, const DBT *));
+	int *cmpp;
+{
+	BINTERNAL *bi;
+	BKEYDATA *bk;
+	BOVERFLOW *bo;
+	DB *dbp;
+	DBT pg_dbt;
+
+	dbp = dbc->dbp;
+
+	/*
+	 * Returns:
+	 *	< 0 if dbt is < page record
+	 *	= 0 if dbt is = page record
+	 *	> 0 if dbt is > page record
+	 *
+	 * !!!
+	 * We do not clear the pg_dbt DBT even though it's likely to contain
+	 * random bits.  That should be okay, because the app's comparison
+	 * routine had better not be looking at fields other than data, size
+	 * and app_data.  We don't clear it because we go through this path a
+	 * lot and it's expensive.
+	 */
+	switch (TYPE(h)) {
+	case P_LBTREE:
+	case P_LDUP:
+	case P_LRECNO:
+		bk = GET_BKEYDATA(dbp, h, indx);
+		if (B_TYPE(bk->type) == B_OVERFLOW)
+			bo = (BOVERFLOW *)bk;
+		else {
+			pg_dbt.app_data = NULL;
+			pg_dbt.data = bk->data;
+			pg_dbt.size = bk->len;
+			*cmpp = func(dbp, dbt, &pg_dbt);
+			return (0);
+		}
+		break;
+	case P_IBTREE:
+		/*
+		 * The following code guarantees that the left-most key on an
+		 * internal page at any place in the tree sorts less than any
+		 * user-specified key.  The reason is that if we have reached
+		 * this internal page, we know the user key must sort greater
+		 * than the key we're storing for this page in any internal
+		 * pages at levels above us in the tree.  It then follows that
+		 * any user-specified key cannot sort less than the first page
+		 * which we reference, and so there's no reason to call the
+		 * comparison routine.  While this may save us a comparison
+		 * routine call or two, the real reason for this is because
+		 * we don't maintain a copy of the smallest key in the tree,
+		 * so that we don't have to update all the levels of the tree
+		 * should the application store a new smallest key.  And, so,
+		 * we may not have a key to compare, which makes doing the
+		 * comparison difficult and error prone.
+		 */
+		if (indx == 0) {
+			*cmpp = 1;
+			return (0);
+		}
+
+		bi = GET_BINTERNAL(dbp, h, indx);
+		if (B_TYPE(bi->type) == B_OVERFLOW)
+			bo = (BOVERFLOW *)(bi->data);
+		else {
+			pg_dbt.app_data = NULL;
+			pg_dbt.data = bi->data;
+			pg_dbt.size = bi->len;
+			*cmpp = func(dbp, dbt, &pg_dbt);
+			return (0);
+		}
+		break;
+	default:
+		return (__db_pgfmt(dbp->env, PGNO(h)));
+	}
+
+	/*
+	 * Overflow.
+	 */
+	return (__db_moff(dbc, dbt, bo->pgno, bo->tlen,
+	    func == __bam_defcmp ? NULL : func, cmpp));
+}
+
+/*
+ * __bam_defcmp --
+ *	Default comparison routine.
+ *
+ * PUBLIC: int __bam_defcmp __P((DB *, const DBT *, const DBT *));
+ */
+int
+__bam_defcmp(dbp, a, b)
+	DB *dbp;
+	const DBT *a, *b;
+{
+	size_t len;
+	u_int8_t *p1, *p2;
+
+	COMPQUIET(dbp, NULL);
+
+	/*
+	 * Returns:
+	 *	< 0 if a is < b
+	 *	= 0 if a is = b
+	 *	> 0 if a is > b
+	 *
+	 * XXX
+	 * If a size_t doesn't fit into a long, or if the difference between
+	 * any two characters doesn't fit into an int, this routine can lose.
+	 * What we need is a signed integral type that's guaranteed to be at
+	 * least as large as a size_t, and there is no such thing.
+	 */
+	len = a->size > b->size ? b->size : a->size;
+	for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
+		if (*p1 != *p2)
+			return ((long)*p1 - (long)*p2);
+	return ((long)a->size - (long)b->size);
+}
+
+/*
+ * __bam_defpfx --
+ *	Default prefix routine.
+ *
+ * PUBLIC: size_t __bam_defpfx __P((DB *, const DBT *, const DBT *));
+ */
+size_t
+__bam_defpfx(dbp, a, b)
+	DB *dbp;
+	const DBT *a, *b;
+{
+	size_t cnt, len;
+	u_int8_t *p1, *p2;
+
+	COMPQUIET(dbp, NULL);
+
+	cnt = 1;
+	len = a->size > b->size ? b->size : a->size;
+	for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
+		if (*p1 != *p2)
+			return (cnt);
+
+	/*
+	 * They match up to the smaller of the two sizes.
+	 * Collate the longer after the shorter.
+	 */
+	if (a->size < b->size)
+		return (a->size + 1);
+	if (b->size < a->size)
+		return (b->size + 1);
+	return (b->size);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_conv.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,117 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_swap.h"
+#include "dbinc/btree.h"
+
+/*
+ * __bam_pgin --
+ *	Convert host-specific page layout from the host-independent format
+ *	stored on disk.
+ *
+ * PUBLIC: int __bam_pgin __P((DB *, db_pgno_t, void *, DBT *));
+ */
+int
+__bam_pgin(dbp, pg, pp, cookie)
+	DB *dbp;
+	db_pgno_t pg;
+	void *pp;
+	DBT *cookie;
+{
+	DB_PGINFO *pginfo;
+	PAGE *h;
+
+	pginfo = (DB_PGINFO *)cookie->data;
+	if (!F_ISSET(pginfo, DB_AM_SWAP))
+		return (0);
+
+	h = pp;
+	return (TYPE(h) == P_BTREEMETA ?  __bam_mswap(dbp->env, pp) :
+	    __db_byteswap(dbp, pg, pp, pginfo->db_pagesize, 1));
+}
+
+/*
+ * __bam_pgout --
+ *	Convert host-specific page layout to the host-independent format
+ *	stored on disk.
+ *
+ * PUBLIC: int __bam_pgout __P((DB *, db_pgno_t, void *, DBT *));
+ */
+int
+__bam_pgout(dbp, pg, pp, cookie)
+	DB *dbp;
+	db_pgno_t pg;
+	void *pp;
+	DBT *cookie;
+{
+	DB_PGINFO *pginfo;
+	PAGE *h;
+
+	pginfo = (DB_PGINFO *)cookie->data;
+	if (!F_ISSET(pginfo, DB_AM_SWAP))
+		return (0);
+
+	h = pp;
+	return (TYPE(h) == P_BTREEMETA ?  __bam_mswap(dbp->env, pp) :
+	    __db_byteswap(dbp, pg, pp, pginfo->db_pagesize, 0));
+}
+
+/*
+ * __bam_mswap --
+ *	Swap the bytes on the btree metadata page.
+ *
+ * PUBLIC: int __bam_mswap __P((ENV *, PAGE *));
+ */
+int
+__bam_mswap(env, pg)
+	ENV *env;
+	PAGE *pg;
+{
+	u_int8_t *p;
+
+	COMPQUIET(env, NULL);
+
+	__db_metaswap(pg);
+	p = (u_int8_t *)pg + sizeof(DBMETA);
+
+	p += sizeof(u_int32_t);	/* unused */
+	SWAP32(p);		/* minkey */
+	SWAP32(p);		/* re_len */
+	SWAP32(p);		/* re_pad */
+	SWAP32(p);		/* root */
+	p += 92 * sizeof(u_int32_t); /* unused */
+	SWAP32(p);		/* crypto_magic */
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_curadj.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,716 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/mp.h"
+
+static int __bam_opd_cursor __P((DB *, DBC *, db_pgno_t, u_int32_t, u_int32_t));
+static int __bam_ca_delete_func
+    __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *));
+static int __ram_ca_delete_func
+    __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *));
+static int __bam_ca_di_func
+    __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *));
+static int __bam_ca_dup_func
+    __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *));
+static int __bam_ca_undodup_func
+    __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *));
+static int __bam_ca_rsplit_func
+    __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *));
+static int __bam_ca_split_func
+    __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *));
+static int __bam_ca_undosplit_func
+    __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *));
+
+/*
+ * Cursor adjustments are logged if they are for subtransactions.  This is
+ * because it's possible for a subtransaction to adjust cursors which will
+ * still be active after the subtransaction aborts, and so which must be
+ * restored to their previous locations.  Cursors that can be both affected
+ * by our cursor adjustments and active after our transaction aborts can
+ * only be found in our parent transaction -- cursors in other transactions,
+ * including other child transactions of our parent, must have conflicting
+ * locker IDs, and so cannot be affected by adjustments in this transaction.
+ */
+
+ /*
+  * __bam_ca_delete_func
+  *	Callback function for walking cursors to update them due to a delete.
+  */
+ static int
+ __bam_ca_delete_func(dbc, my_dbc, countp, pgno, indx, args)
+	DBC *dbc, *my_dbc;
+	u_int32_t *countp;
+	db_pgno_t pgno;
+	u_int32_t indx;
+	void *args;
+{
+	BTREE_CURSOR *cp;
+	u_int32_t del;
+
+	COMPQUIET(my_dbc, NULL);
+	del = *(u_int32_t *)args;
+
+	cp = (BTREE_CURSOR *)dbc->internal;
+	if (cp->pgno == pgno && cp->indx == indx &&
+	    !MVCC_SKIP_CURADJ(dbc, pgno)) {
+		/*
+		 * [#8032] This assert is checking for possible race
+		 * conditions where we hold a cursor position without
+		 * a lock.  Unfortunately, there are paths in the
+		 * Btree code that do not satisfy these conditions.
+		 * None of them are known to be a problem, but this
+		 * assert should be re-activated when the Btree stack
+		 * code is re-written.
+		DB_ASSERT(env, !STD_LOCKING(dbc) ||
+		    cp->lock_mode != DB_LOCK_NG);
+		 */
+		if (del) {
+			F_SET(cp, C_DELETED);
+			/*
+			 * If we're deleting the item, we can't
+			 * keep a streaming offset cached.
+			 */
+			cp->stream_start_pgno = PGNO_INVALID;
+		} else
+			F_CLR(cp, C_DELETED);
+
+#ifdef HAVE_COMPRESSION
+		/*
+		 * We also set the C_COMPRESS_MODIFIED flag, which
+		 * prompts the compression code to look for it's
+		 * current entry again if it needs to.
+		 *
+		 * The flag isn't cleared, because the compression
+		 * code still needs to do that even for an entry that
+		 * becomes undeleted.
+		 *
+		 * This flag also needs to be set if an entry is
+		 * updated, but since the compression code always
+		 * deletes before an update, setting it here is
+		 * sufficient.
+		 */
+		F_SET(cp, C_COMPRESS_MODIFIED);
+#endif
+
+		++(*countp);
+	}
+	return (0);
+}
+
+/*
+ * __bam_ca_delete --
+ *	Update the cursors when items are deleted and when already deleted
+ *	items are overwritten.  Return the number of relevant cursors found.
+ *
+ * PUBLIC: int __bam_ca_delete __P((DB *,
+ * PUBLIC:     db_pgno_t, u_int32_t, int, u_int32_t *));
+ */
+int
+__bam_ca_delete(dbp, pgno, indx, del, countp)
+	DB *dbp;
+	db_pgno_t pgno;
+	u_int32_t indx;
+	int del;
+	u_int32_t *countp;
+{
+	int ret;
+	u_int32_t count;
+
+	/*
+	 * Adjust the cursors.  We have the page write locked, so the
+	 * only other cursors that can be pointing at a page are
+	 * those in the same thread of control.  Unfortunately, we don't
+	 * know that they're using the same DB handle, so traverse
+	 * all matching DB handles in the same ENV, then all cursors
+	 * on each matching DB handle.
+	 *
+	 * Each cursor is single-threaded, so we only need to lock the
+	 * list of DBs and then the list of cursors in each DB.
+	 */
+	if ((ret = __db_walk_cursors(dbp, NULL,
+	    __bam_ca_delete_func, &count, pgno, indx, &del)) != 0)
+		return (ret);
+
+	if (countp != NULL)
+		*countp = count;
+	return (0);
+}
+
+static int
+__ram_ca_delete_func(dbc, my_dbc, countp, root_pgno, indx, args)
+	DBC *dbc, *my_dbc;
+	u_int32_t *countp;
+	db_pgno_t root_pgno;
+	u_int32_t indx;
+	void *args;
+{
+	COMPQUIET(indx, 0);
+	COMPQUIET(my_dbc, NULL);
+	COMPQUIET(args, NULL);
+
+	if (dbc->internal->root == root_pgno &&
+	    !MVCC_SKIP_CURADJ(dbc, root_pgno)) {
+		(*countp)++;
+		return (EEXIST);
+	}
+	return (0);
+}
+
+/*
+ * __ram_ca_delete --
+ *	Return if any relevant cursors found.
+ *
+ * PUBLIC: int __ram_ca_delete __P((DB *, db_pgno_t, u_int32_t *));
+ */
+int
+__ram_ca_delete(dbp, root_pgno, foundp)
+	DB *dbp;
+	db_pgno_t root_pgno;
+	u_int32_t *foundp;
+{
+	int ret;
+
+	if ((ret = __db_walk_cursors(dbp, NULL, __ram_ca_delete_func,
+	    foundp, root_pgno, 0, NULL)) != 0 && ret != EEXIST)
+		return (ret);
+
+	return (0);
+}
+
+struct __bam_ca_di_args {
+	int adjust;
+	DB_TXN *my_txn;
+};
+
+static int
+__bam_ca_di_func(dbc, my_dbc, foundp, pgno, indx, vargs)
+	DBC *dbc, *my_dbc;
+	u_int32_t *foundp;
+	db_pgno_t pgno;
+	u_int32_t indx;
+	void *vargs;
+{
+	DBC_INTERNAL *cp;
+	struct __bam_ca_di_args *args;
+
+	if (dbc->dbtype == DB_RECNO)
+		return (0);
+
+	cp = dbc->internal;
+	args = vargs;
+	if (cp->pgno == pgno && cp->indx >= indx &&
+	    (dbc == my_dbc || !MVCC_SKIP_CURADJ(dbc, pgno))) {
+		/* Cursor indices should never be negative. */
+		DB_ASSERT(dbc->dbp->env, cp->indx != 0 || args->adjust > 0);
+		/* [#8032]
+		DB_ASSERT(env, !STD_LOCKING(dbc) ||
+		    cp->lock_mode != DB_LOCK_NG);
+		*/
+		cp->indx += args->adjust;
+		if (args->my_txn != NULL && args->my_txn != dbc->txn)
+			*foundp = 1;
+	}
+	return (0);
+}
+/*
+ * __bam_ca_di --
+ *	Adjust the cursors during a delete or insert.
+ *
+ * PUBLIC: int __bam_ca_di __P((DBC *, db_pgno_t, u_int32_t, int));
+ */
+int
+__bam_ca_di(my_dbc, pgno, indx, adjust)
+	DBC *my_dbc;
+	db_pgno_t pgno;
+	u_int32_t indx;
+	int adjust;
+{
+	DB *dbp;
+	DB_LSN lsn;
+	int ret;
+	u_int32_t found;
+	struct __bam_ca_di_args args;
+
+	dbp = my_dbc->dbp;
+	args.adjust = adjust;
+	args.my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL;
+
+	/*
+	 * Adjust the cursors.  See the comment in __bam_ca_delete().
+	 */
+	if ((ret = __db_walk_cursors(dbp, my_dbc, __bam_ca_di_func,
+	    &found, pgno, indx, &args)) != 0)
+		return (ret);
+
+	if (found != 0 && DBC_LOGGING(my_dbc)) {
+		if ((ret = __bam_curadj_log(dbp, my_dbc->txn, &lsn, 0,
+		    DB_CA_DI, pgno, 0, 0, (u_int32_t)adjust, indx, 0)) != 0)
+			return (ret);
+	}
+
+	return (0);
+}
+
+/*
+ * __bam_opd_cursor -- create a new opd cursor.
+ */
+static int
+__bam_opd_cursor(dbp, dbc, first, tpgno, ti)
+	DB *dbp;
+	DBC *dbc;
+	db_pgno_t tpgno;
+	u_int32_t first, ti;
+{
+	BTREE_CURSOR *cp, *orig_cp;
+	DBC *dbc_nopd;
+	int ret;
+
+	orig_cp = (BTREE_CURSOR *)dbc->internal;
+	dbc_nopd = NULL;
+
+	/*
+	 * Allocate a new cursor and create the stack.  If duplicates
+	 * are sorted, we've just created an off-page duplicate Btree.
+	 * If duplicates aren't sorted, we've just created a Recno tree.
+	 *
+	 * Note that in order to get here at all, there shouldn't be
+	 * an old off-page dup cursor--to augment the checking dbc_newopd
+	 * will do, assert this.
+	 */
+	DB_ASSERT(dbp->env, orig_cp->opd == NULL);
+	if ((ret = __dbc_newopd(dbc, tpgno, orig_cp->opd, &dbc_nopd)) != 0)
+		return (ret);
+
+	cp = (BTREE_CURSOR *)dbc_nopd->internal;
+	cp->pgno = tpgno;
+	cp->indx = ti;
+
+	if (dbp->dup_compare == NULL) {
+		/*
+		 * Converting to off-page Recno trees is tricky.  The
+		 * record number for the cursor is the index + 1 (to
+		 * convert to 1-based record numbers).
+		 */
+		cp->recno = ti + 1;
+	}
+
+	/*
+	 * Transfer the deleted flag from the top-level cursor to the
+	 * created one.
+	 */
+	if (F_ISSET(orig_cp, C_DELETED)) {
+		F_SET(cp, C_DELETED);
+		F_CLR(orig_cp, C_DELETED);
+	}
+
+	/* Stack the cursors and reset the initial cursor's index. */
+	orig_cp->opd = dbc_nopd;
+	orig_cp->indx = first;
+	return (0);
+}
+
+struct __bam_ca_dup_args {
+	db_pgno_t tpgno;
+	db_indx_t first, ti;
+	DB_TXN *my_txn;
+};
+
+static int
+__bam_ca_dup_func(dbc, my_dbc, foundp, fpgno, fi, vargs)
+	DBC *dbc;
+	DBC *my_dbc;
+	u_int32_t *foundp;
+	db_pgno_t fpgno;
+	u_int32_t fi;
+	void *vargs;
+{
+	BTREE_CURSOR *orig_cp;
+	DB *dbp;
+	int ret;
+	struct __bam_ca_dup_args *args;
+
+	COMPQUIET(my_dbc, NULL);
+
+	/*
+	 * Since we rescan the list see if this is already
+	 * converted.
+	 */
+	orig_cp = (BTREE_CURSOR *)dbc->internal;
+	if (orig_cp->opd != NULL)
+		return (0);
+
+	/* Find cursors pointing to this record. */
+	if (orig_cp->pgno != fpgno || orig_cp->indx != fi ||
+	    MVCC_SKIP_CURADJ(dbc, fpgno))
+		return (0);
+
+	dbp = dbc->dbp;
+	args = vargs;
+
+	MUTEX_UNLOCK(dbp->env, dbp->mutex);
+
+	if ((ret = __bam_opd_cursor(dbp,
+	    dbc, args->first, args->tpgno, args->ti)) != 0) {
+		MUTEX_LOCK(dbp->env, dbp->mutex);
+		return (ret);
+	}
+	if (args->my_txn != NULL && args->my_txn != dbc->txn)
+		*foundp = 1;
+	/* We released the mutex to get a cursor, start over. */
+	return (DB_LOCK_NOTGRANTED);
+}
+
+/*
+ * __bam_ca_dup --
+ *	Adjust the cursors when moving items from a leaf page to a duplicates
+ *	page.
+ *
+ * PUBLIC: int __bam_ca_dup __P((DBC *,
+ * PUBLIC:    u_int32_t, db_pgno_t, u_int32_t, db_pgno_t, u_int32_t));
+ */
+int
+__bam_ca_dup(my_dbc, first, fpgno, fi, tpgno, ti)
+	DBC *my_dbc;
+	db_pgno_t fpgno, tpgno;
+	u_int32_t first, fi, ti;
+{
+	DB *dbp;
+	DB_LSN lsn;
+	int ret, t_ret;
+	u_int32_t found;
+	struct __bam_ca_dup_args args;
+
+	dbp = my_dbc->dbp;
+
+	args.first = first;
+	args.tpgno = tpgno;
+	args.ti = ti;
+	args.my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL;
+
+	if ((ret = __db_walk_cursors(dbp,
+	    my_dbc, __bam_ca_dup_func, &found, fpgno, fi, &args)) != 0)
+		return (ret);
+
+	if (found != 0 && DBC_LOGGING(my_dbc)) {
+		if ((t_ret = __bam_curadj_log(dbp, my_dbc->txn,
+		    &lsn, 0, DB_CA_DUP, fpgno, tpgno, 0, first, fi, ti)) != 0 &&
+		    ret == 0)
+			ret = t_ret;
+	}
+
+	return (ret);
+}
+
+static int
+__bam_ca_undodup_func(dbc, my_dbc, countp, fpgno, fi, vargs)
+	DBC *dbc;
+	DBC *my_dbc;
+	u_int32_t *countp;
+	db_pgno_t fpgno;
+	u_int32_t fi;
+	void *vargs;
+{
+	BTREE_CURSOR *orig_cp;
+	DB *dbp;
+	int ret;
+	struct __bam_ca_dup_args *args;
+
+	COMPQUIET(my_dbc, NULL);
+	COMPQUIET(countp, NULL);
+
+	orig_cp = (BTREE_CURSOR *)dbc->internal;
+	dbp = dbc->dbp;
+	args = vargs;
+	/*
+	 * A note on the orig_cp->opd != NULL requirement here:
+	 * it's possible that there's a cursor that refers to
+	 * the same duplicate set, but which has no opd cursor,
+	 * because it refers to a different item and we took
+	 * care of it while processing a previous record.
+	 */
+	if (orig_cp->pgno != fpgno ||
+	    orig_cp->indx != args->first ||
+	    orig_cp->opd == NULL || ((BTREE_CURSOR *)
+	    orig_cp->opd->internal)->indx != args->ti ||
+	    MVCC_SKIP_CURADJ(dbc, fpgno))
+		return (0);
+	MUTEX_UNLOCK(dbp->env, dbp->mutex);
+	if ((ret = __dbc_close(orig_cp->opd)) != 0) {
+		MUTEX_LOCK(dbp->env, dbp->mutex);
+		return (ret);
+	}
+	orig_cp->opd = NULL;
+	orig_cp->indx = fi;
+	/*
+	 * We released the mutex to free a cursor,
+	 * start over.
+	 */
+	return (DB_LOCK_NOTGRANTED);
+}
+
+/*
+ * __bam_ca_undodup --
+ *	Adjust the cursors when returning items to a leaf page
+ *	from a duplicate page.
+ *	Called only during undo processing.
+ *
+ * PUBLIC: int __bam_ca_undodup __P((DB *,
+ * PUBLIC:    u_int32_t, db_pgno_t, u_int32_t, u_int32_t));
+ */
+int
+__bam_ca_undodup(dbp, first, fpgno, fi, ti)
+	DB *dbp;
+	db_pgno_t fpgno;
+	u_int32_t first, fi, ti;
+{
+	u_int32_t count;
+	struct __bam_ca_dup_args args;
+
+	args.first = first;
+	args.ti = ti;
+	return (__db_walk_cursors(dbp, NULL,
+	    __bam_ca_undodup_func, &count, fpgno, fi, &args));
+
+}
+
+static int
+__bam_ca_rsplit_func(dbc, my_dbc, foundp, fpgno, indx, args)
+	DBC *dbc;
+	DBC *my_dbc;
+	u_int32_t *foundp;
+	db_pgno_t fpgno;
+	u_int32_t indx;
+	void *args;
+{
+	db_pgno_t tpgno;
+
+	COMPQUIET(indx, 0);
+
+	if (dbc->dbtype == DB_RECNO)
+		return (0);
+
+	tpgno = *(db_pgno_t *)args;
+	if (dbc->internal->pgno == fpgno &&
+	    !MVCC_SKIP_CURADJ(dbc, fpgno)) {
+		dbc->internal->pgno = tpgno;
+		/* [#8032]
+		DB_ASSERT(env, !STD_LOCKING(dbc) ||
+		    dbc->internal->lock_mode != DB_LOCK_NG);
+		*/
+		if (IS_SUBTRANSACTION(my_dbc->txn) && dbc->txn != my_dbc->txn)
+			*foundp = 1;
+	}
+	return (0);
+}
+
+/*
+ * __bam_ca_rsplit --
+ *	Adjust the cursors when doing reverse splits.
+ *
+ * PUBLIC: int __bam_ca_rsplit __P((DBC *, db_pgno_t, db_pgno_t));
+ */
+int
+__bam_ca_rsplit(my_dbc, fpgno, tpgno)
+	DBC* my_dbc;
+	db_pgno_t fpgno, tpgno;
+{
+	DB *dbp;
+	DB_LSN lsn;
+	int ret;
+	u_int32_t found;
+
+	dbp = my_dbc->dbp;
+
+	if ((ret = __db_walk_cursors(dbp, my_dbc,
+	    __bam_ca_rsplit_func, &found, fpgno, 0, &tpgno)) != 0)
+		return (ret);
+
+	if (found != 0 && DBC_LOGGING(my_dbc)) {
+		if ((ret = __bam_curadj_log(dbp, my_dbc->txn,
+		    &lsn, 0, DB_CA_RSPLIT, fpgno, tpgno, 0, 0, 0, 0)) != 0)
+			return (ret);
+	}
+	return (0);
+}
+
+struct __bam_ca_split_args {
+	db_pgno_t lpgno, rpgno;
+	int cleft;
+	DB_TXN *my_txn;
+};
+
+static int
+__bam_ca_split_func(dbc, my_dbc, foundp, ppgno, split_indx, vargs)
+	DBC *dbc;
+	DBC *my_dbc;
+	u_int32_t *foundp;
+	db_pgno_t ppgno;
+	u_int32_t split_indx;
+	void *vargs;
+{
+	DBC_INTERNAL *cp;
+	struct __bam_ca_split_args *args;
+
+	COMPQUIET(my_dbc, NULL);
+
+	if (dbc->dbtype == DB_RECNO)
+		return (0);
+	cp = dbc->internal;
+	args = vargs;
+	if (cp->pgno == ppgno &&
+	    !MVCC_SKIP_CURADJ(dbc, ppgno)) {
+		/* [#8032]
+		DB_ASSERT(env, !STD_LOCKING(dbc) ||
+		    cp->lock_mode != DB_LOCK_NG);
+		*/
+		if (args->my_txn != NULL && args->my_txn != dbc->txn)
+			*foundp = 1;
+		if (cp->indx < split_indx) {
+			if (args->cleft)
+				cp->pgno = args->lpgno;
+		} else {
+			cp->pgno = args->rpgno;
+			cp->indx -= split_indx;
+		}
+	}
+	return (0);
+}
+
+/*
+ * __bam_ca_split --
+ *	Adjust the cursors when splitting a page.
+ *
+ * PUBLIC: int __bam_ca_split __P((DBC *,
+ * PUBLIC:    db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t, int));
+ */
+int
+__bam_ca_split(my_dbc, ppgno, lpgno, rpgno, split_indx, cleft)
+	DBC *my_dbc;
+	db_pgno_t ppgno, lpgno, rpgno;
+	u_int32_t split_indx;
+	int cleft;
+{
+	DB *dbp;
+	DB_LSN lsn;
+	int ret;
+	u_int32_t found;
+	struct __bam_ca_split_args args;
+
+	dbp = my_dbc->dbp;
+
+	/*
+	 * If splitting the page that a cursor was on, the cursor has to be
+	 * adjusted to point to the same record as before the split.  Most
+	 * of the time we don't adjust pointers to the left page, because
+	 * we're going to copy its contents back over the original page.  If
+	 * the cursor is on the right page, it is decremented by the number of
+	 * records split to the left page.
+	 */
+	args.lpgno = lpgno;
+	args.rpgno = rpgno;
+	args.cleft = cleft;
+	args.my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL;
+	if ((ret = __db_walk_cursors(dbp, my_dbc,
+	    __bam_ca_split_func, &found, ppgno, split_indx, &args)) != 0)
+		return (ret);
+
+	if (found != 0 && DBC_LOGGING(my_dbc)) {
+		if ((ret = __bam_curadj_log(dbp,
+		    my_dbc->txn, &lsn, 0, DB_CA_SPLIT, ppgno, rpgno,
+		    cleft ? lpgno : PGNO_INVALID, 0, split_indx, 0)) != 0)
+			return (ret);
+	}
+
+	return (0);
+}
+
+static int
+__bam_ca_undosplit_func(dbc, my_dbc, foundp, frompgno, split_indx, vargs)
+	DBC *dbc;
+	DBC *my_dbc;
+	u_int32_t *foundp;
+	db_pgno_t frompgno;
+	u_int32_t split_indx;
+	void *vargs;
+{
+	DBC_INTERNAL *cp;
+	struct __bam_ca_split_args *args;
+
+	COMPQUIET(my_dbc, NULL);
+	COMPQUIET(foundp, NULL);
+
+	if (dbc->dbtype == DB_RECNO)
+		return (0);
+	cp = dbc->internal;
+	args = vargs;
+	if (cp->pgno == args->rpgno &&
+	    !MVCC_SKIP_CURADJ(dbc, args->rpgno)) {
+		cp->pgno = frompgno;
+		cp->indx += split_indx;
+	} else if (cp->pgno == args->lpgno &&
+	    !MVCC_SKIP_CURADJ(dbc, args->lpgno))
+		cp->pgno = frompgno;
+
+	return (0);
+}
+
+/*
+ * __bam_ca_undosplit --
+ *	Adjust the cursors when undoing a split of a page.
+ *	If we grew a level we will execute this for both the
+ *	left and the right pages.
+ *	Called only during undo processing.
+ *
+ * PUBLIC: int __bam_ca_undosplit __P((DB *,
+ * PUBLIC:    db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t));
+ */
+int
+__bam_ca_undosplit(dbp, frompgno, topgno, lpgno, split_indx)
+	DB *dbp;
+	db_pgno_t frompgno, topgno, lpgno;
+	u_int32_t split_indx;
+{
+	u_int32_t count;
+	struct __bam_ca_split_args args;
+
+	/*
+	 * When backing out a split, we move the cursor back
+	 * to the original offset and bump it by the split_indx.
+	 */
+	args.lpgno = lpgno;
+	args.rpgno = topgno;
+	return (__db_walk_cursors(dbp, NULL,
+	    __bam_ca_undosplit_func, &count, frompgno, split_indx, &args));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_cursor.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,3098 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+
+static int  __bam_bulk __P((DBC *, DBT *, u_int32_t));
+static int  __bamc_close __P((DBC *, db_pgno_t, int *));
+static int  __bamc_del __P((DBC *, u_int32_t));
+static int  __bamc_destroy __P((DBC *));
+static int  __bamc_get __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
+static int  __bamc_getstack __P((DBC *));
+static int  __bamc_next __P((DBC *, int, int));
+static int  __bamc_physdel __P((DBC *));
+static int  __bamc_prev __P((DBC *));
+static int  __bamc_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
+static int  __bamc_search __P((DBC *,
+		db_pgno_t, const DBT *, u_int32_t, int *));
+static int  __bamc_writelock __P((DBC *));
+static int  __bam_getboth_finddatum __P((DBC *, DBT *, u_int32_t));
+static int  __bam_getbothc __P((DBC *, DBT *));
+static int  __bam_get_prev __P((DBC *));
+static int  __bam_isopd __P((DBC *, db_pgno_t *));
+#ifdef HAVE_COMPRESSION
+static int  __bam_getlte __P((DBC *, DBT *, DBT *));
+#endif
+
+/*
+ * Acquire a new page/lock.  If we hold a page/lock, discard the page, and
+ * lock-couple the lock.
+ *
+ * !!!
+ * We have to handle both where we have a lock to lock-couple and where we
+ * don't -- we don't duplicate locks when we duplicate cursors if we are
+ * running in a transaction environment as there's no point if locks are
+ * never discarded.  This means that the cursor may or may not hold a lock.
+ * In the case where we are descending the tree we always want to unlock
+ * the held interior page so we use ACQUIRE_COUPLE.
+ */
+#undef	ACQUIRE
+#define	ACQUIRE(dbc, mode, lpgno, lock, fpgno, pagep, flags, ret) do {	\
+	DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf;				\
+	if ((pagep) != NULL) {						\
+		ret = __memp_fput(__mpf,				\
+		     (dbc)->thread_info, pagep, dbc->priority);		\
+		pagep = NULL;						\
+	} else								\
+		ret = 0;						\
+	if ((ret) == 0 && STD_LOCKING(dbc))				\
+		ret = __db_lget(					\
+		    dbc, LCK_COUPLE, lpgno, mode, flags, &(lock));	\
+	if ((ret) == 0)							\
+		ret = __memp_fget(__mpf, &(fpgno),			\
+		    (dbc)->thread_info, (dbc)->txn, 0, &(pagep));	\
+} while (0)
+
+/* Acquire a new page/lock for a cursor. */
+#undef	ACQUIRE_CUR
+#define	ACQUIRE_CUR(dbc, mode, p, flags, ret) do {			\
+	BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal;		\
+	if (p != __cp->pgno)						\
+		__cp->pgno = PGNO_INVALID;				\
+	ACQUIRE(dbc, mode, p, __cp->lock, p, __cp->page, flags, ret);	\
+	if ((ret) == 0) {						\
+		__cp->pgno = p;						\
+		__cp->lock_mode = (mode);				\
+	}								\
+} while (0)
+
+/*
+ * Acquire a write lock if we don't already have one.
+ *
+ * !!!
+ * See ACQUIRE macro on why we handle cursors that don't have locks.
+ */
+#undef	ACQUIRE_WRITE_LOCK
+#define	ACQUIRE_WRITE_LOCK(dbc, ret) do {				\
+	BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal;		\
+	DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf;				\
+	int __get_page = 0;						\
+	ret = 0;							\
+	if (STD_LOCKING(dbc) &&	__cp->lock_mode != DB_LOCK_WRITE) {	\
+		if (__cp->page != NULL) {				\
+			(ret) = __memp_fput(__mpf, (dbc)->thread_info,	\
+			    __cp->page, (dbc)->priority);		\
+			__cp->page = NULL;				\
+			__get_page = 1;					\
+			if ((ret) !=0)					\
+				break;					\
+		}							\
+		if (((ret) = __db_lget((dbc),				\
+		    LOCK_ISSET(__cp->lock) ? LCK_COUPLE : 0,		\
+		    __cp->pgno, DB_LOCK_WRITE, 0, &__cp->lock)) != 0)	\
+			break;						\
+		__cp->lock_mode = DB_LOCK_WRITE;			\
+		if (__get_page == 0)					\
+			break;						\
+		(ret) = __memp_fget(__mpf, &__cp->pgno,		\
+		    (dbc)->thread_info,					\
+		    (dbc)->txn, DB_MPOOL_DIRTY, &__cp->page);		\
+	}								\
+} while (0)
+
+/* Discard the current page/lock for a cursor. */
+#undef	DISCARD_CUR
+#define	DISCARD_CUR(dbc, ret) do {					\
+	BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal;		\
+	DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf;				\
+	int __t_ret;							\
+	if ((__cp->page) != NULL) {					\
+		__t_ret = __memp_fput(__mpf,				\
+		     (dbc)->thread_info, __cp->page, dbc->priority);\
+		__cp->page = NULL;					\
+	} else								\
+		__t_ret = 0;						\
+	if (__t_ret != 0 && (ret) == 0)					\
+		ret = __t_ret;						\
+	__t_ret = __TLPUT((dbc), __cp->lock);				\
+	if (__t_ret != 0 && (ret) == 0)					\
+		ret = __t_ret;						\
+	if ((ret) == 0 && !LOCK_ISSET(__cp->lock))			\
+		__cp->lock_mode = DB_LOCK_NG;				\
+	__cp->stream_start_pgno = PGNO_INVALID;				\
+} while (0)
+
+/* If on-page item is a deleted record. */
+#undef	IS_DELETED
+#define	IS_DELETED(dbp, page, indx)					\
+	B_DISSET(GET_BKEYDATA(dbp, page,				\
+	    (indx) + (TYPE(page) == P_LBTREE ? O_INDX : 0))->type)
+#undef	IS_CUR_DELETED
+#define	IS_CUR_DELETED(dbc)						\
+	IS_DELETED((dbc)->dbp, (dbc)->internal->page, (dbc)->internal->indx)
+
+/*
+ * Test to see if two cursors could point to duplicates of the same key.
+ * In the case of off-page duplicates they are they same, as the cursors
+ * will be in the same off-page duplicate tree.  In the case of on-page
+ * duplicates, the key index offsets must be the same.  For the last test,
+ * as the original cursor may not have a valid page pointer, we use the
+ * current cursor's.
+ */
+#undef	IS_DUPLICATE
+#define	IS_DUPLICATE(dbc, i1, i2)					\
+	    (P_INP((dbc)->dbp,((PAGE *)(dbc)->internal->page))[i1] ==	\
+	     P_INP((dbc)->dbp,((PAGE *)(dbc)->internal->page))[i2])
+#undef	IS_CUR_DUPLICATE
+#define	IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)			\
+	(F_ISSET(dbc, DBC_OPD) ||					\
+	    (orig_pgno == (dbc)->internal->pgno &&			\
+	    IS_DUPLICATE(dbc, (dbc)->internal->indx, orig_indx)))
+
+/*
+ * __bamc_init --
+ *	Initialize the access private portion of a cursor
+ *
+ * PUBLIC: int __bamc_init __P((DBC *, DBTYPE));
+ */
+int
+__bamc_init(dbc, dbtype)
+	DBC *dbc;
+	DBTYPE dbtype;
+{
+	ENV *env;
+	int ret;
+#ifdef HAVE_COMPRESSION
+	BTREE_CURSOR *cp;
+#endif
+
+	env = dbc->env;
+
+	/* Allocate/initialize the internal structure. */
+	if (dbc->internal == NULL) {
+		if ((ret = __os_calloc(
+		    env, 1, sizeof(BTREE_CURSOR), &dbc->internal)) != 0)
+			return (ret);
+
+#ifdef HAVE_COMPRESSION
+		cp = (BTREE_CURSOR*)dbc->internal;
+		cp->compressed.flags = DB_DBT_USERMEM;
+		cp->key1.flags = DB_DBT_USERMEM;
+		cp->key2.flags = DB_DBT_USERMEM;
+		cp->data1.flags = DB_DBT_USERMEM;
+		cp->data2.flags = DB_DBT_USERMEM;
+		cp->del_key.flags = DB_DBT_USERMEM;
+		cp->del_data.flags = DB_DBT_USERMEM;
+#endif
+	}
+
+	/* Initialize methods. */
+	dbc->close = dbc->c_close = __dbc_close_pp;
+	dbc->cmp = __dbc_cmp_pp;
+	dbc->count = dbc->c_count = __dbc_count_pp;
+	dbc->del = dbc->c_del = __dbc_del_pp;
+	dbc->dup = dbc->c_dup = __dbc_dup_pp;
+	dbc->get = dbc->c_get = __dbc_get_pp;
+	dbc->pget = dbc->c_pget = __dbc_pget_pp;
+	dbc->put = dbc->c_put = __dbc_put_pp;
+	if (dbtype == DB_BTREE) {
+		dbc->am_bulk = __bam_bulk;
+		dbc->am_close = __bamc_close;
+		dbc->am_del = __bamc_del;
+		dbc->am_destroy = __bamc_destroy;
+		dbc->am_get = __bamc_get;
+		dbc->am_put = __bamc_put;
+		dbc->am_writelock = __bamc_writelock;
+	} else {
+		dbc->am_bulk = __bam_bulk;
+		dbc->am_close = __bamc_close;
+		dbc->am_del = __ramc_del;
+		dbc->am_destroy = __bamc_destroy;
+		dbc->am_get = __ramc_get;
+		dbc->am_put = __ramc_put;
+		dbc->am_writelock = __bamc_writelock;
+	}
+
+	return (0);
+}
+
+/*
+ * __bamc_refresh
+ *	Set things up properly for cursor re-use.
+ *
+ * PUBLIC: int __bamc_refresh __P((DBC *));
+ */
+int
+__bamc_refresh(dbc)
+	DBC *dbc;
+{
+	BTREE *t;
+	BTREE_CURSOR *cp;
+	DB *dbp;
+
+	dbp = dbc->dbp;
+	t = dbp->bt_internal;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	/*
+	 * If our caller set the root page number, it's because the root was
+	 * known.  This is always the case for off page dup cursors.  Else,
+	 * pull it out of our internal information, unless this is a subdb.
+	 */
+	if (cp->root == PGNO_INVALID && t->bt_meta == PGNO_BASE_MD)
+		cp->root = t->bt_root;
+
+	LOCK_INIT(cp->lock);
+	cp->lock_mode = DB_LOCK_NG;
+
+	if (cp->sp == NULL) {
+		cp->sp = cp->stack;
+		cp->esp = cp->stack + sizeof(cp->stack) / sizeof(cp->stack[0]);
+	}
+	BT_STK_CLR(cp);
+
+#ifdef HAVE_COMPRESSION
+	/* Initialize compression */
+	cp->prevKey = 0;
+	cp->prevData = 0;
+	cp->currentKey = 0;
+	cp->currentData = 0;
+	cp->compcursor = 0;
+	cp->compend = 0;
+	cp->prevcursor = 0;
+	cp->prev2cursor = 0;
+#endif
+
+	/*
+	 * The btree leaf page data structures require that two key/data pairs
+	 * (or four items) fit on a page, but other than that there's no fixed
+	 * requirement.  The btree off-page duplicates only require two items,
+	 * to be exact, but requiring four for them as well seems reasonable.
+	 *
+	 * Recno uses the btree bt_ovflsize value -- it's close enough.
+	 */
+	cp->ovflsize = B_MINKEY_TO_OVFLSIZE(
+	    dbp,  F_ISSET(dbc, DBC_OPD) ? 2 : t->bt_minkey, dbp->pgsize);
+
+	cp->recno = RECNO_OOB;
+	cp->order = INVALID_ORDER;
+	cp->flags = 0;
+
+	/* Initialize for record numbers. */
+	if (F_ISSET(dbc, DBC_OPD) ||
+	    dbc->dbtype == DB_RECNO || F_ISSET(dbp, DB_AM_RECNUM)) {
+		F_SET(cp, C_RECNUM);
+
+		/*
+		 * All btrees that support record numbers, optionally standard
+		 * recno trees, and all off-page duplicate recno trees have
+		 * mutable record numbers.
+		 */
+		if ((F_ISSET(dbc, DBC_OPD) && dbc->dbtype == DB_RECNO) ||
+		    F_ISSET(dbp, DB_AM_RECNUM | DB_AM_RENUMBER))
+			F_SET(cp, C_RENUMBER);
+	}
+
+	return (0);
+}
+
+/*
+ * __bamc_close --
+ *	Close down the cursor.
+ */
+static int
+__bamc_close(dbc, root_pgno, rmroot)
+	DBC *dbc;
+	db_pgno_t root_pgno;
+	int *rmroot;
+{
+	BTREE_CURSOR *cp, *cp_opd, *cp_c;
+	DB *dbp;
+	DBC *dbc_opd, *dbc_c;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h;
+	int cdb_lock, ret;
+	u_int32_t count;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	cp_opd = (dbc_opd = cp->opd) == NULL ?
+	    NULL : (BTREE_CURSOR *)dbc_opd->internal;
+	cdb_lock = ret = 0;
+
+	/*
+	 * There are 3 ways this function is called:
+	 *
+	 * 1. Closing a primary cursor: we get called with a pointer to a
+	 *    primary cursor that has a NULL opd field.  This happens when
+	 *    closing a btree/recno database cursor without an associated
+	 *    off-page duplicate tree.
+	 *
+	 * 2. Closing a primary and an off-page duplicate cursor stack: we
+	 *    get called with a pointer to the primary cursor which has a
+	 *    non-NULL opd field.  This happens when closing a btree cursor
+	 *    into database with an associated off-page btree/recno duplicate
+	 *    tree. (It can't be a primary recno database, recno databases
+	 *    don't support duplicates.)
+	 *
+	 * 3. Closing an off-page duplicate cursor stack: we get called with
+	 *    a pointer to the off-page duplicate cursor.  This happens when
+	 *    closing a non-btree database that has an associated off-page
+	 *    btree/recno duplicate tree or for a btree database when the
+	 *    opd tree is not empty (root_pgno == PGNO_INVALID).
+	 *
+	 * If either the primary or off-page duplicate cursor deleted a btree
+	 * key/data pair, check to see if the item is still referenced by a
+	 * different cursor.  If it is, confirm that cursor's delete flag is
+	 * set and leave it to that cursor to do the delete.
+	 *
+	 * NB: The test for == 0 below is correct.  Our caller already removed
+	 * our cursor argument from the active queue, we won't find it when we
+	 * search the queue in __bam_ca_delete().
+	 * NB: It can't be true that both the primary and off-page duplicate
+	 * cursors have deleted a btree key/data pair.  Either the primary
+	 * cursor may have deleted an item and there's no off-page duplicate
+	 * cursor, or there's an off-page duplicate cursor and it may have
+	 * deleted an item.
+	 *
+	 * Primary recno databases aren't an issue here.  Recno keys are either
+	 * deleted immediately or never deleted, and do not have to be handled
+	 * here.
+	 *
+	 * Off-page duplicate recno databases are an issue here, cases #2 and
+	 * #3 above can both be off-page recno databases.  The problem is the
+	 * same as the final problem for off-page duplicate btree databases.
+	 * If we no longer need the off-page duplicate tree, we want to remove
+	 * it.  For off-page duplicate btrees, we are done with the tree when
+	 * we delete the last item it contains, i.e., there can be no further
+	 * references to it when it's empty.  For off-page duplicate recnos,
+	 * we remove items from the tree as the application calls the remove
+	 * function, so we are done with the tree when we close the last cursor
+	 * that references it.
+	 *
+	 * We optionally take the root page number from our caller.  If the
+	 * primary database is a btree, we can get it ourselves because dbc
+	 * is the primary cursor.  If the primary database is not a btree,
+	 * the problem is that we may be dealing with a stack of pages.  The
+	 * cursor we're using to do the delete points at the bottom of that
+	 * stack and we need the top of the stack.
+	 */
+	if (F_ISSET(cp, C_DELETED)) {
+		dbc_c = dbc;
+		switch (dbc->dbtype) {
+		case DB_BTREE:				/* Case #1, #3. */
+			if ((ret = __bam_ca_delete(
+			    dbp, cp->pgno, cp->indx, 1, &count)) != 0)
+				goto err;
+			if (count == 0)
+				goto lock;
+			goto done;
+		case DB_RECNO:
+			if (!F_ISSET(dbc, DBC_OPD))	/* Case #1. */
+				goto done;
+							/* Case #3. */
+			if ((ret = __ram_ca_delete(dbp, cp->root, &count)) != 0)
+				goto err;
+			if (count == 0)
+				goto lock;
+			goto done;
+		case DB_HASH:
+		case DB_QUEUE:
+		case DB_UNKNOWN:
+		default:
+			ret = __db_unknown_type(
+			    env, "DbCursor.close", dbc->dbtype);
+			goto err;
+		}
+	}
+
+	if (dbc_opd == NULL)
+		goto done;
+
+	if (F_ISSET(cp_opd, C_DELETED)) {		/* Case #2. */
+		/*
+		 * We will not have been provided a root page number.  Acquire
+		 * one from the primary database.
+		 */
+		if ((h = cp->page) == NULL && (ret = __memp_fget(mpf, &cp->pgno,
+		     dbc->thread_info, dbc->txn, 0, &h)) != 0)
+			goto err;
+		root_pgno = GET_BOVERFLOW(dbp, h, cp->indx + O_INDX)->pgno;
+		if ((ret = __memp_fput(mpf,
+		     dbc->thread_info, h, dbc->priority)) != 0)
+			goto err;
+		cp->page = NULL;
+
+		dbc_c = dbc_opd;
+		switch (dbc_opd->dbtype) {
+		case DB_BTREE:
+			if ((ret = __bam_ca_delete(
+			    dbp, cp_opd->pgno, cp_opd->indx, 1, &count)) != 0)
+				goto err;
+			if (count == 0)
+				goto lock;
+			goto done;
+		case DB_RECNO:
+			if ((ret =
+			    __ram_ca_delete(dbp, cp_opd->root, &count)) != 0)
+				goto err;
+			if (count == 0)
+				goto lock;
+			goto done;
+		case DB_HASH:
+		case DB_QUEUE:
+		case DB_UNKNOWN:
+		default:
+			ret = __db_unknown_type(
+			   env, "DbCursor.close", dbc->dbtype);
+			goto err;
+		}
+	}
+	goto done;
+
+lock:	cp_c = (BTREE_CURSOR *)dbc_c->internal;
+
+	/*
+	 * If this is CDB, upgrade the lock if necessary.  While we acquired
+	 * the write lock to logically delete the record, we released it when
+	 * we returned from that call, and so may not be holding a write lock
+	 * at the moment.
+	 */
+	if (CDB_LOCKING(env)) {
+		if (F_ISSET(dbc, DBC_WRITECURSOR)) {
+			if ((ret = __lock_get(env,
+			    dbc->locker, DB_LOCK_UPGRADE, &dbc->lock_dbt,
+			    DB_LOCK_WRITE, &dbc->mylock)) != 0)
+				goto err;
+			cdb_lock = 1;
+		}
+		goto do_del;
+	}
+
+	/*
+	 * The variable dbc_c has been initialized to reference the cursor in
+	 * which we're going to do the delete.  Initialize the cursor's lock
+	 * structures as necessary.
+	 *
+	 * First, we may not need to acquire any locks.  If we're in case #3,
+	 * that is, the primary database isn't a btree database, our caller
+	 * is responsible for acquiring any necessary locks before calling us.
+	 */
+	if (F_ISSET(dbc, DBC_OPD))
+		goto do_del;
+
+	/*
+	 * Otherwise, acquire a write lock on the primary database's page.
+	 *
+	 * Lock the primary database page, regardless of whether we're deleting
+	 * an item on a primary database page or an off-page duplicates page.
+	 *
+	 * If the cursor that did the initial logical deletion (and had a write
+	 * lock) is not the same cursor doing the physical deletion (which may
+	 * have only ever had a read lock on the item), we need to upgrade to a
+	 * write lock.  The confusion comes as follows:
+	 *
+	 *	C1	created, acquires item read lock
+	 *	C2	dup C1, create C2, also has item read lock.
+	 *	C1	acquire write lock, delete item
+	 *	C1	close
+	 *	C2	close, needs a write lock to physically delete item.
+	 *
+	 * If we're in a TXN, we know that C2 will be able to acquire the write
+	 * lock, because no locker other than the one shared by C1 and C2 can
+	 * acquire a write lock -- the original write lock C1 acquired was never
+	 * discarded.
+	 *
+	 * If we're not in a TXN, it's nastier.  Other cursors might acquire
+	 * read locks on the item after C1 closed, discarding its write lock,
+	 * and such locks would prevent C2 from acquiring a read lock.  That's
+	 * OK, though, we'll simply wait until we can acquire a write lock, or
+	 * we'll deadlock.  (Which better not happen, since we're not in a TXN.)
+	 *
+	 * There are similar scenarios with dirty reads, where the cursor may
+	 * have downgraded its write lock to a was-write lock.
+	 */
+	if (STD_LOCKING(dbc))
+		if ((ret = __db_lget(dbc,
+		    LCK_COUPLE, cp->pgno, DB_LOCK_WRITE, 0, &cp->lock)) != 0)
+			goto err;
+
+do_del:	/*
+	 * If the delete occurred in a Btree, we're going to look at the page
+	 * to see if the item has to be physically deleted.  Otherwise, we do
+	 * not need the actual page (and it may not even exist, it might have
+	 * been truncated from the file after an allocation aborted).
+	 *
+	 * Delete the on-page physical item referenced by the cursor.
+	 */
+	if (F_ISSET(dbc_c, DBC_OPD))
+		LOCK_CHECK_OFF(dbc_c->thread_info);
+	if (dbc_c->dbtype == DB_BTREE) {
+		if ((ret = __memp_fget(mpf, &cp_c->pgno, dbc->thread_info,
+		    dbc->txn, DB_MPOOL_DIRTY, &cp_c->page)) != 0)
+			goto err_c;
+		if ((ret = __bamc_physdel(dbc_c)) != 0)
+			goto err_c;
+	}
+
+	/*
+	 * If we're not working in an off-page duplicate tree, then we're
+	 * done.
+	 */
+	if (!F_ISSET(dbc_c, DBC_OPD) || root_pgno == PGNO_INVALID)
+		goto done;
+
+	/*
+	 * We may have just deleted the last element in the off-page duplicate
+	 * tree, and closed the last cursor in the tree.  For an off-page btree
+	 * there are no other cursors in the tree by definition, if the tree is
+	 * empty.  For an off-page recno we know we have closed the last cursor
+	 * in the tree because the __ram_ca_delete call above returned 0 only
+	 * in that case.  So, if the off-page duplicate tree is empty at this
+	 * point, we want to remove it.
+	 */
+	if (((h = dbc_c->internal->page) == NULL || h->pgno != root_pgno) &&
+	    (ret = __memp_fget(mpf,
+	    &root_pgno, dbc->thread_info, dbc->txn, 0, &h)) != 0)
+		goto err_c;
+	if ((count = NUM_ENT(h)) == 0) {
+		if (h != dbc_c->internal->page)
+			DISCARD_CUR(dbc_c, ret);
+		else
+			dbc_c->internal->page = NULL;
+		if (ret == 0)
+			ret = __db_free(dbc, h, 0);
+	} else if (h != dbc_c->internal->page)
+		ret = __memp_fput(mpf, dbc->thread_info, h, dbc->priority);
+
+err_c:	if (F_ISSET(dbc_c, DBC_OPD))
+		LOCK_CHECK_ON(dbc_c->thread_info);
+	if (ret != 0)
+		goto err;
+
+	if (count != 0)
+		goto done;
+
+	/*
+	 * When removing the tree, we have to do one of two things.  If this is
+	 * case #2, that is, the primary tree is a btree, delete the key that's
+	 * associated with the tree from the btree leaf page.  We know we are
+	 * the only reference to it and we already have the correct lock.  We
+	 * detect this case because the cursor that was passed to us references
+	 * an off-page duplicate cursor.
+	 *
+	 * If this is case #3, that is, the primary tree isn't a btree, pass
+	 * the information back to our caller, it's their job to do cleanup on
+	 * the primary page.
+	 */
+	if (dbc_opd != NULL) {
+		if ((ret = __memp_fget(mpf, &cp->pgno, dbc->thread_info,
+		    dbc->txn, DB_MPOOL_DIRTY, &cp->page)) != 0)
+			goto err;
+		if ((ret = __bamc_physdel(dbc)) != 0)
+			goto err;
+	} else
+		*rmroot = 1;
+err:
+done:	/*
+	 * Discard the page references and locks, and confirm that the stack
+	 * has been emptied.
+	 */
+	if (dbc_opd != NULL)
+		DISCARD_CUR(dbc_opd, ret);
+	DISCARD_CUR(dbc, ret);
+
+	/* Downgrade any CDB lock we acquired. */
+	if (cdb_lock)
+		(void)__lock_downgrade(env, &dbc->mylock, DB_LOCK_IWRITE, 0);
+
+	return (ret);
+}
+
+/*
+ * __bamc_cmp --
+ *	Compare two btree cursors for equality.
+ *
+ * This function is only called with two cursors that point to the same item.
+ * It only distinguishes cursors pointing to deleted and undeleted items at
+ * the same location.
+ *
+ * PUBLIC: int __bamc_cmp __P((DBC *, DBC *, int *));
+ */
+int
+__bamc_cmp(dbc, other_dbc, result)
+	DBC *dbc, *other_dbc;
+	int *result;
+{
+	ENV *env;
+	BTREE_CURSOR *bcp, *obcp;
+
+	env = dbc->env;
+	bcp = (BTREE_CURSOR *)dbc->internal;
+	obcp = (BTREE_CURSOR *)other_dbc->internal;
+
+	DB_ASSERT (env, bcp->pgno == obcp->pgno);
+	DB_ASSERT (env, bcp->indx == obcp->indx);
+
+	/* Check to see if both cursors have the same deleted flag. */
+	*result =
+	    ((F_ISSET(bcp, C_DELETED)) == F_ISSET(obcp, C_DELETED)) ? 0 : 1;
+	return (0);
+}
+
+/*
+ * __bamc_destroy --
+ *	Close a single cursor -- internal version.
+ */
+static int
+__bamc_destroy(dbc)
+	DBC *dbc;
+{
+	BTREE_CURSOR *cp;
+	ENV *env;
+
+	cp = (BTREE_CURSOR *)dbc->internal;
+	env = dbc->env;
+
+	/* Discard the structures. */
+	if (cp->sp != cp->stack)
+		__os_free(env, cp->sp);
+
+#ifdef HAVE_COMPRESSION
+	/* Free the memory used for compression */
+	__os_free(env, cp->compressed.data);
+	__os_free(env, cp->key1.data);
+	__os_free(env, cp->key2.data);
+	__os_free(env, cp->data1.data);
+	__os_free(env, cp->data2.data);
+	__os_free(env, cp->del_key.data);
+	__os_free(env, cp->del_data.data);
+#endif
+
+	__os_free(env, cp);
+
+	return (0);
+}
+
+/*
+ * __bamc_count --
+ *	Return a count of on and off-page duplicates.
+ *
+ * PUBLIC: int __bamc_count __P((DBC *, db_recno_t *));
+ */
+int
+__bamc_count(dbc, recnop)
+	DBC *dbc;
+	db_recno_t *recnop;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DB_MPOOLFILE *mpf;
+	db_indx_t indx, top;
+	db_recno_t recno;
+	int ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	/*
+	 * Called with the top-level cursor that may reference an off-page
+	 * duplicates tree.  We don't have to acquire any new locks, we have
+	 * to have a read lock to even get here.
+	 */
+	if (cp->opd == NULL) {
+		/*
+		 * On-page duplicates, get the page and count.
+		 */
+		DB_ASSERT(dbp->env, cp->page == NULL);
+		if ((ret = __memp_fget(mpf, &cp->pgno,
+		    dbc->thread_info, dbc->txn, 0, &cp->page)) != 0)
+			return (ret);
+
+		/*
+		 * Move back to the beginning of the set of duplicates and
+		 * then count forward.
+		 */
+		for (indx = cp->indx;; indx -= P_INDX)
+			if (indx == 0 ||
+			    !IS_DUPLICATE(dbc, indx, indx - P_INDX))
+				break;
+		for (recno = 0,
+		    top = NUM_ENT(cp->page) - P_INDX;; indx += P_INDX) {
+			if (!IS_DELETED(dbp, cp->page, indx))
+				++recno;
+			if (indx == top ||
+			    !IS_DUPLICATE(dbc, indx, indx + P_INDX))
+				break;
+		}
+	} else {
+		/*
+		 * Off-page duplicates tree, get the root page of the off-page
+		 * duplicate tree.
+		 */
+		if ((ret = __memp_fget(mpf, &cp->opd->internal->root,
+		    dbc->thread_info, dbc->txn, 0, &cp->page)) != 0)
+			return (ret);
+
+		/*
+		 * If the page is an internal page use the page's count as it's
+		 * up-to-date and reflects the status of cursors in the tree.
+		 * If the page is a leaf page for unsorted duplicates, use the
+		 * page's count as cursors don't mark items deleted on the page
+		 * and wait, cursor delete items immediately.
+		 * If the page is a leaf page for sorted duplicates, there may
+		 * be cursors on the page marking deleted items -- count.
+		 */
+		if (TYPE(cp->page) == P_LDUP)
+			for (recno = 0, indx = 0,
+			    top = NUM_ENT(cp->page) - O_INDX;; indx += O_INDX) {
+				if (!IS_DELETED(dbp, cp->page, indx))
+					++recno;
+				if (indx == top)
+					break;
+			}
+		else
+			recno = RE_NREC(cp->page);
+	}
+
+	*recnop = recno;
+
+	ret = __memp_fput(mpf, dbc->thread_info, cp->page, dbc->priority);
+	cp->page = NULL;
+
+	return (ret);
+}
+
+/*
+ * __bamc_del --
+ *	Delete using a cursor.
+ */
+static int
+__bamc_del(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DB_MPOOLFILE *mpf;
+	int ret, t_ret;
+	u_int32_t count;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	ret = 0;
+	COMPQUIET(flags, 0);
+
+	/* If the item was already deleted, return failure. */
+	if (F_ISSET(cp, C_DELETED))
+		return (DB_KEYEMPTY);
+
+	/*
+	 * This code is always called with a page lock but no page.
+	 */
+	DB_ASSERT(dbp->env, cp->page == NULL);
+
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_OFF(dbc->thread_info);
+
+	/*
+	 * We don't physically delete the record until the cursor moves, so
+	 * we have to have a long-lived write lock on the page instead of a
+	 * a long-lived read lock.  Note, we have to have a read lock to even
+	 * get here.
+	 *
+	 * If we're maintaining record numbers, we lock the entire tree, else
+	 * we lock the single page.
+	 */
+	if (F_ISSET(cp, C_RECNUM)) {
+		if ((ret = __bamc_getstack(dbc)) != 0)
+			goto err;
+		cp->page = cp->csp->page;
+	} else {
+		ACQUIRE_CUR(dbc, DB_LOCK_WRITE, cp->pgno, 0, ret);
+		if (ret != 0)
+			goto err;
+	}
+
+	/* Mark the page dirty. */
+	if ((ret = __memp_dirty(mpf,
+	    &cp->page, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+		goto err;
+
+	/* Log the change. */
+	if (DBC_LOGGING(dbc)) {
+		if ((ret = __bam_cdel_log(dbp, dbc->txn, &LSN(cp->page), 0,
+		    PGNO(cp->page), &LSN(cp->page), cp->indx)) != 0)
+			goto err;
+	} else
+		LSN_NOT_LOGGED(LSN(cp->page));
+
+	/* Set the intent-to-delete flag on the page. */
+	if (TYPE(cp->page) == P_LBTREE)
+		B_DSET(GET_BKEYDATA(dbp, cp->page, cp->indx + O_INDX)->type);
+	else
+		B_DSET(GET_BKEYDATA(dbp, cp->page, cp->indx)->type);
+
+err:	/*
+	 * If we've been successful so far and the tree has record numbers,
+	 * adjust the record counts.  Either way, release acquired page(s).
+	 */
+	if (F_ISSET(cp, C_RECNUM)) {
+		cp->csp->page = cp->page;
+		if (ret == 0)
+			ret = __bam_adjust(dbc, -1);
+		(void)__bam_stkrel(dbc, 0);
+	} else
+		if (cp->page != NULL &&
+		    (t_ret = __memp_fput(mpf, dbc->thread_info,
+		    cp->page, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+
+	cp->page = NULL;
+
+	/*
+	 * Update the cursors last, after all chance of recoverable failure
+	 * is past.
+	 */
+	if (ret == 0)
+		ret = __bam_ca_delete(dbp, cp->pgno, cp->indx, 1, &count);
+
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_ON(dbc->thread_info);
+	return (ret);
+}
+
+/*
+ * __bamc_dup --
+ *	Duplicate a btree cursor, such that the new one holds appropriate
+ *	locks for the position of the original.
+ *
+ * PUBLIC: int __bamc_dup __P((DBC *, DBC *, u_int32_t));
+ */
+int
+__bamc_dup(orig_dbc, new_dbc, flags)
+	DBC *orig_dbc, *new_dbc;
+	u_int32_t flags;
+{
+	BTREE_CURSOR *orig, *new;
+
+	orig = (BTREE_CURSOR *)orig_dbc->internal;
+	new = (BTREE_CURSOR *)new_dbc->internal;
+
+	new->ovflsize = orig->ovflsize;
+	new->recno = orig->recno;
+	new->flags = orig->flags;
+
+#ifdef HAVE_COMPRESSION
+	/* Copy the compression state */
+	return (__bamc_compress_dup(orig_dbc, new_dbc, flags));
+#else
+	COMPQUIET(flags, 0);
+
+	return (0);
+#endif
+}
+
+/*
+ * __bamc_get --
+ *	Get using a cursor (btree).
+ */
+static int
+__bamc_get(dbc, key, data, flags, pgnop)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+	db_pgno_t *pgnop;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DB_MPOOLFILE *mpf;
+	db_pgno_t orig_pgno;
+	db_indx_t orig_indx;
+	int exact, newopd, ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	orig_pgno = cp->pgno;
+	orig_indx = cp->indx;
+
+	newopd = 0;
+	switch (flags) {
+	case DB_CURRENT:
+		/* It's not possible to return a deleted record. */
+		if (F_ISSET(cp, C_DELETED)) {
+			ret = DB_KEYEMPTY;
+			goto err;
+		}
+
+		/*
+		 * Acquire the current page.  We have at least a read-lock
+		 * already.  The caller may have set DB_RMW asking for a
+		 * write lock, but upgrading to a write lock has no better
+		 * chance of succeeding now instead of later, so don't try.
+		 */
+		if ((ret = __memp_fget(mpf, &cp->pgno,
+		    dbc->thread_info, dbc->txn, 0, &cp->page)) != 0)
+			goto err;
+		break;
+	case DB_FIRST:
+		newopd = 1;
+		if ((ret = __bamc_search(dbc,
+		     PGNO_INVALID, NULL, flags, &exact)) != 0)
+			goto err;
+		break;
+	case DB_GET_BOTH:
+	case DB_GET_BOTH_RANGE:
+		/*
+		 * There are two ways to get here based on DBcursor->get
+		 * with the DB_GET_BOTH/DB_GET_BOTH_RANGE flags set:
+		 *
+		 * 1. Searching a sorted off-page duplicate tree: do a tree
+		 * search.
+		 *
+		 * 2. Searching btree: do a tree search.  If it returns a
+		 * reference to off-page duplicate tree, return immediately
+		 * and let our caller deal with it.  If the search doesn't
+		 * return a reference to off-page duplicate tree, continue
+		 * with an on-page search.
+		 */
+		if (F_ISSET(dbc, DBC_OPD)) {
+			if ((ret = __bamc_search(
+			    dbc, PGNO_INVALID, data, flags, &exact)) != 0)
+				goto err;
+			if (flags == DB_GET_BOTH) {
+				if (!exact) {
+					ret = DB_NOTFOUND;
+					goto err;
+				}
+				break;
+			}
+
+			/*
+			 * We didn't require an exact match, so the search may
+			 * may have returned an entry past the end of the page,
+			 * or we may be referencing a deleted record.  If so,
+			 * move to the next entry.
+			 */
+			if ((cp->indx == NUM_ENT(cp->page) ||
+			    IS_CUR_DELETED(dbc)) &&
+			    (ret = __bamc_next(dbc, 1, 0)) != 0)
+				goto err;
+		} else {
+			if ((ret = __bamc_search(
+			    dbc, PGNO_INVALID, key, flags, &exact)) != 0)
+				return (ret);
+			if (!exact) {
+				ret = DB_NOTFOUND;
+				goto err;
+			}
+
+			if (pgnop != NULL && __bam_isopd(dbc, pgnop)) {
+				newopd = 1;
+				break;
+			}
+			if ((ret =
+			    __bam_getboth_finddatum(dbc, data, flags)) != 0)
+				goto err;
+		}
+		break;
+#ifdef HAVE_COMPRESSION
+	case DB_SET_LTE:
+		if ((ret = __bam_getlte(dbc, key, NULL)) != 0)
+			goto err;
+		break;
+	case DB_GET_BOTH_LTE:
+		if ((ret = __bam_getlte(dbc, key, data)) != 0)
+			goto err;
+		break;
+#endif
+	case DB_GET_BOTHC:
+		if ((ret = __bam_getbothc(dbc, data)) != 0)
+			goto err;
+		break;
+	case DB_LAST:
+		newopd = 1;
+		if ((ret = __bamc_search(dbc,
+		     PGNO_INVALID, NULL, flags, &exact)) != 0)
+			goto err;
+		break;
+	case DB_NEXT:
+		newopd = 1;
+		if (cp->pgno == PGNO_INVALID) {
+			if ((ret = __bamc_search(dbc,
+			     PGNO_INVALID, NULL, DB_FIRST, &exact)) != 0)
+				goto err;
+		} else
+			if ((ret = __bamc_next(dbc, 1, 0)) != 0)
+				goto err;
+		break;
+	case DB_NEXT_DUP:
+		if ((ret = __bamc_next(dbc, 1, 0)) != 0)
+			goto err;
+		if (!IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)) {
+			ret = DB_NOTFOUND;
+			goto err;
+		}
+		break;
+	case DB_NEXT_NODUP:
+		newopd = 1;
+		if (cp->pgno == PGNO_INVALID) {
+			if ((ret = __bamc_search(dbc,
+			     PGNO_INVALID, NULL, DB_FIRST, &exact)) != 0)
+				goto err;
+		} else
+			do {
+				if ((ret = __bamc_next(dbc, 1, 0)) != 0)
+					goto err;
+			} while (IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx));
+		break;
+	case DB_PREV:
+		newopd = 1;
+		if (cp->pgno == PGNO_INVALID) {
+			if ((ret = __bamc_search(dbc,
+			     PGNO_INVALID, NULL, DB_LAST, &exact)) != 0)
+				goto err;
+		} else
+			if ((ret = __bamc_prev(dbc)) != 0)
+				goto err;
+		break;
+	case DB_PREV_DUP:
+		if ((ret = __bamc_prev(dbc)) != 0)
+			goto err;
+		if (!IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)) {
+			ret = DB_NOTFOUND;
+			goto err;
+		}
+		break;
+	case DB_PREV_NODUP:
+		newopd = 1;
+		if (cp->pgno == PGNO_INVALID) {
+			if ((ret = __bamc_search(dbc,
+			     PGNO_INVALID, NULL, DB_LAST, &exact)) != 0)
+				goto err;
+		} else
+			do {
+				if ((ret = __bamc_prev(dbc)) != 0)
+					goto err;
+			} while (IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx));
+		break;
+	case DB_SET:
+	case DB_SET_RECNO:
+		newopd = 1;
+		if ((ret = __bamc_search(dbc,
+		    PGNO_INVALID, key, flags, &exact)) != 0)
+			goto err;
+		break;
+	case DB_SET_RANGE:
+		newopd = 1;
+		if ((ret = __bamc_search(dbc,
+		    PGNO_INVALID, key, flags, &exact)) != 0)
+			goto err;
+
+		/*
+		 * As we didn't require an exact match, the search function
+		 * may have returned an entry past the end of the page.  Or,
+		 * we may be referencing a deleted record.  If so, move to
+		 * the next entry.
+		 */
+		if (cp->indx == NUM_ENT(cp->page) || IS_CUR_DELETED(dbc))
+			if ((ret = __bamc_next(dbc, 0, 0)) != 0)
+				goto err;
+		break;
+	default:
+		ret = __db_unknown_flag(dbp->env, "__bamc_get", flags);
+		goto err;
+	}
+
+	/*
+	 * We may have moved to an off-page duplicate tree.  Return that
+	 * information to our caller.
+	 */
+	if (newopd && pgnop != NULL)
+		(void)__bam_isopd(dbc, pgnop);
+
+err:	/*
+	 * Regardless of whether we were successful or not, if the cursor
+	 * moved, clear the delete flag, DBcursor->get never references a
+	 * deleted key, if it moved at all.
+	 */
+	if (F_ISSET(cp, C_DELETED) &&
+	    (cp->pgno != orig_pgno || cp->indx != orig_indx))
+		F_CLR(cp, C_DELETED);
+
+	return (ret);
+}
+
+static int
+__bam_get_prev(dbc)
+	DBC *dbc;
+{
+	BTREE_CURSOR *cp;
+	DBT key, data;
+	db_pgno_t pgno;
+	int ret;
+
+	if ((ret = __bamc_prev(dbc)) != 0)
+		return (ret);
+
+	if (__bam_isopd(dbc, &pgno)) {
+		cp = (BTREE_CURSOR *)dbc->internal;
+		if ((ret = __dbc_newopd(dbc, pgno, cp->opd, &cp->opd)) != 0)
+			return (ret);
+		if ((ret = cp->opd->am_get(cp->opd,
+		    &key, &data, DB_LAST, NULL)) != 0)
+			return (ret);
+	}
+
+	return (0);
+}
+
+/*
+ * __bam_bulk -- Return bulk data from a btree.
+ */
+static int
+__bam_bulk(dbc, data, flags)
+	DBC *dbc;
+	DBT *data;
+	u_int32_t flags;
+{
+	BKEYDATA *bk;
+	BOVERFLOW *bo;
+	BTREE_CURSOR *cp;
+	PAGE *pg;
+	db_indx_t *inp, indx, pg_keyoff;
+	int32_t  *endp, key_off, *offp, *saveoffp;
+	u_int8_t *dbuf, *dp, *np;
+	u_int32_t key_size, pagesize, size, space;
+	int adj, is_key, need_pg, next_key, no_dup, rec_key, ret;
+
+	ret = 0;
+	key_off = 0;
+	size = 0;
+	pagesize = dbc->dbp->pgsize;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	/*
+	 * dp tracks the beginning of the page in the buffer.
+	 * np is the next place to copy things into the buffer.
+	 * dbuf always stays at the beginning of the buffer.
+	 */
+	dbuf = data->data;
+	np = dp = dbuf;
+
+	/* Keep track of space that is left.  There is a termination entry */
+	space = data->ulen;
+	space -= sizeof(*offp);
+
+	/* Build the offset/size table from the end up. */
+	endp = (int32_t *)((u_int8_t *)dbuf + data->ulen);
+	endp--;
+	offp = endp;
+
+	key_size = 0;
+
+	/*
+	 * Distinguish between BTREE and RECNO.
+	 * There are no keys in RECNO.  If MULTIPLE_KEY is specified
+	 * then we return the record numbers.
+	 * is_key indicates that multiple btree keys are returned.
+	 * rec_key is set if we are returning record numbers.
+	 * next_key is set if we are going after the next key rather than dup.
+	 */
+	if (dbc->dbtype == DB_BTREE) {
+		is_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1: 0;
+		rec_key = 0;
+		next_key = is_key && LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP;
+		adj = 2;
+	} else {
+		is_key = 0;
+		rec_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1 : 0;
+		next_key = LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP;
+		adj = 1;
+	}
+	no_dup = LF_ISSET(DB_OPFLAGS_MASK) == DB_NEXT_NODUP;
+
+next_pg:
+	indx = cp->indx;
+	pg = cp->page;
+
+	inp = P_INP(dbc->dbp, pg);
+	/* The current page is not yet in the buffer. */
+	need_pg = 1;
+
+	/*
+	 * Keep track of the offset of the current key on the page.
+	 * If we are returning keys, set it to 0 first so we force
+	 * the copy of the key to the buffer.
+	 */
+	pg_keyoff = 0;
+	if (is_key == 0)
+		pg_keyoff = inp[indx];
+
+	do {
+		if (IS_DELETED(dbc->dbp, pg, indx)) {
+			if (dbc->dbtype != DB_RECNO)
+				continue;
+
+			cp->recno++;
+			/*
+			 * If we are not returning recnos then we
+			 * need to fill in every slot so the user
+			 * can calculate the record numbers.
+			 */
+			if (rec_key != 0)
+				continue;
+
+			space -= 2 * sizeof(*offp);
+			/* Check if space as underflowed. */
+			if (space > data->ulen)
+				goto back_up;
+
+			/* Just mark the empty recno slots. */
+			*offp-- = 0;
+			*offp-- = 0;
+			continue;
+		}
+
+		/*
+		 * Check to see if we have a new key.
+		 * If so, then see if we need to put the
+		 * key on the page.  If its already there
+		 * then we just point to it.
+		 */
+		if (is_key && pg_keyoff != inp[indx]) {
+			bk = GET_BKEYDATA(dbc->dbp, pg, indx);
+			if (B_TYPE(bk->type) == B_OVERFLOW) {
+				bo = (BOVERFLOW *)bk;
+				size = key_size = bo->tlen;
+				if (key_size > space)
+					goto get_key_space;
+				if ((ret = __bam_bulk_overflow(dbc,
+				    bo->tlen, bo->pgno, np)) != 0)
+					return (ret);
+				space -= key_size;
+				key_off = (int32_t)(np - dbuf);
+				np += key_size;
+			} else {
+				if (need_pg) {
+					dp = np;
+					size = pagesize - HOFFSET(pg);
+					if (space < size) {
+get_key_space:
+						/* Nothing added, then error. */
+						if (offp == endp) {
+							data->size = (u_int32_t)
+							    DB_ALIGN(size +
+							    pagesize, 1024);
+							return
+							    (DB_BUFFER_SMALL);
+						}
+						/*
+						 * We need to back up to the
+						 * last record put into the
+						 * buffer so that it is
+						 * CURRENT.
+						 */
+						if (indx != 0)
+							indx -= P_INDX;
+						else {
+							if ((ret =
+							    __bam_get_prev(
+							    dbc)) != 0)
+								return (ret);
+							indx = cp->indx;
+							pg = cp->page;
+						}
+						break;
+					}
+					/*
+					 * Move the data part of the page
+					 * to the buffer.
+					 */
+					memcpy(dp,
+					   (u_int8_t *)pg + HOFFSET(pg), size);
+					need_pg = 0;
+					space -= size;
+					np += size;
+				}
+				key_size = bk->len;
+				key_off = (int32_t)((inp[indx] - HOFFSET(pg))
+				    + (dp - dbuf) + SSZA(BKEYDATA, data));
+				pg_keyoff = inp[indx];
+			}
+		}
+
+		/*
+		 * Reserve space for the pointers and sizes.
+		 * Either key/data pair or just for a data item.
+		 */
+		space -= (is_key ? 4 : 2) * sizeof(*offp);
+		if (rec_key)
+			space -= sizeof(*offp);
+
+		/* Check to see if space has underflowed. */
+		if (space > data->ulen)
+			goto back_up;
+
+		/*
+		 * Determine if the next record is in the
+		 * buffer already or if it needs to be copied in.
+		 * If we have an off page dup, then copy as many
+		 * as will fit into the buffer.
+		 */
+		bk = GET_BKEYDATA(dbc->dbp, pg, indx + adj - 1);
+		if (B_TYPE(bk->type) == B_DUPLICATE) {
+			bo = (BOVERFLOW *)bk;
+			if (is_key) {
+				*offp-- = (int32_t)key_off;
+				*offp-- = (int32_t)key_size;
+			}
+			/*
+			 * We pass the offset of the current key.
+			 * On return we check to see if offp has
+			 * moved to see if any data fit.
+			 */
+			saveoffp = offp;
+			if ((ret = __bam_bulk_duplicates(dbc, bo->pgno,
+			    dbuf, is_key ? offp + P_INDX : NULL,
+			    &offp, &np, &space, no_dup)) != 0) {
+				if (ret == DB_BUFFER_SMALL) {
+					size = space;
+					space = 0;
+					/* If nothing was added, then error. */
+					if (offp == saveoffp) {
+						offp += 2;
+						goto back_up;
+					}
+					goto get_space;
+				}
+				return (ret);
+			}
+		} else if (B_TYPE(bk->type) == B_OVERFLOW) {
+			bo = (BOVERFLOW *)bk;
+			size = bo->tlen;
+			if (size > space)
+				goto back_up;
+			if ((ret =
+			    __bam_bulk_overflow(dbc,
+				bo->tlen, bo->pgno, np)) != 0)
+				return (ret);
+			space -= size;
+			if (is_key) {
+				*offp-- = (int32_t)key_off;
+				*offp-- = (int32_t)key_size;
+			} else if (rec_key)
+				*offp-- = (int32_t)cp->recno;
+			*offp-- = (int32_t)(np - dbuf);
+			np += size;
+			*offp-- = (int32_t)size;
+		} else {
+			if (need_pg) {
+				dp = np;
+				size = pagesize - HOFFSET(pg);
+				if (space < size) {
+back_up:
+					/*
+					 * Back up the index so that the
+					 * last record in the buffer is CURRENT
+					 */
+					if (indx >= adj)
+						indx -= adj;
+					else {
+						if ((ret =
+						    __bam_get_prev(dbc)) != 0 &&
+						    ret != DB_NOTFOUND)
+							return (ret);
+						indx = cp->indx;
+						pg = cp->page;
+					}
+					if (dbc->dbtype == DB_RECNO)
+						cp->recno--;
+get_space:
+					/*
+					 * See if we put anything in the
+					 * buffer or if we are doing a DBP->get
+					 * did we get all of the data.
+					 */
+					if (offp >=
+					    (is_key ? &endp[-1] : endp) ||
+					    F_ISSET(dbc, DBC_FROM_DB_GET)) {
+						data->size = (u_int32_t)
+						    DB_ALIGN(size +
+						    data->ulen - space, 1024);
+						return (DB_BUFFER_SMALL);
+					}
+					break;
+				}
+				memcpy(dp, (u_int8_t *)pg + HOFFSET(pg), size);
+				need_pg = 0;
+				space -= size;
+				np += size;
+			}
+			/*
+			 * Add the offsets and sizes to the end of the buffer.
+			 * First add the key info then the data info.
+			 */
+			if (is_key) {
+				*offp-- = (int32_t)key_off;
+				*offp-- = (int32_t)key_size;
+			} else if (rec_key)
+				*offp-- = (int32_t)cp->recno;
+			*offp-- = (int32_t)((inp[indx + adj - 1] - HOFFSET(pg))
+			    + (dp - dbuf) + SSZA(BKEYDATA, data));
+			*offp-- = bk->len;
+		}
+		if (dbc->dbtype == DB_RECNO)
+			cp->recno++;
+		else if (no_dup) {
+			while (indx + adj < NUM_ENT(pg) &&
+			    pg_keyoff == inp[indx + adj])
+				indx += adj;
+		}
+	/*
+	 * Stop when we either run off the page or we move to the next key and
+	 * we are not returning multiple keys.
+	 */
+	} while ((indx += adj) < NUM_ENT(pg) &&
+	    (next_key || pg_keyoff == inp[indx]));
+
+	/* If we are off the page then try to the next page. */
+	if (ret == 0 && next_key && indx >= NUM_ENT(pg)) {
+		cp->indx = indx;
+		ret = __bamc_next(dbc, 0, 1);
+		if (ret == 0)
+			goto next_pg;
+		if (ret != DB_NOTFOUND)
+			return (ret);
+	}
+
+	/*
+	 * If we did a DBP->get we must error if we did not return
+	 * all the data for the current key because there is
+	 * no way to know if we did not get it all, nor any
+	 * interface to fetch the balance.
+	 */
+
+	if (ret == 0 && indx < pg->entries &&
+	    F_ISSET(dbc, DBC_TRANSIENT) && pg_keyoff == inp[indx]) {
+		data->size = (data->ulen - space) + size;
+		return (DB_BUFFER_SMALL);
+	}
+	/*
+	 * Must leave the index pointing at the last record fetched.
+	 * If we are not fetching keys, we may have stepped to the
+	 * next key.
+	 */
+	if (ret == DB_BUFFER_SMALL || next_key || pg_keyoff == inp[indx])
+		cp->indx = indx;
+	else
+		cp->indx = indx - P_INDX;
+
+	if (rec_key == 1)
+		*offp = RECNO_OOB;
+	else
+		*offp = -1;
+	return (0);
+}
+
+/*
+ * __bam_bulk_overflow --
+ *	Dump overflow record into the buffer.
+ *	The space requirements have already been checked.
+ * PUBLIC: int __bam_bulk_overflow
+ * PUBLIC:    __P((DBC *, u_int32_t, db_pgno_t, u_int8_t *));
+ */
+int
+__bam_bulk_overflow(dbc, len, pgno, dp)
+	DBC *dbc;
+	u_int32_t len;
+	db_pgno_t pgno;
+	u_int8_t *dp;
+{
+	DBT dbt;
+
+	memset(&dbt, 0, sizeof(dbt));
+	F_SET(&dbt, DB_DBT_USERMEM);
+	dbt.ulen = len;
+	dbt.data = (void *)dp;
+	return (__db_goff(dbc, &dbt, len, pgno, NULL, NULL));
+}
+
+/*
+ * __bam_bulk_duplicates --
+ *	Put as many off page duplicates as will fit into the buffer.
+ * This routine will adjust the cursor to reflect the position in
+ * the overflow tree.
+ * PUBLIC: int __bam_bulk_duplicates __P((DBC *,
+ * PUBLIC:       db_pgno_t, u_int8_t *, int32_t *,
+ * PUBLIC:	 int32_t **, u_int8_t **, u_int32_t *, int));
+ */
+int
+__bam_bulk_duplicates(dbc, pgno, dbuf, keyoff, offpp, dpp, spacep, no_dup)
+	DBC *dbc;
+	db_pgno_t pgno;
+	u_int8_t *dbuf;
+	int32_t *keyoff, **offpp;
+	u_int8_t **dpp;
+	u_int32_t *spacep;
+	int no_dup;
+{
+	BKEYDATA *bk;
+	BOVERFLOW *bo;
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DBC *opd;
+	DBT key, data;
+	PAGE *pg;
+	db_indx_t indx, *inp;
+	int32_t *offp;
+	u_int32_t pagesize, size, space;
+	u_int8_t *dp, *np;
+	int first, need_pg, ret, t_ret;
+
+	ret = 0;
+
+	dbp = dbc->dbp;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	opd = cp->opd;
+
+	if (opd == NULL) {
+		if ((ret = __dbc_newopd(dbc, pgno, NULL, &opd)) != 0)
+			return (ret);
+		cp->opd = opd;
+		if ((ret = opd->am_get(opd,
+		    &key, &data, DB_FIRST, NULL)) != 0)
+			goto close_opd;
+	}
+
+	pagesize = opd->dbp->pgsize;
+	cp = (BTREE_CURSOR *)opd->internal;
+	space = *spacep;
+	/* Get current offset slot. */
+	offp = *offpp;
+
+	/*
+	 * np is the next place to put data.
+	 * dp is the beginning of the current page in the buffer.
+	 */
+	np = dp = *dpp;
+	first = 1;
+	indx = cp->indx;
+
+	do {
+		/* Fetch the current record.  No initial move. */
+		if ((ret = __bamc_next(opd, 0, 0)) != 0)
+			break;
+		pg = cp->page;
+		indx = cp->indx;
+		inp = P_INP(dbp, pg);
+		/* We need to copy the page to the buffer. */
+		need_pg = 1;
+
+		do {
+			if (IS_DELETED(dbp, pg, indx))
+				goto contin;
+			bk = GET_BKEYDATA(dbp, pg, indx);
+			space -= 2 * sizeof(*offp);
+			/* Allocate space for key if needed. */
+			if (first == 0 && keyoff != NULL)
+				space -= 2 * sizeof(*offp);
+
+			/* Did space underflow? */
+			if (space > *spacep) {
+				ret = DB_BUFFER_SMALL;
+				if (first == 1) {
+					/* Get the absolute value. */
+					space = -(int32_t)space;
+					space = *spacep + space;
+					if (need_pg)
+						space += pagesize - HOFFSET(pg);
+				}
+				break;
+			}
+			if (B_TYPE(bk->type) == B_OVERFLOW) {
+				bo = (BOVERFLOW *)bk;
+				size = bo->tlen;
+				if (size > space) {
+					ret = DB_BUFFER_SMALL;
+					space = *spacep + size;
+					break;
+				}
+				if (first == 0 && keyoff != NULL) {
+					*offp-- = keyoff[0];
+					*offp-- = keyoff[-1];
+				}
+				if ((ret = __bam_bulk_overflow(dbc,
+				    bo->tlen, bo->pgno, np)) != 0)
+					return (ret);
+				space -= size;
+				*offp-- = (int32_t)(np - dbuf);
+				np += size;
+			} else {
+				if (need_pg) {
+					dp = np;
+					size = pagesize - HOFFSET(pg);
+					if (space < size) {
+						ret = DB_BUFFER_SMALL;
+						/* Return space required. */
+						space = *spacep + size;
+						break;
+					}
+					memcpy(dp,
+					    (u_int8_t *)pg + HOFFSET(pg), size);
+					need_pg = 0;
+					space -= size;
+					np += size;
+				}
+				if (first == 0 && keyoff != NULL) {
+					*offp-- = keyoff[0];
+					*offp-- = keyoff[-1];
+				}
+				size = bk->len;
+				*offp-- = (int32_t)((inp[indx] - HOFFSET(pg))
+				    + (dp - dbuf) + SSZA(BKEYDATA, data));
+			}
+			*offp-- = (int32_t)size;
+			first = 0;
+			if (no_dup)
+				break;
+contin:
+			indx++;
+			if (opd->dbtype == DB_RECNO)
+				cp->recno++;
+		} while (indx < NUM_ENT(pg));
+		if (no_dup)
+			break;
+		cp->indx = indx;
+
+	} while (ret == 0);
+
+	/* Return the updated information. */
+	*spacep = space;
+	*offpp = offp;
+	*dpp = np;
+
+	/*
+	 * If we ran out of space back up the pointer.
+	 * If we did not return any dups or reached the end, close the opd.
+	 */
+	if (ret == DB_BUFFER_SMALL) {
+		if (opd->dbtype == DB_RECNO) {
+			if (--cp->recno == 0)
+				goto close_opd;
+		} else if (indx != 0)
+			cp->indx--;
+		else {
+			t_ret = __bamc_prev(opd);
+			if (t_ret == DB_NOTFOUND)
+				goto close_opd;
+			if (t_ret != 0)
+				ret = t_ret;
+		}
+	} else if (keyoff == NULL && ret == DB_NOTFOUND) {
+		cp->indx--;
+		if (opd->dbtype == DB_RECNO)
+			--cp->recno;
+	} else if (indx == 0 || ret == DB_NOTFOUND) {
+close_opd:
+		if (ret == DB_NOTFOUND)
+			ret = 0;
+		if ((t_ret = __dbc_close(opd)) != 0 && ret == 0)
+			ret = t_ret;
+		((BTREE_CURSOR *)dbc->internal)->opd = NULL;
+	}
+	if (ret == DB_NOTFOUND)
+		ret = 0;
+
+	return (ret);
+}
+
+/*
+ * __bam_getbothc --
+ *	Search for a matching data item on a join.
+ */
+static int
+__bam_getbothc(dbc, data)
+	DBC *dbc;
+	DBT *data;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DB_MPOOLFILE *mpf;
+	int cmp, exact, ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	/*
+	 * Acquire the current page.  We have at least a read-lock
+	 * already.  The caller may have set DB_RMW asking for a
+	 * write lock, but upgrading to a write lock has no better
+	 * chance of succeeding now instead of later, so don't try.
+	 */
+	if ((ret = __memp_fget(mpf, &cp->pgno,
+	     dbc->thread_info, dbc->txn, 0, &cp->page)) != 0)
+		return (ret);
+
+	/*
+	 * An off-page duplicate cursor.  Search the remaining duplicates
+	 * for one which matches (do a normal btree search, then verify
+	 * that the retrieved record is greater than the original one).
+	 */
+	if (F_ISSET(dbc, DBC_OPD)) {
+		/*
+		 * Check to make sure the desired item comes strictly after
+		 * the current position;  if it doesn't, return DB_NOTFOUND.
+		 */
+		if ((ret = __bam_cmp(dbc, data, cp->page, cp->indx,
+		    dbp->dup_compare == NULL ? __bam_defcmp : dbp->dup_compare,
+		    &cmp)) != 0)
+			return (ret);
+
+		if (cmp <= 0)
+			return (DB_NOTFOUND);
+
+		/* Discard the current page, we're going to do a full search. */
+		if ((ret = __memp_fput(mpf,
+		     dbc->thread_info, cp->page, dbc->priority)) != 0)
+			return (ret);
+		cp->page = NULL;
+
+		return (__bamc_search(dbc,
+		    PGNO_INVALID, data, DB_GET_BOTH, &exact));
+	}
+
+	/*
+	 * We're doing a DBC->get(DB_GET_BOTHC) and we're already searching
+	 * a set of on-page duplicates (either sorted or unsorted).  Continue
+	 * a linear search from after the current position.
+	 *
+	 * (Note that we could have just finished a "set" of one duplicate,
+	 * i.e. not a duplicate at all, but the following check will always
+	 * return DB_NOTFOUND in this case, which is the desired behavior.)
+	 */
+	if (cp->indx + P_INDX >= NUM_ENT(cp->page) ||
+	    !IS_DUPLICATE(dbc, cp->indx, cp->indx + P_INDX))
+		return (DB_NOTFOUND);
+	cp->indx += P_INDX;
+
+	return (__bam_getboth_finddatum(dbc, data, DB_GET_BOTH));
+}
+
+#ifdef HAVE_COMPRESSION
+/*
+ * __bam_getlte --
+ *	Search for the largest entry <= key/data - used by compression.
+ *
+ *	data == NULL indicates the DB_SET_LTE flag
+ *	data != NULL indicates the DB_GET_BOTH_LTE flag
+ *
+ *	Only works for a primary cursor - not an OPD cursor. Handles the
+ *	OPD manipulation as well - no need to return to the caller to
+ *	perform more OPD movements.
+ */
+static int
+__bam_getlte(dbc, key, data)
+	DBC *dbc;
+	DBT *key, *data;
+{
+	BTREE_CURSOR *cp, *ocp;
+	DB *dbp;
+	db_pgno_t pgno;
+	int exact, ret;
+
+	dbp = dbc->dbp;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	/* Begin by searching for the key */
+	ret = __bamc_search(dbc, PGNO_INVALID, key, DB_SET_RANGE, &exact);
+	if (ret == DB_NOTFOUND)
+		goto find_last;
+	if (ret != 0)
+		goto end;
+
+	if (cp->indx == NUM_ENT(cp->page) || IS_CUR_DELETED(dbc)) {
+		/*
+		 * Move to the next entry if we're past the end of the
+		 * page or on a deleted entry.
+		 */
+		ret = __bamc_next(dbc, 0, 0);
+		if (ret == DB_NOTFOUND)
+			goto find_last;
+		if (ret != 0)
+			goto end;
+
+		/* Check if we're still on the correct key */
+		if ((ret = __bam_cmp(dbc, key, cp->page, cp->indx,
+		    ((BTREE*)dbp->bt_internal)->bt_compare, &exact)) != 0)
+			goto end;
+		exact = (exact == 0);
+	}
+
+	if (exact == 0) {
+		ret = __bam_get_prev(dbc);
+		goto end;
+	}
+
+	if (__bam_isopd(dbc, &pgno)) {
+		/*
+		 * We want to do unusual things with off-page duplicates, so
+		 * deal with them here rather than returning to handle them.
+		 */
+		if ((ret = __dbc_newopd(dbc, pgno, cp->opd, &cp->opd)) != 0)
+			goto end;
+
+		/* Search for the correct duplicate */
+		ret = __bamc_search(cp->opd, PGNO_INVALID, data,
+			data == NULL ? DB_FIRST : DB_SET_RANGE, &exact);
+		if (ret == DB_NOTFOUND)
+			goto find_last_dup;
+		if (ret != 0)
+			goto end;
+
+		ocp = (BTREE_CURSOR *)cp->opd->internal;
+		if (ocp->indx == NUM_ENT(ocp->page) ||
+		    IS_CUR_DELETED(cp->opd)) {
+			/*
+			 * Move to the next entry if we're past the end of the
+			 * page or on a deleted entry.
+			 */
+			ret = __bamc_next(cp->opd, 0, 0);
+			if (ret == DB_NOTFOUND)
+				goto find_last_dup;
+			if (ret != 0)
+				goto end;
+
+			if (data != NULL) {
+				/* Check if we're still on the correct data */
+				if ((ret = __bam_cmp(
+					    dbc, data, ocp->page, ocp->indx,
+					    dbp->dup_compare, &exact)) != 0)
+					goto end;
+				exact = (exact == 0);
+			} else
+				exact = 1;
+		}
+
+		if (exact == 0) {
+			/* Move to the previous entry */
+			ret = __bamc_prev(cp->opd);
+			if (ret == DB_NOTFOUND) {
+				if ((ret = __dbc_close(cp->opd)) != 0)
+					goto end;
+				cp->opd = NULL;
+				ret = __bam_get_prev(dbc);
+			}
+		}
+	} else if (data != NULL) {
+		/*
+		 * If we got an exact match with on-page duplicates, we need to
+		 * search in them.
+		 */
+		ret = __bam_getboth_finddatum(dbc, data, DB_GET_BOTH_RANGE);
+		if (ret == DB_NOTFOUND)
+			exact = 0;
+		else if (ret != 0)
+			goto end;
+		else {
+			/* Check if we're still on the correct data */
+			if ((ret = __bam_cmp(dbc, data, cp->page,
+			    cp->indx + O_INDX, dbp->dup_compare, &exact)) != 0)
+				goto end;
+			exact = (exact == 0);
+		}
+
+		if (exact == 0) {
+			ret = __bam_get_prev(dbc);
+		}
+	}
+
+ end:
+	return (ret);
+
+ find_last:
+	if ((ret = __bamc_search(
+	    dbc, PGNO_INVALID, NULL, DB_LAST, &exact)) != 0)
+		return (ret);
+
+	if (__bam_isopd(dbc, &pgno)) {
+		if ((ret = __dbc_newopd(dbc, pgno, cp->opd, &cp->opd)) != 0)
+			return (ret);
+ find_last_dup:
+		if ((ret = __bamc_search(
+		    cp->opd, PGNO_INVALID, NULL, DB_LAST, &exact)) != 0)
+			return (ret);
+	}
+
+	return (ret);
+}
+#endif
+
+/*
+ * __bam_getboth_finddatum --
+ *	Find a matching on-page data item.
+ */
+static int
+__bam_getboth_finddatum(dbc, data, flags)
+	DBC *dbc;
+	DBT *data;
+	u_int32_t flags;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	db_indx_t base, lim, top;
+	int cmp, ret;
+
+	dbp = dbc->dbp;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	cmp = 0;
+
+	/*
+	 * Called (sometimes indirectly) from DBC->get to search on-page data
+	 * item(s) for a matching value.  If the original flag was DB_GET_BOTH
+	 * or DB_GET_BOTH_RANGE, the cursor is set to the first undeleted data
+	 * item for the key.  If the original flag was DB_GET_BOTHC, the cursor
+	 * argument is set to the first data item we can potentially return.
+	 * In both cases, there may or may not be additional duplicate data
+	 * items to search.
+	 *
+	 * If the duplicates are not sorted, do a linear search.
+	 */
+	if (dbp->dup_compare == NULL) {
+		for (;; cp->indx += P_INDX) {
+			if (!IS_CUR_DELETED(dbc)) {
+				if ((ret = __bam_cmp(
+				    dbc, data, cp->page, cp->indx + O_INDX,
+				    __bam_defcmp, &cmp)) != 0)
+					return (ret);
+				if (cmp == 0)
+					return (0);
+			}
+
+			if (cp->indx + P_INDX >= NUM_ENT(cp->page) ||
+			    !IS_DUPLICATE(dbc, cp->indx, cp->indx + P_INDX))
+				break;
+		}
+		return (DB_NOTFOUND);
+	}
+
+	/*
+	 * If the duplicates are sorted, do a binary search.  The reason for
+	 * this is that large pages and small key/data pairs result in large
+	 * numbers of on-page duplicates before they get pushed off-page.
+	 *
+	 * Find the top and bottom of the duplicate set.  Binary search
+	 * requires at least two items, don't loop if there's only one.
+	 */
+	for (base = top = cp->indx; top < NUM_ENT(cp->page); top += P_INDX)
+		if (!IS_DUPLICATE(dbc, cp->indx, top))
+			break;
+	if (base == (top - P_INDX)) {
+		if  ((ret = __bam_cmp(dbc, data, cp->page,
+		    cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0)
+			return (ret);
+		if (cmp == 0 || (cmp < 0 && flags == DB_GET_BOTH_RANGE))
+			return (0);
+		cp->indx = top;
+		return DB_NOTFOUND;
+	}
+
+	for (lim = (top - base) / (db_indx_t)P_INDX; lim != 0; lim >>= 1) {
+		cp->indx = base + ((lim >> 1) * P_INDX);
+		if ((ret = __bam_cmp(dbc, data, cp->page,
+		    cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0)
+			return (ret);
+		if (cmp == 0) {
+			/*
+			 * XXX
+			 * No duplicate duplicates in sorted duplicate sets,
+			 * so there can be only one.
+			 */
+			if (!IS_CUR_DELETED(dbc))
+				return (0);
+			break;
+		}
+		if (cmp > 0) {
+			base = cp->indx + P_INDX;
+			--lim;
+		}
+	}
+
+	/* No match found; if we're looking for an exact match, we're done. */
+	if (flags == DB_GET_BOTH)
+		return (DB_NOTFOUND);
+
+	/*
+	 * Base is the smallest index greater than the data item, may be zero
+	 * or a last + O_INDX index, and may be deleted.  Find an undeleted
+	 * item.
+	 */
+	cp->indx = base;
+	while (cp->indx < top && IS_CUR_DELETED(dbc))
+		cp->indx += P_INDX;
+	return (cp->indx < top ? 0 : DB_NOTFOUND);
+}
+
+/*
+ * __bamc_put --
+ *	Put using a cursor.
+ */
+static int
+__bamc_put(dbc, key, data, flags, pgnop)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+	db_pgno_t *pgnop;
+{
+	BTREE *t;
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DBT dbt;
+	DB_MPOOLFILE *mpf;
+	db_pgno_t root_pgno;
+	int cmp, exact, own, ret, stack;
+	u_int32_t iiop;
+	void *arg;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	root_pgno = cp->root;
+
+split:	ret = stack = 0;
+	switch (flags) {
+	case DB_CURRENT:
+		if (F_ISSET(cp, C_DELETED))
+			return (DB_NOTFOUND);
+		/* FALLTHROUGH */
+	case DB_AFTER:
+	case DB_BEFORE:
+		iiop = flags;
+		own = 1;
+
+		/* Acquire the current page with a write lock. */
+		ACQUIRE_WRITE_LOCK(dbc, ret);
+		if (ret != 0)
+			goto err;
+		if (cp->page == NULL && (ret = __memp_fget(mpf, &cp->pgno,
+		    dbc->thread_info, dbc->txn, 0, &cp->page)) != 0)
+			goto err;
+		break;
+	case DB_KEYFIRST:
+	case DB_KEYLAST:
+	case DB_NODUPDATA:
+	case DB_NOOVERWRITE:
+	case DB_OVERWRITE_DUP:
+		own = 0;
+		/*
+		 * Searching off-page, sorted duplicate tree: do a tree search
+		 * for the correct item; __bamc_search returns the smallest
+		 * slot greater than the key, use it.
+		 *
+		 * See comment below regarding where we can start the search.
+		 */
+		if (F_ISSET(dbc, DBC_OPD)) {
+			if ((ret = __bamc_search(dbc,
+			    F_ISSET(cp, C_RECNUM) ? cp->root : root_pgno,
+			    data, flags, &exact)) != 0)
+				goto err;
+			stack = 1;
+
+			/* Disallow "sorted" duplicate duplicates. */
+			if (exact != 0) {
+				if (flags == DB_OVERWRITE_DUP ||
+				    IS_DELETED(dbp, cp->page, cp->indx)) {
+					iiop = DB_CURRENT;
+					break;
+				}
+				ret = __db_duperr(dbp, flags);
+				goto err;
+			}
+			iiop = DB_BEFORE;
+			break;
+		}
+
+		/*
+		 * Searching a btree.
+		 *
+		 * If we've done a split, we can start the search from the
+		 * parent of the split page, which __bam_split returned
+		 * for us in root_pgno, unless we're in a Btree with record
+		 * numbering.  In that case, we'll need the true root page
+		 * in order to adjust the record count.
+		 */
+		if ((ret = __bamc_search(dbc,
+		    F_ISSET(cp, C_RECNUM) ? cp->root : root_pgno, key,
+		    flags == DB_KEYFIRST || dbp->dup_compare != NULL ?
+		    DB_KEYFIRST : DB_KEYLAST, &exact)) != 0)
+			goto err;
+		stack = 1;
+
+		/*
+		 * If we don't have an exact match, __bamc_search returned
+		 * the smallest slot greater than the key, use it.
+		 */
+		if (!exact) {
+			iiop = DB_KEYFIRST;
+			break;
+
+		/*
+		 * Check for NOOVERWRITE.  It is possible that there
+		 * is a key with an empty duplicate page attached.
+		 */
+		} else if (flags == DB_NOOVERWRITE && !IS_CUR_DELETED(dbc)) {
+			if (pgnop != NULL && __bam_isopd(dbc, pgnop))
+				ret = __bam_opd_exists(dbc, *pgnop);
+			else
+				ret = DB_KEYEXIST;
+			if (ret != 0)
+				goto err;
+		}
+
+		/*
+		 * If duplicates aren't supported, replace the current item.
+		 */
+		if (!F_ISSET(dbp, DB_AM_DUP)) {
+			iiop = DB_CURRENT;
+			break;
+		}
+
+		/*
+		 * If we find a matching entry, it may be an off-page duplicate
+		 * tree.  Return the page number to our caller, we need a new
+		 * cursor.
+		 */
+		if (pgnop != NULL && __bam_isopd(dbc, pgnop))
+			goto done;
+
+		/* If the duplicates aren't sorted, move to the right slot. */
+		if (dbp->dup_compare == NULL) {
+			if (flags == DB_KEYFIRST)
+				iiop = DB_BEFORE;
+			else
+				for (;; cp->indx += P_INDX)
+					if (cp->indx + P_INDX >=
+					    NUM_ENT(cp->page) ||
+					    !IS_DUPLICATE(dbc, cp->indx,
+					    cp->indx + P_INDX)) {
+						iiop = DB_AFTER;
+						break;
+					}
+			break;
+		}
+
+		/*
+		 * We know that we're looking at the first of a set of sorted
+		 * on-page duplicates.  Walk the list to find the right slot.
+		 */
+		for (;; cp->indx += P_INDX) {
+			if ((ret = __bam_cmp(dbc, data, cp->page,
+			    cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0)
+				goto err;
+			if (cmp < 0) {
+				iiop = DB_BEFORE;
+				break;
+			}
+
+			/* Disallow "sorted" duplicate duplicates. */
+			if (cmp == 0) {
+				if (flags == DB_OVERWRITE_DUP ||
+				    IS_DELETED(dbp, cp->page, cp->indx)) {
+					iiop = DB_CURRENT;
+					break;
+				}
+				ret = __db_duperr(dbp, flags);
+				goto err;
+			}
+
+			if (cp->indx + P_INDX >= NUM_ENT(cp->page) ||
+			    P_INP(dbp, ((PAGE *)cp->page))[cp->indx] !=
+			    P_INP(dbp, ((PAGE *)cp->page))[cp->indx + P_INDX]) {
+				iiop = DB_AFTER;
+				break;
+			}
+		}
+		break;
+	default:
+		ret = __db_unknown_flag(dbp->env, "__bamc_put", flags);
+		goto err;
+	}
+
+	switch (ret = __bam_iitem(dbc, key, data, iiop, 0)) {
+	case 0:
+		break;
+	case DB_NEEDSPLIT:
+		/*
+		 * To split, we need a key for the page.  Either use the key
+		 * argument or get a copy of the key from the page.
+		 */
+		if (flags == DB_AFTER ||
+		    flags == DB_BEFORE || flags == DB_CURRENT) {
+			memset(&dbt, 0, sizeof(DBT));
+			if ((ret = __db_ret(dbc, cp->page, 0, &dbt,
+			    &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0)
+				goto err;
+			arg = &dbt;
+		} else
+			arg = F_ISSET(dbc, DBC_OPD) ? data : key;
+
+		/*
+		 * Discard any locks and pinned pages (the locks are discarded
+		 * even if we're running with transactions, as they lock pages
+		 * that we're sorry we ever acquired).  If stack is set and the
+		 * cursor entries are valid, they point to the same entries as
+		 * the stack, don't free them twice.
+		 */
+		if (stack)
+			ret = __bam_stkrel(dbc, STK_CLRDBC | STK_NOLOCK);
+		else
+			DISCARD_CUR(dbc, ret);
+		if (ret != 0)
+			goto err;
+
+		/*
+		 * SR [#6059]
+		 * If we do not own a lock on the page any more, then clear the
+		 * cursor so we don't point at it.  Even if we call __bam_stkrel
+		 * above we still may have entered the routine with the cursor
+		 * positioned to a particular record.  This is in the case
+		 * where C_RECNUM is set.
+		 */
+		if (own == 0) {
+			cp->pgno = PGNO_INVALID;
+			cp->indx = 0;
+		}
+
+		/* Split the tree. */
+		if ((ret = __bam_split(dbc, arg, &root_pgno)) != 0)
+			return (ret);
+
+		goto split;
+	default:
+		goto err;
+	}
+
+err:
+done:	/*
+	 * If we inserted a key into the first or last slot of the tree,
+	 * remember where it was so we can do it more quickly next time.
+	 * If the tree has record numbers, we need a complete stack so
+	 * that we can adjust the record counts, so skipping the tree search
+	 * isn't possible.  For subdatabases we need to be careful that the
+	 * page does not move from one db to another, so we track its LSN.
+	 *
+	 * If there are duplicates and we are inserting into the last slot,
+	 * the cursor will point _to_ the last item, not after it, which
+	 * is why we subtract P_INDX below.
+	 */
+
+	t = dbp->bt_internal;
+	if (ret == 0 && TYPE(cp->page) == P_LBTREE &&
+	    (flags == DB_KEYFIRST || flags == DB_KEYLAST) &&
+	    !F_ISSET(cp, C_RECNUM) &&
+	    (!F_ISSET(dbp, DB_AM_SUBDB) ||
+	    (LOGGING_ON(dbp->env) && !F_ISSET(dbp, DB_AM_NOT_DURABLE))) &&
+	    ((NEXT_PGNO(cp->page) == PGNO_INVALID &&
+	    cp->indx >= NUM_ENT(cp->page) - P_INDX) ||
+	    (PREV_PGNO(cp->page) == PGNO_INVALID && cp->indx == 0))) {
+		t->bt_lpgno = cp->pgno;
+		if (F_ISSET(dbp, DB_AM_SUBDB))
+			t->bt_llsn = LSN(cp->page);
+	} else
+		t->bt_lpgno = PGNO_INVALID;
+	/*
+	 * Discard any pages pinned in the tree and their locks, except for
+	 * the leaf page.  Note, the leaf page participated in any stack we
+	 * acquired, and so we have to adjust the stack as necessary.  If
+	 * there was only a single page on the stack, we don't have to free
+	 * further stack pages.
+	 */
+	if (stack && BT_STK_POP(cp) != NULL)
+		(void)__bam_stkrel(dbc, 0);
+
+	/*
+	 * Regardless of whether we were successful or not, clear the delete
+	 * flag.  If we're successful, we either moved the cursor or the item
+	 * is no longer deleted.  If we're not successful, then we're just a
+	 * copy, no need to have the flag set.
+	 *
+	 * We may have instantiated off-page duplicate cursors during the put,
+	 * so clear the deleted bit from the off-page duplicate cursor as well.
+	 */
+	F_CLR(cp, C_DELETED);
+	if (cp->opd != NULL) {
+		cp = (BTREE_CURSOR *)cp->opd->internal;
+		F_CLR(cp, C_DELETED);
+	}
+
+	return (ret);
+}
+
+/*
+ * __bamc_rget --
+ *	Return the record number for a cursor.
+ *
+ * PUBLIC: int __bamc_rget __P((DBC *, DBT *));
+ */
+int
+__bamc_rget(dbc, data)
+	DBC *dbc;
+	DBT *data;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DBT dbt;
+	DB_MPOOLFILE *mpf;
+	db_recno_t recno;
+	int exact, ret, t_ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	/*
+	 * Get the page with the current item on it.
+	 * Get a copy of the key.
+	 * Release the page, making sure we don't release it twice.
+	 */
+	if ((ret = __memp_fget(mpf, &cp->pgno,
+	     dbc->thread_info, dbc->txn, 0, &cp->page)) != 0)
+		return (ret);
+	memset(&dbt, 0, sizeof(DBT));
+	if ((ret = __db_ret(dbc, cp->page, cp->indx, &dbt,
+	    &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0)
+		goto err;
+	ret = __memp_fput(mpf, dbc->thread_info, cp->page, dbc->priority);
+	cp->page = NULL;
+	if (ret != 0)
+		return (ret);
+
+	if ((ret = __bam_search(dbc, PGNO_INVALID, &dbt,
+	    F_ISSET(dbc, DBC_RMW) ? SR_FIND_WR : SR_FIND,
+	    1, &recno, &exact)) != 0)
+		goto err;
+
+	ret = __db_retcopy(dbc->env, data,
+	    &recno, sizeof(recno), &dbc->rdata->data, &dbc->rdata->ulen);
+
+	/* Release the stack. */
+err:	if ((t_ret = __bam_stkrel(dbc, 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __bamc_writelock --
+ *	Upgrade the cursor to a write lock.
+ */
+static int
+__bamc_writelock(dbc)
+	DBC *dbc;
+{
+	BTREE_CURSOR *cp;
+	int ret;
+
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	if (cp->lock_mode == DB_LOCK_WRITE)
+		return (0);
+
+	/*
+	 * When writing to an off-page duplicate tree, we need to have the
+	 * appropriate page in the primary tree locked.  The general DBC
+	 * code calls us first with the primary cursor so we can acquire the
+	 * appropriate lock.
+	 */
+	ACQUIRE_WRITE_LOCK(dbc, ret);
+	return (ret);
+}
+
+/*
+ * __bamc_next --
+ *	Move to the next record.
+ */
+static int
+__bamc_next(dbc, initial_move, deleted_okay)
+	DBC *dbc;
+	int initial_move, deleted_okay;
+{
+	BTREE_CURSOR *cp;
+	db_indx_t adjust;
+	db_lockmode_t lock_mode;
+	db_pgno_t pgno;
+	int ret;
+
+	cp = (BTREE_CURSOR *)dbc->internal;
+	ret = 0;
+
+	/*
+	 * We're either moving through a page of duplicates or a btree leaf
+	 * page.
+	 *
+	 * !!!
+	 * This code handles empty pages and pages with only deleted entries.
+	 */
+	if (F_ISSET(dbc, DBC_OPD)) {
+		adjust = O_INDX;
+		lock_mode = DB_LOCK_NG;
+	} else {
+		adjust = dbc->dbtype == DB_BTREE ? P_INDX : O_INDX;
+		lock_mode =
+		    F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE : DB_LOCK_READ;
+	}
+	if (cp->page == NULL) {
+		ACQUIRE_CUR(dbc, lock_mode, cp->pgno, 0, ret);
+		if (ret != 0)
+			return (ret);
+	}
+
+	if (initial_move)
+		cp->indx += adjust;
+
+	for (;;) {
+		/*
+		 * If at the end of the page, move to a subsequent page.
+		 *
+		 * !!!
+		 * Check for >= NUM_ENT.  If the original search landed us on
+		 * NUM_ENT, we may have incremented indx before the test.
+		 */
+		if (cp->indx >= NUM_ENT(cp->page)) {
+			if ((pgno = NEXT_PGNO(cp->page)) == PGNO_INVALID)
+				return (DB_NOTFOUND);
+
+			ACQUIRE_CUR(dbc, lock_mode, pgno, 0, ret);
+			if (ret != 0)
+				return (ret);
+			cp->indx = 0;
+			continue;
+		}
+		if (!deleted_okay && IS_CUR_DELETED(dbc)) {
+			cp->indx += adjust;
+			continue;
+		}
+		break;
+	}
+	return (0);
+}
+
+/*
+ * __bamc_prev --
+ *	Move to the previous record.
+ */
+static int
+__bamc_prev(dbc)
+	DBC *dbc;
+{
+	BTREE_CURSOR *cp;
+	db_indx_t adjust;
+	db_lockmode_t lock_mode;
+	db_pgno_t pgno;
+	int ret;
+
+	cp = (BTREE_CURSOR *)dbc->internal;
+	ret = 0;
+
+	/*
+	 * We're either moving through a page of duplicates or a btree leaf
+	 * page.
+	 *
+	 * !!!
+	 * This code handles empty pages and pages with only deleted entries.
+	 */
+	if (F_ISSET(dbc, DBC_OPD)) {
+		adjust = O_INDX;
+		lock_mode = DB_LOCK_NG;
+	} else {
+		adjust = dbc->dbtype == DB_BTREE ? P_INDX : O_INDX;
+		lock_mode =
+		    F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE : DB_LOCK_READ;
+	}
+	if (cp->page == NULL) {
+		ACQUIRE_CUR(dbc, lock_mode, cp->pgno, 0, ret);
+		if (ret != 0)
+			return (ret);
+	}
+
+	for (;;) {
+		/* If at the beginning of the page, move to a previous one. */
+		if (cp->indx == 0) {
+			if ((pgno =
+			    PREV_PGNO(cp->page)) == PGNO_INVALID)
+				return (DB_NOTFOUND);
+
+			ACQUIRE_CUR(dbc, lock_mode, pgno, 0, ret);
+			if (ret != 0)
+				return (ret);
+
+			if ((cp->indx = NUM_ENT(cp->page)) == 0)
+				continue;
+		}
+
+		/* Ignore deleted records. */
+		cp->indx -= adjust;
+		if (IS_CUR_DELETED(dbc))
+			continue;
+
+		break;
+	}
+	return (0);
+}
+
+/*
+ * __bamc_search --
+ *	Move to a specified record.
+ */
+static int
+__bamc_search(dbc, root_pgno, key, flags, exactp)
+	DBC *dbc;
+	db_pgno_t root_pgno;
+	const DBT *key;
+	u_int32_t flags;
+	int *exactp;
+{
+	BTREE *t;
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	PAGE *h;
+	db_indx_t base, indx, *inp, lim;
+	db_pgno_t bt_lpgno;
+	db_recno_t recno;
+	u_int32_t sflags;
+	int bulk, cmp, ret, t_ret;
+
+	COMPQUIET(cmp, 0);
+	dbp = dbc->dbp;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	t = dbp->bt_internal;
+	ret = 0;
+	bulk = (F_ISSET(dbc, DBC_BULK) && cp->pgno != PGNO_INVALID);
+
+	/*
+	 * Find an entry in the database.  Discard any lock we currently hold,
+	 * we're going to search the tree.
+	 */
+	DISCARD_CUR(dbc, ret);
+	if (ret != 0)
+		return (ret);
+
+	switch (flags) {
+	case DB_FIRST:
+		sflags = (F_ISSET(dbc, DBC_RMW) ? SR_WRITE : SR_READ) | SR_MIN;
+		goto search;
+	case DB_LAST:
+		sflags = (F_ISSET(dbc, DBC_RMW) ? SR_WRITE : SR_READ) | SR_MAX;
+		goto search;
+	case DB_SET_RECNO:
+		if ((ret = __ram_getno(dbc, key, &recno, 0)) != 0)
+			return (ret);
+		sflags =
+		    (F_ISSET(dbc, DBC_RMW) ?  SR_FIND_WR : SR_FIND) | SR_EXACT;
+		if ((ret = __bam_rsearch(dbc, &recno, sflags, 1, exactp)) != 0)
+			return (ret);
+		goto done;
+	case DB_SET:
+	case DB_GET_BOTH:
+		sflags =
+		    (F_ISSET(dbc, DBC_RMW) ? SR_FIND_WR : SR_FIND) | SR_EXACT;
+		if (bulk)
+			break;
+		goto search;
+	case DB_GET_BOTH_RANGE:
+		sflags = (F_ISSET(dbc, DBC_RMW) ? SR_FIND_WR : SR_FIND);
+		goto search;
+	case DB_SET_RANGE:
+		sflags =
+		    (F_ISSET(dbc, DBC_RMW) ? SR_WRITE : SR_READ) | SR_DUPFIRST;
+		goto search;
+	case DB_KEYFIRST:
+	case DB_NOOVERWRITE:
+		sflags = SR_KEYFIRST;
+		break;
+	case DB_KEYLAST:
+	case DB_NODUPDATA:
+	case DB_OVERWRITE_DUP:
+		sflags = SR_KEYLAST;
+		break;
+	default:
+		return (__db_unknown_flag(dbp->env, "__bamc_search", flags));
+	}
+
+	/*
+	 * If the application has a history of inserting into the first or last
+	 * pages of the database, we check those pages first to avoid doing a
+	 * full search.  Similarly, if the cursor is configured as a bulk
+	 * cursor, check whether this operation belongs on the same page as the
+	 * last one.
+	 */
+	if (bulk)
+		bt_lpgno = cp->pgno;
+	else {
+		if (F_ISSET(dbc, DBC_OPD))
+			goto search;
+
+		/*
+		 * !!!
+		 * We do not mutex protect the t->bt_lpgno field, which means
+		 * that it can only be used in an advisory manner.  If we find
+		 * page we can use, great.  If we don't, we don't care, we do
+		 * it the slow way instead.  Regardless, copy it into a local
+		 * variable, otherwise we might acquire a lock for a page and
+		 * then read a different page because it changed underfoot.
+		 */
+		bt_lpgno = t->bt_lpgno;
+	}
+
+	/*
+	 * If the tree has no history of insertion, do it the slow way.
+	 */
+	if (bt_lpgno == PGNO_INVALID)
+		goto search;
+
+	/*
+	 * Lock and retrieve the page on which we last inserted.
+	 *
+	 * The page may not exist: if a transaction created the page
+	 * and then aborted, the page might have been truncated from
+	 * the end of the file.  We don't want to wait on the lock.
+	 * The page may not even be relevant to this search.
+	 */
+	h = NULL;
+	ACQUIRE_CUR(dbc, DB_LOCK_WRITE, bt_lpgno, DB_LOCK_NOWAIT, ret);
+	if (ret != 0) {
+		if (ret == DB_LOCK_DEADLOCK ||
+		    ret == DB_LOCK_NOTGRANTED ||
+		    ret == DB_PAGE_NOTFOUND)
+			ret = 0;
+		goto fast_miss;
+	}
+
+	h = cp->page;
+	inp = P_INP(dbp, h);
+
+	/*
+	 * It's okay if the page type isn't right or it's empty, it
+	 * just means that the world changed.
+	 */
+	if (TYPE(h) != P_LBTREE || NUM_ENT(h) == 0)
+		goto fast_miss;
+
+	/* Verify that this page cannot have moved to another db. */
+	if (F_ISSET(dbp, DB_AM_SUBDB) &&
+	    LOG_COMPARE(&t->bt_llsn, &LSN(h)) != 0)
+		goto fast_miss;
+
+	/*
+	 * What we do here is test to see if we're at the beginning or
+	 * end of the tree and if the new item sorts before/after the
+	 * first/last page entry.  We only try to catch inserts into
+	 * the middle of the tree for bulk cursors.
+	 */
+	if (h->next_pgno == PGNO_INVALID) {
+		indx = NUM_ENT(h) - P_INDX;
+		if ((ret = __bam_cmp(dbc, key, h, indx,
+		    t->bt_compare, &cmp)) != 0)
+			goto fast_miss;
+		if (cmp > 0) {
+			if (FLD_ISSET(sflags, SR_EXACT))
+				return (DB_NOTFOUND);
+			else
+				indx += P_INDX;
+		}
+		if (cmp >= 0)
+			goto fast_hit;
+	}
+	if (h->prev_pgno == PGNO_INVALID) {
+		indx = 0;
+		if ((ret = __bam_cmp(dbc, key, h, indx,
+		    t->bt_compare, &cmp)) != 0)
+			goto fast_miss;
+		if (cmp < 0 && FLD_ISSET(sflags, SR_EXACT))
+			return (DB_NOTFOUND);
+		if (cmp <= 0)
+			goto fast_hit;
+	}
+	if (bulk) {
+		DB_BINARY_SEARCH_FOR(base, lim, NUM_ENT(h), P_INDX) {
+			DB_BINARY_SEARCH_INCR(indx, base, lim, P_INDX);
+			if ((ret = __bam_cmp(dbc, key, h, indx,
+			    t->bt_compare, &cmp)) != 0)
+				goto fast_miss;
+
+			if (cmp == 0)
+				goto fast_hit;
+			if (cmp > 0)
+				DB_BINARY_SEARCH_SHIFT_BASE(indx, base,
+				    lim, P_INDX);
+		}
+		/*
+		 * No match found: base is the smallest index greater than
+		 * the key and may be zero or NUM_ENT(h).
+		 */
+		indx = base;
+		if (indx > 0 && indx < NUM_ENT(h)) {
+			if (FLD_ISSET(sflags, SR_EXACT))
+				return (DB_NOTFOUND);
+			goto fast_hit;
+		}
+	}
+	goto fast_miss;
+
+fast_hit:
+	if (cmp == 0) {
+		/*
+		 * Found a duplicate.  Deal with DB_KEYFIRST / DB_KEYLAST.
+		 */
+		if (FLD_ISSET(sflags, SR_DUPFIRST))
+			while (indx > 0 && inp[indx - P_INDX] == inp[indx])
+				indx -= P_INDX;
+		else if (FLD_ISSET(sflags, SR_DUPLAST))
+			while (indx < (db_indx_t)(NUM_ENT(h) - P_INDX) &&
+			    inp[indx] == inp[indx + P_INDX])
+				indx += P_INDX;
+	}
+
+	/* Set the exact match flag, we may have found a duplicate. */
+	*exactp = (cmp == 0);
+
+	/*
+	 * Insert the entry in the stack.  (Our caller is likely to
+	 * call __bam_stkrel() after our return.)
+	 */
+	BT_STK_CLR(cp);
+	BT_STK_ENTER(dbp->env,
+	    cp, h, indx, cp->lock, cp->lock_mode, ret);
+	if (ret != 0)
+		return (ret);
+	goto done;
+
+fast_miss:
+	/*
+	 * This was not the right page, so we do not need to retain
+	 * the lock even in the presence of transactions.
+	 *
+	 * This is also an error path, so ret may have been set.
+	 */
+	DISCARD_CUR(dbc, ret);
+	cp->pgno = PGNO_INVALID;
+	if ((t_ret = __LPUT(dbc, cp->lock)) != 0 && ret == 0)
+		ret = t_ret;
+	if (ret != 0)
+		return (ret);
+
+search:
+	if ((ret = __bam_search(dbc, root_pgno,
+	    key, sflags, 1, NULL, exactp)) != 0)
+		return (ret);
+
+done:	/* Initialize the cursor from the stack. */
+	cp->page = cp->csp->page;
+	cp->pgno = cp->csp->page->pgno;
+	cp->indx = cp->csp->indx;
+	cp->lock = cp->csp->lock;
+	cp->lock_mode = cp->csp->lock_mode;
+
+	/* If on an empty page or a deleted record, move to the next one. */
+	if (flags == DB_FIRST &&
+	    (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc)))
+		if ((ret = __bamc_next(dbc, 0, 0)) != 0)
+			return (ret);
+	if (flags == DB_LAST &&
+	    (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc)))
+		if ((ret = __bamc_prev(dbc)) != 0)
+			return (ret);
+
+	return (0);
+}
+
+/*
+ * __bamc_physdel --
+ *	Physically remove an item from the page.
+ */
+static int
+__bamc_physdel(dbc)
+	DBC *dbc;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DBT key;
+	DB_LOCK next_lock, prev_lock;
+	db_pgno_t pgno;
+	int delete_page, empty_page, exact, ret;
+
+	dbp = dbc->dbp;
+	memset(&key, 0, sizeof(DBT));
+	cp = (BTREE_CURSOR *)dbc->internal;
+	delete_page = empty_page = ret = 0;
+	LOCK_INIT(next_lock);
+	LOCK_INIT(prev_lock);
+
+	/* If the page is going to be emptied, consider deleting it. */
+	delete_page = empty_page =
+	    NUM_ENT(cp->page) == (TYPE(cp->page) == P_LBTREE ? 2 : 1);
+
+	/*
+	 * Check if the application turned off reverse splits.  Applications
+	 * can't turn off reverse splits in off-page duplicate trees, that
+	 * space will never be reused unless the exact same key is specified.
+	 */
+	if (delete_page &&
+	    !F_ISSET(dbc, DBC_OPD) && F_ISSET(dbp, DB_AM_REVSPLITOFF))
+		delete_page = 0;
+
+	/*
+	 * We never delete the last leaf page.  (Not really true -- we delete
+	 * the last leaf page of off-page duplicate trees, but that's handled
+	 * by our caller, not down here.)
+	 */
+	if (delete_page && cp->pgno == BAM_ROOT_PGNO(dbc))
+		delete_page = 0;
+
+	/*
+	 * To delete a leaf page other than an empty root page, we need a
+	 * copy of a key from the page.  Use the 0th page index since it's
+	 * the last key the page held.
+	 *
+	 * !!!
+	 * Note that because __bamc_physdel is always called from a cursor
+	 * close, it should be safe to use the cursor's own "my_rkey" memory
+	 * to temporarily hold this key.  We shouldn't own any returned-data
+	 * memory of interest--if we do, we're in trouble anyway.
+	 */
+	if (delete_page) {
+		if ((ret = __db_ret(dbc, cp->page, 0, &key,
+		    &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0)
+			goto err;
+	}
+
+	/*
+	 * Delete the items.  If page isn't empty, we adjust the cursors.
+	 *
+	 * !!!
+	 * The following operations to delete a page may deadlock.  The easy
+	 * scenario is if we're deleting an item because we're closing cursors
+	 * because we've already deadlocked and want to call txn->abort.  If
+	 * we fail due to deadlock, we'll leave a locked, possibly empty page
+	 * in the tree, which won't be empty long because we'll undo the delete
+	 * when we undo the transaction's modifications.
+	 *
+	 * !!!
+	 * Delete the key item first, otherwise the on-page duplicate checks
+	 * in __bam_ditem() won't work!
+	 */
+	if ((ret = __memp_dirty(dbp->mpf,
+	    &cp->page, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+		goto err;
+	if (TYPE(cp->page) == P_LBTREE) {
+		if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0)
+			goto err;
+		if (!empty_page)
+			if ((ret = __bam_ca_di(dbc,
+			    PGNO(cp->page), cp->indx, -1)) != 0)
+				goto err;
+	}
+	if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0)
+		goto err;
+
+	/* Clear the deleted flag, the item is gone. */
+	F_CLR(cp, C_DELETED);
+
+	if (!empty_page)
+		if ((ret = __bam_ca_di(dbc, PGNO(cp->page), cp->indx, -1)) != 0)
+			goto err;
+
+	/*
+	 * Need to downgrade write locks here or non-txn locks will get stuck.
+	 */
+	if (F_ISSET(dbc->dbp, DB_AM_READ_UNCOMMITTED)) {
+		if ((ret = __TLPUT(dbc, cp->lock)) != 0)
+			goto err;
+		cp->lock_mode = DB_LOCK_WWRITE;
+		if (cp->page != NULL &&
+		    (ret = __memp_shared(dbp->mpf, cp->page)) != 0)
+			goto err;
+	}
+	/* If we're not going to try and delete the page, we're done. */
+	if (!delete_page)
+		return (0);
+
+	/*
+	 * Lock the previous and next pages before latching the parent
+	 * sub tree.
+	 */
+	if (STD_LOCKING(dbc)) {
+		if ((pgno = PREV_PGNO(cp->page)) != PGNO_INVALID &&
+		    (ret = __db_lget(dbc,
+		    0, pgno, DB_LOCK_WRITE, 0, &prev_lock)) != 0)
+			return (ret);
+		if ((pgno = NEXT_PGNO(cp->page)) != PGNO_INVALID &&
+		    (ret = __db_lget(dbc,
+		    0, pgno, DB_LOCK_WRITE, 0, &next_lock)) != 0) {
+			(void)__TLPUT(dbc, next_lock);
+			return (ret);
+		}
+	}
+	DISCARD_CUR(dbc, ret);
+	if (ret != 0)
+		goto err;
+	ret = __bam_search(dbc, PGNO_INVALID, &key, SR_DEL, 0, NULL, &exact);
+
+	/*
+	 * If everything worked, delete the stack, otherwise, release the
+	 * stack and page locks without further damage.
+	 */
+	if (ret == 0)
+		ret = __bam_dpages(dbc, 1, BTD_RELINK);
+	else
+		(void)__bam_stkrel(dbc, 0);
+
+err:	if (ret != 0)
+		F_SET(dbc, DBC_ERROR);
+	(void)__TLPUT(dbc, prev_lock);
+	(void)__TLPUT(dbc, next_lock);
+	return (ret);
+}
+
+/*
+ * __bamc_getstack --
+ *	Acquire a full stack for a cursor.
+ */
+static int
+__bamc_getstack(dbc)
+	DBC *dbc;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DBT dbt;
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	int exact, ret, t_ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	/*
+	 * Get the page with the current item on it.  The caller of this
+	 * routine has to already hold a read lock on the page, so there
+	 * is no additional lock to acquire.
+	 */
+	if ((ret = __memp_fget(mpf, &cp->pgno,
+	     dbc->thread_info, dbc->txn, 0, &h)) != 0)
+		return (ret);
+
+	/* Get a copy of a key from the page. */
+	memset(&dbt, 0, sizeof(DBT));
+	ret = __db_ret(dbc, h, 0, &dbt,
+	     &dbc->my_rkey.data, &dbc->my_rkey.ulen);
+	if ((t_ret = __memp_fput(mpf,
+	     dbc->thread_info, h, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	if (ret != 0)
+		return (ret);
+
+	/* Get a write-locked stack for the page. */
+	exact = 0;
+	ret = __bam_search(dbc, PGNO_INVALID,
+	    &dbt, SR_KEYFIRST, 1, NULL, &exact);
+
+	return (ret);
+}
+
+/*
+ * __bam_isopd --
+ *	Return if the cursor references an off-page duplicate tree via its
+ *	page number.
+ */
+static int
+__bam_isopd(dbc, pgnop)
+	DBC *dbc;
+	db_pgno_t *pgnop;
+{
+	BOVERFLOW *bo;
+
+	if (TYPE(dbc->internal->page) != P_LBTREE)
+		return (0);
+
+	bo = GET_BOVERFLOW(dbc->dbp,
+	    dbc->internal->page, dbc->internal->indx + O_INDX);
+	if (B_TYPE(bo->type) == B_DUPLICATE) {
+		*pgnop = bo->pgno;
+		return (1);
+	}
+	return (0);
+}
+
+/*
+ * __bam_opd_exists --
+ *	Return if the current position has any data.
+ * PUBLIC: int  __bam_opd_exists __P((DBC *, db_pgno_t));
+ */
+int
+__bam_opd_exists(dbc, pgno)
+	DBC *dbc;
+	db_pgno_t pgno;
+{
+	PAGE *h;
+	int ret;
+
+	if ((ret = __memp_fget(dbc->dbp->mpf, &pgno,
+	    dbc->thread_info, dbc->txn, 0, &h)) != 0)
+		return (ret);
+
+	/*
+	 * We always collapse OPD trees so we only need to check
+	 * the number of entries on the root.  If there is a non-empty
+	 * tree then there will be duplicates.
+	 */
+	if (NUM_ENT(h) == 0)
+		ret = 0;
+	else
+		ret = DB_KEYEXIST;
+
+	(void)__memp_fput(dbc->dbp->mpf, dbc->thread_info, h, dbc->priority);
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_delete.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,563 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+
+/*
+ * __bam_ditem --
+ *	Delete one or more entries from a page.
+ *
+ * PUBLIC: int __bam_ditem __P((DBC *, PAGE *, u_int32_t));
+ */
+int
+__bam_ditem(dbc, h, indx)
+	DBC *dbc;
+	PAGE *h;
+	u_int32_t indx;
+{
+	BINTERNAL *bi;
+	BKEYDATA *bk;
+	DB *dbp;
+	u_int32_t nbytes;
+	int ret;
+	db_indx_t *inp;
+
+	dbp = dbc->dbp;
+	inp = P_INP(dbp, h);
+
+	/* The page should already have been dirtied by our caller. */
+	DB_ASSERT(dbp->env, IS_DIRTY(h));
+
+	switch (TYPE(h)) {
+	case P_IBTREE:
+		bi = GET_BINTERNAL(dbp, h, indx);
+		switch (B_TYPE(bi->type)) {
+		case B_DUPLICATE:
+		case B_KEYDATA:
+			nbytes = BINTERNAL_SIZE(bi->len);
+			break;
+		case B_OVERFLOW:
+			nbytes = BINTERNAL_SIZE(bi->len);
+			if ((ret =
+			    __db_doff(dbc, ((BOVERFLOW *)bi->data)->pgno)) != 0)
+				return (ret);
+			break;
+		default:
+			return (__db_pgfmt(dbp->env, PGNO(h)));
+		}
+		break;
+	case P_IRECNO:
+		nbytes = RINTERNAL_SIZE;
+		break;
+	case P_LBTREE:
+		/*
+		 * If it's a duplicate key, discard the index and don't touch
+		 * the actual page item.
+		 *
+		 * !!!
+		 * This works because no data item can have an index matching
+		 * any other index so even if the data item is in a key "slot",
+		 * it won't match any other index.
+		 */
+		if ((indx % 2) == 0) {
+			/*
+			 * Check for a duplicate after us on the page.  NOTE:
+			 * we have to delete the key item before deleting the
+			 * data item, otherwise the "indx + P_INDX" calculation
+			 * won't work!
+			 */
+			if (indx + P_INDX < (u_int32_t)NUM_ENT(h) &&
+			    inp[indx] == inp[indx + P_INDX])
+				return (__bam_adjindx(dbc,
+				    h, indx, indx + O_INDX, 0));
+			/*
+			 * Check for a duplicate before us on the page.  It
+			 * doesn't matter if we delete the key item before or
+			 * after the data item for the purposes of this one.
+			 */
+			if (indx > 0 && inp[indx] == inp[indx - P_INDX])
+				return (__bam_adjindx(dbc,
+				    h, indx, indx - P_INDX, 0));
+		}
+		/* FALLTHROUGH */
+	case P_LDUP:
+	case P_LRECNO:
+		bk = GET_BKEYDATA(dbp, h, indx);
+		switch (B_TYPE(bk->type)) {
+		case B_DUPLICATE:
+			nbytes = BOVERFLOW_SIZE;
+			break;
+		case B_OVERFLOW:
+			nbytes = BOVERFLOW_SIZE;
+			if ((ret = __db_doff(
+			    dbc, (GET_BOVERFLOW(dbp, h, indx))->pgno)) != 0)
+				return (ret);
+			break;
+		case B_KEYDATA:
+			nbytes = BKEYDATA_SIZE(bk->len);
+			break;
+		default:
+			return (__db_pgfmt(dbp->env, PGNO(h)));
+		}
+		break;
+	default:
+		return (__db_pgfmt(dbp->env, PGNO(h)));
+	}
+
+	/* Delete the item and mark the page dirty. */
+	if ((ret = __db_ditem(dbc, h, indx, nbytes)) != 0)
+		return (ret);
+
+	return (0);
+}
+
+/*
+ * __bam_adjindx --
+ *	Adjust an index on the page.
+ *
+ * PUBLIC: int __bam_adjindx __P((DBC *, PAGE *, u_int32_t, u_int32_t, int));
+ */
+int
+__bam_adjindx(dbc, h, indx, indx_copy, is_insert)
+	DBC *dbc;
+	PAGE *h;
+	u_int32_t indx, indx_copy;
+	int is_insert;
+{
+	DB *dbp;
+	db_indx_t copy, *inp;
+	int ret;
+
+	dbp = dbc->dbp;
+	inp = P_INP(dbp, h);
+
+	/* Log the change. */
+	if (DBC_LOGGING(dbc)) {
+	    if ((ret = __bam_adj_log(dbp, dbc->txn, &LSN(h), 0,
+		PGNO(h), &LSN(h), indx, indx_copy, (u_int32_t)is_insert)) != 0)
+			return (ret);
+	} else
+		LSN_NOT_LOGGED(LSN(h));
+
+	/* Shuffle the indices and mark the page dirty. */
+	if (is_insert) {
+		copy = inp[indx_copy];
+		if (indx != NUM_ENT(h))
+			memmove(&inp[indx + O_INDX], &inp[indx],
+			    sizeof(db_indx_t) * (NUM_ENT(h) - indx));
+		inp[indx] = copy;
+		++NUM_ENT(h);
+	} else {
+		--NUM_ENT(h);
+		if (indx != NUM_ENT(h))
+			memmove(&inp[indx], &inp[indx + O_INDX],
+			    sizeof(db_indx_t) * (NUM_ENT(h) - indx));
+	}
+
+	return (0);
+}
+
+/*
+ * __bam_dpages --
+ *	Delete a set of locked pages.
+ *
+ * PUBLIC: int __bam_dpages __P((DBC *, int, int));
+ */
+int
+__bam_dpages(dbc, use_top, flags)
+	DBC *dbc;
+	int use_top;
+	int flags;
+{
+	BINTERNAL *bi;
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DBT a, b;
+	DB_LOCK c_lock, p_lock;
+	DB_MPOOLFILE *mpf;
+	EPG *epg, *save_sp, *stack_epg;
+	PAGE *child, *parent;
+	db_indx_t nitems;
+	db_pgno_t pgno, root_pgno;
+	db_recno_t rcnt;
+	int done, ret, t_ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	nitems = 0;
+	pgno = PGNO_INVALID;
+
+	/*
+	 * We have the entire stack of deletable pages locked.
+	 *
+	 * Btree calls us with the first page in the stack is to have a
+	 * single item deleted, and the rest of the pages are to be removed.
+	 *
+	 * Recno always has a stack to the root and __bam_merge operations
+	 * may have unneeded items in the sack.  We find the lowest page
+	 * in the stack that has more than one record in it and start there.
+	 */
+	ret = 0;
+	if (use_top)
+		stack_epg = cp->sp;
+	else
+		for (stack_epg = cp->csp; stack_epg > cp->sp; --stack_epg)
+			if (NUM_ENT(stack_epg->page) > 1)
+				break;
+	epg = stack_epg;
+	/*
+	 * !!!
+	 * There is an interesting deadlock situation here.  We have to relink
+	 * the leaf page chain around the leaf page being deleted.  Consider
+	 * a cursor walking through the leaf pages, that has the previous page
+	 * read-locked and is waiting on a lock for the page we're deleting.
+	 * It will deadlock here.  Before we unlink the subtree, we relink the
+	 * leaf page chain.
+	 */
+	if (LF_ISSET(BTD_RELINK) && LEVEL(cp->csp->page) == 1 &&
+	    (ret = __db_relink(dbc, cp->csp->page, NULL, PGNO_INVALID)) != 0)
+		goto discard;
+
+	/*
+	 * Delete the last item that references the underlying pages that are
+	 * to be deleted, and adjust cursors that reference that page.  Then,
+	 * save that page's page number and item count and release it.  If
+	 * the application isn't retaining locks because it's running without
+	 * transactions, this lets the rest of the tree get back to business
+	 * immediately.
+	 */
+	if ((ret = __memp_dirty(mpf,
+	    &epg->page, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+		goto discard;
+	if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0)
+		goto discard;
+	if ((ret = __bam_ca_di(dbc, PGNO(epg->page), epg->indx, -1)) != 0)
+		goto discard;
+
+	if (LF_ISSET(BTD_UPDATE) && epg->indx == 0) {
+		save_sp = cp->csp;
+		cp->csp = epg;
+		ret = __bam_pupdate(dbc, epg->page);
+		cp->csp = save_sp;
+		if (ret != 0)
+			goto discard;
+	}
+
+	pgno = PGNO(epg->page);
+	nitems = NUM_ENT(epg->page);
+
+	ret = __memp_fput(mpf, dbc->thread_info, epg->page, dbc->priority);
+	epg->page = NULL;
+	if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
+		ret = t_ret;
+	if (ret != 0)
+		goto err_inc;
+
+	/* Then, discard any pages that we don't care about. */
+discard: for (epg = cp->sp; epg < stack_epg; ++epg) {
+		if ((t_ret = __memp_fput(mpf, dbc->thread_info,
+		     epg->page, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+		epg->page = NULL;
+		if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+	if (ret != 0)
+		goto err;
+
+	/* Free the rest of the pages in the stack. */
+	while (++epg <= cp->csp) {
+		if ((ret = __memp_dirty(mpf, &epg->page,
+		    dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+			goto err;
+		/*
+		 * Delete page entries so they will be restored as part of
+		 * recovery.  We don't need to do cursor adjustment here as
+		 * the pages are being emptied by definition and so cannot
+		 * be referenced by a cursor.
+		 */
+		if (NUM_ENT(epg->page) != 0) {
+			DB_ASSERT(dbp->env, LEVEL(epg->page) != 1);
+
+			if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0)
+				goto err;
+			/*
+			 * Sheer paranoia: if we find any pages that aren't
+			 * emptied by the delete, someone else added an item
+			 * while we were walking the tree, and we discontinue
+			 * the delete.  Shouldn't be possible, but we check
+			 * regardless.
+			 */
+			if (NUM_ENT(epg->page) != 0)
+				goto err;
+		}
+
+		ret = __db_free(dbc, epg->page, 0);
+		if (cp->page == epg->page)
+			cp->page = NULL;
+		epg->page = NULL;
+		if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
+			ret = t_ret;
+		if (ret != 0)
+			goto err_inc;
+	}
+
+	if (0) {
+err_inc:	++epg;
+err:		for (; epg <= cp->csp; ++epg) {
+			if (epg->page != NULL) {
+				(void)__memp_fput(mpf, dbc->thread_info,
+				     epg->page, dbc->priority);
+				epg->page = NULL;
+			}
+			(void)__TLPUT(dbc, epg->lock);
+		}
+		BT_STK_CLR(cp);
+		return (ret);
+	}
+	BT_STK_CLR(cp);
+
+	/*
+	 * If we just deleted the next-to-last item from the root page, the
+	 * tree can collapse one or more levels.  While there remains only a
+	 * single item on the root page, write lock the last page referenced
+	 * by the root page and copy it over the root page.
+	 * Note that if pgno is the root of a btree database then the root
+	 * cannot change as we have it locked.
+	 */
+	if (nitems != 1)
+		return (0);
+	root_pgno = BAM_ROOT_PGNO(dbc);
+	if (pgno != root_pgno)
+		return (0);
+
+	for (done = 0; !done;) {
+		/* Initialize. */
+		parent = child = NULL;
+		LOCK_INIT(p_lock);
+		LOCK_INIT(c_lock);
+
+		/* Get the root. */
+		root_pgno = cp->root;
+		BAM_GET_ROOT(dbc, root_pgno,
+		    parent, DB_MPOOL_DIRTY, DB_LOCK_WRITE, p_lock, ret);
+
+		DB_ASSERT(dbp->env, parent != NULL);
+		if (ret != 0 || NUM_ENT(parent) != 1)
+			goto stop;
+
+		switch (TYPE(parent)) {
+		case P_IBTREE:
+			/*
+			 * If this is overflow, then try to delete it.
+			 * The child may or may not still point at it.
+			 */
+			bi = GET_BINTERNAL(dbp, parent, 0);
+			if (B_TYPE(bi->type) == B_OVERFLOW)
+				if ((ret = __db_doff(dbc,
+				    ((BOVERFLOW *)bi->data)->pgno)) != 0)
+					goto stop;
+			pgno = bi->pgno;
+			break;
+		case P_IRECNO:
+			pgno = GET_RINTERNAL(dbp, parent, 0)->pgno;
+			break;
+		default:
+			goto stop;
+		}
+
+		/* Lock the child page. */
+		if ((ret =
+		    __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, &c_lock)) != 0)
+			goto stop;
+		if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn,
+		    DB_MPOOL_DIRTY, &child)) != 0)
+			goto stop;
+
+		/* Log the change. */
+		if (DBC_LOGGING(dbc)) {
+			memset(&a, 0, sizeof(a));
+			a.data = child;
+			a.size = dbp->pgsize;
+			memset(&b, 0, sizeof(b));
+			b.data = P_ENTRY(dbp, parent, 0);
+			b.size = TYPE(parent) == P_IRECNO ? RINTERNAL_SIZE :
+			    BINTERNAL_SIZE(((BINTERNAL *)b.data)->len);
+			if ((ret = __bam_rsplit_log(dbp, dbc->txn,
+			    &child->lsn, 0, PGNO(child), &a, PGNO(parent),
+			    RE_NREC(parent), &b, &parent->lsn)) != 0)
+				goto stop;
+		} else
+			LSN_NOT_LOGGED(child->lsn);
+
+		/*
+		 * Make the switch.
+		 *
+		 * One fixup -- internal pages below the top level do not store
+		 * a record count, so we have to preserve it if we're not
+		 * converting to a leaf page.  Note also that we are about to
+		 * overwrite the parent page, including its LSN.  This is OK
+		 * because the log message we wrote describing this update
+		 * stores its LSN on the child page.  When the child is copied
+		 * onto the parent, the correct LSN is copied into place.
+		 */
+		COMPQUIET(rcnt, 0);
+		if (F_ISSET(cp, C_RECNUM) && LEVEL(child) > LEAFLEVEL)
+			rcnt = RE_NREC(parent);
+		memcpy(parent, child, dbp->pgsize);
+		PGNO(parent) = root_pgno;
+		if (F_ISSET(cp, C_RECNUM) && LEVEL(child) > LEAFLEVEL)
+			RE_NREC_SET(parent, rcnt);
+
+		/* Adjust the cursors. */
+		if ((ret = __bam_ca_rsplit(dbc, PGNO(child), root_pgno)) != 0)
+			goto stop;
+
+		/*
+		 * Free the page copied onto the root page and discard its
+		 * lock.  (The call to __db_free() discards our reference
+		 * to the page.)
+		 */
+		if ((ret = __db_free(dbc, child, 0)) != 0) {
+			child = NULL;
+			goto stop;
+		}
+		child = NULL;
+
+		if (0) {
+stop:			done = 1;
+		}
+		if ((t_ret = __TLPUT(dbc, p_lock)) != 0 && ret == 0)
+			ret = t_ret;
+		if (parent != NULL &&
+		    (t_ret = __memp_fput(mpf, dbc->thread_info,
+		    parent, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+		if ((t_ret = __TLPUT(dbc, c_lock)) != 0 && ret == 0)
+			ret = t_ret;
+		if (child != NULL &&
+		    (t_ret = __memp_fput(mpf, dbc->thread_info,
+		    child, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+
+	return (ret);
+}
+
+/*
+ * __bam_pupdate --
+ *	Update parent key pointers up the tree.
+ *
+ * PUBLIC: int __bam_pupdate __P((DBC *, PAGE *));
+ */
+int
+__bam_pupdate(dbc, lpg)
+	DBC *dbc;
+	PAGE *lpg;
+{
+	BTREE_CURSOR *cp;
+	ENV *env;
+	EPG *epg;
+	int ret;
+
+	env = dbc->env;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	ret = 0;
+
+	/*
+	 * Update the parents up the tree.  __bam_pinsert only looks at the
+	 * left child if is a leaf page, so we don't need to change it.  We
+	 * just do a delete and insert; a replace is possible but reusing
+	 * pinsert is better.
+	 */
+	for (epg = &cp->csp[-1]; epg >= cp->sp; epg--) {
+		if ((ret = __memp_dirty(dbc->dbp->mpf, &epg->page,
+		    dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+			return (ret);
+		epg->indx--;
+		if ((ret = __bam_pinsert(dbc, epg, 0,
+		    lpg, epg[1].page, BPI_NORECNUM | BPI_REPLACE)) != 0) {
+			if (ret == DB_NEEDSPLIT) {
+				/* This should not happen. */
+				__db_errx(env, DB_STR_A("1020",
+				    "Not enough room in parent: %s: page %lu",
+				    "%s %lu"), dbc->dbp->fname,
+				    (u_long)PGNO(epg->page));
+				ret = __env_panic(env, EINVAL);
+			}
+			epg->indx++;
+			return (ret);
+		}
+		epg->indx++;
+	}
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_method.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,727 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/qam.h"
+
+static int __bam_set_bt_minkey __P((DB *, u_int32_t));
+static int __bam_get_bt_compare
+	       __P((DB *, int (**)(DB *, const DBT *, const DBT *)));
+static int __bam_get_bt_prefix
+	       __P((DB *, size_t(**)(DB *, const DBT *, const DBT *)));
+static int __bam_set_bt_prefix
+	       __P((DB *, size_t(*)(DB *, const DBT *, const DBT *)));
+static int __ram_get_re_delim __P((DB *, int *));
+static int __ram_set_re_delim __P((DB *, int));
+static int __ram_set_re_len __P((DB *, u_int32_t));
+static int __ram_set_re_pad __P((DB *, int));
+static int __ram_get_re_source __P((DB *, const char **));
+static int __ram_set_re_source __P((DB *, const char *));
+
+/*
+ * __bam_db_create --
+ *	Btree specific initialization of the DB structure.
+ *
+ * PUBLIC: int __bam_db_create __P((DB *));
+ */
+int
+__bam_db_create(dbp)
+	DB *dbp;
+{
+	BTREE *t;
+	int ret;
+
+	/* Allocate and initialize the private btree structure. */
+	if ((ret = __os_calloc(dbp->env, 1, sizeof(BTREE), &t)) != 0)
+		return (ret);
+	dbp->bt_internal = t;
+
+	t->bt_minkey = DEFMINKEYPAGE;		/* Btree */
+	t->bt_compare = __bam_defcmp;
+	t->bt_prefix = __bam_defpfx;
+#ifdef HAVE_COMPRESSION
+	t->bt_compress = NULL;
+	t->bt_decompress = NULL;
+	t->compress_dup_compare = NULL;
+
+	/*
+	 * DB_AM_COMPRESS may have been set in __bam_metachk before the
+	 * bt_internal structure existed.
+	 */
+	if (F_ISSET(dbp, DB_AM_COMPRESS) &&
+	    (ret = __bam_set_bt_compress(dbp, NULL, NULL)) != 0)
+		return (ret);
+#endif
+
+	dbp->get_bt_compare = __bam_get_bt_compare;
+	dbp->set_bt_compare = __bam_set_bt_compare;
+	dbp->get_bt_minkey = __bam_get_bt_minkey;
+	dbp->set_bt_minkey = __bam_set_bt_minkey;
+	dbp->get_bt_prefix = __bam_get_bt_prefix;
+	dbp->set_bt_prefix = __bam_set_bt_prefix;
+
+	t->re_pad = ' ';			/* Recno */
+	t->re_delim = '\n';
+	t->re_eof = 1;
+
+	dbp->get_re_delim = __ram_get_re_delim;
+	dbp->set_re_delim = __ram_set_re_delim;
+	dbp->get_re_len = __ram_get_re_len;
+	dbp->set_re_len = __ram_set_re_len;
+	dbp->get_re_pad = __ram_get_re_pad;
+	dbp->set_re_pad = __ram_set_re_pad;
+	dbp->get_re_source = __ram_get_re_source;
+	dbp->set_re_source = __ram_set_re_source;
+
+	return (0);
+}
+
+/*
+ * __bam_db_close --
+ *	Btree specific discard of the DB structure.
+ *
+ * PUBLIC: int __bam_db_close __P((DB *));
+ */
+int
+__bam_db_close(dbp)
+	DB *dbp;
+{
+	BTREE *t;
+
+	if ((t = dbp->bt_internal) == NULL)
+		return (0);
+						/* Recno */
+	/* Close any backing source file descriptor. */
+	if (t->re_fp != NULL)
+		(void)fclose(t->re_fp);
+
+	/* Free any backing source file name. */
+	if (t->re_source != NULL)
+		__os_free(dbp->env, t->re_source);
+
+	__os_free(dbp->env, t);
+	dbp->bt_internal = NULL;
+
+	return (0);
+}
+
+/*
+ * __bam_map_flags --
+ *	Map Btree specific flags from public to the internal values.
+ *
+ * PUBLIC: void __bam_map_flags __P((DB *, u_int32_t *, u_int32_t *));
+ */
+void
+__bam_map_flags(dbp, inflagsp, outflagsp)
+	DB *dbp;
+	u_int32_t *inflagsp, *outflagsp;
+{
+	COMPQUIET(dbp, NULL);
+
+	if (FLD_ISSET(*inflagsp, DB_DUP)) {
+		FLD_SET(*outflagsp, DB_AM_DUP);
+		FLD_CLR(*inflagsp, DB_DUP);
+	}
+	if (FLD_ISSET(*inflagsp, DB_DUPSORT)) {
+		FLD_SET(*outflagsp, DB_AM_DUP | DB_AM_DUPSORT);
+		FLD_CLR(*inflagsp, DB_DUPSORT);
+	}
+	if (FLD_ISSET(*inflagsp, DB_RECNUM)) {
+		FLD_SET(*outflagsp, DB_AM_RECNUM);
+		FLD_CLR(*inflagsp, DB_RECNUM);
+	}
+	if (FLD_ISSET(*inflagsp, DB_REVSPLITOFF)) {
+		FLD_SET(*outflagsp, DB_AM_REVSPLITOFF);
+		FLD_CLR(*inflagsp, DB_REVSPLITOFF);
+	}
+}
+
+/*
+ * __bam_set_flags --
+ *	Set Btree specific flags.
+ *
+ * PUBLIC: int __bam_set_flags __P((DB *, u_int32_t *flagsp));
+ */
+int
+__bam_set_flags(dbp, flagsp)
+	DB *dbp;
+	u_int32_t *flagsp;
+{
+	BTREE *t;
+	u_int32_t flags;
+
+	t = dbp->bt_internal;
+
+	flags = *flagsp;
+	if (LF_ISSET(DB_DUP | DB_DUPSORT | DB_RECNUM | DB_REVSPLITOFF))
+		DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags");
+
+	/*
+	 * The DB_DUP and DB_DUPSORT flags are shared by the Hash
+	 * and Btree access methods.
+	 */
+	if (LF_ISSET(DB_DUP | DB_DUPSORT))
+		DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH);
+
+	if (LF_ISSET(DB_RECNUM | DB_REVSPLITOFF))
+		DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH);
+
+	/* DB_DUP/DB_DUPSORT is incompatible with DB_RECNUM. */
+	if (LF_ISSET(DB_DUP | DB_DUPSORT) && F_ISSET(dbp, DB_AM_RECNUM))
+		goto incompat;
+
+	/* DB_RECNUM is incompatible with DB_DUP/DB_DUPSORT. */
+	if (LF_ISSET(DB_RECNUM) && F_ISSET(dbp, DB_AM_DUP))
+		goto incompat;
+
+	/* DB_RECNUM is incompatible with DB_DUP/DB_DUPSORT. */
+	if (LF_ISSET(DB_RECNUM) && LF_ISSET(DB_DUP | DB_DUPSORT))
+		goto incompat;
+
+#ifdef HAVE_COMPRESSION
+	/* DB_RECNUM is incompatible with compression */
+	if (LF_ISSET(DB_RECNUM) && DB_IS_COMPRESSED(dbp)) {
+		__db_errx(dbp->env, DB_STR("1024",
+		    "DB_RECNUM cannot be used with compression"));
+		return (EINVAL);
+	}
+
+	/* DB_DUP without DB_DUPSORT is incompatible with compression */
+	if (LF_ISSET(DB_DUP) && !LF_ISSET(DB_DUPSORT) &&
+		!F_ISSET(dbp, DB_AM_DUPSORT) && DB_IS_COMPRESSED(dbp)) {
+		__db_errx(dbp->env, DB_STR("1025",
+	    "DB_DUP cannot be used with compression without DB_DUPSORT"));
+		return (EINVAL);
+	}
+#endif
+
+	if (LF_ISSET(DB_DUPSORT) && dbp->dup_compare == NULL) {
+#ifdef HAVE_COMPRESSION
+		if (DB_IS_COMPRESSED(dbp)) {
+			dbp->dup_compare = __bam_compress_dupcmp;
+			t->compress_dup_compare = __bam_defcmp;
+		} else
+#endif
+			dbp->dup_compare = __bam_defcmp;
+	}
+
+	__bam_map_flags(dbp, flagsp, &dbp->flags);
+	return (0);
+
+incompat:
+	return (__db_ferr(dbp->env, "DB->set_flags", 1));
+}
+
+/*
+ * __bam_get_bt_compare --
+ *	Get the comparison function.
+ */
+static int
+__bam_get_bt_compare(dbp, funcp)
+	DB *dbp;
+	int (**funcp) __P((DB *, const DBT *, const DBT *));
+{
+	BTREE *t;
+
+	DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
+
+	t = dbp->bt_internal;
+
+	if (funcp != NULL)
+		*funcp = t->bt_compare;
+
+	return (0);
+}
+
+/*
+ * __bam_set_bt_compare --
+ *	Set the comparison function.
+ *
+ * PUBLIC: int __bam_set_bt_compare
+ * PUBLIC:         __P((DB *, int (*)(DB *, const DBT *, const DBT *)));
+ */
+int
+__bam_set_bt_compare(dbp, func)
+	DB *dbp;
+	int (*func) __P((DB *, const DBT *, const DBT *));
+{
+	BTREE *t;
+
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_compare");
+	DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
+
+	t = dbp->bt_internal;
+
+	/*
+	 * Can't default the prefix routine if the user supplies a comparison
+	 * routine; shortening the keys can break their comparison algorithm.
+	 */
+	t->bt_compare = func;
+	if (t->bt_prefix == __bam_defpfx)
+		t->bt_prefix = NULL;
+
+	return (0);
+}
+
+/*
+ * __bam_set_bt_compress --
+ *	Set the compression functions.
+ *
+ * PUBLIC: int __bam_set_bt_compress __P((DB *,
+ * PUBLIC:  int (*)(DB *, const DBT *, const DBT *,
+ * PUBLIC:	    const DBT *, const DBT *, DBT *),
+ * PUBLIC:  int (*)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *)));
+ */
+int
+__bam_set_bt_compress(dbp, compress, decompress)
+	DB *dbp;
+	int (*compress) __P((DB *, const DBT *, const DBT *, const DBT *,
+				    const DBT *, DBT *));
+	int (*decompress) __P((DB *, const DBT *, const DBT *, DBT *, DBT *,
+				      DBT *));
+{
+#ifdef HAVE_COMPRESSION
+	BTREE *t;
+
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_compress");
+	DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
+
+	t = dbp->bt_internal;
+
+	/* compression is incompatible with DB_RECNUM */
+	if (F_ISSET(dbp, DB_AM_RECNUM)) {
+		__db_errx(dbp->env, DB_STR("1027",
+		    "compression cannot be used with DB_RECNUM"));
+		return (EINVAL);
+	}
+
+	/* compression is incompatible with DB_DUP without DB_DUPSORT */
+	if (F_ISSET(dbp, DB_AM_DUP) && !F_ISSET(dbp, DB_AM_DUPSORT)) {
+		__db_errx(dbp->env, DB_STR("1028",
+	    "compression cannot be used with DB_DUP without DB_DUPSORT"));
+		return (EINVAL);
+	}
+
+	if (compress != 0 && decompress != 0) {
+		t->bt_compress = compress;
+		t->bt_decompress = decompress;
+	} else if (compress == 0 && decompress == 0) {
+		t->bt_compress = __bam_defcompress;
+		t->bt_decompress = __bam_defdecompress;
+	} else {
+		__db_errx(dbp->env, DB_STR("1029",
+    "to enable compression you need to supply both function arguments"));
+		return (EINVAL);
+	}
+	F_SET(dbp, DB_AM_COMPRESS);
+
+	/* Copy dup_compare to compress_dup_compare, and use the compression
+	   duplicate compare */
+	if (F_ISSET(dbp, DB_AM_DUPSORT)) {
+		t->compress_dup_compare = dbp->dup_compare;
+		dbp->dup_compare = __bam_compress_dupcmp;
+	}
+
+	return (0);
+#else
+	COMPQUIET(compress, NULL);
+	COMPQUIET(decompress, NULL);
+
+	__db_errx(dbp->env, DB_STR("1030",
+	    "compression support has not been compiled in"));
+	return (EINVAL);
+#endif
+}
+
+/*
+ * __db_get_bt_minkey --
+ *	Get the minimum keys per page.
+ *
+ * PUBLIC: int __bam_get_bt_minkey __P((DB *, u_int32_t *));
+ */
+int
+__bam_get_bt_minkey(dbp, bt_minkeyp)
+	DB *dbp;
+	u_int32_t *bt_minkeyp;
+{
+	BTREE *t;
+
+	DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
+
+	t = dbp->bt_internal;
+	*bt_minkeyp = t->bt_minkey;
+	return (0);
+}
+
+/*
+ * __bam_set_bt_minkey --
+ *	Set the minimum keys per page.
+ */
+static int
+__bam_set_bt_minkey(dbp, bt_minkey)
+	DB *dbp;
+	u_int32_t bt_minkey;
+{
+	BTREE *t;
+
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_minkey");
+	DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
+
+	t = dbp->bt_internal;
+
+	if (bt_minkey < 2) {
+		__db_errx(dbp->env, DB_STR("1031",
+		    "minimum bt_minkey value is 2"));
+		return (EINVAL);
+	}
+
+	t->bt_minkey = bt_minkey;
+	return (0);
+}
+
+/*
+ * __bam_get_bt_prefix --
+ *	Get the prefix function.
+ */
+static int
+__bam_get_bt_prefix(dbp, funcp)
+	DB *dbp;
+	size_t (**funcp) __P((DB *, const DBT *, const DBT *));
+{
+	BTREE *t;
+
+	DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
+
+	t = dbp->bt_internal;
+	if (funcp != NULL)
+		*funcp = t->bt_prefix;
+	return (0);
+}
+
+/*
+ * __bam_set_bt_prefix --
+ *	Set the prefix function.
+ */
+static int
+__bam_set_bt_prefix(dbp, func)
+	DB *dbp;
+	size_t (*func) __P((DB *, const DBT *, const DBT *));
+{
+	BTREE *t;
+
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_prefix");
+	DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
+
+	t = dbp->bt_internal;
+
+	t->bt_prefix = func;
+	return (0);
+}
+
+/*
+ * __bam_copy_config
+ *	Copy the configuration of one DB handle to another.
+ * PUBLIC: void __bam_copy_config __P((DB *, DB*, u_int32_t));
+ */
+void
+__bam_copy_config(src, dst, nparts)
+	DB *src, *dst;
+	u_int32_t nparts;
+{
+	BTREE *s, *d;
+
+	COMPQUIET(nparts, 0);
+
+	s = src->bt_internal;
+	d = dst->bt_internal;
+	d->bt_compare = s->bt_compare;
+	d->bt_minkey = s->bt_minkey;
+	d->bt_minkey = s->bt_minkey;
+	d->bt_prefix = s->bt_prefix;
+#ifdef HAVE_COMPRESSION
+	d->bt_compress = s->bt_compress;
+	d->bt_decompress = s->bt_decompress;
+	d->compress_dup_compare = s->compress_dup_compare;
+#endif
+}
+
+/*
+ * __ram_map_flags --
+ *	Map Recno specific flags from public to the internal values.
+ *
+ * PUBLIC: void __ram_map_flags __P((DB *, u_int32_t *, u_int32_t *));
+ */
+void
+__ram_map_flags(dbp, inflagsp, outflagsp)
+	DB *dbp;
+	u_int32_t *inflagsp, *outflagsp;
+{
+	COMPQUIET(dbp, NULL);
+
+	if (FLD_ISSET(*inflagsp, DB_RENUMBER)) {
+		FLD_SET(*outflagsp, DB_AM_RENUMBER);
+		FLD_CLR(*inflagsp, DB_RENUMBER);
+	}
+	if (FLD_ISSET(*inflagsp, DB_SNAPSHOT)) {
+		FLD_SET(*outflagsp, DB_AM_SNAPSHOT);
+		FLD_CLR(*inflagsp, DB_SNAPSHOT);
+	}
+}
+
+/*
+ * __ram_set_flags --
+ *	Set Recno specific flags.
+ *
+ * PUBLIC: int __ram_set_flags __P((DB *, u_int32_t *flagsp));
+ */
+int
+__ram_set_flags(dbp, flagsp)
+	DB *dbp;
+	u_int32_t *flagsp;
+{
+	u_int32_t flags;
+
+	flags = *flagsp;
+	if (LF_ISSET(DB_RENUMBER | DB_SNAPSHOT)) {
+		DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags");
+		DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
+	}
+
+	__ram_map_flags(dbp, flagsp, &dbp->flags);
+	return (0);
+}
+
+/*
+ * __db_get_re_delim --
+ *	Get the variable-length input record delimiter.
+ */
+static int
+__ram_get_re_delim(dbp, re_delimp)
+	DB *dbp;
+	int *re_delimp;
+{
+	BTREE *t;
+
+	DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
+	t = dbp->bt_internal;
+	*re_delimp = t->re_delim;
+	return (0);
+}
+
+/*
+ * __ram_set_re_delim --
+ *	Set the variable-length input record delimiter.
+ */
+static int
+__ram_set_re_delim(dbp, re_delim)
+	DB *dbp;
+	int re_delim;
+{
+	BTREE *t;
+
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_delim");
+	DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
+
+	t = dbp->bt_internal;
+
+	t->re_delim = re_delim;
+	F_SET(dbp, DB_AM_DELIMITER);
+
+	return (0);
+}
+
+/*
+ * __db_get_re_len --
+ *	Get the variable-length input record length.
+ *
+ * PUBLIC: int __ram_get_re_len __P((DB *, u_int32_t *));
+ */
+int
+__ram_get_re_len(dbp, re_lenp)
+	DB *dbp;
+	u_int32_t *re_lenp;
+{
+	BTREE *t;
+	QUEUE *q;
+
+	DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
+
+	/*
+	 * This has to work for all access methods, before or after opening the
+	 * database.  When the record length is set with __ram_set_re_len, the
+	 * value in both the BTREE and QUEUE structs will be correct.
+	 * Otherwise, this only makes sense after the database in opened, in
+	 * which case we know the type.
+	 */
+	if (dbp->type == DB_QUEUE) {
+		q = dbp->q_internal;
+		*re_lenp = q->re_len;
+	} else {
+		t = dbp->bt_internal;
+		*re_lenp = t->re_len;
+	}
+
+	return (0);
+}
+
+/*
+ * __ram_set_re_len --
+ *	Set the variable-length input record length.
+ */
+static int
+__ram_set_re_len(dbp, re_len)
+	DB *dbp;
+	u_int32_t re_len;
+{
+	BTREE *t;
+#ifdef HAVE_QUEUE
+	QUEUE *q;
+#endif
+
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_len");
+	DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
+
+	t = dbp->bt_internal;
+	t->re_len = re_len;
+
+#ifdef HAVE_QUEUE
+	q = dbp->q_internal;
+	q->re_len = re_len;
+#endif
+
+	F_SET(dbp, DB_AM_FIXEDLEN);
+
+	return (0);
+}
+
+/*
+ * __db_get_re_pad --
+ *	Get the fixed-length record pad character.
+ *
+ * PUBLIC: int __ram_get_re_pad __P((DB *, int *));
+ */
+int
+__ram_get_re_pad(dbp, re_padp)
+	DB *dbp;
+	int *re_padp;
+{
+	BTREE *t;
+	QUEUE *q;
+
+	DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
+
+	/*
+	 * This has to work for all access methods, before or after opening the
+	 * database.  When the record length is set with __ram_set_re_pad, the
+	 * value in both the BTREE and QUEUE structs will be correct.
+	 * Otherwise, this only makes sense after the database in opened, in
+	 * which case we know the type.
+	 */
+	if (dbp->type == DB_QUEUE) {
+		q = dbp->q_internal;
+		*re_padp = q->re_pad;
+	} else {
+		t = dbp->bt_internal;
+		*re_padp = t->re_pad;
+	}
+
+	return (0);
+}
+
+/*
+ * __ram_set_re_pad --
+ *	Set the fixed-length record pad character.
+ */
+static int
+__ram_set_re_pad(dbp, re_pad)
+	DB *dbp;
+	int re_pad;
+{
+	BTREE *t;
+#ifdef HAVE_QUEUE
+	QUEUE *q;
+#endif
+
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_pad");
+	DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
+
+	t = dbp->bt_internal;
+	t->re_pad = re_pad;
+
+#ifdef HAVE_QUEUE
+	q = dbp->q_internal;
+	q->re_pad = re_pad;
+#endif
+
+	F_SET(dbp, DB_AM_PAD);
+
+	return (0);
+}
+
+/*
+ * __db_get_re_source --
+ *	Get the backing source file name.
+ */
+static int
+__ram_get_re_source(dbp, re_sourcep)
+	DB *dbp;
+	const char **re_sourcep;
+{
+	BTREE *t;
+
+	DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
+
+	t = dbp->bt_internal;
+	*re_sourcep = t->re_source;
+	return (0);
+}
+
+/*
+ * __ram_set_re_source --
+ *	Set the backing source file name.
+ */
+static int
+__ram_set_re_source(dbp, re_source)
+	DB *dbp;
+	const char *re_source;
+{
+	BTREE *t;
+
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_source");
+	DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
+
+	t = dbp->bt_internal;
+
+	return (__os_strdup(dbp->env, re_source, &t->re_source));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_open.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,699 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/crypto.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_swap.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+#include "dbinc/fop.h"
+
+static void __bam_init_meta __P((DB *, BTMETA *, db_pgno_t, DB_LSN *));
+
+/*
+ * __bam_open --
+ *	Open a btree.
+ *
+ * PUBLIC: int __bam_open __P((DB *, DB_THREAD_INFO *,
+ * PUBLIC:      DB_TXN *, const char *, db_pgno_t, u_int32_t));
+ */
+int
+__bam_open(dbp, ip, txn, name, base_pgno, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name;
+	db_pgno_t base_pgno;
+	u_int32_t flags;
+{
+	BTREE *t;
+
+	COMPQUIET(name, NULL);
+	t = dbp->bt_internal;
+
+	/*
+	 * We don't permit the user to specify a prefix routine if they didn't
+	 * also specify a comparison routine, they can't know enough about our
+	 * comparison routine to get it right.
+	 */
+	if (t->bt_compare == __bam_defcmp && t->bt_prefix != __bam_defpfx) {
+		__db_errx(dbp->env, DB_STR("1006",
+"prefix comparison may not be specified for default comparison routine"));
+		return (EINVAL);
+	}
+
+	/*
+	 * Verify that the bt_minkey value specified won't cause the
+	 * calculation of ovflsize to underflow [#2406] for this pagesize.
+	 */
+	if (B_MINKEY_TO_OVFLSIZE(dbp, t->bt_minkey, dbp->pgsize) >
+	    B_MINKEY_TO_OVFLSIZE(dbp, DEFMINKEYPAGE, dbp->pgsize)) {
+		__db_errx(dbp->env, DB_STR_A("1007",
+		    "bt_minkey value of %lu too high for page size of %lu",
+		    "%lu %lu"), (u_long)t->bt_minkey, (u_long)dbp->pgsize);
+		return (EINVAL);
+	}
+
+	/* Start up the tree. */
+	return (__bam_read_root(dbp, ip, txn, base_pgno, flags));
+}
+
+/*
+ * __bam_metachk --
+ *
+ * PUBLIC: int __bam_metachk __P((DB *, const char *, BTMETA *));
+ */
+int
+__bam_metachk(dbp, name, btm)
+	DB *dbp;
+	const char *name;
+	BTMETA *btm;
+{
+	ENV *env;
+	u_int32_t vers;
+	int ret;
+
+	env = dbp->env;
+
+	/*
+	 * At this point, all we know is that the magic number is for a Btree.
+	 * Check the version, the database may be out of date.
+	 */
+	vers = btm->dbmeta.version;
+	if (F_ISSET(dbp, DB_AM_SWAP))
+		M_32_SWAP(vers);
+	switch (vers) {
+	case 6:
+	case 7:
+		__db_errx(env, DB_STR_A("1008",
+		    "%s: btree version %lu requires a version upgrade",
+		    "%s %lu"), name, (u_long)vers);
+		return (DB_OLD_VERSION);
+	case 8:
+	case 9:
+		break;
+	default:
+		__db_errx(env, DB_STR_A("1009",
+		    "%s: unsupported btree version: %lu", "%s %lu"),
+		    name, (u_long)vers);
+		return (EINVAL);
+	}
+
+	/* Swap the page if we need to. */
+	if (F_ISSET(dbp, DB_AM_SWAP) &&
+	    (ret = __bam_mswap(env, (PAGE *)btm)) != 0)
+		return (ret);
+
+	/*
+	 * Check application info against metadata info, and set info, flags,
+	 * and type based on metadata info.
+	 */
+	if ((ret =
+	    __db_fchk(env, "DB->open", btm->dbmeta.flags, BTM_MASK)) != 0)
+		return (ret);
+
+	if (F_ISSET(&btm->dbmeta, BTM_RECNO)) {
+		if (dbp->type == DB_BTREE)
+			goto wrong_type;
+		dbp->type = DB_RECNO;
+		DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
+	} else {
+		if (dbp->type == DB_RECNO)
+			goto wrong_type;
+		dbp->type = DB_BTREE;
+		DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
+	}
+
+	if (F_ISSET(&btm->dbmeta, BTM_DUP))
+		F_SET(dbp, DB_AM_DUP);
+	else
+		if (F_ISSET(dbp, DB_AM_DUP)) {
+			__db_errx(env, DB_STR_A("1010",
+		"%s: DB_DUP specified to open method but not set in database",
+			    "%s"), name);
+			return (EINVAL);
+		}
+
+	if (F_ISSET(&btm->dbmeta, BTM_RECNUM)) {
+		if (dbp->type != DB_BTREE)
+			goto wrong_type;
+		F_SET(dbp, DB_AM_RECNUM);
+
+		if ((ret = __db_fcchk(env,
+		    "DB->open", dbp->flags, DB_AM_DUP, DB_AM_RECNUM)) != 0)
+			return (ret);
+	} else
+		if (F_ISSET(dbp, DB_AM_RECNUM)) {
+			__db_errx(env, DB_STR_A("1011",
+	    "%s: DB_RECNUM specified to open method but not set in database",
+			    "%s"), name);
+			return (EINVAL);
+		}
+
+	if (F_ISSET(&btm->dbmeta, BTM_FIXEDLEN)) {
+		if (dbp->type != DB_RECNO)
+			goto wrong_type;
+		F_SET(dbp, DB_AM_FIXEDLEN);
+	} else
+		if (F_ISSET(dbp, DB_AM_FIXEDLEN)) {
+			__db_errx(env, DB_STR_A("1012",
+	"%s: DB_FIXEDLEN specified to open method but not set in database",
+			"%s"), name);
+			return (EINVAL);
+		}
+
+	if (F_ISSET(&btm->dbmeta, BTM_RENUMBER)) {
+		if (dbp->type != DB_RECNO)
+			goto wrong_type;
+		F_SET(dbp, DB_AM_RENUMBER);
+	} else
+		if (F_ISSET(dbp, DB_AM_RENUMBER)) {
+			__db_errx(env, DB_STR_A("1013",
+	    "%s: DB_RENUMBER specified to open method but not set in database",
+			    "%s"), name);
+			return (EINVAL);
+		}
+
+	if (F_ISSET(&btm->dbmeta, BTM_SUBDB))
+		F_SET(dbp, DB_AM_SUBDB);
+	else
+		if (F_ISSET(dbp, DB_AM_SUBDB)) {
+			__db_errx(env, DB_STR_A("1014",
+	    "%s: multiple databases specified but not supported by file",
+			    "%s"), name);
+			return (EINVAL);
+		}
+
+	if (F_ISSET(&btm->dbmeta, BTM_DUPSORT)) {
+		if (dbp->dup_compare == NULL)
+			dbp->dup_compare = __bam_defcmp;
+		F_SET(dbp, DB_AM_DUPSORT);
+	} else
+		if (dbp->dup_compare != NULL) {
+			__db_errx(env, DB_STR_A("1015",
+		"%s: duplicate sort specified but not supported in database",
+			    "%s"), name);
+			return (EINVAL);
+		}
+
+#ifdef HAVE_COMPRESSION
+	if (F_ISSET(&btm->dbmeta, BTM_COMPRESS)) {
+		F_SET(dbp, DB_AM_COMPRESS);
+		if ((BTREE *)dbp->bt_internal != NULL &&
+		    !DB_IS_COMPRESSED(dbp) &&
+		    (ret = __bam_set_bt_compress(dbp, NULL, NULL)) != 0)
+			return (ret);
+	} else {
+		if ((BTREE *)dbp->bt_internal != NULL &&
+		    DB_IS_COMPRESSED(dbp)) {
+			__db_errx(env, DB_STR_A("1016",
+	"%s: compresssion specified to open method but not set in database",
+			    "%s"), name);
+			return (EINVAL);
+		}
+	}
+#else
+	if (F_ISSET(&btm->dbmeta, BTM_COMPRESS)) {
+		__db_errx(env, DB_STR_A("1017",
+		    "%s: compression support has not been compiled in", "%s"),
+		    name);
+		return (EINVAL);
+	}
+#endif
+
+	/* Set the page size. */
+	dbp->pgsize = btm->dbmeta.pagesize;
+
+	/* Copy the file's ID. */
+	memcpy(dbp->fileid, btm->dbmeta.uid, DB_FILE_ID_LEN);
+
+	return (0);
+
+wrong_type:
+	if (dbp->type == DB_BTREE)
+		__db_errx(env, DB_STR("1018",
+		    "open method type is Btree, database type is Recno"));
+	else
+		__db_errx(env, DB_STR("1019",
+		    "open method type is Recno, database type is Btree"));
+	return (EINVAL);
+}
+
+/*
+ * __bam_read_root --
+ *	Read the root page and check a tree.
+ *
+ * PUBLIC: int __bam_read_root __P((DB *,
+ * PUBLIC:      DB_THREAD_INFO *, DB_TXN *, db_pgno_t, u_int32_t));
+ */
+int
+__bam_read_root(dbp, ip, txn, base_pgno, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	db_pgno_t base_pgno;
+	u_int32_t flags;
+{
+	BTMETA *meta;
+	BTREE *t;
+	DBC *dbc;
+	DB_LOCK metalock;
+	DB_MPOOLFILE *mpf;
+	int ret, t_ret;
+
+	COMPQUIET(flags, 0);
+
+	meta = NULL;
+	t = dbp->bt_internal;
+	LOCK_INIT(metalock);
+	mpf = dbp->mpf;
+	ret = 0;
+
+	/* Get a cursor.  */
+	if ((ret = __db_cursor(dbp, ip, txn, &dbc,
+	    F_ISSET(dbp, DB_AM_RECOVER) ? DB_RECOVER : 0)) != 0)
+		return (ret);
+
+	/* Get the metadata page. */
+	if ((ret =
+	    __db_lget(dbc, 0, base_pgno, DB_LOCK_READ, 0, &metalock)) != 0)
+		goto err;
+	if ((ret = __memp_fget(mpf, &base_pgno, ip, dbc->txn, 0, &meta)) != 0)
+		goto err;
+
+	/*
+	 * If the magic number is set, the tree has been created.  Correct
+	 * any fields that may not be right.  Note, all of the local flags
+	 * were set by DB->open.
+	 *
+	 * Otherwise, we'd better be in recovery or abort, in which case the
+	 * metadata page will be created/initialized elsewhere.
+	 *
+	 * Ignore the last_pgno on the metadata page for snapshot transactions:
+	 * we may be reading an old version of the page, and we've already
+	 * set last_pgno from the file size.  The only time this would matter
+	 * is if we don't have ftruncate and there are some free pages at the
+	 * end of the file: we could end up with holes.
+	 */
+	if (meta->dbmeta.magic == DB_BTREEMAGIC) {
+		t->bt_minkey = meta->minkey;
+		t->re_pad = (int)meta->re_pad;
+		t->re_len = meta->re_len;
+
+		t->bt_meta = base_pgno;
+		t->bt_root = meta->root;
+		t->revision = dbp->mpf->mfp->revision;
+		if (PGNO(meta) == PGNO_BASE_MD &&
+		    !F_ISSET(dbp, DB_AM_RECOVER) &&
+		    (txn == NULL || !F_ISSET(txn, TXN_SNAPSHOT)) && (ret =
+		    __memp_set_last_pgno(mpf, meta->dbmeta.last_pgno)) != 0)
+			goto err;
+	} else {
+		DB_ASSERT(dbp->env,
+		    IS_RECOVERING(dbp->env) || F_ISSET(dbp, DB_AM_RECOVER));
+	}
+
+	/*
+	 * !!!
+	 * If creating a subdatabase, we've already done an insert when
+	 * we put the subdatabase's entry into the master database, so
+	 * our last-page-inserted value is wrongly initialized for the
+	 * master database, not the subdatabase we're creating.  I'm not
+	 * sure where the *right* place to clear this value is, it's not
+	 * intuitively obvious that it belongs here.
+	 */
+	t->bt_lpgno = PGNO_INVALID;
+
+err:	/* Put the metadata page back. */
+	if (meta != NULL && (t_ret = __memp_fput(mpf,
+	    ip, meta, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+/*
+ * __bam_init_meta --
+ *
+ * Initialize a btree meta-data page.  The following fields may need
+ * to be updated later: last_pgno, root.
+ */
+static void
+__bam_init_meta(dbp, meta, pgno, lsnp)
+	DB *dbp;
+	BTMETA *meta;
+	db_pgno_t pgno;
+	DB_LSN *lsnp;
+{
+	BTREE *t;
+#ifdef HAVE_PARTITION
+	DB_PARTITION *part;
+#endif
+	ENV *env;
+
+	env = dbp->env;
+	t = dbp->bt_internal;
+
+	memset(meta, 0, sizeof(BTMETA));
+	meta->dbmeta.lsn = *lsnp;
+	meta->dbmeta.pgno = pgno;
+	meta->dbmeta.magic = DB_BTREEMAGIC;
+	meta->dbmeta.version = DB_BTREEVERSION;
+	meta->dbmeta.pagesize = dbp->pgsize;
+	if (F_ISSET(dbp, DB_AM_CHKSUM))
+		FLD_SET(meta->dbmeta.metaflags, DBMETA_CHKSUM);
+	if (F_ISSET(dbp, DB_AM_ENCRYPT)) {
+		meta->dbmeta.encrypt_alg = env->crypto_handle->alg;
+		DB_ASSERT(env, meta->dbmeta.encrypt_alg != 0);
+		meta->crypto_magic = meta->dbmeta.magic;
+	}
+	meta->dbmeta.type = P_BTREEMETA;
+	meta->dbmeta.free = PGNO_INVALID;
+	meta->dbmeta.last_pgno = pgno;
+	if (F_ISSET(dbp, DB_AM_DUP))
+		F_SET(&meta->dbmeta, BTM_DUP);
+	if (F_ISSET(dbp, DB_AM_FIXEDLEN))
+		F_SET(&meta->dbmeta, BTM_FIXEDLEN);
+	if (F_ISSET(dbp, DB_AM_RECNUM))
+		F_SET(&meta->dbmeta, BTM_RECNUM);
+	if (F_ISSET(dbp, DB_AM_RENUMBER))
+		F_SET(&meta->dbmeta, BTM_RENUMBER);
+	if (F_ISSET(dbp, DB_AM_SUBDB))
+		F_SET(&meta->dbmeta, BTM_SUBDB);
+	if (dbp->dup_compare != NULL)
+		F_SET(&meta->dbmeta, BTM_DUPSORT);
+#ifdef HAVE_COMPRESSION
+	if (DB_IS_COMPRESSED(dbp))
+		F_SET(&meta->dbmeta, BTM_COMPRESS);
+#endif
+	if (dbp->type == DB_RECNO)
+		F_SET(&meta->dbmeta, BTM_RECNO);
+	memcpy(meta->dbmeta.uid, dbp->fileid, DB_FILE_ID_LEN);
+
+	meta->minkey = t->bt_minkey;
+	meta->re_len = t->re_len;
+	meta->re_pad = (u_int32_t)t->re_pad;
+
+#ifdef HAVE_PARTITION
+	if ((part = dbp->p_internal) != NULL) {
+		meta->dbmeta.nparts = part->nparts;
+		if (F_ISSET(part, PART_CALLBACK))
+			FLD_SET(meta->dbmeta.metaflags, DBMETA_PART_CALLBACK);
+		if (F_ISSET(part, PART_RANGE))
+			FLD_SET(meta->dbmeta.metaflags, DBMETA_PART_RANGE);
+	}
+#endif
+}
+
+/*
+ * __bam_new_file --
+ * Create the necessary pages to begin a new database file.
+ *
+ * This code appears more complex than it is because of the two cases (named
+ * and unnamed).  The way to read the code is that for each page being created,
+ * there are three parts: 1) a "get page" chunk (which either uses malloc'd
+ * memory or calls __memp_fget), 2) the initialization, and 3) the "put page"
+ * chunk which either does a fop write or an __memp_fput.
+ *
+ * PUBLIC: int __bam_new_file __P((DB *,
+ * PUBLIC:      DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *));
+ */
+int
+__bam_new_file(dbp, ip, txn, fhp, name)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DB_FH *fhp;
+	const char *name;
+{
+	BTMETA *meta;
+	DBT pdbt;
+	DB_LSN lsn;
+	DB_MPOOLFILE *mpf;
+	DB_PGINFO pginfo;
+	ENV *env;
+	PAGE *root;
+	db_pgno_t pgno;
+	int ret, t_ret;
+	void *buf;
+
+	env = dbp->env;
+	mpf = dbp->mpf;
+	root = NULL;
+	meta = NULL;
+	buf = NULL;
+
+	if (F_ISSET(dbp, DB_AM_INMEM)) {
+		/* Build the meta-data page. */
+		pgno = PGNO_BASE_MD;
+		if ((ret = __memp_fget(mpf, &pgno,
+		    ip, txn, DB_MPOOL_CREATE | DB_MPOOL_DIRTY, &meta)) != 0)
+			return (ret);
+		LSN_NOT_LOGGED(lsn);
+		__bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
+		meta->root = 1;
+		meta->dbmeta.last_pgno = 1;
+		if ((ret =
+		    __db_log_page(dbp, txn, &lsn, pgno, (PAGE *)meta)) != 0)
+			goto err;
+		ret = __memp_fput(mpf, ip, meta, dbp->priority);
+		meta = NULL;
+		if (ret != 0)
+			goto err;
+
+		/* Build the root page. */
+		pgno = 1;
+		if ((ret = __memp_fget(mpf, &pgno,
+		    ip, txn, DB_MPOOL_CREATE | DB_MPOOL_DIRTY, &root)) != 0)
+			goto err;
+		P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
+		    LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
+		LSN_NOT_LOGGED(root->lsn);
+		if ((ret =
+		    __db_log_page(dbp, txn, &root->lsn, pgno, root)) != 0)
+			goto err;
+		ret = __memp_fput(mpf, ip, root, dbp->priority);
+		root = NULL;
+		if (ret != 0)
+			goto err;
+	} else {
+		memset(&pdbt, 0, sizeof(pdbt));
+
+		/* Build the meta-data page. */
+		pginfo.db_pagesize = dbp->pgsize;
+		pginfo.flags =
+		    F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP));
+		pginfo.type = dbp->type;
+		pdbt.data = &pginfo;
+		pdbt.size = sizeof(pginfo);
+		if ((ret = __os_calloc(env, 1, dbp->pgsize, &buf)) != 0)
+			return (ret);
+		meta = (BTMETA *)buf;
+		LSN_NOT_LOGGED(lsn);
+		__bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn);
+		meta->root = 1;
+		meta->dbmeta.last_pgno = 1;
+		if ((ret = __db_pgout(
+		    dbp->dbenv, PGNO_BASE_MD, meta, &pdbt)) != 0)
+			goto err;
+		if ((ret = __fop_write(env, txn, name, dbp->dirname,
+		    DB_APP_DATA, fhp,
+		    dbp->pgsize, 0, 0, buf, dbp->pgsize, 1, F_ISSET(
+		    dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0)
+			goto err;
+		meta = NULL;
+
+		/* Build the root page. */
+#ifdef DIAGNOSTIC
+		memset(buf, CLEAR_BYTE, dbp->pgsize);
+#endif
+		root = (PAGE *)buf;
+		P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID,
+		    LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE);
+		LSN_NOT_LOGGED(root->lsn);
+		if ((ret =
+		    __db_pgout(dbp->dbenv, root->pgno, root, &pdbt)) != 0)
+			goto err;
+		if ((ret =
+		    __fop_write(env, txn, name, dbp->dirname, DB_APP_DATA,
+		    fhp, dbp->pgsize, 1, 0, buf, dbp->pgsize, 1, F_ISSET(
+		    dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0)
+			goto err;
+		root = NULL;
+	}
+
+err:	if (buf != NULL)
+		__os_free(env, buf);
+	else {
+		if (meta != NULL &&
+		    (t_ret = __memp_fput(mpf, ip,
+		    meta, dbp->priority)) != 0 && ret == 0)
+			ret = t_ret;
+		if (root != NULL &&
+		    (t_ret = __memp_fput(mpf, ip,
+		    root, dbp->priority)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+	return (ret);
+}
+
+/*
+ * __bam_new_subdb --
+ *	Create a metadata page and a root page for a new btree.
+ *
+ * PUBLIC: int __bam_new_subdb __P((DB *, DB *, DB_THREAD_INFO *, DB_TXN *));
+ */
+int
+__bam_new_subdb(mdbp, dbp, ip, txn)
+	DB *mdbp, *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+{
+	BTMETA *meta;
+	DBC *dbc;
+	DB_LOCK metalock;
+	DB_LSN lsn;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *root;
+	int ret, t_ret;
+
+	env = mdbp->env;
+	mpf = mdbp->mpf;
+	dbc = NULL;
+	meta = NULL;
+	root = NULL;
+
+	if ((ret = __db_cursor(mdbp, ip, txn,
+	    &dbc, CDB_LOCKING(env) ?  DB_WRITECURSOR : 0)) != 0)
+		return (ret);
+
+	/* Get, and optionally create the metadata page. */
+	if ((ret = __db_lget(dbc,
+	    0, dbp->meta_pgno, DB_LOCK_WRITE, 0, &metalock)) != 0)
+		goto err;
+	if ((ret = __memp_fget(mpf, &dbp->meta_pgno,
+	    ip, txn, DB_MPOOL_CREATE | DB_MPOOL_DIRTY, &meta)) != 0)
+		goto err;
+
+	/* Build meta-data page. */
+	lsn = meta->dbmeta.lsn;
+	__bam_init_meta(dbp, meta, dbp->meta_pgno, &lsn);
+	if ((ret = __db_log_page(mdbp,
+	    txn, &meta->dbmeta.lsn, dbp->meta_pgno, (PAGE *)meta)) != 0)
+		goto err;
+
+	/* Create and initialize a root page. */
+	if ((ret = __db_new(dbc,
+	    dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE, NULL, &root)) != 0)
+		goto err;
+	root->level = LEAFLEVEL;
+
+	if (DBENV_LOGGING(env) &&
+#if !defined(DEBUG_WOP)
+	    txn != NULL &&
+#endif
+
+	    (ret = __bam_root_log(mdbp, txn, &meta->dbmeta.lsn, 0,
+	    meta->dbmeta.pgno, root->pgno, &meta->dbmeta.lsn)) != 0)
+		goto err;
+
+	meta->root = root->pgno;
+	if ((ret =
+	    __db_log_page(mdbp, txn, &root->lsn, root->pgno, root)) != 0)
+		goto err;
+
+	/* Release the metadata and root pages. */
+	if ((ret = __memp_fput(mpf, ip, meta, dbc->priority)) != 0)
+		goto err;
+	meta = NULL;
+	if ((ret = __memp_fput(mpf, ip, root, dbc->priority)) != 0)
+		goto err;
+	root = NULL;
+err:
+	if (meta != NULL)
+		if ((t_ret = __memp_fput(mpf, ip,
+		meta, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+	if (root != NULL)
+		if ((t_ret = __memp_fput(mpf, ip,
+		root, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+	if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
+		ret = t_ret;
+	if (dbc != NULL)
+		if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+			ret = t_ret;
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_put.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1109 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+
+static int __bam_build
+	       __P((DBC *, u_int32_t, DBT *, PAGE *, u_int32_t, u_int32_t));
+static int __bam_dup_check __P((DBC *, u_int32_t,
+		PAGE *, u_int32_t, u_int32_t, db_indx_t *));
+static int __bam_dup_convert __P((DBC *, PAGE *, u_int32_t, u_int32_t));
+static int __bam_ovput
+	       __P((DBC *, u_int32_t, db_pgno_t, PAGE *, u_int32_t, DBT *));
+static u_int32_t
+	   __bam_partsize __P((DB *, u_int32_t, DBT *, PAGE *, u_int32_t));
+
+/*
+ * __bam_iitem --
+ *	Insert an item into the tree.
+ *
+ * PUBLIC: int __bam_iitem __P((DBC *, DBT *, DBT *, u_int32_t, u_int32_t));
+ */
+int
+__bam_iitem(dbc, key, data, op, flags)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t op, flags;
+{
+	BKEYDATA *bk, bk_tmp;
+	BTREE *t;
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DBT bk_hdr, tdbt;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h;
+	db_indx_t cnt, indx;
+	u_int32_t data_size, have_bytes, need_bytes, needed, pages, pagespace;
+	char tmp_ch;
+	int cmp, bigkey, bigdata, del, dupadjust;
+	int padrec, replace, ret, t_ret, was_deleted;
+
+	COMPQUIET(cnt, 0);
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	t = dbp->bt_internal;
+	h = cp->page;
+	indx = cp->indx;
+	del = dupadjust = replace = was_deleted = 0;
+
+	/*
+	 * Fixed-length records with partial puts: it's an error to specify
+	 * anything other simple overwrite.
+	 */
+	if (F_ISSET(dbp, DB_AM_FIXEDLEN) &&
+	    F_ISSET(data, DB_DBT_PARTIAL) && data->size != data->dlen)
+		return (__db_rec_repl(env, data->size, data->dlen));
+
+	/*
+	 * Figure out how much space the data will take, including if it's a
+	 * partial record.
+	 *
+	 * Fixed-length records: it's an error to specify a record that's
+	 * longer than the fixed-length, and we never require less than
+	 * the fixed-length record size.
+	 */
+	data_size = F_ISSET(data, DB_DBT_PARTIAL) ?
+	    __bam_partsize(dbp, op, data, h, indx) : data->size;
+	padrec = 0;
+	if (F_ISSET(dbp, DB_AM_FIXEDLEN)) {
+		if (data_size > t->re_len)
+			return (__db_rec_toobig(env, data_size, t->re_len));
+
+		/* Records that are deleted anyway needn't be padded out. */
+		if (!LF_ISSET(BI_DELETED) && data_size < t->re_len) {
+			padrec = 1;
+			data_size = t->re_len;
+		}
+	}
+
+	/*
+	 * Handle partial puts or short fixed-length records: check whether we
+	 * can just append the data or else build the real record.  We can't
+	 * append if there are secondaries: we need the whole data item for the
+	 * application's secondary callback.
+	 */
+	if (op == DB_CURRENT && dbp->dup_compare == NULL &&
+	    F_ISSET(data, DB_DBT_PARTIAL) && !DB_IS_PRIMARY(dbp)) {
+		bk = GET_BKEYDATA(
+		    dbp, h, indx + (TYPE(h) == P_LBTREE ? O_INDX : 0));
+		/*
+		 * If the item is an overflow type, and the input DBT is
+		 * partial, and begins at the length of the current item then
+		 * it is an append. Avoid deleting and re-creating the entire
+		 * offpage item.
+		 */
+		if (B_TYPE(bk->type) == B_OVERFLOW &&
+		    data->doff == ((BOVERFLOW *)bk)->tlen) {
+			/*
+			 * If the cursor has not already cached the last page
+			 * in the offpage chain. We need to walk the chain
+			 * to be sure that the page has been read.
+			 */
+			if (cp->stream_start_pgno != ((BOVERFLOW *)bk)->pgno ||
+			    cp->stream_off > data->doff || data->doff >
+			    cp->stream_off + P_MAXSPACE(dbp, dbp->pgsize)) {
+				memset(&tdbt, 0, sizeof(DBT));
+				tdbt.doff = data->doff - 1;
+				/*
+				 * Set the length to 1, to force __db_goff
+				 * to do the traversal.
+				 */
+				tdbt.dlen = tdbt.ulen = 1;
+				tdbt.data = &tmp_ch;
+				tdbt.flags = DB_DBT_PARTIAL | DB_DBT_USERMEM;
+
+				/*
+				 * Read to the last page.  It will be cached
+				 * in the cursor.
+				 */
+				if ((ret = __db_goff(
+				    dbc, &tdbt, ((BOVERFLOW *)bk)->tlen,
+				    ((BOVERFLOW *)bk)->pgno, NULL, NULL)) != 0)
+					return (ret);
+			}
+
+			/*
+			 * Since this is an append, dlen is irrelevant (there
+			 * are no bytes to overwrite). We need the caller's
+			 * DBT size to end up with the total size of the item.
+			 * From now on, use dlen as the length of the user's
+			 * data that we are going to append.
+			 * Don't futz with the caller's DBT any more than we
+			 * have to in order to send back the size.
+			 */
+			tdbt = *data;
+			tdbt.dlen = data->size;
+			tdbt.size = data_size;
+			data = &tdbt;
+			F_SET(data, DB_DBT_STREAMING);
+		}
+	}
+	if (!F_ISSET(data, DB_DBT_STREAMING) &&
+	    (padrec || F_ISSET(data, DB_DBT_PARTIAL))) {
+		tdbt = *data;
+		if ((ret =
+		    __bam_build(dbc, op, &tdbt, h, indx, data_size)) != 0)
+			return (ret);
+		data = &tdbt;
+	}
+
+	/*
+	 * If the user has specified a duplicate comparison function, return
+	 * an error if DB_CURRENT was specified and the replacement data
+	 * doesn't compare equal to the current data.  This stops apps from
+	 * screwing up the duplicate sort order.  We have to do this after
+	 * we build the real record so that we're comparing the real items.
+	 */
+	if (op == DB_CURRENT && dbp->dup_compare != NULL) {
+		if ((ret = __bam_cmp(dbc, data, h,
+		    indx + (TYPE(h) == P_LBTREE ? O_INDX : 0),
+		    dbp->dup_compare, &cmp)) != 0)
+			return (ret);
+		if (cmp != 0) {
+			__db_errx(env, DB_STR("1004",
+			    "Existing data sorts differently from put data"));
+			return (EINVAL);
+		}
+	}
+
+	/*
+	 * If the key or data item won't fit on a page, we'll have to store
+	 * them on overflow pages.
+	 */
+	needed = 0;
+	bigdata = data_size > cp->ovflsize;
+	switch (op) {
+	case DB_KEYFIRST:
+		/* We're adding a new key and data pair. */
+		bigkey = key->size > cp->ovflsize;
+		if (bigkey)
+			needed += BOVERFLOW_PSIZE;
+		else
+			needed += BKEYDATA_PSIZE(key->size);
+		if (bigdata)
+			needed += BOVERFLOW_PSIZE;
+		else
+			needed += BKEYDATA_PSIZE(data_size);
+		break;
+	case DB_AFTER:
+	case DB_BEFORE:
+	case DB_CURRENT:
+		/*
+		 * We're either overwriting the data item of a key/data pair
+		 * or we're creating a new on-page duplicate and only adding
+		 * a data item.
+		 *
+		 * !!!
+		 * We're not currently correcting for space reclaimed from
+		 * already deleted items, but I don't think it's worth the
+		 * complexity.
+		 */
+		bigkey = 0;
+		if (op == DB_CURRENT) {
+			bk = GET_BKEYDATA(dbp, h,
+			    indx + (TYPE(h) == P_LBTREE ? O_INDX : 0));
+			if (B_TYPE(bk->type) == B_KEYDATA)
+				have_bytes = BKEYDATA_PSIZE(bk->len);
+			else
+				have_bytes = BOVERFLOW_PSIZE;
+			need_bytes = 0;
+		} else {
+			have_bytes = 0;
+			need_bytes = sizeof(db_indx_t);
+		}
+		if (bigdata)
+			need_bytes += BOVERFLOW_PSIZE;
+		else
+			need_bytes += BKEYDATA_PSIZE(data_size);
+
+		if (have_bytes < need_bytes)
+			needed += need_bytes - have_bytes;
+		break;
+	default:
+		return (__db_unknown_flag(env, "DB->put", op));
+	}
+
+	/* Split the page if there's not enough room. */
+	if (P_FREESPACE(dbp, h) < needed)
+		return (DB_NEEDSPLIT);
+
+	/*
+	 * Check to see if we will convert to off page duplicates -- if
+	 * so, we'll need a page.
+	 */
+	if (F_ISSET(dbp, DB_AM_DUP) &&
+	    TYPE(h) == P_LBTREE && op != DB_KEYFIRST &&
+	    P_FREESPACE(dbp, h) - needed <= dbp->pgsize / 2 &&
+	    __bam_dup_check(dbc, op, h, indx, needed, &cnt)) {
+		pages = 1;
+		dupadjust = 1;
+	} else
+		pages = 0;
+
+	/*
+	 * If we are not using transactions and there is a page limit
+	 * set on the file, then figure out if things will fit before
+	 * taking action.
+	 */
+	if (dbc->txn == NULL && mpf->mfp->maxpgno != 0) {
+		pagespace = P_MAXSPACE(dbp, dbp->pgsize);
+		if (bigdata)
+			pages += ((data_size - 1) / pagespace) + 1;
+		if (bigkey)
+			pages += ((key->size - 1) / pagespace) + 1;
+
+		if (pages > (mpf->mfp->maxpgno - mpf->mfp->last_pgno))
+			return (__db_space_err(dbp));
+	}
+
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_OFF(dbc->thread_info);
+	ret = __memp_dirty(mpf, &h,
+	     dbc->thread_info, dbc->txn, dbc->priority, 0);
+	if (cp->csp->page == cp->page)
+		cp->csp->page = h;
+	cp->page = h;
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_ON(dbc->thread_info);
+	if (ret != 0)
+		return (ret);
+
+	/*
+	 * The code breaks it up into five cases:
+	 *
+	 * 1. Insert a new key/data pair.
+	 * 2. Append a new data item (a new duplicate).
+	 * 3. Insert a new data item (a new duplicate).
+	 * 4. Delete and re-add the data item (overflow item).
+	 * 5. Overwrite the data item.
+	 */
+	switch (op) {
+	case DB_KEYFIRST:		/* 1. Insert a new key/data pair. */
+		if (bigkey) {
+			if ((ret = __bam_ovput(dbc,
+			    B_OVERFLOW, PGNO_INVALID, h, indx, key)) != 0)
+				return (ret);
+		} else
+			if ((ret = __db_pitem(dbc, h, indx,
+			    BKEYDATA_SIZE(key->size), NULL, key)) != 0)
+				return (ret);
+
+		if ((ret = __bam_ca_di(dbc, PGNO(h), indx, 1)) != 0)
+			return (ret);
+		++indx;
+		break;
+	case DB_AFTER:			/* 2. Append a new data item. */
+		if (TYPE(h) == P_LBTREE) {
+			/* Copy the key for the duplicate and adjust cursors. */
+			if ((ret =
+			    __bam_adjindx(dbc, h, indx + P_INDX, indx, 1)) != 0)
+				return (ret);
+			if ((ret =
+			    __bam_ca_di(dbc, PGNO(h), indx + P_INDX, 1)) != 0)
+				return (ret);
+
+			indx += 3;
+
+			cp->indx += 2;
+		} else {
+			++indx;
+			cp->indx += 1;
+		}
+		break;
+	case DB_BEFORE:			/* 3. Insert a new data item. */
+		if (TYPE(h) == P_LBTREE) {
+			/* Copy the key for the duplicate and adjust cursors. */
+			if ((ret = __bam_adjindx(dbc, h, indx, indx, 1)) != 0)
+				return (ret);
+			if ((ret = __bam_ca_di(dbc, PGNO(h), indx, 1)) != 0)
+				return (ret);
+
+			++indx;
+		}
+		break;
+	case DB_CURRENT:
+		 /*
+		  * Clear the cursor's deleted flag.  The problem is that if
+		  * we deadlock or fail while deleting the overflow item or
+		  * replacing the non-overflow item, a subsequent cursor close
+		  * will try and remove the item because the cursor's delete
+		  * flag is set.
+		  */
+		if ((ret = __bam_ca_delete(dbp, PGNO(h), indx, 0, NULL)) != 0)
+			return (ret);
+
+		if (TYPE(h) == P_LBTREE)
+			++indx;
+		bk = GET_BKEYDATA(dbp, h, indx);
+
+		/*
+		 * In a Btree deleted records aren't counted (deleted records
+		 * are counted in a Recno because all accesses are based on
+		 * record number).  If it's a Btree and it's a DB_CURRENT
+		 * operation overwriting a previously deleted record, increment
+		 * the record count.
+		 */
+		if (TYPE(h) == P_LBTREE || TYPE(h) == P_LDUP)
+			was_deleted = B_DISSET(bk->type);
+
+		/*
+		 * 4. Delete and re-add the data item.
+		 *
+		 * If we're changing the type of the on-page structure, or we
+		 * are referencing offpage items, we have to delete and then
+		 * re-add the item.  We do not do any cursor adjustments here
+		 * because we're going to immediately re-add the item into the
+		 * same slot.
+		 */
+		if (bigdata || B_TYPE(bk->type) != B_KEYDATA) {
+			/*
+			 * If streaming, don't delete the overflow item,
+			 * just delete the item pointing to the overflow item.
+			 * It will be added back in later, with the new size.
+			 * We can't simply adjust the size of the item on the
+			 * page, because there is no easy way to log a
+			 * modification.
+			 */
+			if (F_ISSET(data, DB_DBT_STREAMING)) {
+				if ((ret = __db_ditem(
+				    dbc, h, indx, BOVERFLOW_SIZE)) != 0)
+					return (ret);
+			} else if ((ret = __bam_ditem(dbc, h, indx)) != 0)
+				return (ret);
+			del = 1;
+			break;
+		}
+
+		/* 5. Overwrite the data item. */
+		replace = 1;
+		break;
+	default:
+		return (__db_unknown_flag(env, "DB->put", op));
+	}
+
+	/* Add the data. */
+	if (bigdata) {
+		/*
+		 * We do not have to handle deleted (BI_DELETED) records
+		 * in this case; the actual records should never be created.
+		 */
+		DB_ASSERT(env, !LF_ISSET(BI_DELETED));
+		ret = __bam_ovput(dbc,
+		    B_OVERFLOW, PGNO_INVALID, h, indx, data);
+	} else {
+		if (LF_ISSET(BI_DELETED)) {
+			B_TSET_DELETED(bk_tmp.type, B_KEYDATA);
+			bk_tmp.len = data->size;
+			bk_hdr.data = &bk_tmp;
+			bk_hdr.size = SSZA(BKEYDATA, data);
+			ret = __db_pitem(dbc, h, indx,
+			    BKEYDATA_SIZE(data->size), &bk_hdr, data);
+		} else if (replace)
+			ret = __bam_ritem(dbc, h, indx, data, 0);
+		else
+			ret = __db_pitem(dbc, h, indx,
+			    BKEYDATA_SIZE(data->size), NULL, data);
+	}
+	if (ret != 0) {
+		if (del == 1 && (t_ret =
+		     __bam_ca_di(dbc, PGNO(h), indx + 1, -1)) != 0) {
+			__db_err(env, t_ret, DB_STR("1005",
+			    "cursor adjustment after delete failed"));
+			return (__env_panic(env, t_ret));
+		}
+		return (ret);
+	}
+
+	/*
+	 * Re-position the cursors if necessary and reset the current cursor
+	 * to point to the new item.
+	 */
+	if (op != DB_CURRENT) {
+		if ((ret = __bam_ca_di(dbc, PGNO(h), indx, 1)) != 0)
+			return (ret);
+		cp->indx = TYPE(h) == P_LBTREE ? indx - O_INDX : indx;
+	}
+
+	/*
+	 * If we've changed the record count, update the tree.  There's no
+	 * need to adjust the count if the operation not performed on the
+	 * current record or when the current record was previously deleted.
+	 */
+	if (F_ISSET(cp, C_RECNUM) && (op != DB_CURRENT || was_deleted))
+		if ((ret = __bam_adjust(dbc, 1)) != 0)
+			return (ret);
+
+	/*
+	 * If a Btree leaf page is at least 50% full and we may have added or
+	 * modified a duplicate data item, see if the set of duplicates takes
+	 * up at least 25% of the space on the page.  If it does, move it onto
+	 * its own page.
+	 */
+	if (dupadjust &&
+	    (ret = __bam_dup_convert(dbc, h, indx - O_INDX, cnt)) != 0)
+		return (ret);
+
+	/* If we've modified a recno file, set the flag. */
+	if (dbc->dbtype == DB_RECNO)
+		t->re_modified = 1;
+
+	return (ret);
+}
+
+/*
+ * __bam_partsize --
+ *	Figure out how much space a partial data item is in total.
+ */
+static u_int32_t
+__bam_partsize(dbp, op, data, h, indx)
+	DB *dbp;
+	u_int32_t op, indx;
+	DBT *data;
+	PAGE *h;
+{
+	BKEYDATA *bk;
+	u_int32_t nbytes;
+
+	/*
+	 * If the record doesn't already exist, it's simply the data we're
+	 * provided.
+	 */
+	if (op != DB_CURRENT)
+		return (data->doff + data->size);
+
+	/*
+	 * Otherwise, it's the data provided plus any already existing data
+	 * that we're not replacing.
+	 */
+	bk = GET_BKEYDATA(dbp, h, indx + (TYPE(h) == P_LBTREE ? O_INDX : 0));
+	nbytes =
+	    B_TYPE(bk->type) == B_OVERFLOW ? ((BOVERFLOW *)bk)->tlen : bk->len;
+
+	return (__db_partsize(nbytes, data));
+}
+
+/*
+ * __bam_build --
+ *	Build the real record for a partial put, or short fixed-length record.
+ */
+static int
+__bam_build(dbc, op, dbt, h, indx, nbytes)
+	DBC *dbc;
+	u_int32_t op, indx, nbytes;
+	DBT *dbt;
+	PAGE *h;
+{
+	BKEYDATA *bk, tbk;
+	BOVERFLOW *bo;
+	BTREE *t;
+	DB *dbp;
+	DBT copy, *rdata;
+	u_int32_t len, tlen;
+	u_int8_t *p;
+	int ret;
+
+	COMPQUIET(bo, NULL);
+
+	dbp = dbc->dbp;
+	t = dbp->bt_internal;
+
+	/* We use the record data return memory, it's only a short-term use. */
+	rdata = &dbc->my_rdata;
+	if (rdata->ulen < nbytes) {
+		if ((ret = __os_realloc(dbp->env,
+		    nbytes, &rdata->data)) != 0) {
+			rdata->ulen = 0;
+			rdata->data = NULL;
+			return (ret);
+		}
+		rdata->ulen = nbytes;
+	}
+
+	/*
+	 * We use nul or pad bytes for any part of the record that isn't
+	 * specified; get it over with.
+	 */
+	memset(rdata->data,
+	   F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_pad : 0, nbytes);
+
+	/*
+	 * In the next clauses, we need to do three things: a) set p to point
+	 * to the place at which to copy the user's data, b) set tlen to the
+	 * total length of the record, not including the bytes contributed by
+	 * the user, and c) copy any valid data from an existing record.  If
+	 * it's not a partial put (this code is called for both partial puts
+	 * and fixed-length record padding) or it's a new key, we can cut to
+	 * the chase.
+	 */
+	if (!F_ISSET(dbt, DB_DBT_PARTIAL) || op != DB_CURRENT) {
+		p = (u_int8_t *)rdata->data + dbt->doff;
+		tlen = dbt->doff;
+		goto user_copy;
+	}
+
+	/* Find the current record. */
+	if (indx < NUM_ENT(h)) {
+		bk = GET_BKEYDATA(dbp, h, indx + (TYPE(h) == P_LBTREE ?
+		    O_INDX : 0));
+		bo = (BOVERFLOW *)bk;
+	} else {
+		bk = &tbk;
+		B_TSET(bk->type, B_KEYDATA);
+		bk->len = 0;
+	}
+	if (B_TYPE(bk->type) == B_OVERFLOW) {
+		/*
+		 * In the case of an overflow record, we shift things around
+		 * in the current record rather than allocate a separate copy.
+		 */
+		memset(&copy, 0, sizeof(copy));
+		if ((ret = __db_goff(dbc, &copy, bo->tlen, bo->pgno,
+		    &rdata->data, &rdata->ulen)) != 0)
+			return (ret);
+
+		/* Skip any leading data from the original record. */
+		tlen = dbt->doff;
+		p = (u_int8_t *)rdata->data + dbt->doff;
+
+		/*
+		 * Copy in any trailing data from the original record.
+		 *
+		 * If the original record was larger than the original offset
+		 * plus the bytes being deleted, there is trailing data in the
+		 * original record we need to preserve.  If we aren't deleting
+		 * the same number of bytes as we're inserting, copy it up or
+		 * down, into place.
+		 *
+		 * Use memmove(), the regions may overlap.
+		 */
+		if (bo->tlen > dbt->doff + dbt->dlen) {
+			len = bo->tlen - (dbt->doff + dbt->dlen);
+			if (dbt->dlen != dbt->size)
+				memmove(p + dbt->size, p + dbt->dlen, len);
+			tlen += len;
+		}
+	} else {
+		/* Copy in any leading data from the original record. */
+		memcpy(rdata->data,
+		    bk->data, dbt->doff > bk->len ? bk->len : dbt->doff);
+		tlen = dbt->doff;
+		p = (u_int8_t *)rdata->data + dbt->doff;
+
+		/* Copy in any trailing data from the original record. */
+		len = dbt->doff + dbt->dlen;
+		if (bk->len > len) {
+			memcpy(p + dbt->size, bk->data + len, bk->len - len);
+			tlen += bk->len - len;
+		}
+	}
+
+user_copy:
+	/*
+	 * Copy in the application provided data -- p and tlen must have been
+	 * initialized above.
+	 */
+	memcpy(p, dbt->data, dbt->size);
+	tlen += dbt->size;
+
+	/* Set the DBT to reference our new record. */
+	rdata->size = F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_len : tlen;
+	rdata->dlen = 0;
+	rdata->doff = 0;
+	rdata->flags = 0;
+	*dbt = *rdata;
+	return (0);
+}
+
+/*
+ * __bam_ritem --
+ *	Replace an item on a page.
+ *
+ * PUBLIC: int __bam_ritem __P((DBC *, PAGE *, u_int32_t, DBT *, u_int32_t));
+ */
+int
+__bam_ritem(dbc, h, indx, data, typeflag)
+	DBC *dbc;
+	PAGE *h;
+	u_int32_t indx;
+	DBT *data;
+	u_int32_t typeflag;
+{
+	BKEYDATA *bk;
+	DB *dbp;
+	DBT orig, repl;
+	db_indx_t min, prefix, suffix;
+	u_int32_t len;
+	int ret;
+	u_int8_t *dp, *p, *t, type;
+
+	dbp = dbc->dbp;
+
+	/*
+	 * Replace a single item onto a page.  The logic figuring out where
+	 * to insert and whether it fits is handled in the caller.  All we do
+	 * here is manage the page shuffling.
+	 */
+	bk = GET_BKEYDATA(dbp, h, indx);
+	len = bk->len;
+	dp = bk->data;
+	type = bk->type;
+	typeflag = B_DISSET(type);
+
+	/* Log the change. */
+	if (DBC_LOGGING(dbc)) {
+		/*
+		 * We might as well check to see if the two data items share
+		 * a common prefix and suffix -- it can save us a lot of log
+		 * message if they're large.
+		 */
+		min = data->size < len ? data->size : len;
+		for (prefix = 0,
+		    p = dp, t = data->data;
+		    prefix < min && *p == *t; ++prefix, ++p, ++t)
+			;
+
+		min -= prefix;
+		for (suffix = 0,
+		    p = (u_int8_t *)dp + len - 1,
+		    t = (u_int8_t *)data->data + data->size - 1;
+		    suffix < min && *p == *t; ++suffix, --p, --t)
+			;
+
+		/* We only log the parts of the keys that have changed. */
+		orig.data = (u_int8_t *)dp + prefix;
+		orig.size = len - (prefix + suffix);
+		repl.data = (u_int8_t *)data->data + prefix;
+		repl.size = data->size - (prefix + suffix);
+		if ((ret = __bam_repl_log(dbp, dbc->txn, &LSN(h), 0, PGNO(h),
+		    &LSN(h), (u_int32_t)indx, typeflag,
+		    &orig, &repl, (u_int32_t)prefix, (u_int32_t)suffix)) != 0)
+			return (ret);
+	} else
+		LSN_NOT_LOGGED(LSN(h));
+
+	return (__bam_ritem_nolog(dbc, h, indx, NULL, data, type));
+}
+
+/*
+ * __bam_ritem_nolog --
+ *	Replace an item on a page.
+ *
+ * PUBLIC: int __bam_ritem_nolog __P((DBC *,
+ * PUBLIC:      PAGE *, u_int32_t, DBT *, DBT *, u_int32_t));
+ */
+int
+__bam_ritem_nolog(dbc, h, indx, hdr, data, type)
+	DBC *dbc;
+	PAGE *h;
+	u_int32_t indx;
+	DBT *hdr, *data;
+	u_int32_t type;
+{
+	BKEYDATA *bk;
+	BINTERNAL *bi;
+	DB *dbp;
+	db_indx_t cnt, off, lo, ln;
+	db_indx_t *inp;
+	int32_t nbytes;
+	u_int8_t *p, *t;
+
+	dbp = dbc->dbp;
+	/*
+	 * Set references to the first in-use byte on the page and the
+	 * first byte of the item being replaced.
+	 */
+	inp = P_INP(dbp, h);
+	p = (u_int8_t *)h + HOFFSET(h);
+	if (TYPE(h) == P_IBTREE) {
+		bi = GET_BINTERNAL(dbp, h, indx);
+		t = (u_int8_t *)bi;
+		lo = (db_indx_t)BINTERNAL_SIZE(bi->len);
+		if (data == NULL) {
+			DB_ASSERT(dbp->env, hdr != NULL);
+			bi = (BINTERNAL*)hdr->data;
+			P_16_COPY(&bi->len, &cnt);
+			ln = (db_indx_t)BINTERNAL_SIZE(cnt);
+		} else
+			ln = (db_indx_t)BINTERNAL_SIZE(data->size);
+	} else {
+		bk = GET_BKEYDATA(dbp, h, indx);
+		t = (u_int8_t *)bk;
+		lo = (db_indx_t)BKEYDATA_SIZE(bk->len);
+		ln = (db_indx_t)BKEYDATA_SIZE(data->size);
+	}
+
+	/*
+	 * If the entry is growing in size, shift the beginning of the data
+	 * part of the page down.  If the entry is shrinking in size, shift
+	 * the beginning of the data part of the page up.  Use memmove(3),
+	 * the regions overlap.
+	 */
+	if (lo != ln) {
+		nbytes = (int32_t)(lo - ln);	/* Signed difference. */
+		if (p == t)			/* First index is fast. */
+			inp[indx] += (u_int32_t)nbytes;
+		else {				/* Else, shift the page. */
+			memmove(p + nbytes, p, (size_t)(t - p));
+
+			/* Adjust the indices' offsets. */
+			off = (u_int32_t)inp[indx];
+			for (cnt = 0; cnt < NUM_ENT(h); ++cnt)
+				if (inp[cnt] <= off)
+					inp[cnt] += (u_int32_t)nbytes;
+		}
+
+		/* Clean up the page and adjust the item's reference. */
+		HOFFSET(h) += (u_int32_t)nbytes;
+		t += nbytes;
+	}
+
+	/* Copy the new item onto the page. */
+	if (TYPE(h) == P_IBTREE) {
+		DB_ASSERT(dbp->env, hdr != NULL);
+		memcpy(t, hdr->data, hdr->size);
+		bi = (BINTERNAL *)t;
+		if (data != NULL && data->size != 0)
+			memcpy(bi->data, data->data, data->size);
+	} else {
+		bk = (BKEYDATA *)t;
+		bk->len = data->size;
+		B_TSET(bk->type, type);
+		memcpy(bk->data, data->data, bk->len);
+	}
+
+	return (0);
+}
+
+/*
+ * __bam_irep --
+ *	Replace an item on an internal page.
+ *
+ * PUBLIC: int __bam_irep __P((DBC *, PAGE *, u_int32_t, DBT *, DBT *));
+ */
+int
+__bam_irep(dbc, h, indx, hdr, data)
+	DBC *dbc;
+	PAGE *h;
+	u_int32_t indx;
+	DBT *hdr;
+	DBT *data;
+{
+	BINTERNAL *bi, *bn;
+	DB *dbp;
+	DBT dbt;
+	int ret;
+
+	dbp = dbc->dbp;
+
+	bi = GET_BINTERNAL(dbp, h, indx);
+	bn = (BINTERNAL *) hdr->data;
+
+	if (B_TYPE(bi->type) == B_OVERFLOW &&
+	    (ret = __db_doff(dbc, ((BOVERFLOW *)bi->data)->pgno)) != 0)
+		return (ret);
+
+	if (DBC_LOGGING(dbc)) {
+		dbt.data = bi;
+		dbt.size = BINTERNAL_SIZE(bi->len);
+		if ((ret = __bam_irep_log(dbp, dbc->txn, &LSN(h), 0, PGNO(h),
+		    &LSN(h), (u_int32_t)indx, TYPE(h), hdr, data, &dbt)) != 0)
+			return (ret);
+	} else
+		LSN_NOT_LOGGED(LSN(h));
+
+	return (__bam_ritem_nolog(dbc, h, indx, hdr, data, bn->type));
+}
+
+/*
+ * __bam_dup_check --
+ *	Check to see if the duplicate set at indx should have its own page.
+ */
+static int
+__bam_dup_check(dbc, op, h, indx, sz, cntp)
+	DBC *dbc;
+	u_int32_t op;
+	PAGE *h;
+	u_int32_t indx, sz;
+	db_indx_t *cntp;
+{
+	BKEYDATA *bk;
+	DB *dbp;
+	db_indx_t cnt, first, *inp;
+
+	dbp = dbc->dbp;
+	inp = P_INP(dbp, h);
+
+	/*
+	 * Count the duplicate records and calculate how much room they're
+	 * using on the page.
+	 */
+	while (indx > 0 && inp[indx] == inp[indx - P_INDX])
+		indx -= P_INDX;
+
+	/* Count the key once. */
+	bk = GET_BKEYDATA(dbp, h, indx);
+	sz += B_TYPE(bk->type) == B_KEYDATA ?
+	    BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE;
+
+	/*
+	 * Sum up all the data items.
+	 * Account for the record being inserted.  If we are replacing it,
+	 * don't count it twice.
+	 *
+	 * We execute the loop with first == indx to get the size of the
+	 * first record.
+	 */
+	cnt = op == DB_CURRENT ? 0 : 1;
+	for (first = indx;
+	    indx < NUM_ENT(h) && inp[first] == inp[indx];
+	    ++cnt, indx += P_INDX) {
+		bk = GET_BKEYDATA(dbp, h, indx + O_INDX);
+		sz += B_TYPE(bk->type) == B_KEYDATA ?
+		    BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE;
+	}
+
+	/*
+	 * We have to do these checks when the user is replacing the cursor's
+	 * data item -- if the application replaces a duplicate item with a
+	 * larger data item, it can increase the amount of space used by the
+	 * duplicates, requiring this check.  But that means we may have done
+	 * this check when it wasn't a duplicate item after all.
+	 */
+	if (cnt == 1)
+		return (0);
+
+	/*
+	 * If this set of duplicates is using more than 25% of the page, move
+	 * them off.  The choice of 25% is a WAG, but the value must be small
+	 * enough that we can always split a page without putting duplicates
+	 * on two different pages.
+	 */
+	if (sz < dbp->pgsize / 4)
+		return (0);
+
+	*cntp = cnt;
+	return (1);
+}
+
+/*
+ * __bam_dup_convert --
+ *	Move a set of duplicates off-page and into their own tree.
+ */
+static int
+__bam_dup_convert(dbc, h, indx, cnt)
+	DBC *dbc;
+	PAGE *h;
+	u_int32_t indx, cnt;
+{
+	BKEYDATA *bk;
+	DB *dbp;
+	DBT hdr;
+	DB_LOCK lock;
+	DB_MPOOLFILE *mpf;
+	PAGE *dp;
+	db_indx_t cpindx, dindx, first, *inp;
+	int ret, t_ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	inp = P_INP(dbp, h);
+
+	/* Move to the beginning of the dup set. */
+	while (indx > 0 && inp[indx] == inp[indx - P_INDX])
+		indx -= P_INDX;
+
+	/* Get a new page. */
+	if ((ret = __db_new(dbc,
+	    dbp->dup_compare == NULL ? P_LRECNO : P_LDUP, &lock, &dp)) != 0)
+		return (ret);
+	P_INIT(dp, dbp->pgsize, dp->pgno,
+	    PGNO_INVALID, PGNO_INVALID, LEAFLEVEL, TYPE(dp));
+
+	/*
+	 * Move this set of duplicates off the page.  First points to the first
+	 * key of the first duplicate key/data pair, cnt is the number of pairs
+	 * we're dealing with.
+	 */
+	memset(&hdr, 0, sizeof(hdr));
+	first = indx;
+	dindx = indx;
+	cpindx = 0;
+	do {
+		/* Move cursors referencing the old entry to the new entry. */
+		if ((ret = __bam_ca_dup(dbc, first,
+		    PGNO(h), indx, PGNO(dp), cpindx)) != 0)
+			goto err;
+
+		/*
+		 * Copy the entry to the new page.  If the off-duplicate page
+		 * If the off-duplicate page is a Btree page (i.e. dup_compare
+		 * will be non-NULL, we use Btree pages for sorted dups,
+		 * and Recno pages for unsorted dups), move all entries
+		 * normally, even deleted ones.  If it's a Recno page,
+		 * deleted entries are discarded (if the deleted entry is
+		 * overflow, then free up those pages).
+		 */
+		bk = GET_BKEYDATA(dbp, h, dindx + 1);
+		hdr.data = bk;
+		hdr.size = B_TYPE(bk->type) == B_KEYDATA ?
+		    BKEYDATA_SIZE(bk->len) : BOVERFLOW_SIZE;
+		if (dbp->dup_compare == NULL && B_DISSET(bk->type)) {
+			/*
+			 * Unsorted dups, i.e. recno page, and we have
+			 * a deleted entry, don't move it, but if it was
+			 * an overflow entry, we need to free those pages.
+			 */
+			if (B_TYPE(bk->type) == B_OVERFLOW &&
+			    (ret = __db_doff(dbc,
+			    (GET_BOVERFLOW(dbp, h, dindx + 1))->pgno)) != 0)
+				goto err;
+		} else {
+			if ((ret = __db_pitem(
+			    dbc, dp, cpindx, hdr.size, &hdr, NULL)) != 0)
+				goto err;
+			++cpindx;
+		}
+		/* Delete all but the last reference to the key. */
+		if (cnt != 1) {
+			if ((ret = __bam_adjindx(dbc,
+			    h, dindx, first + 1, 0)) != 0)
+				goto err;
+		} else
+			dindx++;
+
+		/* Delete the data item. */
+		if ((ret = __db_ditem(dbc, h, dindx, hdr.size)) != 0)
+			goto err;
+		indx += P_INDX;
+	} while (--cnt);
+
+	/* Put in a new data item that points to the duplicates page. */
+	if ((ret = __bam_ovput(dbc,
+	    B_DUPLICATE, dp->pgno, h, first + 1, NULL)) != 0)
+		goto err;
+
+	/* Adjust cursors for all the above movements. */
+	ret = __bam_ca_di(dbc,
+	    PGNO(h), first + P_INDX, (int)(first + P_INDX - indx));
+
+err:	if ((t_ret = __memp_fput(mpf,
+	     dbc->thread_info, dp, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+
+	(void)__TLPUT(dbc, lock);
+	return (ret);
+}
+
+/*
+ * __bam_ovput --
+ *	Build an item for an off-page duplicates page or overflow page and
+ *	insert it on the page.
+ */
+static int
+__bam_ovput(dbc, type, pgno, h, indx, item)
+	DBC *dbc;
+	u_int32_t type, indx;
+	db_pgno_t pgno;
+	PAGE *h;
+	DBT *item;
+{
+	BOVERFLOW bo;
+	DBT hdr;
+	int ret;
+
+	UMRW_SET(bo.unused1);
+	B_TSET(bo.type, type);
+	UMRW_SET(bo.unused2);
+
+	/*
+	 * If we're creating an overflow item, do so and acquire the page
+	 * number for it.  If we're creating an off-page duplicates tree,
+	 * we are giving the page number as an argument.
+	 */
+	if (type == B_OVERFLOW) {
+		if ((ret = __db_poff(dbc, item, &bo.pgno)) != 0)
+			return (ret);
+		bo.tlen = item->size;
+	} else {
+		bo.pgno = pgno;
+		bo.tlen = 0;
+	}
+
+	/* Store the new record on the page. */
+	memset(&hdr, 0, sizeof(hdr));
+	hdr.data = &bo;
+	hdr.size = BOVERFLOW_SIZE;
+	return (__db_pitem(dbc, h, indx, BOVERFLOW_SIZE, &hdr, NULL));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_reclaim.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,120 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+
+/*
+ * __bam_reclaim --
+ *	Free a database.
+ *
+ * PUBLIC: int __bam_reclaim __P((DB *, DB_THREAD_INFO *, DB_TXN *, u_int32_t));
+ */
+int
+__bam_reclaim(dbp, ip, txn, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	u_int32_t flags;
+{
+	DBC *dbc;
+	DB_LOCK meta_lock;
+	int ret, t_ret;
+
+	/* Acquire a cursor. */
+	if ((ret = __db_cursor(dbp, ip, txn, &dbc, 0)) != 0)
+		return (ret);
+
+	/* Write lock the metapage for deallocations. */
+	if ((ret = __db_lget(dbc,
+	    0, PGNO_BASE_MD, DB_LOCK_WRITE, 0, &meta_lock)) != 0)
+		goto err;
+
+	/* Avoid locking every page, we have the handle locked exclusive. */
+	F_SET(dbc, DBC_DONTLOCK);
+
+	/* Walk the tree, freeing pages. */
+	ret = __bam_traverse(dbc, DB_LOCK_WRITE,
+	    PGNO_INVALID, __db_reclaim_callback, &flags);
+
+	if ((t_ret = __TLPUT(dbc, meta_lock)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Discard the cursor. */
+err:	if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __bam_truncate --
+ *	Truncate a database.
+ *
+ * PUBLIC: int __bam_truncate __P((DBC *, u_int32_t *));
+ */
+int
+__bam_truncate(dbc, countp)
+	DBC *dbc;
+	u_int32_t *countp;
+{
+	u_int32_t count;
+	int ret;
+
+#ifdef HAVE_COMPRESSION
+	u_int32_t comp_count;
+
+	comp_count = 0;
+	if (DB_IS_COMPRESSED(dbc->dbp) &&
+	    (ret = __bam_compress_count(dbc, NULL, &comp_count)) != 0)
+		return (ret);
+#endif
+
+	count = 0;
+
+	/* Walk the tree, freeing pages. */
+	ret = __bam_traverse(dbc,
+	    DB_LOCK_WRITE, PGNO_INVALID, __db_truncate_callback, &count);
+
+#ifdef HAVE_COMPRESSION
+	if (DB_IS_COMPRESSED(dbc->dbp)) {
+		if (countp != NULL)
+			*countp = comp_count;
+	} else
+#endif
+	if (countp != NULL)
+		*countp = count;
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_recno.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1449 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+
+static int  __ram_add __P((DBC *, db_recno_t *, DBT *, u_int32_t, u_int32_t));
+static int  __ram_source __P((DB *));
+static int  __ram_sread __P((DBC *, db_recno_t));
+static int  __ram_update __P((DBC *, db_recno_t, int));
+static int __ram_ca_getorder
+    __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *));
+static int __ram_ca_setorder
+    __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *));
+/*
+ * In recno, there are two meanings to the on-page "deleted" flag.  If we're
+ * re-numbering records, it means the record was implicitly created.  We skip
+ * over implicitly created records if doing a cursor "next" or "prev", and
+ * return DB_KEYEMPTY if they're explicitly requested..  If not re-numbering
+ * records, it means that the record was implicitly created, or was deleted.
+ * We skip over implicitly created or deleted records if doing a cursor "next"
+ * or "prev", and return DB_KEYEMPTY if they're explicitly requested.
+ *
+ * If we're re-numbering records, then we have to detect in the cursor that
+ * a record was deleted, and adjust the cursor as necessary on the next get.
+ * If we're not re-numbering records, then we can detect that a record has
+ * been deleted by looking at the actual on-page record, so we completely
+ * ignore the cursor's delete flag.  This is different from the B+tree code.
+ * It also maintains whether the cursor references a deleted record in the
+ * cursor, and it doesn't always check the on-page value.
+ */
+#define	CD_SET(cp) {							\
+	if (F_ISSET(cp, C_RENUMBER))					\
+		F_SET(cp, C_DELETED);					\
+}
+#define	CD_CLR(cp) {							\
+	if (F_ISSET(cp, C_RENUMBER)) {					\
+		F_CLR(cp, C_DELETED);					\
+		cp->order = INVALID_ORDER;				\
+	}								\
+}
+#define	CD_ISSET(cp)							\
+	(F_ISSET(cp, C_RENUMBER) && F_ISSET(cp, C_DELETED) ? 1 : 0)
+
+/*
+ * Macros for comparing the ordering of two cursors.
+ * cp1 comes before cp2 iff one of the following holds:
+ *	cp1's recno is less than cp2's recno
+ *	recnos are equal, both deleted, and cp1's order is less than cp2's
+ *	recnos are equal, cp1 deleted, and cp2 not deleted
+ */
+#define	C_LESSTHAN(cp1, cp2)						\
+    (((cp1)->recno < (cp2)->recno) ||					\
+    (((cp1)->recno == (cp2)->recno) &&					\
+    ((CD_ISSET((cp1)) && CD_ISSET((cp2)) && (cp1)->order < (cp2)->order) || \
+    (CD_ISSET((cp1)) && !CD_ISSET((cp2))))))
+
+/*
+ * cp1 is equal to cp2 iff their recnos and delete flags are identical,
+ * and if the delete flag is set their orders are also identical.
+ */
+#define	C_EQUAL(cp1, cp2)						\
+    ((cp1)->recno == (cp2)->recno && CD_ISSET((cp1)) == CD_ISSET((cp2)) && \
+    (!CD_ISSET((cp1)) || (cp1)->order == (cp2)->order))
+
+/*
+ * Do we need to log the current cursor adjustment?
+ */
+#define	CURADJ_LOG(dbc)							\
+	(DBC_LOGGING((dbc)) && (dbc)->txn != NULL && (dbc)->txn->parent != NULL)
+
+/*
+ * After a search, copy the found page into the cursor, discarding any
+ * currently held lock.
+ */
+#define	STACK_TO_CURSOR(cp, ret) {					\
+	int __t_ret;							\
+	(cp)->page = (cp)->csp->page;					\
+	(cp)->pgno = (cp)->csp->page->pgno;				\
+	(cp)->indx = (cp)->csp->indx;					\
+	if ((__t_ret = __TLPUT(dbc, (cp)->lock)) != 0 && (ret) == 0)	\
+		ret = __t_ret;						\
+	(cp)->lock = (cp)->csp->lock;					\
+	(cp)->lock_mode = (cp)->csp->lock_mode;				\
+}
+
+/*
+ * __ram_open --
+ *	Recno open function.
+ *
+ * PUBLIC: int __ram_open __P((DB *, DB_THREAD_INFO *,
+ * PUBLIC:      DB_TXN *, const char *, db_pgno_t, u_int32_t));
+ */
+int
+__ram_open(dbp, ip, txn, name, base_pgno, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name;
+	db_pgno_t base_pgno;
+	u_int32_t flags;
+{
+	BTREE *t;
+	DBC *dbc;
+	int ret, t_ret;
+
+	COMPQUIET(name, NULL);
+	t = dbp->bt_internal;
+
+	/* Start up the tree. */
+	if ((ret = __bam_read_root(dbp, ip, txn, base_pgno, flags)) != 0)
+		return (ret);
+
+	/*
+	 * If the user specified a source tree, open it and map it in.
+	 *
+	 * !!!
+	 * We don't complain if the user specified transactions or threads.
+	 * It's possible to make it work, but you'd better know what you're
+	 * doing!
+	 */
+	if (t->re_source != NULL && (ret = __ram_source(dbp)) != 0)
+		return (ret);
+
+	/* If we're snapshotting an underlying source file, do it now. */
+	if (F_ISSET(dbp, DB_AM_SNAPSHOT)) {
+		/* Allocate a cursor. */
+		if ((ret = __db_cursor(dbp, ip, NULL, &dbc, 0)) != 0)
+			return (ret);
+
+		/* Do the snapshot. */
+		if ((ret = __ram_update(dbc,
+		    DB_MAX_RECORDS, 0)) != 0 && ret == DB_NOTFOUND)
+			ret = 0;
+
+		/* Discard the cursor. */
+		if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+
+	return (ret);
+}
+
+/*
+ * __ram_append --
+ *	Recno append function.
+ *
+ * PUBLIC: int __ram_append __P((DBC *, DBT *, DBT *));
+ */
+int
+__ram_append(dbc, key, data)
+	DBC *dbc;
+	DBT *key, *data;
+{
+	BTREE_CURSOR *cp;
+	int ret;
+
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	/*
+	 * Make sure we've read in all of the backing source file.  If
+	 * we found the record or it simply didn't exist, add the
+	 * user's record.
+	 */
+	ret = __ram_update(dbc, DB_MAX_RECORDS, 0);
+	if (ret == 0 || ret == DB_NOTFOUND)
+		ret = __ram_add(dbc, &cp->recno, data, DB_APPEND, 0);
+
+	/* Return the record number. */
+	if (ret == 0 && key != NULL)
+		ret = __db_retcopy(dbc->env, key, &cp->recno,
+		    sizeof(cp->recno), &dbc->rkey->data, &dbc->rkey->ulen);
+
+	if (!DB_RETOK_DBCPUT(ret))
+		F_SET(dbc, DBC_ERROR);
+	return (ret);
+}
+
+/*
+ * __ramc_del --
+ *	Recno DBC->del function.
+ *
+ * PUBLIC: int __ramc_del __P((DBC *, u_int32_t));
+ */
+int
+__ramc_del(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	BKEYDATA bk;
+	BTREE *t;
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DBT hdr, data;
+	DB_LOCK next_lock, prev_lock;
+	DB_LSN lsn;
+	db_pgno_t npgno, ppgno, save_npgno, save_ppgno;
+	int exact, nc, ret, stack, t_ret;
+
+	dbp = dbc->dbp;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	t = dbp->bt_internal;
+	stack = 0;
+	save_npgno = save_ppgno = PGNO_INVALID;
+	LOCK_INIT(next_lock);
+	LOCK_INIT(prev_lock);
+	COMPQUIET(flags, 0);
+
+	/*
+	 * The semantics of cursors during delete are as follows: in
+	 * non-renumbering recnos, records are replaced with a marker
+	 * containing a delete flag.  If the record referenced by this cursor
+	 * has already been deleted, we will detect that as part of the delete
+	 * operation, and fail.
+	 *
+	 * In renumbering recnos, cursors which represent deleted items
+	 * are flagged with the C_DELETED flag, and it is an error to
+	 * call c_del a second time without an intervening cursor motion.
+	 */
+	if (CD_ISSET(cp))
+		return (DB_KEYEMPTY);
+
+	/* Search the tree for the key; delete only deletes exact matches. */
+retry:	if ((ret = __bam_rsearch(dbc, &cp->recno, SR_DELETE, 1, &exact)) != 0)
+		goto err;
+	if (!exact) {
+		ret = DB_NOTFOUND;
+		goto err;
+	}
+	stack = 1;
+
+	/* Copy the page into the cursor. */
+	STACK_TO_CURSOR(cp, ret);
+	if (ret != 0)
+		goto err;
+
+	/*
+	 * If re-numbering records, the on-page deleted flag can only mean
+	 * that this record was implicitly created.  Applications aren't
+	 * permitted to delete records they never created, return an error.
+	 *
+	 * If not re-numbering records, the on-page deleted flag means that
+	 * this record was implicitly created, or, was deleted at some time.
+	 * The former is an error because applications aren't permitted to
+	 * delete records they never created, the latter is an error because
+	 * if the record was "deleted", we could never have found it.
+	 */
+	if (B_DISSET(GET_BKEYDATA(dbp, cp->page, cp->indx)->type)) {
+		ret = DB_KEYEMPTY;
+		goto err;
+	}
+
+	if (F_ISSET(cp, C_RENUMBER)) {
+		/* If we are going to drop the page, lock its neighbors. */
+		if (STD_LOCKING(dbc) && NUM_ENT(cp->page) == 1 &&
+		    PGNO(cp->page) != BAM_ROOT_PGNO(dbc)) {
+			if ((npgno = NEXT_PGNO(cp->page)) != PGNO_INVALID)
+				TRY_LOCK(dbc, npgno, save_npgno,
+				    next_lock, DB_LOCK_WRITE, retry);
+			if (ret != 0)
+				goto err;
+			if ((ppgno = PREV_PGNO(cp->page)) != PGNO_INVALID)
+				TRY_LOCK(dbc, ppgno, save_ppgno,
+				    prev_lock, DB_LOCK_WRITE, retry);
+			if (ret != 0)
+				goto err;
+		}
+		/* Delete the item, adjust the counts, adjust the cursors. */
+		if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0)
+			goto err;
+		if ((ret = __bam_adjust(dbc, -1)) != 0)
+			goto err;
+		if ((ret = __ram_ca(dbc, CA_DELETE, &nc)) != 0)
+			goto err;
+		if (nc > 0 && CURADJ_LOG(dbc) &&
+		    (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0,
+		    CA_DELETE, BAM_ROOT_PGNO(dbc), cp->recno, cp->order)) != 0)
+			goto err;
+
+		/*
+		 * If the page is empty, delete it.
+		 *
+		 * We never delete a root page.  First, root pages of primary
+		 * databases never go away, recno or otherwise.  However, if
+		 * it's the root page of an off-page duplicates database, then
+		 * it can be deleted.   We don't delete it here because we have
+		 * no way of telling the primary database page holder (e.g.,
+		 * the hash access method) that its page element should cleaned
+		 * up because the underlying tree is gone.  So, we keep the page
+		 * around until the last cursor referencing the empty tree is
+		 * are closed, and then clean it up.
+		 */
+		if (NUM_ENT(cp->page) == 0 &&
+		    PGNO(cp->page) != BAM_ROOT_PGNO(dbc)) {
+			/*
+			 * We want to delete a single item out of the last page
+			 * that we're not deleting.
+			 */
+			if (F_ISSET(dbc, DBC_OPD))
+				LOCK_CHECK_OFF(dbc->thread_info);
+			ret = __bam_dpages(dbc, 0, BTD_RELINK);
+			if (F_ISSET(dbc, DBC_OPD))
+				LOCK_CHECK_ON(dbc->thread_info);
+
+			/*
+			 * Regardless of the return from __bam_dpages, it will
+			 * discard our stack and pinned page.
+			 */
+			stack = 0;
+			cp->page = NULL;
+			LOCK_INIT(cp->lock);
+			cp->lock_mode = DB_LOCK_NG;
+		}
+	} else {
+		/* Use a delete/put pair to replace the record with a marker. */
+		if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0)
+			goto err;
+
+		B_TSET_DELETED(bk.type, B_KEYDATA);
+		bk.len = 0;
+		DB_INIT_DBT(hdr, &bk, SSZA(BKEYDATA, data));
+		DB_INIT_DBT(data, "", 0);
+		if ((ret = __db_pitem(dbc,
+		    cp->page, cp->indx, BKEYDATA_SIZE(0), &hdr, &data)) != 0)
+			goto err;
+	}
+
+	t->re_modified = 1;
+
+err:	if (!DB_RETOK_DBCDEL(ret))
+		F_SET(dbc, DBC_ERROR);
+	if (stack && (t_ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __TLPUT(dbc, next_lock)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __TLPUT(dbc, prev_lock)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __ramc_get --
+ *	Recno DBC->get function.
+ *
+ * PUBLIC: int __ramc_get
+ * PUBLIC:     __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
+ */
+int
+__ramc_get(dbc, key, data, flags, pgnop)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+	db_pgno_t *pgnop;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	int cmp, exact, ret;
+
+	COMPQUIET(pgnop, NULL);
+
+	dbp = dbc->dbp;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	LF_CLR(DB_MULTIPLE|DB_MULTIPLE_KEY);
+retry:	switch (flags) {
+	case DB_CURRENT:
+		/*
+		 * If we're using mutable records and the deleted flag is
+		 * set, the cursor is pointing at a nonexistent record;
+		 * return an error.
+		 */
+		if (CD_ISSET(cp))
+			return (DB_KEYEMPTY);
+		break;
+	case DB_NEXT_DUP:
+		/*
+		 * If we're not in an off-page dup set, we know there's no
+		 * next duplicate since recnos don't have them.  If we
+		 * are in an off-page dup set, the next item assuredly is
+		 * a dup, so we set flags to DB_NEXT and keep going.
+		 */
+		if (!F_ISSET(dbc, DBC_OPD))
+			return (DB_NOTFOUND);
+		/* FALLTHROUGH */
+	case DB_NEXT_NODUP:
+		/*
+		 * Recno databases don't have duplicates, set flags to DB_NEXT
+		 * and keep going.
+		 */
+		/* FALLTHROUGH */
+	case DB_NEXT:
+		flags = DB_NEXT;
+		/*
+		 * If record numbers are mutable: if we just deleted a record,
+		 * we have to avoid incrementing the record number so that we
+		 * return the right record by virtue of renumbering the tree.
+		 */
+		if (CD_ISSET(cp)) {
+			/*
+			 * Clear the flag, we've moved off the deleted record.
+			 */
+			CD_CLR(cp);
+			break;
+		}
+
+		if (cp->recno != RECNO_OOB) {
+			++cp->recno;
+			break;
+		}
+		/* FALLTHROUGH */
+	case DB_FIRST:
+		flags = DB_NEXT;
+		cp->recno = 1;
+		break;
+	case DB_PREV_DUP:
+		/*
+		 * If we're not in an off-page dup set, we know there's no
+		 * previous duplicate since recnos don't have them.  If we
+		 * are in an off-page dup set, the previous item assuredly
+		 * is a dup, so we set flags to DB_PREV and keep going.
+		 */
+		if (!F_ISSET(dbc, DBC_OPD))
+			return (DB_NOTFOUND);
+		/* FALLTHROUGH */
+	case DB_PREV_NODUP:
+		/*
+		 * Recno databases don't have duplicates, set flags to DB_PREV
+		 * and keep going.
+		 */
+		/* FALLTHROUGH */
+	case DB_PREV:
+		flags = DB_PREV;
+		if (cp->recno != RECNO_OOB) {
+			if (cp->recno == 1) {
+				ret = DB_NOTFOUND;
+				goto err;
+			}
+			--cp->recno;
+			break;
+		}
+		/* FALLTHROUGH */
+	case DB_LAST:
+		flags = DB_PREV;
+		if (((ret = __ram_update(dbc,
+		    DB_MAX_RECORDS, 0)) != 0) && ret != DB_NOTFOUND)
+			goto err;
+		if ((ret = __bam_nrecs(dbc, &cp->recno)) != 0)
+			goto err;
+		if (cp->recno == 0) {
+			ret = DB_NOTFOUND;
+			goto err;
+		}
+		break;
+	case DB_GET_BOTHC:
+		/*
+		 * If we're doing a join and these are offpage dups,
+		 * we want to keep searching forward from after the
+		 * current cursor position.  Increment the recno by 1,
+		 * then proceed as for a DB_SET.
+		 *
+		 * Otherwise, we know there are no additional matching
+		 * data, as recnos don't have dups.  return DB_NOTFOUND.
+		 */
+		if (F_ISSET(dbc, DBC_OPD)) {
+			cp->recno++;
+			break;
+		}
+		ret = DB_NOTFOUND;
+		goto err;
+		/* NOTREACHED */
+	case DB_GET_BOTH:
+	case DB_GET_BOTH_RANGE:
+		/*
+		 * If we're searching a set of off-page dups, we start
+		 * a new linear search from the first record.  Otherwise,
+		 * we compare the single data item associated with the
+		 * requested record for a match.
+		 */
+		if (F_ISSET(dbc, DBC_OPD)) {
+			cp->recno = 1;
+			break;
+		}
+		/* FALLTHROUGH */
+	case DB_SET:
+	case DB_SET_RANGE:
+		if ((ret = __ram_getno(dbc, key, &cp->recno, 0)) != 0)
+			goto err;
+		break;
+	default:
+		ret = __db_unknown_flag(dbp->env, "__ramc_get", flags);
+		goto err;
+	}
+
+	/*
+	 * For DB_PREV, DB_LAST, DB_SET and DB_SET_RANGE, we have already
+	 * called __ram_update() to make sure sufficient records have been
+	 * read from the backing source file.  Do it now for DB_CURRENT (if
+	 * the current record was deleted we may need more records from the
+	 * backing file for a DB_CURRENT operation), DB_FIRST and DB_NEXT.
+	 * (We don't have to test for flags == DB_FIRST, because the switch
+	 * statement above re-set flags to DB_NEXT in that case.)
+	 */
+	if ((flags == DB_NEXT || flags == DB_CURRENT) && ((ret =
+	    __ram_update(dbc, cp->recno, 0)) != 0) && ret != DB_NOTFOUND)
+		goto err;
+
+	for (;; ++cp->recno) {
+		/* Search the tree for the record. */
+		if ((ret = __bam_rsearch(dbc, &cp->recno,
+		    F_ISSET(dbc, DBC_RMW) ? SR_FIND_WR : SR_FIND,
+		    1, &exact)) != 0)
+			goto err;
+		if (!exact) {
+			ret = DB_NOTFOUND;
+			goto err;
+		}
+
+		/* Copy the page into the cursor. */
+		STACK_TO_CURSOR(cp, ret);
+		if (ret != 0)
+			goto err;
+
+		/*
+		 * If re-numbering records, the on-page deleted flag means this
+		 * record was implicitly created.  If not re-numbering records,
+		 * the on-page deleted flag means this record was implicitly
+		 * created, or, it was deleted at some time.  Regardless, we
+		 * skip such records if doing cursor next/prev operations or
+		 * walking through off-page duplicates, and fail if they were
+		 * requested explicitly by the application.
+		 */
+		if (B_DISSET(GET_BKEYDATA(dbp, cp->page, cp->indx)->type))
+			switch (flags) {
+			case DB_NEXT:
+			case DB_PREV:
+				(void)__bam_stkrel(dbc, STK_CLRDBC);
+				PERFMON4(env, race, ramc_get,
+				    dbp->fname, dbp->dname, cp->page, flags);
+				goto retry;
+			case DB_GET_BOTH:
+			case DB_GET_BOTH_RANGE:
+				/*
+				 * If we're an OPD tree, we don't care about
+				 * matching a record number on a DB_GET_BOTH
+				 * -- everything belongs to the same tree.  A
+				 * normal recno should give up and return
+				 * DB_NOTFOUND if the matching recno is deleted.
+				 */
+				if (F_ISSET(dbc, DBC_OPD)) {
+					(void)__bam_stkrel(dbc, STK_CLRDBC);
+					continue;
+				}
+				ret = DB_NOTFOUND;
+				goto err;
+			default:
+				ret = DB_KEYEMPTY;
+				goto err;
+			}
+
+		if (flags == DB_GET_BOTH ||
+		    flags == DB_GET_BOTHC || flags == DB_GET_BOTH_RANGE) {
+			if ((ret = __bam_cmp(dbc, data, cp->page, cp->indx,
+			    __bam_defcmp, &cmp)) != 0)
+				return (ret);
+			if (cmp == 0)
+				break;
+			if (!F_ISSET(dbc, DBC_OPD)) {
+				ret = DB_NOTFOUND;
+				goto err;
+			}
+			(void)__bam_stkrel(dbc, STK_CLRDBC);
+		} else
+			break;
+	}
+
+	/* Return the key if the user didn't give us one. */
+	if (!F_ISSET(dbc, DBC_OPD) && !F_ISSET(key, DB_DBT_ISSET)) {
+		ret = __db_retcopy(dbp->env,
+		    key, &cp->recno, sizeof(cp->recno),
+		    &dbc->rkey->data, &dbc->rkey->ulen);
+		F_SET(key, DB_DBT_ISSET);
+	}
+
+	/* The cursor was reset, no further delete adjustment is necessary. */
+err:	CD_CLR(cp);
+
+	return (ret);
+}
+
+/*
+ * __ramc_put --
+ *	Recno DBC->put function.
+ *
+ * PUBLIC: int __ramc_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
+ */
+int
+__ramc_put(dbc, key, data, flags, pgnop)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+	db_pgno_t *pgnop;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DB_LSN lsn;
+	ENV *env;
+	u_int32_t iiflags;
+	int exact, nc, ret, t_ret;
+	void *arg;
+
+	COMPQUIET(pgnop, NULL);
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	/*
+	 * DB_KEYFIRST and DB_KEYLAST mean different things if they're
+	 * used in an off-page duplicate tree.  If we're an off-page
+	 * duplicate tree, they really mean "put at the beginning of the
+	 * tree" and "put at the end of the tree" respectively, so translate
+	 * them to something else.
+	 */
+	if (F_ISSET(dbc, DBC_OPD))
+		switch (flags) {
+		case DB_KEYFIRST:
+			cp->recno = 1;
+			flags = DB_BEFORE;
+			break;
+		case DB_KEYLAST:
+			if ((ret = __ram_add(dbc,
+			    &cp->recno, data, DB_APPEND, 0)) != 0)
+				return (ret);
+			if (CURADJ_LOG(dbc) &&
+			    (ret = __bam_rcuradj_log(dbp, dbc->txn,
+			    &lsn, 0, CA_ICURRENT,
+			    BAM_ROOT_PGNO(dbc), cp->recno, cp->order)) != 0)
+				return (ret);
+			return (0);
+		default:
+			break;
+		}
+
+	/*
+	 * Handle normal DB_KEYFIRST/DB_KEYLAST;  for a recno, which has
+	 * no duplicates, these are identical and mean "put the given
+	 * datum at the given recno".
+	 */
+	if (flags == DB_KEYFIRST || flags == DB_KEYLAST ||
+	    flags == DB_NOOVERWRITE || flags == DB_OVERWRITE_DUP) {
+		ret = __ram_getno(dbc, key, &cp->recno, 1);
+		if (ret == 0 || ret == DB_NOTFOUND)
+			ret = __ram_add(dbc, &cp->recno, data, flags, 0);
+		return (ret);
+	}
+
+	/*
+	 * If we're putting with a cursor that's marked C_DELETED, we need to
+	 * take special care;  the cursor doesn't "really" reference the item
+	 * corresponding to its current recno, but instead is "between" that
+	 * record and the current one.  Translate the actual insert into
+	 * DB_BEFORE, and let the __ram_ca work out the gory details of what
+	 * should wind up pointing where.
+	 */
+	if (CD_ISSET(cp))
+		iiflags = DB_BEFORE;
+	else
+		iiflags = flags;
+
+split:	if ((ret = __bam_rsearch(dbc, &cp->recno, SR_INSERT, 1, &exact)) != 0)
+		goto err;
+	/*
+	 * An inexact match is okay;  it just means we're one record past the
+	 * end, which is reasonable if we're marked deleted.
+	 */
+	DB_ASSERT(env, exact || CD_ISSET(cp));
+
+	/* Copy the page into the cursor. */
+	STACK_TO_CURSOR(cp, ret);
+	if (ret != 0)
+		goto err;
+
+	ret = __bam_iitem(dbc, key, data, iiflags, 0);
+	t_ret = __bam_stkrel(dbc, STK_CLRDBC);
+
+	if (t_ret != 0 && (ret == 0 || ret == DB_NEEDSPLIT))
+		ret = t_ret;
+	else if (ret == DB_NEEDSPLIT) {
+		arg = &cp->recno;
+		if ((ret = __bam_split(dbc, arg, NULL)) != 0)
+			goto err;
+		goto split;
+	}
+	if (ret != 0)
+		goto err;
+
+	switch (flags) {			/* Adjust the cursors. */
+	case DB_AFTER:
+		if ((ret = __ram_ca(dbc, CA_IAFTER, &nc)) != 0)
+			goto err;
+
+		/*
+		 * We only need to adjust this cursor forward if we truly added
+		 * the item after the current recno, rather than remapping it
+		 * to DB_BEFORE.
+		 */
+		if (iiflags == DB_AFTER)
+			++cp->recno;
+
+		/* Only log if __ram_ca found any relevant cursors. */
+		if (nc > 0 && CURADJ_LOG(dbc) &&
+		    (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, CA_IAFTER,
+		    BAM_ROOT_PGNO(dbc), cp->recno, cp->order)) != 0)
+			goto err;
+		break;
+	case DB_BEFORE:
+		if ((ret = __ram_ca(dbc, CA_IBEFORE, &nc)) != 0)
+			goto err;
+		--cp->recno;
+
+		/* Only log if __ram_ca found any relevant cursors. */
+		if (nc > 0 && CURADJ_LOG(dbc) &&
+		    (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, CA_IBEFORE,
+		    BAM_ROOT_PGNO(dbc), cp->recno, cp->order)) != 0)
+			goto err;
+		break;
+	case DB_CURRENT:
+		/*
+		 * We only need to do an adjustment if we actually
+		 * added an item, which we only would have done if the
+		 * cursor was marked deleted.
+		 */
+		if (!CD_ISSET(cp))
+			break;
+
+		/* Only log if __ram_ca found any relevant cursors. */
+		if ((ret = __ram_ca(dbc, CA_ICURRENT, &nc)) != 0)
+			goto err;
+		if (nc > 0 && CURADJ_LOG(dbc) && (ret = __bam_rcuradj_log(dbp,
+		    dbc->txn, &lsn, 0, CA_ICURRENT,
+		    BAM_ROOT_PGNO(dbc), cp->recno, cp->order)) != 0)
+			goto err;
+		break;
+	default:
+		break;
+	}
+
+	/* Return the key if we've created a new record. */
+	if (!F_ISSET(dbc, DBC_OPD) &&
+	    (flags == DB_AFTER || flags == DB_BEFORE) && key != NULL)
+		ret = __db_retcopy(env, key, &cp->recno,
+		    sizeof(cp->recno), &dbc->rkey->data, &dbc->rkey->ulen);
+
+	/* The cursor was reset, no further delete adjustment is necessary. */
+err:	CD_CLR(cp);
+
+	if (!DB_RETOK_DBCDEL(ret))
+		F_SET(dbc, DBC_ERROR);
+	return (ret);
+}
+
+static int
+__ram_ca_getorder(dbc, my_dbc, orderp, root_pgno, recno, args)
+	DBC *dbc, *my_dbc;
+	u_int32_t *orderp;
+	db_pgno_t root_pgno;
+	u_int32_t recno;
+	void *args;
+{
+	BTREE_CURSOR *cp;
+
+	COMPQUIET(my_dbc, NULL);
+	COMPQUIET(args, NULL);
+
+	cp = (BTREE_CURSOR *)dbc->internal;
+	if (root_pgno == BAM_ROOT_PGNO(dbc) &&
+	    recno == cp->recno && CD_ISSET(cp) &&
+	    *orderp <= cp->order &&
+	    !MVCC_SKIP_CURADJ(dbc, BAM_ROOT_PGNO(dbc)))
+		*orderp = cp->order;
+	return (0);
+}
+
+static int
+__ram_ca_setorder(dbc, my_dbc, foundp, pgno, order, args)
+	DBC *dbc, *my_dbc;
+	u_int32_t *foundp;
+	db_pgno_t pgno;
+	u_int32_t order;
+	void *args;
+{
+	BTREE_CURSOR *cp, *cp_arg;
+	int adjusted;
+	ca_recno_arg op;
+	db_recno_t recno;
+
+	COMPQUIET(pgno, 0);
+
+	cp = (BTREE_CURSOR *)dbc->internal;
+	cp_arg = (BTREE_CURSOR *)my_dbc->internal;
+	op = *(ca_recno_arg *)args;
+
+	if (cp_arg->root != cp->root ||
+	    MVCC_SKIP_CURADJ(dbc, BAM_ROOT_PGNO(dbc)))
+		return (0);
+	++(*foundp);
+	adjusted = 0;
+	recno = cp_arg->recno;
+	switch (op) {
+	case CA_DELETE:
+		if (recno < cp->recno) {
+			--cp->recno;
+			/*
+			 * If the adjustment made them equal,
+			 * we have to merge the orders.
+			 */
+			if (recno == cp->recno && CD_ISSET(cp))
+				cp->order += order;
+		} else if (recno == cp->recno &&
+		    !CD_ISSET(cp)) {
+			CD_SET(cp);
+			cp->order = order;
+			/*
+			 * If we're deleting the item, we can't
+			 * keep a streaming offset cached.
+			 */
+			cp->stream_start_pgno = PGNO_INVALID;
+		}
+		break;
+	case CA_IBEFORE:
+		/*
+		 * IBEFORE is just like IAFTER, except that we
+		 * adjust cursors on the current record too.
+		 */
+		if (C_EQUAL(cp_arg, cp)) {
+			++cp->recno;
+			adjusted = 1;
+		}
+		goto iafter;
+	case CA_ICURRENT:
+
+		/*
+		 * If the original cursor wasn't deleted, we
+		 * just did a replacement and so there's no
+		 * need to adjust anything--we shouldn't have
+		 * gotten this far.  Otherwise, we behave
+		 * much like an IAFTER, except that all
+		 * cursors pointing to the current item get
+		 * marked undeleted and point to the new
+		 * item.
+		 */
+		DB_ASSERT(dbc->dbp->env, CD_ISSET(cp_arg));
+		if (C_EQUAL(cp_arg, cp)) {
+			CD_CLR(cp);
+			break;
+		}
+		/* FALLTHROUGH */
+	case CA_IAFTER:
+iafter:		if (!adjusted && C_LESSTHAN(cp_arg, cp)) {
+			++cp->recno;
+			adjusted = 1;
+		}
+		if (recno == cp->recno && adjusted)
+			/*
+			 * If we've moved this cursor's recno,
+			 * split its order number--i.e.,
+			 * decrement it by enough so that
+			 * the lowest cursor moved has order 1.
+			 * cp_arg->order is the split point,
+			 * so decrement by one less than that.
+			 */
+			cp->order -= (cp_arg->order - 1);
+		break;
+	}
+	return (0);
+}
+
+/*
+ * __ram_ca --
+ *	Adjust cursors.  Returns the number of relevant cursors.
+ *
+ * PUBLIC: int __ram_ca __P((DBC *, ca_recno_arg, int *));
+ */
+int
+__ram_ca(dbc_arg, op, foundp)
+	DBC *dbc_arg;
+	ca_recno_arg op;
+	int *foundp;
+{
+	BTREE_CURSOR *cp_arg;
+	DB *dbp;
+	ENV *env;
+	db_recno_t recno;
+	u_int32_t found, order;
+	int ret;
+
+	dbp = dbc_arg->dbp;
+	env = dbp->env;
+	cp_arg = (BTREE_CURSOR *)dbc_arg->internal;
+	recno = cp_arg->recno;
+
+	/*
+	 * It only makes sense to adjust cursors if we're a renumbering
+	 * recno;  we should only be called if this is one.
+	 */
+	DB_ASSERT(env, F_ISSET(cp_arg, C_RENUMBER));
+
+	/*
+	 * Adjust the cursors.  See the comment in __bam_ca_delete().
+	 *
+	 * If we're doing a delete, we need to find the highest
+	 * order of any cursor currently pointing at this item,
+	 * so we can assign a higher order to the newly deleted
+	 * cursor.  Unfortunately, this requires a second pass through
+	 * the cursor list.
+	 */
+	if (op == CA_DELETE) {
+		if ((ret = __db_walk_cursors(dbp, NULL, __ram_ca_getorder,
+		    &order, BAM_ROOT_PGNO(dbc_arg), recno, NULL)) != 0)
+			return (ret);
+		order++;
+	} else
+		order = INVALID_ORDER;
+
+	if ((ret = __db_walk_cursors(dbp, dbc_arg,
+	    __ram_ca_setorder, &found, 0, order, &op)) != 0)
+		return (ret);
+	if (foundp != NULL)
+		*foundp = (int)found;
+	return (0);
+}
+
+/*
+ * __ram_getno --
+ *	Check the user's record number, and make sure we've seen it.
+ *
+ * PUBLIC: int __ram_getno __P((DBC *, const DBT *, db_recno_t *, int));
+ */
+int
+__ram_getno(dbc, key, rep, can_create)
+	DBC *dbc;
+	const DBT *key;
+	db_recno_t *rep;
+	int can_create;
+{
+	DB *dbp;
+	db_recno_t recno;
+
+	dbp = dbc->dbp;
+
+	/* If passed an empty DBT from Java, key->data may be NULL */
+	if (key->size != sizeof(db_recno_t)) {
+		__db_errx(dbp->env, DB_STR("1001",
+		    "illegal record number size"));
+		return (EINVAL);
+	}
+
+	/* Check the user's record number. */
+	if ((recno = *(db_recno_t *)key->data) == 0) {
+		__db_errx(dbp->env, DB_STR("1002",
+		    "illegal record number of 0"));
+		return (EINVAL);
+	}
+	if (rep != NULL)
+		*rep = recno;
+
+	/*
+	 * Btree can neither create records nor read them in.  Recno can
+	 * do both, see if we can find the record.
+	 */
+	return (dbc->dbtype == DB_RECNO ?
+	    __ram_update(dbc, recno, can_create) : 0);
+}
+
+/*
+ * __ram_update --
+ *	Ensure the tree has records up to and including the specified one.
+ */
+static int
+__ram_update(dbc, recno, can_create)
+	DBC *dbc;
+	db_recno_t recno;
+	int can_create;
+{
+	BTREE *t;
+	DB *dbp;
+	DBT *rdata;
+	db_recno_t nrecs;
+	int ret;
+
+	dbp = dbc->dbp;
+	t = dbp->bt_internal;
+
+	/*
+	 * If we can't create records and we've read the entire backing input
+	 * file, we're done.
+	 */
+	if (!can_create && t->re_eof)
+		return (0);
+
+	/*
+	 * If we haven't seen this record yet, try to get it from the original
+	 * file.
+	 */
+	if ((ret = __bam_nrecs(dbc, &nrecs)) != 0)
+		return (ret);
+	if (!t->re_eof && recno > nrecs) {
+		if ((ret = __ram_sread(dbc, recno)) != 0 && ret != DB_NOTFOUND)
+			return (ret);
+		if ((ret = __bam_nrecs(dbc, &nrecs)) != 0)
+			return (ret);
+	}
+
+	/*
+	 * If we can create records, create empty ones up to the requested
+	 * record.
+	 */
+	if (!can_create || recno <= nrecs + 1)
+		return (0);
+
+	rdata = &dbc->my_rdata;
+	rdata->flags = 0;
+	rdata->size = 0;
+
+	while (recno > ++nrecs)
+		if ((ret = __ram_add(dbc,
+		    &nrecs, rdata, 0, BI_DELETED)) != 0)
+			return (ret);
+	return (0);
+}
+
+/*
+ * __ram_source --
+ *	Load information about the backing file.
+ */
+static int
+__ram_source(dbp)
+	DB *dbp;
+{
+	BTREE *t;
+	ENV *env;
+	char *source;
+	int ret;
+
+	env = dbp->env;
+	t = dbp->bt_internal;
+
+	/* Find the real name, and swap out the one we had before. */
+	if ((ret = __db_appname(env,
+	    DB_APP_DATA, t->re_source, NULL, &source)) != 0)
+		return (ret);
+	__os_free(env, t->re_source);
+	t->re_source = source;
+
+	/*
+	 * !!!
+	 * It's possible that the backing source file is read-only.  We don't
+	 * much care other than we'll complain if there are any modifications
+	 * when it comes time to write the database back to the source.
+	 */
+	if ((t->re_fp = fopen(t->re_source, "rb")) == NULL) {
+		ret = __os_get_errno();
+		__db_err(env, ret, "%s", t->re_source);
+		return (ret);
+	}
+
+	t->re_eof = 0;
+	return (0);
+}
+
+/*
+ * __ram_writeback --
+ *	Rewrite the backing file.
+ *
+ * PUBLIC: int __ram_writeback __P((DB *));
+ */
+int
+__ram_writeback(dbp)
+	DB *dbp;
+{
+	BTREE *t;
+	DBC *dbc;
+	DBT key, data;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	FILE *fp;
+	db_recno_t keyno;
+	int ret, t_ret;
+	u_int8_t delim, *pad;
+
+	t = dbp->bt_internal;
+	env = dbp->env;
+	fp = NULL;
+	pad = NULL;
+
+	/* If the file wasn't modified, we're done. */
+	if (!t->re_modified)
+		return (0);
+
+	/* If there's no backing source file, we're done. */
+	if (t->re_source == NULL) {
+		t->re_modified = 0;
+		return (0);
+	}
+
+	/*
+	 * We step through the records, writing each one out.  Use the record
+	 * number and the dbp->get() function, instead of a cursor, so we find
+	 * and write out "deleted" or non-existent records.  The DB handle may
+	 * be threaded, so allocate memory as we go.
+	 */
+	memset(&key, 0, sizeof(key));
+	key.size = sizeof(db_recno_t);
+	key.data = &keyno;
+	memset(&data, 0, sizeof(data));
+	F_SET(&data, DB_DBT_REALLOC);
+
+	/* Allocate a cursor. */
+	ENV_GET_THREAD_INFO(env, ip);
+	if ((ret = __db_cursor(dbp, ip, NULL, &dbc, 0)) != 0)
+		return (ret);
+
+	/*
+	 * Read any remaining records into the tree.
+	 *
+	 * !!!
+	 * This is why we can't support transactions when applications specify
+	 * backing (re_source) files.  At this point we have to read in the
+	 * rest of the records from the file so that we can write all of the
+	 * records back out again, which could modify a page for which we'd
+	 * have to log changes and which we don't have locked.  This could be
+	 * partially fixed by taking a snapshot of the entire file during the
+	 * DB->open as DB->open is transaction protected.  But, if a checkpoint
+	 * occurs then, the part of the log holding the copy of the file could
+	 * be discarded, and that would make it impossible to recover in the
+	 * face of disaster.  This could all probably be fixed, but it would
+	 * require transaction protecting the backing source file.
+	 *
+	 * XXX
+	 * This could be made to work now that we have transactions protecting
+	 * file operations.  Margo has specifically asked for the privilege of
+	 * doing this work.
+	 */
+	if ((ret =
+	    __ram_update(dbc, DB_MAX_RECORDS, 0)) != 0 && ret != DB_NOTFOUND)
+		goto err;
+
+	/*
+	 * Close any existing file handle and re-open the file, truncating it.
+	 */
+	if (t->re_fp != NULL) {
+		if (fclose(t->re_fp) != 0) {
+			ret = __os_get_errno();
+			__db_err(env, ret, "%s", t->re_source);
+			goto err;
+		}
+		t->re_fp = NULL;
+	}
+	if ((fp = fopen(t->re_source, "wb")) == NULL) {
+		ret = __os_get_errno();
+		__db_err(env, ret, "%s", t->re_source);
+		goto err;
+	}
+
+	/*
+	 * We'll need the delimiter if we're doing variable-length records,
+	 * and the pad character if we're doing fixed-length records.
+	 */
+	delim = t->re_delim;
+	for (keyno = 1;; ++keyno) {
+		switch (ret = __db_get(dbp, ip, NULL, &key, &data, 0)) {
+		case 0:
+			if (data.size != 0 &&
+			    fwrite(data.data, 1, data.size, fp) != data.size)
+				goto write_err;
+			break;
+		case DB_KEYEMPTY:
+			if (F_ISSET(dbp, DB_AM_FIXEDLEN)) {
+				if (pad == NULL) {
+					if ((ret = __os_malloc(
+					    env, t->re_len, &pad)) != 0)
+						goto err;
+					memset(pad, t->re_pad, t->re_len);
+				}
+				if (fwrite(pad, 1, t->re_len, fp) != t->re_len)
+					goto write_err;
+			}
+			break;
+		case DB_NOTFOUND:
+			ret = 0;
+			goto done;
+		default:
+			goto err;
+		}
+		if (!F_ISSET(dbp, DB_AM_FIXEDLEN) &&
+		    fwrite(&delim, 1, 1, fp) != 1) {
+write_err:		ret = __os_get_errno();
+			__db_err(env, ret, DB_STR_A("1003",
+			    "%s: write failed to backing file", "%s"),
+			    t->re_source);
+			goto err;
+		}
+	}
+
+err:
+done:	/* Close the file descriptor. */
+	if (fp != NULL && fclose(fp) != 0) {
+		t_ret = __os_get_errno();
+		__db_err(env, t_ret, "%s", t->re_source);
+		if (ret == 0)
+			ret = t_ret;
+	}
+
+	/* Discard the cursor. */
+	if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Discard memory allocated to hold the data items. */
+	if (data.data != NULL)
+		__os_ufree(env, data.data);
+	if (pad != NULL)
+		__os_free(env, pad);
+
+	if (ret == 0)
+		t->re_modified = 0;
+
+	return (ret);
+}
+
+/*
+ * __ram_sread --
+ *	Read records from a source file.
+ */
+static int
+__ram_sread(dbc, top)
+	DBC *dbc;
+	db_recno_t top;
+{
+	BTREE *t;
+	DB *dbp;
+	DBT data, *rdata;
+	db_recno_t recno;
+	size_t len;
+	int ch, ret, was_modified;
+
+	t = dbc->dbp->bt_internal;
+	dbp = dbc->dbp;
+	was_modified = t->re_modified;
+
+	if ((ret = __bam_nrecs(dbc, &recno)) != 0)
+		return (ret);
+
+	/*
+	 * Use the record key return memory, it's only a short-term use.
+	 * The record data return memory is used by __bam_iitem, which
+	 * we'll indirectly call, so use the key so as not to collide.
+	 */
+	len = F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_len : 256;
+	rdata = &dbc->my_rkey;
+	if (rdata->ulen < len) {
+		if ((ret = __os_realloc(
+		    dbp->env, len, &rdata->data)) != 0) {
+			rdata->ulen = 0;
+			rdata->data = NULL;
+			return (ret);
+		}
+		rdata->ulen = (u_int32_t)len;
+	}
+
+	memset(&data, 0, sizeof(data));
+	while (recno < top) {
+		data.data = rdata->data;
+		data.size = 0;
+		if (F_ISSET(dbp, DB_AM_FIXEDLEN))
+			for (len = t->re_len; len > 0; --len) {
+				if ((ch = fgetc(t->re_fp)) == EOF) {
+					if (data.size == 0)
+						goto eof;
+					break;
+				}
+				((u_int8_t *)data.data)[data.size++] = ch;
+			}
+		else
+			for (;;) {
+				if ((ch = fgetc(t->re_fp)) == EOF) {
+					if (data.size == 0)
+						goto eof;
+					break;
+				}
+				if (ch == t->re_delim)
+					break;
+
+				((u_int8_t *)data.data)[data.size++] = ch;
+				if (data.size == rdata->ulen) {
+					if ((ret = __os_realloc(dbp->env,
+					    rdata->ulen *= 2,
+					    &rdata->data)) != 0) {
+						rdata->ulen = 0;
+						rdata->data = NULL;
+						return (ret);
+					} else
+						data.data = rdata->data;
+				}
+			}
+
+		/*
+		 * Another process may have read this record from the input
+		 * file and stored it into the database already, in which
+		 * case we don't need to repeat that operation.  We detect
+		 * this by checking if the last record we've read is greater
+		 * or equal to the number of records in the database.
+		 */
+		if (t->re_last >= recno) {
+			++recno;
+			if ((ret = __ram_add(dbc, &recno, &data, 0, 0)) != 0)
+				goto err;
+		}
+		++t->re_last;
+	}
+
+	if (0) {
+eof:		t->re_eof = 1;
+		ret = DB_NOTFOUND;
+	}
+err:	if (!was_modified)
+		t->re_modified = 0;
+
+	return (ret);
+}
+
+/*
+ * __ram_add --
+ *	Add records into the tree.
+ */
+static int
+__ram_add(dbc, recnop, data, flags, bi_flags)
+	DBC *dbc;
+	db_recno_t *recnop;
+	DBT *data;
+	u_int32_t flags, bi_flags;
+{
+	BTREE_CURSOR *cp;
+	int exact, ret, stack, t_ret;
+
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+retry:	/* Find the slot for insertion. */
+	if ((ret = __bam_rsearch(dbc, recnop,
+	    SR_INSERT | (flags == DB_APPEND ? SR_APPEND : 0), 1, &exact)) != 0)
+		return (ret);
+	stack = 1;
+
+	/* Copy the page into the cursor. */
+	STACK_TO_CURSOR(cp, ret);
+	if (ret != 0)
+		goto err;
+
+	if (exact && flags == DB_NOOVERWRITE && !CD_ISSET(cp) &&
+	    !B_DISSET(GET_BKEYDATA(dbc->dbp, cp->page, cp->indx)->type)) {
+		ret = DB_KEYEXIST;
+		goto err;
+	}
+
+	/*
+	 * The application may modify the data based on the selected record
+	 * number.
+	 */
+	if (flags == DB_APPEND && dbc->dbp->db_append_recno != NULL &&
+	    (ret = dbc->dbp->db_append_recno(dbc->dbp, data, *recnop)) != 0)
+		goto err;
+
+	/*
+	 * Select the arguments for __bam_iitem() and do the insert.  If the
+	 * key is an exact match, or we're replacing the data item with a
+	 * new data item, replace the current item.  If the key isn't an exact
+	 * match, we're inserting a new key/data pair, before the search
+	 * location.
+	 */
+	switch (ret = __bam_iitem(dbc,
+	    NULL, data, exact ? DB_CURRENT : DB_BEFORE, bi_flags)) {
+	case 0:
+		/*
+		 * Don't adjust anything.
+		 *
+		 * If we inserted a record, no cursors need adjusting because
+		 * the only new record it's possible to insert is at the very
+		 * end of the tree.  The necessary adjustments to the internal
+		 * page counts were made by __bam_iitem().
+		 *
+		 * If we overwrote a record, no cursors need adjusting because
+		 * future DBcursor->get calls will simply return the underlying
+		 * record (there's no adjustment made for the DB_CURRENT flag
+		 * when a cursor get operation immediately follows a cursor
+		 * delete operation, and the normal adjustment for the DB_NEXT
+		 * flag is still correct).
+		 */
+		break;
+	case DB_NEEDSPLIT:
+		/* Discard the stack of pages and split the page. */
+		(void)__bam_stkrel(dbc, STK_CLRDBC);
+		stack = 0;
+
+		if ((ret = __bam_split(dbc, recnop, NULL)) != 0)
+			goto err;
+
+		goto retry;
+		/* NOTREACHED */
+	default:
+		goto err;
+	}
+
+err:	if (stack && (t_ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_rsearch.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,535 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+
+/*
+ * __bam_rsearch --
+ *	Search a btree for a record number.
+ *
+ * PUBLIC: int __bam_rsearch __P((DBC *, db_recno_t *, u_int32_t, int, int *));
+ */
+int
+__bam_rsearch(dbc, recnop, flags, stop, exactp)
+	DBC *dbc;
+	db_recno_t *recnop;
+	u_int32_t flags;
+	int stop, *exactp;
+{
+	BINTERNAL *bi;
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DB_LOCK lock;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h;
+	RINTERNAL *ri;
+	db_indx_t adjust, deloffset, indx, top;
+	db_lockmode_t lock_mode;
+	db_pgno_t pg;
+	db_recno_t recno, t_recno, total;
+	u_int32_t get_mode;
+	int ret, stack, t_ret;
+
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_OFF(dbc->thread_info);
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	h = NULL;
+	ret = 0;
+
+	BT_STK_CLR(cp);
+
+	/*
+	 * There are several ways we search a btree tree.  The flags argument
+	 * specifies if we're acquiring read or write locks and if we are
+	 * locking pairs of pages.  In addition, if we're adding or deleting
+	 * an item, we have to lock the entire tree, regardless.  See btree.h
+	 * for more details.
+	 *
+	 * If write-locking pages, we need to know whether or not to acquire a
+	 * write lock on a page before getting it.  This depends on how deep it
+	 * is in tree, which we don't know until we acquire the root page.  So,
+	 * if we need to lock the root page we may have to upgrade it later,
+	 * because we won't get the correct lock initially.
+	 *
+	 * Retrieve the root page.
+	 */
+
+	if ((ret = __bam_get_root(dbc, PGNO_INVALID, stop, flags, &stack)) != 0)
+		goto done;
+	lock_mode = cp->csp->lock_mode;
+	get_mode = lock_mode == DB_LOCK_WRITE ? DB_MPOOL_DIRTY : 0;
+	lock = cp->csp->lock;
+	h = cp->csp->page;
+
+	BT_STK_CLR(cp);
+	/*
+	 * If appending to the tree, set the record number now -- we have the
+	 * root page locked.
+	 *
+	 * Delete only deletes exact matches, read only returns exact matches.
+	 * Note, this is different from __bam_search(), which returns non-exact
+	 * matches for read.
+	 *
+	 * The record may not exist.  We can only return the correct location
+	 * for the record immediately after the last record in the tree, so do
+	 * a fast check now.
+	 */
+	total = RE_NREC(h);
+	if (LF_ISSET(SR_APPEND)) {
+		*exactp = 0;
+		*recnop = recno = total + 1;
+	} else {
+		recno = *recnop;
+		if (recno <= total)
+			*exactp = 1;
+		else {
+			*exactp = 0;
+			if (!LF_ISSET(SR_PAST_EOF) || recno > total + 1) {
+				/*
+				 * Keep the page locked for serializability.
+				 *
+				 * XXX
+				 * This leaves the root page locked, which will
+				 * eliminate any concurrency.  A possible fix
+				 * would be to lock the last leaf page instead.
+				 */
+				ret = __memp_fput(mpf,
+				    dbc->thread_info, h, dbc->priority);
+				if ((t_ret =
+				    __TLPUT(dbc, lock)) != 0 && ret == 0)
+					ret = t_ret;
+				if (ret == 0)
+					ret = DB_NOTFOUND;
+				goto done;
+			}
+		}
+	}
+
+	/*
+	 * !!!
+	 * Record numbers in the tree are 0-based, but the recno is
+	 * 1-based.  All of the calculations below have to take this
+	 * into account.
+	 */
+	for (total = 0;;) {
+		switch (TYPE(h)) {
+		case P_LBTREE:
+			if (LF_ISSET(SR_MAX)) {
+				indx = NUM_ENT(h) - 2;
+				goto enter;
+			}
+			/* FALLTHROUGH */
+		case P_LDUP:
+			if (LF_ISSET(SR_MAX)) {
+				indx = NUM_ENT(h) - 1;
+				goto enter;
+			}
+			recno -= total;
+			/*
+			 * There may be logically deleted records on the page.
+			 * If there are enough, the record may not exist.
+			 */
+			if (TYPE(h) == P_LBTREE) {
+				adjust = P_INDX;
+				deloffset = O_INDX;
+			} else {
+				adjust = O_INDX;
+				deloffset = 0;
+			}
+			for (t_recno = 0, indx = 0;; indx += adjust) {
+				if (indx >= NUM_ENT(h)) {
+					*exactp = 0;
+					if (!LF_ISSET(SR_PAST_EOF) ||
+					    recno > t_recno + 1) {
+						ret = __memp_fput(mpf,
+						    dbc->thread_info,
+						    h, dbc->priority);
+						h = NULL;
+						if ((t_ret = __TLPUT(dbc,
+						    lock)) != 0 && ret == 0)
+							ret = t_ret;
+						if (ret == 0)
+							ret = DB_NOTFOUND;
+						goto err;
+					}
+				}
+				if (!B_DISSET(GET_BKEYDATA(dbp, h,
+				    indx + deloffset)->type) &&
+				    ++t_recno == recno)
+					break;
+			}
+
+			BT_STK_ENTER(env, cp, h, indx, lock, lock_mode, ret);
+			if (ret != 0)
+				goto err;
+			if (LF_ISSET(SR_BOTH))
+				goto get_prev;
+			goto done;
+		case P_IBTREE:
+			if (LF_ISSET(SR_MAX)) {
+				indx = NUM_ENT(h);
+				bi = GET_BINTERNAL(dbp, h, indx - 1);
+			} else for (indx = 0, top = NUM_ENT(h);;) {
+				bi = GET_BINTERNAL(dbp, h, indx);
+				if (++indx == top || total + bi->nrecs >= recno)
+					break;
+				total += bi->nrecs;
+			}
+			pg = bi->pgno;
+			break;
+		case P_LRECNO:
+			if (LF_ISSET(SR_MAX))
+				recno = NUM_ENT(h);
+			else
+				recno -= total;
+
+			/* Correct from 1-based to 0-based for a page offset. */
+			--recno;
+enter:			BT_STK_ENTER(env, cp, h, recno, lock, lock_mode, ret);
+			if (ret != 0)
+				goto err;
+			if (LF_ISSET(SR_BOTH)) {
+get_prev:			DB_ASSERT(env, LF_ISSET(SR_NEXT));
+				/*
+				 * We have a NEXT tree, now add the sub tree
+				 * that points gets to the previous page.
+				 */
+				cp->csp++;
+				indx = cp->sp->indx - 1;
+				h = cp->sp->page;
+				if (TYPE(h) == P_IRECNO) {
+					ri = GET_RINTERNAL(dbp, h, indx);
+					pg = ri->pgno;
+				} else {
+					DB_ASSERT(env, TYPE(h) == P_IBTREE);
+					bi = GET_BINTERNAL(dbp, h, indx);
+					pg = bi->pgno;
+				}
+				LF_CLR(SR_NEXT | SR_BOTH);
+				LF_SET(SR_MAX);
+				stack = 1;
+				h = NULL;
+				goto lock_next;
+			}
+			goto done;
+		case P_IRECNO:
+			if (LF_ISSET(SR_MAX)) {
+				indx = NUM_ENT(h);
+				ri = GET_RINTERNAL(dbp, h, indx - 1);
+			} else for (indx = 0, top = NUM_ENT(h);;) {
+				ri = GET_RINTERNAL(dbp, h, indx);
+				if (++indx == top || total + ri->nrecs >= recno)
+					break;
+				total += ri->nrecs;
+			}
+			pg = ri->pgno;
+			break;
+		default:
+			ret = __db_pgfmt(env, h->pgno);
+			goto done;
+		}
+		--indx;
+
+		/* Return if this is the lowest page wanted. */
+		if (stop == LEVEL(h)) {
+			BT_STK_ENTER(env, cp, h, indx, lock, lock_mode, ret);
+			if (ret != 0)
+				goto err;
+			goto done;
+		}
+		if (stack) {
+			BT_STK_PUSH(env, cp, h, indx, lock, lock_mode, ret);
+			if (ret != 0)
+				goto err;
+			h = NULL;
+
+			lock_mode = DB_LOCK_WRITE;
+			get_mode = DB_MPOOL_DIRTY;
+			if ((ret =
+			    __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
+				goto err;
+		} else if (LF_ISSET(SR_NEXT)) {
+			/*
+			 * For RECNO if we are doing a NEXT search the
+			 * search recno is the one we are looking for
+			 * but we want to keep the stack from the spanning
+			 * node on down.  We only know we have the spanning
+			 * node when its child's index is 0, so save
+			 * each node and discard the tree when we find out
+			 * its not needed.
+			 */
+			if (indx != 0 && cp->sp->page != NULL) {
+				BT_STK_POP(cp);
+				if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0)
+					goto err;
+			}
+
+			BT_STK_PUSH(env, cp, h, indx, lock, lock_mode, ret);
+			h = NULL;
+			if (ret != 0)
+				goto err;
+lock_next:		if ((ret =
+			    __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0)
+				goto err;
+		} else {
+			/*
+			 * Decide if we want to return a pointer to the next
+			 * page in the stack.  If we do, write lock it and
+			 * never unlock it.
+			 */
+			if ((LF_ISSET(SR_PARENT) &&
+			    (u_int8_t)(stop + 1) >= (u_int8_t)(LEVEL(h) - 1)) ||
+			    (LEVEL(h) - 1) == LEAFLEVEL)
+				stack = 1;
+
+			if ((ret = __memp_fput(mpf,
+			    dbc->thread_info, h, dbc->priority)) != 0)
+				goto err;
+			h = NULL;
+
+			lock_mode = stack &&
+			    LF_ISSET(SR_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ;
+			if (lock_mode == DB_LOCK_WRITE)
+				get_mode = DB_MPOOL_DIRTY;
+			if ((ret = __db_lget(dbc,
+			    LCK_COUPLE_ALWAYS, pg, lock_mode, 0, &lock)) != 0) {
+				/*
+				 * If we fail, discard the lock we held.  This
+				 * is OK because this only happens when we are
+				 * descending the tree holding read-locks.
+				 */
+				(void)__LPUT(dbc, lock);
+				goto err;
+			}
+		}
+
+		if ((ret = __memp_fget(mpf, &pg,
+		     dbc->thread_info, dbc->txn, get_mode, &h)) != 0)
+			goto err;
+	}
+	/* NOTREACHED */
+
+err:	if (h != NULL && (t_ret = __memp_fput(mpf,
+	    dbc->thread_info, h, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+
+	BT_STK_POP(cp);
+	(void)__bam_stkrel(dbc, 0);
+
+done:
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_ON(dbc->thread_info);
+	return (ret);
+}
+
+/*
+ * __bam_adjust --
+ *	Adjust the tree after adding or deleting a record.
+ *
+ * PUBLIC: int __bam_adjust __P((DBC *, int32_t));
+ */
+int
+__bam_adjust(dbc, adjust)
+	DBC *dbc;
+	int32_t adjust;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DB_MPOOLFILE *mpf;
+	EPG *epg;
+	PAGE *h;
+	db_pgno_t root_pgno;
+	int ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	root_pgno = BAM_ROOT_PGNO(dbc);
+
+	/* Update the record counts for the tree. */
+	for (epg = cp->sp; epg <= cp->csp; ++epg) {
+		h = epg->page;
+		if (TYPE(h) == P_IBTREE || TYPE(h) == P_IRECNO) {
+			ret = __memp_dirty(mpf, &h,
+			    dbc->thread_info, dbc->txn, dbc->priority, 0);
+			epg->page = h;
+			if (ret != 0)
+				return (ret);
+			if (DBC_LOGGING(dbc)) {
+				if ((ret = __bam_cadjust_log(dbp, dbc->txn,
+				    &LSN(h), 0, PGNO(h), &LSN(h),
+				    (u_int32_t)epg->indx, adjust,
+				    PGNO(h) == root_pgno ?
+				    CAD_UPDATEROOT : 0)) != 0)
+					return (ret);
+			} else
+				LSN_NOT_LOGGED(LSN(h));
+
+			if (TYPE(h) == P_IBTREE)
+				GET_BINTERNAL(dbp, h, epg->indx)->nrecs +=
+				    adjust;
+			else
+				GET_RINTERNAL(dbp, h, epg->indx)->nrecs +=
+				    adjust;
+
+			if (PGNO(h) == root_pgno)
+				RE_NREC_ADJ(h, adjust);
+		}
+	}
+	return (0);
+}
+
+/*
+ * __bam_nrecs --
+ *	Return the number of records in the tree.
+ *
+ * PUBLIC: int __bam_nrecs __P((DBC *, db_recno_t *));
+ */
+int
+__bam_nrecs(dbc, rep)
+	DBC *dbc;
+	db_recno_t *rep;
+{
+	DB *dbp;
+	DB_LOCK lock;
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	db_pgno_t pgno;
+	int ret, t_ret;
+
+	COMPQUIET(h, NULL);
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	LOCK_INIT(lock);
+
+	pgno = PGNO_INVALID;
+	BAM_GET_ROOT(dbc, pgno, h, 0, DB_LOCK_READ, lock, ret);
+	if (ret != 0)
+		goto err;
+	DB_ASSERT(dbp->env, h != NULL);
+
+	*rep = RE_NREC(h);
+
+	ret = __memp_fput(mpf, dbc->thread_info, h, dbc->priority);
+err:	if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __bam_total --
+ *	Return the number of records below a page.
+ *
+ * PUBLIC: db_recno_t __bam_total __P((DB *, PAGE *));
+ */
+db_recno_t
+__bam_total(dbp, h)
+	DB *dbp;
+	PAGE *h;
+{
+	db_recno_t nrecs;
+	db_indx_t indx, top;
+
+	nrecs = 0;
+	top = NUM_ENT(h);
+
+	switch (TYPE(h)) {
+	case P_LBTREE:
+		/* Check for logically deleted records. */
+		for (indx = 0; indx < top; indx += P_INDX)
+			if (!B_DISSET(
+			    GET_BKEYDATA(dbp, h, indx + O_INDX)->type))
+				++nrecs;
+		break;
+	case P_LDUP:
+		/* Check for logically deleted records. */
+		for (indx = 0; indx < top; indx += O_INDX)
+			if (!B_DISSET(GET_BKEYDATA(dbp, h, indx)->type))
+				++nrecs;
+		break;
+	case P_IBTREE:
+		for (indx = 0; indx < top; indx += O_INDX)
+			nrecs += GET_BINTERNAL(dbp, h, indx)->nrecs;
+		break;
+	case P_LRECNO:
+		nrecs = NUM_ENT(h);
+		break;
+	case P_IRECNO:
+		for (indx = 0; indx < top; indx += O_INDX)
+			nrecs += GET_RINTERNAL(dbp, h, indx)->nrecs;
+		break;
+	}
+
+	return (nrecs);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_search.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1050 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+
+/*
+ * __bam_get_root --
+ *	Fetch the root of a tree and see if we want to keep
+ * it in the stack.
+ *
+ * PUBLIC: int __bam_get_root __P((DBC *, db_pgno_t, int, u_int32_t, int *));
+ */
+int
+__bam_get_root(dbc, root_pgno, slevel, flags, stack)
+	DBC *dbc;
+	db_pgno_t root_pgno;
+	int slevel;
+	u_int32_t flags;
+	int *stack;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DB_LOCK lock;
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	db_lockmode_t lock_mode;
+	u_int32_t get_mode;
+	int ret, t_ret;
+
+	COMPQUIET(h, NULL);
+	LOCK_INIT(lock);
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	/*
+	 * If write-locking pages, we need to know whether or not to acquire a
+	 * write lock on a page before getting it.  This depends on how deep it
+	 * is in tree, which we don't know until we acquire the root page.  So,
+	 * if we need to lock the root page we may have to upgrade it later,
+	 * because we won't get the correct lock initially.
+	 *
+	 * Retrieve the root page.
+	 */
+try_again:
+	*stack = LF_ISSET(SR_STACK) &&
+	      (dbc->dbtype == DB_RECNO || F_ISSET(cp, C_RECNUM));
+	lock_mode = DB_LOCK_READ;
+	if (*stack ||
+	    LF_ISSET(SR_DEL) || (LF_ISSET(SR_NEXT) && LF_ISSET(SR_WRITE)))
+		lock_mode = DB_LOCK_WRITE;
+
+	/*
+	 * Get the root.  If the root happens to be a leaf page then
+	 * we are supposed to get a read lock on it before latching
+	 * it.  So if we have not locked it do a try get first.
+	 * If we can't get the root shared, then get a lock on it and
+	 * then wait for the latch.
+	 */
+retry:	if (lock_mode == DB_LOCK_WRITE)
+		get_mode = DB_MPOOL_DIRTY;
+	else if (LOCK_ISSET(lock) || !STD_LOCKING(dbc) ||
+	    F_ISSET(dbc, DBC_DOWNREV) ||
+	    dbc->dbtype == DB_RECNO || F_ISSET(cp, C_RECNUM))
+		get_mode = 0;
+	else
+		get_mode = DB_MPOOL_TRY;
+
+	BAM_GET_ROOT(dbc, root_pgno, h, get_mode, lock_mode, lock, ret);
+	if (ret == DB_LOCK_NOTGRANTED && get_mode == DB_MPOOL_TRY) {
+		DB_ASSERT(dbp->env, !LOCK_ISSET(lock));
+		if ((ret = __db_lget(dbc, 0,
+		    root_pgno == PGNO_INVALID ? BAM_ROOT_PGNO(dbc) : root_pgno,
+		    lock_mode, 0, &lock)) != 0)
+			return (ret);
+		goto retry;
+	}
+	if (ret != 0) {
+		/* Did not read it, so we can release the lock */
+		(void)__LPUT(dbc, lock);
+		return (ret);
+	}
+	DB_ASSERT(dbp->env, TYPE(h) == P_IBTREE || TYPE(h) == P_IRECNO ||
+	    TYPE(h) == P_LBTREE || TYPE(h) == P_LRECNO || TYPE(h) == P_LDUP);
+
+	/*
+	 * Decide if we need to dirty and/or lock this page.
+	 * We must not hold the latch while we get the lock.
+	 */
+	if (!*stack &&
+	    ((LF_ISSET(SR_PARENT) && (u_int8_t)(slevel + 1) >= LEVEL(h)) ||
+	    LEVEL(h) == LEAFLEVEL ||
+	    (LF_ISSET(SR_START) && slevel == LEVEL(h)))) {
+		*stack = 1;
+		/* If we already have the write lock, we are done. */
+		if (dbc->dbtype == DB_RECNO || F_ISSET(cp, C_RECNUM)) {
+			if (lock_mode == DB_LOCK_WRITE)
+				goto done;
+			if ((ret = __LPUT(dbc, lock)) != 0)
+				return (ret);
+		}
+
+		/*
+		 * Now that we know what level the root is at, do we need a
+		 * write lock?  If not or we got the lock before latching
+		 * we are done.
+		 */
+		if (LEVEL(h) != LEAFLEVEL || LF_ISSET(SR_WRITE)) {
+			lock_mode = DB_LOCK_WRITE;
+			/* Drop the read lock if we got it above. */
+			if ((ret = __LPUT(dbc, lock)) != 0)
+				return (ret);
+		} else if (LOCK_ISSET(lock))
+			goto done;
+		if (!STD_LOCKING(dbc)) {
+			if (lock_mode != DB_LOCK_WRITE)
+				goto done;
+			if ((ret = __memp_dirty(mpf, &h, dbc->thread_info,
+			    dbc->txn, dbc->priority, 0)) != 0) {
+				if (h != NULL)
+					(void)__memp_fput(mpf,
+					    dbc->thread_info, h, dbc->priority);
+				return (ret);
+			}
+		} else {
+			/* Try to lock the page without waiting first. */
+			if ((ret = __db_lget(dbc, 0, root_pgno,
+			    lock_mode, DB_LOCK_NOWAIT, &lock)) == 0) {
+				if (lock_mode == DB_LOCK_WRITE && (ret =
+				    __memp_dirty(mpf, &h, dbc->thread_info,
+				    dbc->txn, dbc->priority, 0)) != 0) {
+					if (h != NULL)
+						(void)__memp_fput(mpf,
+						    dbc->thread_info, h,
+						    dbc->priority);
+					return (ret);
+				}
+				goto done;
+			}
+
+			t_ret = __memp_fput(mpf,
+			    dbc->thread_info, h, dbc->priority);
+			h = NULL;
+
+			if (ret == DB_LOCK_DEADLOCK ||
+			    ret == DB_LOCK_NOTGRANTED)
+				ret = 0;
+			if (ret == 0)
+				ret = t_ret;
+
+			if (ret != 0)
+				return (ret);
+			get_mode = 0;
+			if (lock_mode == DB_LOCK_WRITE)
+				get_mode = DB_MPOOL_DIRTY;
+
+			if ((ret = __db_lget(dbc,
+			     0, root_pgno, lock_mode, 0, &lock)) != 0)
+				return (ret);
+			if ((ret = __memp_fget(mpf,
+			     &root_pgno, dbc->thread_info, dbc->txn,
+			     (atomic_read(&mpf->mfp->multiversion) == 0 &&
+			     lock_mode == DB_LOCK_WRITE) ? DB_MPOOL_DIRTY : 0,
+			     &h)) != 0) {
+				/* Did not read it, release the lock */
+				(void)__LPUT(dbc, lock);
+				return (ret);
+			}
+		}
+		/*
+		 * While getting dirty or locked we need to drop the mutex
+		 * so someone else could get in and split the root.
+		 */
+		if (!((LF_ISSET(SR_PARENT) &&
+		    (u_int8_t)(slevel + 1) >= LEVEL(h)) ||
+		    LEVEL(h) == LEAFLEVEL ||
+		    (LF_ISSET(SR_START) && slevel == LEVEL(h)))) {
+			/* Someone else split the root, start over. */
+			ret = __memp_fput(mpf,
+			    dbc->thread_info, h, dbc->priority);
+			h = NULL;
+			if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
+				ret = t_ret;
+			if (ret != 0)
+				return (ret);
+			goto try_again;
+		} else if (atomic_read(&mpf->mfp->multiversion) != 0 &&
+		    lock_mode == DB_LOCK_WRITE && (ret = __memp_dirty(mpf, &h,
+		    dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) {
+			(void)__memp_fput(mpf,
+			    dbc->thread_info, h, dbc->priority);
+			(void)__LPUT(dbc, lock);
+		}
+	}
+
+done:	BT_STK_ENTER(dbp->env, cp, h, 0, lock, lock_mode, ret);
+
+	return (ret);
+}
+
+/*
+ * __bam_search --
+ *	Search a btree for a key.
+ *
+ * PUBLIC: int __bam_search __P((DBC *, db_pgno_t,
+ * PUBLIC:     const DBT *, u_int32_t, int, db_recno_t *, int *));
+ */
+int
+__bam_search(dbc, root_pgno, key, flags, slevel, recnop, exactp)
+	DBC *dbc;
+	db_pgno_t root_pgno;
+	const DBT *key;
+	u_int32_t flags;
+	int slevel, *exactp;
+	db_recno_t *recnop;
+{
+	BTREE *t;
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DB_LOCK lock, saved_lock;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h, *parent_h;
+	db_indx_t base, i, indx, *inp, lim;
+	db_lockmode_t lock_mode;
+	db_pgno_t pg, saved_pg, start_pgno;
+	db_recno_t recno;
+	int adjust, cmp, deloffset, ret, set_stack, stack, t_ret;
+	int getlock, was_next;
+	int (*func) __P((DB *, const DBT *, const DBT *));
+	u_int32_t get_mode, wait;
+	u_int8_t level, saved_level;
+
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_OFF(dbc->thread_info);
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	h = NULL;
+	parent_h = NULL;
+	t = dbp->bt_internal;
+	recno = 0;
+	t_ret = 0;
+
+	BT_STK_CLR(cp);
+	LOCK_INIT(saved_lock);
+	LOCK_INIT(lock);
+	was_next = LF_ISSET(SR_NEXT);
+	wait = DB_LOCK_NOWAIT;
+
+	/*
+	 * There are several ways we search a btree tree.  The flags argument
+	 * specifies if we're acquiring read or write latches, if we position
+	 * to the first or last item in a set of duplicates, if we return
+	 * deleted items, and if we are latching pairs of pages.  In addition,
+	 * if we're modifying record numbers, we have to latch the entire tree
+	 * regardless.  See btree.h for more details.
+	 */
+
+	start_pgno = saved_pg = root_pgno;
+	saved_level = MAXBTREELEVEL;
+retry:	if ((ret = __bam_get_root(dbc, start_pgno, slevel, flags, &stack)) != 0)
+		goto err;
+	lock_mode = cp->csp->lock_mode;
+	get_mode = lock_mode == DB_LOCK_WRITE ? DB_MPOOL_DIRTY : 0;
+	h = cp->csp->page;
+	root_pgno = pg = PGNO(h);
+	lock = cp->csp->lock;
+	set_stack = stack;
+	/*
+	 * Determine if we need to lock interior nodes.
+	 * If we have record numbers we always lock.  Otherwise we only
+	 * need to do this if we are write locking and we are returning
+	 * a stack of nodes.  SR_NEXT will eventually get a stack and
+	 * release the locks above that level.
+	 */
+	if (F_ISSET(dbc, DBC_DOWNREV)) {
+		getlock = 1;
+		wait = 0;
+	} else
+		getlock = F_ISSET(cp, C_RECNUM) ||
+		   (lock_mode == DB_LOCK_WRITE &&
+		   (stack || LF_ISSET(SR_NEXT | SR_DEL)));
+
+	/*
+	 * If we are asked a level that is above the root,
+	 * just return the root.  This can happen if the tree
+	 * collapses while we are trying to lock the root.
+	 */
+	if (!LF_ISSET(SR_START) && LEVEL(h) < slevel)
+		goto done;
+
+	BT_STK_CLR(cp);
+
+	/* Choose a comparison function. */
+	func = F_ISSET(dbc, DBC_OPD) ?
+	    (dbp->dup_compare == NULL ? __bam_defcmp : dbp->dup_compare) :
+	    t->bt_compare;
+
+	for (;;) {
+		if (TYPE(h) == P_LBTREE)
+			adjust = P_INDX;
+		else {
+			/*
+			 * It is possible to catch an internal page as a change
+			 * is being backed out.  Its leaf pages will be locked
+			 * but we must be sure we get to one.  If the page
+			 * is not populated enough lock it.
+			 */
+			if (TYPE(h) != P_LDUP && NUM_ENT(h) == 0) {
+				getlock = 1;
+				level = LEVEL(h) + 1;
+				if ((ret = __memp_fput(mpf, dbc->thread_info,
+				     h, dbc->priority)) != 0)
+					goto err;
+				goto lock_next;
+			}
+			adjust = O_INDX;
+		}
+		inp = P_INP(dbp, h);
+		if (LF_ISSET(SR_MIN | SR_MAX)) {
+			if (LF_ISSET(SR_MIN) || NUM_ENT(h) == 0)
+				indx = 0;
+			else if (TYPE(h) == P_LBTREE)
+				indx = NUM_ENT(h) - 2;
+			else
+				indx = NUM_ENT(h) - 1;
+
+			if (LEVEL(h) == LEAFLEVEL ||
+			     (!LF_ISSET(SR_START) && LEVEL(h) == slevel)) {
+				if (LF_ISSET(SR_NEXT))
+					goto get_next;
+				goto found;
+			}
+			goto next;
+		}
+		/*
+		 * Do a binary search on the current page.  If we're searching
+		 * a Btree leaf page, we have to walk the indices in groups of
+		 * two.  If we're searching an internal page or a off-page dup
+		 * page, they're an index per page item.  If we find an exact
+		 * match on a leaf page, we're done.
+		 */
+		DB_BINARY_SEARCH_FOR(base, lim, NUM_ENT(h), adjust) {
+			DB_BINARY_SEARCH_INCR(indx, base, lim, adjust);
+			if ((ret = __bam_cmp(dbc, key, h, indx,
+			    func, &cmp)) != 0)
+				goto err;
+			if (cmp == 0) {
+				if (LEVEL(h) == LEAFLEVEL ||
+				    (!LF_ISSET(SR_START) &&
+				    LEVEL(h) == slevel)) {
+					if (LF_ISSET(SR_NEXT))
+						goto get_next;
+					goto found;
+				}
+				goto next;
+			}
+			if (cmp > 0)
+				DB_BINARY_SEARCH_SHIFT_BASE(indx, base,
+				    lim, adjust);
+		}
+
+		/*
+		 * No match found.  Base is the smallest index greater than
+		 * key and may be zero or a last + O_INDX index.
+		 *
+		 * If it's a leaf page or the stopping point,
+		 * return base as the "found" value.
+		 * Delete only deletes exact matches.
+		 */
+		if (LEVEL(h) == LEAFLEVEL ||
+		    (!LF_ISSET(SR_START) && LEVEL(h) == slevel)) {
+			*exactp = 0;
+
+			if (LF_ISSET(SR_EXACT)) {
+				ret = DB_NOTFOUND;
+				goto err;
+			}
+
+			if (LF_ISSET(SR_STK_ONLY)) {
+				BT_STK_NUM(env, cp, h, base, ret);
+				if ((t_ret =
+				    __LPUT(dbc, lock)) != 0 && ret == 0)
+					ret = t_ret;
+				if ((t_ret = __memp_fput(mpf, dbc->thread_info,
+				     h, dbc->priority)) != 0 && ret == 0)
+					ret = t_ret;
+				h = NULL;
+				if (ret != 0)
+					goto err;
+				goto done;
+			}
+			if (LF_ISSET(SR_NEXT)) {
+get_next:			/*
+				 * The caller could have asked for a NEXT
+				 * at the root if the tree recently collapsed.
+				 */
+				if (PGNO(h) == root_pgno) {
+					ret = DB_NOTFOUND;
+					goto err;
+				}
+
+				indx = cp->sp->indx + 1;
+				if (indx == NUM_ENT(cp->sp->page)) {
+					ret = DB_NOTFOUND;
+					cp->csp++;
+					goto err;
+				}
+				/*
+				 * If we want both the key page and the next
+				 * page, push the key page on the stack
+				 * otherwise save the root of the subtree
+				 * and drop the rest of the subtree.
+				 * Search down again starting at the
+				 * next child of the root of this subtree.
+				 */
+				LF_SET(SR_MIN);
+				LF_CLR(SR_NEXT);
+				set_stack = stack = 1;
+				if (LF_ISSET(SR_BOTH)) {
+					cp->csp++;
+					BT_STK_PUSH(env,
+					    cp, h, indx, lock, lock_mode, ret);
+					if (ret != 0)
+						goto err;
+					LOCK_INIT(lock);
+					h = cp->sp->page;
+					pg = GET_BINTERNAL(dbp, h, indx)->pgno;
+					level = LEVEL(h);
+					h = NULL;
+					goto lock_next;
+				} else {
+					if ((ret = __LPUT(dbc, lock)) != 0)
+						goto err;
+					if ((ret = __memp_fput(mpf,
+					    dbc->thread_info,
+					    h, dbc->priority)) != 0)
+						goto err;
+					h = cp->sp->page;
+					cp->sp->page = NULL;
+					lock = cp->sp->lock;
+					LOCK_INIT(cp->sp->lock);
+					if ((ret = __bam_stkrel(dbc,
+					    STK_NOLOCK)) != 0)
+						goto err;
+					goto next;
+				}
+			}
+
+			/*
+			 * !!!
+			 * Possibly returning a deleted record -- DB_SET_RANGE,
+			 * DB_KEYFIRST and DB_KEYLAST don't require an exact
+			 * match, and we don't want to walk multiple pages here
+			 * to find an undeleted record.  This is handled by the
+			 * calling routine.
+			 */
+			if (LF_ISSET(SR_DEL) && cp->csp == cp->sp)
+				cp->csp++;
+			BT_STK_ENTER(env, cp, h, base, lock, lock_mode, ret);
+			if (ret != 0)
+				goto err;
+			goto done;
+		}
+
+		/*
+		 * If it's not a leaf page, record the internal page (which is
+		 * a parent page for the key).  Decrement the base by 1 if it's
+		 * non-zero so that if a split later occurs, the inserted page
+		 * will be to the right of the saved page.
+		 */
+		indx = base > 0 ? base - O_INDX : base;
+
+		/*
+		 * If we're trying to calculate the record number, sum up
+		 * all the record numbers on this page up to the indx point.
+		 */
+next:		if (recnop != NULL)
+			for (i = 0; i < indx; ++i)
+				recno += GET_BINTERNAL(dbp, h, i)->nrecs;
+
+		pg = GET_BINTERNAL(dbp, h, indx)->pgno;
+		level = LEVEL(h);
+
+		/* See if we are at the level to start stacking. */
+		if (LF_ISSET(SR_START) && slevel == level)
+			set_stack = stack = 1;
+
+		if (LF_ISSET(SR_STK_ONLY)) {
+			if (slevel == LEVEL(h)) {
+				BT_STK_NUM(env, cp, h, indx, ret);
+				if ((t_ret = __memp_fput(mpf, dbc->thread_info,
+				    h, dbc->priority)) != 0 && ret == 0)
+					ret = t_ret;
+				h = NULL;
+				if (ret != 0)
+					goto err;
+				goto done;
+			}
+			BT_STK_NUMPUSH(env, cp, h, indx, ret);
+			(void)__memp_fput(mpf,
+			    dbc->thread_info, h, dbc->priority);
+			h = NULL;
+		} else if (stack) {
+			/* Return if this is the lowest page wanted. */
+			if (LF_ISSET(SR_PARENT) && slevel == level) {
+				BT_STK_ENTER(env,
+				    cp, h, indx, lock, lock_mode, ret);
+				if (ret != 0)
+					goto err;
+				goto done;
+			}
+			if (LF_ISSET(SR_DEL) && NUM_ENT(h) > 1) {
+				/*
+				 * There was a page with a singleton pointer
+				 * to a non-empty subtree.
+				 */
+				cp->csp--;
+				if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0)
+					goto err;
+				set_stack = stack = 0;
+				goto do_del;
+			}
+			BT_STK_PUSH(env,
+			    cp, h, indx, lock, lock_mode, ret);
+			if (ret != 0)
+				goto err;
+
+			LOCK_INIT(lock);
+			get_mode = DB_MPOOL_DIRTY;
+			lock_mode = DB_LOCK_WRITE;
+			getlock = 1;
+			goto lock_next;
+		} else {
+			/*
+			 * Decide if we want to return a reference to the next
+			 * page in the return stack.  If so, latch it and don't
+			 * unlatch it.  We will want to stack things on the
+			 * next iteration.  The stack variable cannot be
+			 * set until we leave this clause. If we are locking
+			 * then we must lock this level before getting the page.
+			 */
+			if ((LF_ISSET(SR_PARENT) &&
+			    (u_int8_t)(slevel + 1) >= (level - 1)) ||
+			    (level - 1) == LEAFLEVEL)
+				set_stack = 1;
+
+			/*
+			 * Check for a normal search.  If so, we need to
+			 * latch couple the parent/chid buffers.
+			 */
+			if (!LF_ISSET(SR_DEL | SR_NEXT)) {
+				parent_h = h;
+				goto lock_next;
+			}
+
+			/*
+			 * Returning a subtree.  See if we have hit the start
+			 * point if so save the parent and set stack.
+			 * Otherwise free the parent and temporarily
+			 * save this one.
+			 * For SR_DEL we need to find a page with 1 entry.
+			 * For SR_NEXT we want find the minimal subtree
+			 * that contains the key and the next page.
+			 * We save pages as long as we are at the right
+			 * edge of the subtree.  When we leave the right
+			 * edge, then drop the subtree.
+			 */
+
+			if ((LF_ISSET(SR_DEL) && NUM_ENT(h) == 1)) {
+				/*
+				 * We are pushing the things on the stack,
+				 * set the stack variable now to indicate this
+				 * has happened.
+				 */
+				stack = set_stack = 1;
+				LF_SET(SR_WRITE);
+				/* Push the parent. */
+				cp->csp++;
+				/* Push this node. */
+				BT_STK_PUSH(env, cp, h,
+				     indx, lock, DB_LOCK_NG, ret);
+				if (ret != 0)
+					goto err;
+				LOCK_INIT(lock);
+			} else {
+			/*
+			 * See if we want to save the tree so far.
+			 * If we are looking for the next key,
+			 * then we must save this node if we are
+			 * at the end of the page.  If not then
+			 * discard anything we have saved so far.
+			 * For delete only keep one node until
+			 * we find a singleton.
+			 */
+do_del:				if (cp->csp->page != NULL) {
+					if (LF_ISSET(SR_NEXT) &&
+					     indx == NUM_ENT(h) - 1)
+						cp->csp++;
+					else if ((ret =
+					    __bam_stkrel(dbc, STK_NOLOCK)) != 0)
+						goto err;
+				}
+				/* Save this node. */
+				BT_STK_ENTER(env, cp,
+				    h, indx, lock, lock_mode, ret);
+				if (ret != 0)
+					goto err;
+				LOCK_INIT(lock);
+			}
+
+lock_next:		h = NULL;
+
+			if (set_stack && LF_ISSET(SR_WRITE)) {
+				lock_mode = DB_LOCK_WRITE;
+				get_mode = DB_MPOOL_DIRTY;
+				getlock = 1;
+			}
+			/*
+			 * If we are retrying and we are back at the same
+			 * page then we already have it locked.  If we are
+			 * at a different page we want to lock couple and
+			 * release that lock.
+			 */
+			if (level - 1 == saved_level) {
+				if ((ret = __LPUT(dbc, lock)) != 0)
+					goto err;
+				lock = saved_lock;
+				LOCK_INIT(saved_lock);
+				saved_level = MAXBTREELEVEL;
+				if (pg == saved_pg)
+					goto skip_lock;
+			}
+			if ((getlock || level - 1 == LEAFLEVEL) &&
+			    (ret = __db_lget(dbc, LCK_COUPLE_ALWAYS,
+			    pg, lock_mode, wait, &lock)) != 0) {
+				/*
+				 * If we are doing DEL or NEXT then we
+				 * have an extra level saved in the stack,
+				 * push it so it will get freed.
+				 */
+				if (LF_ISSET(SR_DEL | SR_NEXT) && !stack)
+					cp->csp++;
+				PERFMON6(env, race, bam_search, dbp->fname,
+				    dbp->dname, ret, h, parent_h, flags);
+				/*
+				 * If we fail, discard the lock we held.
+				 * This is ok because we will either search
+				 * again or exit without actually looking
+				 * at the data.
+				 */
+				if ((t_ret = __LPUT(dbc, lock)) != 0)
+					ret = t_ret;
+				/*
+				 * If we blocked at a different level release
+				 * the previous saved lock.
+				 */
+				if ((t_ret = __LPUT(dbc, saved_lock)) != 0 &&
+				    ret == 0)
+					ret = t_ret;
+				if (wait == 0 || (ret != DB_LOCK_NOTGRANTED &&
+				     ret != DB_LOCK_DEADLOCK))
+					goto err;
+
+				/* Release the parent if we are holding it. */
+				if (parent_h != NULL &&
+				    (ret = __memp_fput(mpf, dbc->thread_info,
+				    parent_h, dbc->priority)) != 0)
+					goto err;
+				parent_h = NULL;
+
+				BT_STK_POP(cp);
+				if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0)
+					goto err;
+				if ((ret = __db_lget(dbc,
+				    0, pg, lock_mode, 0, &saved_lock)) != 0)
+					goto err;
+				/*
+				 * A very strange case: if this page was
+				 * freed while we wait then we cannot hold
+				 * the lock on it while we reget the root
+				 * latch because allocation is one place
+				 * we lock while holding a latch.
+				 * We want to hold the lock but must ensure
+				 * that the page is not free or cannot become
+				 * free.  If we are at the LEAF level we can
+				 * hold on to the lock if the page is still
+				 * of the right type.  Otherwise we need to
+				 * be sure this page cannot move to an off page
+				 * duplicate tree (which are not locked) and
+				 * masquerade as the page we want.
+				 */
+
+				/*
+				 * If the page is not at leaf level
+				 * then see if OPD trees are around.
+				 * If the page could appear as an
+				 * interior offpage duplicate node
+				 * at the right level the it will
+				 * not be locked and subsequently be
+				 * freed. If there are multiple
+				 * databases in the file then they
+				 * could have OPDs.
+				 */
+				if (level - 1 > LEAFLEVEL &&
+				    (F_ISSET(dbp, DB_AM_SUBDB) ||
+				    (dbp->type == DB_BTREE &&
+				    F_ISSET(dbp, DB_AM_DUPSORT))))
+					goto drop_lock;
+
+				/*
+				 * Take a look at the page.  If it got
+				 * freed it could be very gone.
+				 */
+				if ((ret = __memp_fget(mpf, &pg,
+				     dbc->thread_info, dbc->txn, 0, &h)) != 0 &&
+				     ret != DB_PAGE_NOTFOUND)
+					goto err;
+
+				/*
+				 * Check for right level and page type.
+				 */
+				if (ret != 0 || LEVEL(h) != level - 1 ||
+				    (LEVEL(h) == LEAFLEVEL ?
+				    TYPE(h) != (dbc->dbtype == DB_BTREE ?
+				    P_LBTREE : P_LRECNO) :
+				    TYPE(h) != (dbc->dbtype == DB_BTREE ?
+				    P_IBTREE : P_IRECNO))) {
+drop_lock:				ret = __LPUT(dbc, saved_lock);
+					if (ret != 0)
+						goto err;
+					pg = root_pgno;
+					saved_level = MAXBTREELEVEL;
+				}
+				if (h != NULL && (ret = __memp_fput(mpf,
+				    dbc->thread_info, h, dbc->priority)) != 0)
+					goto err;
+				h = NULL;
+
+				if (was_next) {
+					LF_CLR(SR_MIN);
+					LF_SET(SR_NEXT);
+				}
+				/*
+				 * We have the lock but we dropped the
+				 * latch so we need to search again. If
+				 * we get back to the same page then all
+				 * is good, otherwise we need to try to
+				 * lock the new page.
+				 */
+				saved_pg = pg;
+				saved_level = level - 1;
+				goto retry;
+			}
+skip_lock:		stack = set_stack;
+		}
+		/* Get the child page. */
+		if ((ret = __memp_fget(mpf, &pg,
+		     dbc->thread_info, dbc->txn, get_mode, &h)) != 0)
+			goto err;
+		/* Release the parent. */
+		if (parent_h != NULL && (ret = __memp_fput(mpf,
+		    dbc->thread_info, parent_h, dbc->priority)) != 0)
+			goto err;
+		parent_h = NULL;
+	}
+	/* NOTREACHED */
+
+found:	*exactp = 1;
+
+	/*
+	 * If we got here, we know that we have a Btree leaf or off-page
+	 * duplicates page.  If it's a Btree leaf page, we have to handle
+	 * on-page duplicates.
+	 *
+	 * If there are duplicates, go to the first/last one.  This is
+	 * safe because we know that we're not going to leave the page,
+	 * all duplicate sets that are not on overflow pages exist on a
+	 * single leaf page.
+	 */
+	if (TYPE(h) == P_LBTREE && NUM_ENT(h) > P_INDX) {
+		if (LF_ISSET(SR_DUPLAST))
+			while (indx < (db_indx_t)(NUM_ENT(h) - P_INDX) &&
+			    inp[indx] == inp[indx + P_INDX])
+				indx += P_INDX;
+		else if (LF_ISSET(SR_DUPFIRST))
+			while (indx > 0 &&
+			    inp[indx] == inp[indx - P_INDX])
+				indx -= P_INDX;
+	}
+
+	/*
+	 * Now check if we are allowed to return deleted items; if not, then
+	 * find the next (or previous) non-deleted duplicate entry.  (We do
+	 * not move from the original found key on the basis of the SR_DELNO
+	 * flag.)
+	 */
+	DB_ASSERT(env, recnop == NULL || LF_ISSET(SR_DELNO));
+	if (LF_ISSET(SR_DELNO)) {
+		deloffset = TYPE(h) == P_LBTREE ? O_INDX : 0;
+		if (LF_ISSET(SR_DUPLAST))
+			while (B_DISSET(GET_BKEYDATA(dbp,
+			    h, indx + deloffset)->type) && indx > 0 &&
+			    inp[indx] == inp[indx - adjust])
+				indx -= adjust;
+		else
+			while (B_DISSET(GET_BKEYDATA(dbp,
+			    h, indx + deloffset)->type) &&
+			    indx < (db_indx_t)(NUM_ENT(h) - adjust) &&
+			    inp[indx] == inp[indx + adjust])
+				indx += adjust;
+
+		/*
+		 * If we weren't able to find a non-deleted duplicate, return
+		 * DB_NOTFOUND.
+		 */
+		if (B_DISSET(GET_BKEYDATA(dbp, h, indx + deloffset)->type)) {
+			ret = DB_NOTFOUND;
+			goto err;
+		}
+
+		/*
+		 * Increment the record counter to point to the found element.
+		 * Ignore any deleted key/data pairs.  There doesn't need to
+		 * be any correction for duplicates, as Btree doesn't support
+		 * duplicates and record numbers in the same tree.
+		 */
+		if (recnop != NULL) {
+			DB_ASSERT(env, TYPE(h) == P_LBTREE);
+
+			for (i = 0; i < indx; i += P_INDX)
+				if (!B_DISSET(
+				    GET_BKEYDATA(dbp, h, i + O_INDX)->type))
+					++recno;
+
+			/* Correct the number for a 0-base. */
+			*recnop = recno + 1;
+		}
+	}
+
+	if (LF_ISSET(SR_STK_ONLY)) {
+		BT_STK_NUM(env, cp, h, indx, ret);
+		if ((t_ret = __memp_fput(mpf,
+		     dbc->thread_info, h, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+		h = NULL;
+	} else {
+		if (LF_ISSET(SR_DEL) && cp->csp == cp->sp)
+			cp->csp++;
+		BT_STK_ENTER(env, cp, h, indx, lock, lock_mode, ret);
+	}
+	if (ret != 0)
+		goto err;
+
+	cp->csp->lock = lock;
+	DB_ASSERT(env, parent_h == NULL);
+
+done:
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_ON(dbc->thread_info);
+
+	if ((ret = __LPUT(dbc, saved_lock)) != 0)
+		return (ret);
+
+	return (0);
+
+err:	if (ret == 0)
+		ret = t_ret;
+	if (h != NULL && (t_ret = __memp_fput(mpf,
+	    dbc->thread_info, h, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	if (parent_h != NULL && (t_ret = __memp_fput(mpf,
+	    dbc->thread_info, parent_h, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Keep any not-found page locked for serializability. */
+	if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0)
+		ret = t_ret;
+
+	(void)__LPUT(dbc, saved_lock);
+
+	BT_STK_POP(cp);
+	(void)__bam_stkrel(dbc, 0);
+
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_ON(dbc->thread_info);
+
+	return (ret);
+}
+
+/*
+ * __bam_stkrel --
+ *	Release all pages currently held in the stack.
+ *
+ * PUBLIC: int __bam_stkrel __P((DBC *, u_int32_t));
+ */
+int
+__bam_stkrel(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DB_MPOOLFILE *mpf;
+	EPG *epg;
+	int ret, t_ret;
+
+	DB_ASSERT(NULL, dbc != NULL);
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	/*
+	 * Release inner pages first.
+	 *
+	 * The caller must be sure that setting STK_NOLOCK will not effect
+	 * either serializability or recoverability.
+	 */
+	for (ret = 0, epg = cp->sp; epg <= cp->csp; ++epg) {
+		if (epg->page != NULL) {
+			if (LF_ISSET(STK_CLRDBC) && cp->page == epg->page) {
+				cp->page = NULL;
+				LOCK_INIT(cp->lock);
+			}
+			if ((t_ret = __memp_fput(mpf, dbc->thread_info,
+			     epg->page, dbc->priority)) != 0 && ret == 0)
+				ret = t_ret;
+			epg->page = NULL;
+		}
+		/*
+		 * We set this if we need to release our pins,
+		 * but are not logically ready to have the pages
+		 * visible.
+		 */
+		if (LF_ISSET(STK_PGONLY))
+			continue;
+		if (LF_ISSET(STK_NOLOCK) &&
+		    (epg->lock.mode == DB_LOCK_READ ||
+		    atomic_read(&mpf->mfp->multiversion) == 0)) {
+			if ((t_ret = __LPUT(dbc, epg->lock)) != 0 && ret == 0)
+				ret = t_ret;
+		} else
+			if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0)
+				ret = t_ret;
+	}
+
+	/* Clear the stack, all pages have been released. */
+	if (!LF_ISSET(STK_PGONLY))
+		BT_STK_CLR(cp);
+
+	return (ret);
+}
+
+/*
+ * __bam_stkgrow --
+ *	Grow the stack.
+ *
+ * PUBLIC: int __bam_stkgrow __P((ENV *, BTREE_CURSOR *));
+ */
+int
+__bam_stkgrow(env, cp)
+	ENV *env;
+	BTREE_CURSOR *cp;
+{
+	EPG *p;
+	size_t entries;
+	int ret;
+
+	entries = cp->esp - cp->sp;
+
+	if ((ret = __os_calloc(env, entries * 2, sizeof(EPG), &p)) != 0)
+		return (ret);
+	memcpy(p, cp->sp, entries * sizeof(EPG));
+	if (cp->sp != cp->stack)
+		__os_free(env, cp->sp);
+	cp->sp = p;
+	cp->csp = p + entries;
+	cp->esp = p + entries * 2;
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_split.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1354 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/btree.h"
+
+static int __bam_page __P((DBC *, EPG *, EPG *));
+static int __bam_psplit __P((DBC *, EPG *, PAGE *, PAGE *, db_indx_t *));
+static int __bam_root __P((DBC *, EPG *));
+
+/*
+ * __bam_split --
+ *	Split a page.
+ *
+ * PUBLIC: int __bam_split __P((DBC *, void *, db_pgno_t *));
+ */
+int
+__bam_split(dbc, arg, root_pgnop)
+	DBC *dbc;
+	void *arg;
+	db_pgno_t *root_pgnop;
+{
+	BTREE_CURSOR *cp;
+	DB_LOCK metalock, next_lock;
+	enum { UP, DOWN } dir;
+	db_pgno_t pgno, next_pgno, root_pgno;
+	int exact, level, ret;
+
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_OFF(dbc->thread_info);
+
+	cp = (BTREE_CURSOR *)dbc->internal;
+	LOCK_INIT(next_lock);
+	next_pgno = PGNO_INVALID;
+
+	/*
+	 * First get a lock on the metadata page, we will have to allocate
+	 * pages and cannot get a lock while we have the search tree pinned.
+	 */
+
+	pgno = PGNO_BASE_MD;
+	if ((ret = __db_lget(dbc,
+	    0, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0)
+		goto err;
+	root_pgno = BAM_ROOT_PGNO(dbc);
+
+	/*
+	 * The locking protocol we use to avoid deadlock to acquire locks by
+	 * walking down the tree, but we do it as lazily as possible, locking
+	 * the root only as a last resort.  We expect all stack pages to have
+	 * been discarded before we're called; we discard all short-term locks.
+	 *
+	 * When __bam_split is first called, we know that a leaf page was too
+	 * full for an insert.  We don't know what leaf page it was, but we
+	 * have the key/recno that caused the problem.  We call XX_search to
+	 * reacquire the leaf page, but this time get both the leaf page and
+	 * its parent, locked.  We then split the leaf page and see if the new
+	 * internal key will fit into the parent page.  If it will, we're done.
+	 *
+	 * If it won't, we discard our current locks and repeat the process,
+	 * only this time acquiring the parent page and its parent, locked.
+	 * This process repeats until we succeed in the split, splitting the
+	 * root page as the final resort.  The entire process then repeats,
+	 * as necessary, until we split a leaf page.
+	 *
+	 * XXX
+	 * A traditional method of speeding this up is to maintain a stack of
+	 * the pages traversed in the original search.  You can detect if the
+	 * stack is correct by storing the page's LSN when it was searched and
+	 * comparing that LSN with the current one when it's locked during the
+	 * split.  This would be an easy change for this code, but I have no
+	 * numbers that indicate it's worthwhile.
+	 */
+	for (dir = UP, level = LEAFLEVEL;; dir == UP ? ++level : --level) {
+		/*
+		 * Acquire a page and its parent, locked.
+		 */
+retry:		if ((ret = (dbc->dbtype == DB_BTREE ?
+		    __bam_search(dbc, PGNO_INVALID,
+			arg, SR_WRPAIR, level, NULL, &exact) :
+		    __bam_rsearch(dbc,
+			(db_recno_t *)arg, SR_WRPAIR, level, &exact))) != 0)
+			break;
+
+		if (cp->csp[0].page->pgno == root_pgno) {
+			/* we can overshoot the top of the tree. */
+			level = cp->csp[0].page->level;
+			if (root_pgnop != NULL)
+				*root_pgnop = root_pgno;
+		} else if (root_pgnop != NULL)
+			*root_pgnop = cp->csp[-1].page->pgno;
+
+		/*
+		 * Split the page if it still needs it (it's possible another
+		 * thread of control has already split the page).  If we are
+		 * guaranteed that two items will fit on the page, the split
+		 * is no longer necessary.
+		 */
+		if (2 * B_MAXSIZEONPAGE(cp->ovflsize)
+		    <= (db_indx_t)P_FREESPACE(dbc->dbp, cp->csp[0].page)) {
+			if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0)
+				goto err;
+			goto no_split;
+		}
+
+		/*
+		 * We need to try to lock the next page so we can update
+		 * its PREV.
+		 */
+		if (ISLEAF(cp->csp->page) &&
+		    (pgno = NEXT_PGNO(cp->csp->page)) != PGNO_INVALID) {
+			TRY_LOCK(dbc, pgno,
+			     next_pgno, next_lock, DB_LOCK_WRITE, retry);
+			if (ret != 0)
+				goto err;
+		}
+		ret = cp->csp[0].page->pgno == root_pgno ?
+		    __bam_root(dbc, &cp->csp[0]) :
+		    __bam_page(dbc, &cp->csp[-1], &cp->csp[0]);
+		BT_STK_CLR(cp);
+
+		switch (ret) {
+		case 0:
+no_split:		/* Once we've split the leaf page, we're done. */
+			if (level == LEAFLEVEL)
+				goto done;
+
+			/* Switch directions. */
+			if (dir == UP)
+				dir = DOWN;
+			break;
+		case DB_NEEDSPLIT:
+			/*
+			 * It's possible to fail to split repeatedly, as other
+			 * threads may be modifying the tree, or the page usage
+			 * is sufficiently bad that we don't get enough space
+			 * the first time.
+			 */
+			if (dir == DOWN)
+				dir = UP;
+			break;
+		default:
+			goto err;
+		}
+	}
+
+	if (root_pgnop != NULL)
+		*root_pgnop = BAM_ROOT_PGNO(dbc);
+err:
+done:	(void)__LPUT(dbc, metalock);
+	(void)__TLPUT(dbc, next_lock);
+
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_ON(dbc->thread_info);
+	return (ret);
+}
+
+/*
+ * __bam_root --
+ *	Split the root page of a btree.
+ */
+static int
+__bam_root(dbc, cp)
+	DBC *dbc;
+	EPG *cp;
+{
+	DB *dbp;
+	DBT log_dbt, rootent[2];
+	DB_LOCK llock, rlock;
+	DB_LSN log_lsn;
+	DB_MPOOLFILE *mpf;
+	PAGE *lp, *rp;
+	db_indx_t split;
+	u_int32_t opflags;
+	int ret, t_ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	lp = rp = NULL;
+	LOCK_INIT(llock);
+	LOCK_INIT(rlock);
+	COMPQUIET(log_dbt.data, NULL);
+
+	/* Yeah, right. */
+	if (cp->page->level >= MAXBTREELEVEL) {
+		__db_errx(dbp->env, DB_STR_A("1021",
+		    "Too many btree levels: %d", "%d"), cp->page->level);
+		return (ENOSPC);
+	}
+
+	if ((ret = __memp_dirty(mpf,
+	    &cp->page, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+		goto err;
+
+	/* Create new left and right pages for the split. */
+	if ((ret = __db_new(dbc, TYPE(cp->page), &llock, &lp)) != 0 ||
+	    (ret = __db_new(dbc, TYPE(cp->page), &rlock, &rp)) != 0)
+		goto err;
+	P_INIT(lp, dbp->pgsize, lp->pgno,
+	    PGNO_INVALID, ISINTERNAL(cp->page) ? PGNO_INVALID : rp->pgno,
+	    cp->page->level, TYPE(cp->page));
+	P_INIT(rp, dbp->pgsize, rp->pgno,
+	    ISINTERNAL(cp->page) ?  PGNO_INVALID : lp->pgno, PGNO_INVALID,
+	    cp->page->level, TYPE(cp->page));
+
+	PERFMON5(env, alloc, btree_split,
+	    dbp->fname, dbp->dname, lp->pgno, cp->page->pgno, lp->level);
+
+	/* Split the page. */
+	if ((ret = __bam_psplit(dbc, cp, lp, rp, &split)) != 0)
+		goto err;
+
+	if (DBC_LOGGING(dbc)) {
+		memset(&log_dbt, 0, sizeof(log_dbt));
+		if ((ret =
+		    __os_malloc(dbp->env, dbp->pgsize, &log_dbt.data)) != 0)
+			goto err;
+		log_dbt.size = dbp->pgsize;
+		memcpy(log_dbt.data, cp->page, dbp->pgsize);
+	}
+
+	/* Clean up the new root page. */
+	if ((ret = (dbc->dbtype == DB_RECNO ?
+	    __ram_root(dbc, cp->page, lp, rp) :
+	    __bam_broot(dbc, cp->page, split, lp, rp))) != 0) {
+		if (DBC_LOGGING(dbc))
+			__os_free(dbp->env, log_dbt.data);
+		goto err;
+	}
+
+	/* Log the change. */
+	if (DBC_LOGGING(dbc)) {
+		memset(rootent, 0, sizeof(rootent));
+		rootent[0].data = GET_BINTERNAL(dbp, cp->page, 0);
+		rootent[1].data = GET_BINTERNAL(dbp, cp->page, 1);
+		if (dbc->dbtype == DB_RECNO)
+			rootent[0].size = rootent[1].size = RINTERNAL_SIZE;
+		else {
+			rootent[0].size = BINTERNAL_SIZE(
+			    ((BINTERNAL *)rootent[0].data)->len);
+			rootent[1].size = BINTERNAL_SIZE(
+			    ((BINTERNAL *)rootent[1].data)->len);
+		}
+		ZERO_LSN(log_lsn);
+		opflags = F_ISSET(
+		    (BTREE_CURSOR *)dbc->internal, C_RECNUM) ? SPL_NRECS : 0;
+		if (dbc->dbtype == DB_RECNO)
+			opflags |= SPL_RECNO;
+		ret = __bam_split_log(dbp, dbc->txn, &LSN(cp->page), 0,
+		    OP_SET(opflags, cp->page), PGNO(lp), &LSN(lp),
+		    PGNO(rp), &LSN(rp), (u_int32_t)NUM_ENT(lp),
+		    PGNO_INVALID, &log_lsn, PGNO(cp->page),
+		    &LSN(cp->page), 0, &log_dbt, &rootent[0], &rootent[1]);
+
+		/* On failure, restore the page. */
+		if (ret != 0)
+			memcpy(cp->page, log_dbt.data, dbp->pgsize);
+		__os_free(dbp->env, log_dbt.data);
+
+		if (ret != 0)
+			goto err;
+	} else
+		LSN_NOT_LOGGED(LSN(cp->page));
+	LSN(lp) = LSN(cp->page);
+	LSN(rp) = LSN(cp->page);
+
+	/* Adjust any cursors. */
+	ret = __bam_ca_split(dbc, cp->page->pgno, lp->pgno, rp->pgno, split, 1);
+
+	/* Success or error: release pages and locks. */
+err:	if (cp->page != NULL && (t_ret = __memp_fput(mpf,
+	     dbc->thread_info, cp->page, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	cp->page = NULL;
+
+	/*
+	 * We are done.  Put or downgrade all our locks and release
+	 * the pages.
+	 */
+	if ((t_ret = __TLPUT(dbc, llock)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __TLPUT(dbc, rlock)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __TLPUT(dbc, cp->lock)) != 0 && ret == 0)
+		ret = t_ret;
+	if (lp != NULL && (t_ret = __memp_fput(mpf,
+	     dbc->thread_info, lp, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	if (rp != NULL && (t_ret = __memp_fput(mpf,
+	     dbc->thread_info, rp, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __bam_page --
+ *	Split the non-root page of a btree.
+ */
+static int
+__bam_page(dbc, pp, cp)
+	DBC *dbc;
+	EPG *pp, *cp;
+{
+	BTREE_CURSOR *bc;
+	DB *dbp;
+	DBT log_dbt, rentry;
+	DB_LOCK rplock;
+	DB_LSN log_lsn;
+	DB_LSN save_lsn;
+	DB_MPOOLFILE *mpf;
+	PAGE *lp, *rp, *alloc_rp, *tp;
+	db_indx_t split;
+	u_int32_t opflags;
+	int ret, t_ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	alloc_rp = lp = rp = tp = NULL;
+	LOCK_INIT(rplock);
+	ret = -1;
+
+	/*
+	 * Create new left page for the split, and fill in everything
+	 * except its LSN and next-page page number.
+	 *
+	 * Create a new right page for the split, and fill in everything
+	 * except its LSN and page number.
+	 *
+	 * We malloc space for both the left and right pages, so we don't get
+	 * a new page from the underlying buffer pool until we know the split
+	 * is going to succeed.  The reason is that we can't release locks
+	 * acquired during the get-a-new-page process because metadata page
+	 * locks can't be discarded on failure since we may have modified the
+	 * free list.  So, if you assume that we're holding a write lock on the
+	 * leaf page which ran out of space and started this split (e.g., we
+	 * have already written records to the page, or we retrieved a record
+	 * from it with the DB_RMW flag set), failing in a split with both a
+	 * leaf page locked and the metadata page locked can potentially lock
+	 * up the tree badly, because we've violated the rule of always locking
+	 * down the tree, and never up.
+	 */
+	if ((ret = __os_malloc(dbp->env, dbp->pgsize * 2, &lp)) != 0)
+		goto err;
+	P_INIT(lp, dbp->pgsize, PGNO(cp->page),
+	    ISINTERNAL(cp->page) ?  PGNO_INVALID : PREV_PGNO(cp->page),
+	    ISINTERNAL(cp->page) ?  PGNO_INVALID : 0,
+	    cp->page->level, TYPE(cp->page));
+
+	rp = (PAGE *)((u_int8_t *)lp + dbp->pgsize);
+	P_INIT(rp, dbp->pgsize, 0,
+	    ISINTERNAL(cp->page) ? PGNO_INVALID : PGNO(cp->page),
+	    ISINTERNAL(cp->page) ? PGNO_INVALID : NEXT_PGNO(cp->page),
+	    cp->page->level, TYPE(cp->page));
+
+	/*
+	 * Split right.
+	 *
+	 * Only the indices are sorted on the page, i.e., the key/data pairs
+	 * aren't, so it's simpler to copy the data from the split page onto
+	 * two new pages instead of copying half the data to a new right page
+	 * and compacting the left page in place.  Since the left page can't
+	 * change, we swap the original and the allocated left page after the
+	 * split.
+	 */
+	if ((ret = __bam_psplit(dbc, cp, lp, rp, &split)) != 0)
+		goto err;
+
+	/*
+	 * Test to see if we are going to be able to insert the new pages into
+	 * the parent page.  The interesting failure here is that the parent
+	 * page can't hold the new keys, and has to be split in turn, in which
+	 * case we want to release all the locks we can.
+	 */
+	if ((ret = __bam_pinsert(dbc, pp, split, lp, rp, BPI_SPACEONLY)) != 0)
+		goto err;
+
+	/*
+	 * We've got everything locked down we need, and we know the split
+	 * is going to succeed.  Go and get the additional page we'll need.
+	 */
+	if ((ret = __db_new(dbc, TYPE(cp->page), &rplock, &alloc_rp)) != 0)
+		goto err;
+
+	/*
+	 * Prepare to fix up the previous pointer of any leaf page following
+	 * the split page.  Our caller has already write locked the page so
+	 * we can get it without deadlocking on the parent latch.
+	 */
+	if (ISLEAF(cp->page) && NEXT_PGNO(cp->page) != PGNO_INVALID &&
+	    (ret = __memp_fget(mpf, &NEXT_PGNO(cp->page),
+	    dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &tp)) != 0)
+		goto err;
+
+	PERFMON5(env, alloc, btree_split, dbp->fname,
+	    dbp->dname, cp->page->pgno, pp->page->pgno, cp->page->level);
+
+	/*
+	 * Fix up the page numbers we didn't have before.  We have to do this
+	 * before calling __bam_pinsert because it may copy a page number onto
+	 * the parent page and it takes the page number from its page argument.
+	 */
+	PGNO(rp) = NEXT_PGNO(lp) = PGNO(alloc_rp);
+
+	DB_ASSERT(dbp->env, IS_DIRTY(cp->page));
+	DB_ASSERT(dbp->env, IS_DIRTY(pp->page));
+
+	bc = (BTREE_CURSOR *)dbc->internal;
+
+	/* Actually update the parent page. */
+	if ((ret = __bam_pinsert(dbc,
+	    pp, split, lp, rp, F_ISSET(bc, C_RECNUM) ? 0 : BPI_NOLOGGING)) != 0)
+		goto err;
+
+	/* Log the change. */
+	if (DBC_LOGGING(dbc)) {
+		memset(&log_dbt, 0, sizeof(log_dbt));
+		log_dbt.data = cp->page;
+		log_dbt.size = dbp->pgsize;
+		memset(&rentry, 0, sizeof(rentry));
+		rentry.data = GET_BINTERNAL(dbp, pp->page, pp->indx + 1);
+		opflags = F_ISSET(bc, C_RECNUM) ? SPL_NRECS : 0;
+		if (dbc->dbtype == DB_RECNO) {
+			opflags |= SPL_RECNO;
+			rentry.size = RINTERNAL_SIZE;
+		} else
+			rentry.size =
+			    BINTERNAL_SIZE(((BINTERNAL *)rentry.data)->len);
+		if (tp == NULL)
+			ZERO_LSN(log_lsn);
+		if ((ret = __bam_split_log(dbp, dbc->txn, &LSN(cp->page),
+		    0, OP_SET(opflags, pp->page), PGNO(cp->page),
+		    &LSN(cp->page), PGNO(alloc_rp), &LSN(alloc_rp),
+		    (u_int32_t)NUM_ENT(lp), tp == NULL ? 0 : PGNO(tp),
+		    tp == NULL ? &log_lsn : &LSN(tp), PGNO(pp->page),
+		    &LSN(pp->page), pp->indx, &log_dbt, NULL, &rentry)) != 0) {
+			/*
+			 * If this is not RECNO then undo the update
+			 * to the parent page, which has not been
+			 * logged yet. This must succeed.  Renco
+			 * database trees are locked and therefore
+			 * the parent can be logged independently.
+			 */
+			if (F_ISSET(bc, C_RECNUM) == 0) {
+				t_ret = __db_ditem_nolog(dbc, pp->page,
+				    pp->indx + 1, rentry.size);
+				DB_ASSERT(dbp->env, t_ret == 0);
+			}
+
+			goto err;
+		}
+
+	} else
+		LSN_NOT_LOGGED(LSN(cp->page));
+
+	/* Update the LSNs for all involved pages. */
+	LSN(alloc_rp) = LSN(cp->page);
+	LSN(lp) = LSN(cp->page);
+	LSN(rp) = LSN(cp->page);
+	LSN(pp->page) = LSN(cp->page);
+	if (tp != NULL) {
+		/* Log record has been written; so safe to update next page. */
+		PREV_PGNO(tp) = PGNO(rp);
+		LSN(tp) = LSN(cp->page);
+	}
+
+	/*
+	 * Copy the left and right pages into place.  There are two paths
+	 * through here.  Either we are logging and we set the LSNs in the
+	 * logging path.  However, if we are not logging, then we do not
+	 * have valid LSNs on lp or rp.  The correct LSNs to use are the
+	 * ones on the page we got from __db_new or the one that was
+	 * originally on cp->page.  In both cases, we save the LSN from the
+	 * real database page (not a malloc'd one) and reapply it after we
+	 * do the copy.
+	 */
+	save_lsn = alloc_rp->lsn;
+	memcpy(alloc_rp, rp, LOFFSET(dbp, rp));
+	memcpy((u_int8_t *)alloc_rp + HOFFSET(rp),
+	    (u_int8_t *)rp + HOFFSET(rp), dbp->pgsize - HOFFSET(rp));
+	alloc_rp->lsn = save_lsn;
+
+	save_lsn = cp->page->lsn;
+	memcpy(cp->page, lp, LOFFSET(dbp, lp));
+	memcpy((u_int8_t *)cp->page + HOFFSET(lp),
+	    (u_int8_t *)lp + HOFFSET(lp), dbp->pgsize - HOFFSET(lp));
+	cp->page->lsn = save_lsn;
+
+	/* Adjust any cursors. */
+	if ((ret = __bam_ca_split(dbc,
+	    PGNO(cp->page), PGNO(cp->page), PGNO(rp), split, 0)) != 0)
+		goto err;
+
+	__os_free(dbp->env, lp);
+
+	/*
+	 * Success -- write the real pages back to the store.
+	 */
+	if ((t_ret = __memp_fput(mpf,
+	    dbc->thread_info, alloc_rp, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __TLPUT(dbc, rplock)) != 0 && ret == 0)
+		ret = t_ret;
+	if (tp != NULL) {
+		if ((t_ret = __memp_fput(mpf,
+		    dbc->thread_info, tp, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+	if ((t_ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+
+err:	if (lp != NULL)
+		__os_free(dbp->env, lp);
+	if (alloc_rp != NULL)
+		(void)__memp_fput(mpf,
+		    dbc->thread_info, alloc_rp, dbc->priority);
+	if (tp != NULL)
+		(void)__memp_fput(mpf, dbc->thread_info, tp, dbc->priority);
+
+	if (pp->page != NULL)
+		(void)__memp_fput(mpf,
+		     dbc->thread_info, pp->page, dbc->priority);
+
+	if (ret == DB_NEEDSPLIT && atomic_read(&mpf->mfp->multiversion) == 0)
+		(void)__LPUT(dbc, pp->lock);
+	else
+		(void)__TLPUT(dbc, pp->lock);
+
+	(void)__memp_fput(mpf, dbc->thread_info, cp->page, dbc->priority);
+
+	/*
+	 * We don't drop the left and right page locks.  If we doing dirty
+	 * reads then we need to hold the locks until we abort the transaction.
+	 * If we are not transactional, we are hosed anyway as the tree
+	 * is trashed.  It may be better not to leak the locks.
+	 */
+
+	if (dbc->txn == NULL)
+		(void)__LPUT(dbc, rplock);
+
+	if (dbc->txn == NULL || ret == DB_NEEDSPLIT)
+		(void)__LPUT(dbc, cp->lock);
+
+	return (ret);
+}
+
+/*
+ * __bam_broot --
+ *	Fix up the btree root page after it has been split.
+ * PUBLIC: int __bam_broot __P((DBC *, PAGE *, u_int32_t, PAGE *, PAGE *));
+ */
+int
+__bam_broot(dbc, rootp, split, lp, rp)
+	DBC *dbc;
+	u_int32_t split;
+	PAGE *rootp, *lp, *rp;
+{
+	BINTERNAL bi, bi0, *child_bi;
+	BKEYDATA *child_bk;
+	BOVERFLOW bo, *child_bo;
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DBT hdr, hdr0, data;
+	db_pgno_t root_pgno;
+	int ret;
+
+	dbp = dbc->dbp;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	child_bo = NULL;
+	data.data = NULL;
+	memset(&bi, 0, sizeof(bi));
+
+	switch (TYPE(rootp)) {
+	case P_IBTREE:
+		/* Copy the first key of the child page onto the root page. */
+		child_bi = GET_BINTERNAL(dbp, rootp, split);
+		switch (B_TYPE(child_bi->type)) {
+		case B_KEYDATA:
+			bi.len = child_bi->len;
+			B_TSET(bi.type, B_KEYDATA);
+			bi.pgno = rp->pgno;
+			DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data));
+			if ((ret = __os_malloc(dbp->env,
+			    child_bi->len, &data.data)) != 0)
+				return (ret);
+			memcpy(data.data, child_bi->data, child_bi->len);
+			data.size = child_bi->len;
+			break;
+		case B_OVERFLOW:
+			/* Reuse the overflow key. */
+			child_bo = (BOVERFLOW *)child_bi->data;
+			memset(&bo, 0, sizeof(bo));
+			bo.type = B_OVERFLOW;
+			bo.tlen = child_bo->tlen;
+			bo.pgno = child_bo->pgno;
+			bi.len = BOVERFLOW_SIZE;
+			B_TSET(bi.type, B_OVERFLOW);
+			bi.pgno = rp->pgno;
+			DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data));
+			DB_SET_DBT(data, &bo, BOVERFLOW_SIZE);
+			break;
+		case B_DUPLICATE:
+		default:
+			goto pgfmt;
+		}
+		break;
+	case P_LDUP:
+	case P_LBTREE:
+		/* Copy the first key of the child page onto the root page. */
+		child_bk = GET_BKEYDATA(dbp, rootp, split);
+		switch (B_TYPE(child_bk->type)) {
+		case B_KEYDATA:
+			bi.len = child_bk->len;
+			B_TSET(bi.type, B_KEYDATA);
+			bi.pgno = rp->pgno;
+			DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data));
+			if ((ret = __os_malloc(dbp->env,
+			     child_bk->len, &data.data)) != 0)
+				return (ret);
+			memcpy(data.data, child_bk->data, child_bk->len);
+			data.size = child_bk->len;
+			break;
+		case B_OVERFLOW:
+			/* Copy the overflow key. */
+			child_bo = (BOVERFLOW *)child_bk;
+			memset(&bo, 0, sizeof(bo));
+			bo.type = B_OVERFLOW;
+			bo.tlen = child_bo->tlen;
+			memset(&hdr, 0, sizeof(hdr));
+			if ((ret = __db_goff(dbc, &hdr, child_bo->tlen,
+			     child_bo->pgno, &hdr.data, &hdr.size)) == 0)
+				ret = __db_poff(dbc, &hdr, &bo.pgno);
+
+			if (hdr.data != NULL)
+				__os_free(dbp->env, hdr.data);
+			if (ret != 0)
+				return (ret);
+
+			bi.len = BOVERFLOW_SIZE;
+			B_TSET(bi.type, B_OVERFLOW);
+			bi.pgno = rp->pgno;
+			DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data));
+			DB_SET_DBT(data, &bo, BOVERFLOW_SIZE);
+			break;
+		case B_DUPLICATE:
+		default:
+			goto pgfmt;
+		}
+		break;
+	default:
+pgfmt:		return (__db_pgfmt(dbp->env, rp->pgno));
+	}
+	/*
+	 * If the root page was a leaf page, change it into an internal page.
+	 * We copy the key we split on (but not the key's data, in the case of
+	 * a leaf page) to the new root page.
+	 */
+	root_pgno = BAM_ROOT_PGNO(dbc);
+	P_INIT(rootp, dbp->pgsize,
+	    root_pgno, PGNO_INVALID, PGNO_INVALID, lp->level + 1, P_IBTREE);
+
+	/*
+	 * The btree comparison code guarantees that the left-most key on any
+	 * internal btree page is never used, so it doesn't need to be filled
+	 * in.  Set the record count if necessary.
+	 */
+	memset(&bi0, 0, sizeof(bi0));
+	B_TSET(bi0.type, B_KEYDATA);
+	bi0.pgno = lp->pgno;
+	if (F_ISSET(cp, C_RECNUM)) {
+		bi0.nrecs = __bam_total(dbp, lp);
+		RE_NREC_SET(rootp, bi0.nrecs);
+		bi.nrecs = __bam_total(dbp, rp);
+		RE_NREC_ADJ(rootp, bi.nrecs);
+	}
+	DB_SET_DBT(hdr0, &bi0, SSZA(BINTERNAL, data));
+	if ((ret = __db_pitem_nolog(dbc, rootp,
+	    0, BINTERNAL_SIZE(0), &hdr0, NULL)) != 0)
+		goto err;
+	ret = __db_pitem_nolog(dbc, rootp, 1,
+	    BINTERNAL_SIZE(data.size), &hdr, &data);
+
+err:	if (data.data != NULL && child_bo == NULL)
+		__os_free(dbp->env, data.data);
+	return (ret);
+}
+
+/*
+ * __ram_root --
+ *	Fix up the recno root page after it has been split.
+ * PUBLIC:  int __ram_root __P((DBC *, PAGE *, PAGE *, PAGE *));
+ */
+int
+__ram_root(dbc, rootp, lp, rp)
+	DBC *dbc;
+	PAGE *rootp, *lp, *rp;
+{
+	DB *dbp;
+	DBT hdr;
+	RINTERNAL ri;
+	db_pgno_t root_pgno;
+	int ret;
+
+	dbp = dbc->dbp;
+	root_pgno = BAM_ROOT_PGNO(dbc);
+
+	/* Initialize the page. */
+	P_INIT(rootp, dbp->pgsize,
+	    root_pgno, PGNO_INVALID, PGNO_INVALID, lp->level + 1, P_IRECNO);
+
+	/* Initialize the header. */
+	DB_SET_DBT(hdr, &ri, RINTERNAL_SIZE);
+
+	/* Insert the left and right keys, set the header information. */
+	ri.pgno = lp->pgno;
+	ri.nrecs = __bam_total(dbp, lp);
+	if ((ret = __db_pitem_nolog(dbc,
+	     rootp, 0, RINTERNAL_SIZE, &hdr, NULL)) != 0)
+		return (ret);
+	RE_NREC_SET(rootp, ri.nrecs);
+	ri.pgno = rp->pgno;
+	ri.nrecs = __bam_total(dbp, rp);
+	if ((ret = __db_pitem_nolog(dbc,
+	    rootp, 1, RINTERNAL_SIZE, &hdr, NULL)) != 0)
+		return (ret);
+	RE_NREC_ADJ(rootp, ri.nrecs);
+	return (0);
+}
+
+/*
+ * __bam_pinsert --
+ *	Insert a new key into a parent page, completing the split.
+ *
+ * PUBLIC: int __bam_pinsert
+ * PUBLIC:     __P((DBC *, EPG *, u_int32_t, PAGE *, PAGE *, int));
+ */
+int
+__bam_pinsert(dbc, parent, split, lchild, rchild, flags)
+	DBC *dbc;
+	EPG *parent;
+	u_int32_t split;
+	PAGE *lchild, *rchild;
+	int flags;
+{
+	BINTERNAL bi, *child_bi;
+	BKEYDATA *child_bk, *tmp_bk;
+	BOVERFLOW bo, *child_bo;
+	BTREE *t;
+	BTREE_CURSOR *cp;
+	DB *dbp;
+	DBT a, b, hdr, data;
+	EPG *child;
+	PAGE *ppage;
+	RINTERNAL ri;
+	db_indx_t off;
+	db_recno_t nrecs;
+	size_t (*func) __P((DB *, const DBT *, const DBT *));
+	int (*pitem) __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *));
+	u_int32_t n, nbytes, nksize, oldsize, size;
+	int ret;
+
+	dbp = dbc->dbp;
+	cp = (BTREE_CURSOR *)dbc->internal;
+	t = dbp->bt_internal;
+	ppage = parent->page;
+	child = parent + 1;
+
+	/* If handling record numbers, count records split to the right page. */
+	nrecs = F_ISSET(cp, C_RECNUM) &&
+	    !LF_ISSET(BPI_SPACEONLY) ? __bam_total(dbp, rchild) : 0;
+
+	/*
+	 * Now we insert the new page's first key into the parent page, which
+	 * completes the split.  The parent points to a PAGE and a page index
+	 * offset, where the new key goes ONE AFTER the index, because we split
+	 * to the right.
+	 *
+	 * XXX
+	 * Some btree algorithms replace the key for the old page as well as
+	 * the new page.  We don't, as there's no reason to believe that the
+	 * first key on the old page is any better than the key we have, and,
+	 * in the case of a key being placed at index 0 causing the split, the
+	 * key is unavailable.
+	 */
+	off = parent->indx + O_INDX;
+	if (LF_ISSET(BPI_REPLACE))
+		oldsize = TYPE(ppage) == P_IRECNO ? RINTERNAL_PSIZE :
+		    BINTERNAL_PSIZE(GET_BINTERNAL(dbp, ppage, off)->len);
+	else
+		oldsize = 0;
+
+	/*
+	 * Calculate the space needed on the parent page.
+	 *
+	 * Prefix trees: space hack used when inserting into BINTERNAL pages.
+	 * Retain only what's needed to distinguish between the new entry and
+	 * the LAST entry on the page to its left.  If the keys compare equal,
+	 * retain the entire key.  We ignore overflow keys, and the entire key
+	 * must be retained for the next-to-leftmost key on the leftmost page
+	 * of each level, or the search will fail.  Applicable ONLY to internal
+	 * pages that have leaf pages as children.  Further reduction of the
+	 * key between pairs of internal pages loses too much information.
+	 */
+	switch (TYPE(child->page)) {
+	case P_IBTREE:
+		child_bi = GET_BINTERNAL(dbp, child->page, split);
+		nbytes = BINTERNAL_PSIZE(child_bi->len);
+
+		if (P_FREESPACE(dbp, ppage) + oldsize < nbytes)
+			return (DB_NEEDSPLIT);
+		if (LF_ISSET(BPI_SPACEONLY))
+			return (0);
+
+		switch (B_TYPE(child_bi->type)) {
+		case B_KEYDATA:
+			/* Add a new record for the right page. */
+			memset(&bi, 0, sizeof(bi));
+			bi.len = child_bi->len;
+			B_TSET(bi.type, B_KEYDATA);
+			bi.pgno = rchild->pgno;
+			bi.nrecs = nrecs;
+			DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data));
+			DB_SET_DBT(data, child_bi->data, child_bi->len);
+			size = BINTERNAL_SIZE(child_bi->len);
+			break;
+		case B_OVERFLOW:
+			/* Reuse the overflow key. */
+			child_bo = (BOVERFLOW *)child_bi->data;
+			memset(&bo, 0, sizeof(bo));
+			bo.type = B_OVERFLOW;
+			bo.tlen = child_bo->tlen;
+			bo.pgno = child_bo->pgno;
+			bi.len = BOVERFLOW_SIZE;
+			B_TSET(bi.type, B_OVERFLOW);
+			bi.pgno = rchild->pgno;
+			bi.nrecs = nrecs;
+			DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data));
+			DB_SET_DBT(data, &bo, BOVERFLOW_SIZE);
+			size = BINTERNAL_SIZE(BOVERFLOW_SIZE);
+			break;
+		case B_DUPLICATE:
+		default:
+			goto pgfmt;
+		}
+		break;
+	case P_LDUP:
+	case P_LBTREE:
+		child_bk = GET_BKEYDATA(dbp, child->page, split);
+		switch (B_TYPE(child_bk->type)) {
+		case B_KEYDATA:
+			nbytes = BINTERNAL_PSIZE(child_bk->len);
+			nksize = child_bk->len;
+
+			/*
+			 * Prefix compression:
+			 * We set t->bt_prefix to NULL if we have a comparison
+			 * callback but no prefix compression callback.  But,
+			 * if we're splitting in an off-page duplicates tree,
+			 * we still have to do some checking.  If using the
+			 * default off-page duplicates comparison routine we
+			 * can use the default prefix compression callback. If
+			 * not using the default off-page duplicates comparison
+			 * routine, we can't do any kind of prefix compression
+			 * as there's no way for an application to specify a
+			 * prefix compression callback that corresponds to its
+			 * comparison callback.
+			 *
+			 * No prefix compression if we don't have a compression
+			 * function, or the key we'd compress isn't a normal
+			 * key (for example, it references an overflow page).
+			 *
+			 * Generate a parent page key for the right child page
+			 * from a comparison of the last key on the left child
+			 * page and the first key on the right child page.
+			 */
+			if (F_ISSET(dbc, DBC_OPD)) {
+				if (dbp->dup_compare == __bam_defcmp)
+					func = __bam_defpfx;
+				else
+					func = NULL;
+			} else
+				func = t->bt_prefix;
+			if (func == NULL)
+				goto noprefix;
+			tmp_bk = GET_BKEYDATA(dbp, lchild, NUM_ENT(lchild) -
+			    (TYPE(lchild) == P_LDUP ? O_INDX : P_INDX));
+			if (B_TYPE(tmp_bk->type) != B_KEYDATA)
+				goto noprefix;
+			DB_INIT_DBT(a, tmp_bk->data, tmp_bk->len);
+			DB_INIT_DBT(b, child_bk->data, child_bk->len);
+			nksize = (u_int32_t)func(dbp, &a, &b);
+			if ((n = BINTERNAL_PSIZE(nksize)) < nbytes)
+				nbytes = n;
+			else
+				nksize = child_bk->len;
+
+noprefix:		if (P_FREESPACE(dbp, ppage) + oldsize < nbytes)
+				return (DB_NEEDSPLIT);
+			if (LF_ISSET(BPI_SPACEONLY))
+				return (0);
+
+			memset(&bi, 0, sizeof(bi));
+			bi.len = nksize;
+			B_TSET(bi.type, B_KEYDATA);
+			bi.pgno = rchild->pgno;
+			bi.nrecs = nrecs;
+			DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data));
+			DB_SET_DBT(data, child_bk->data, nksize);
+			size = BINTERNAL_SIZE(nksize);
+			break;
+		case B_OVERFLOW:
+			nbytes = BINTERNAL_PSIZE(BOVERFLOW_SIZE);
+
+			if (P_FREESPACE(dbp, ppage) + oldsize < nbytes)
+				return (DB_NEEDSPLIT);
+			if (LF_ISSET(BPI_SPACEONLY))
+				return (0);
+
+			/* Copy the overflow key. */
+			child_bo = (BOVERFLOW *)child_bk;
+			memset(&bo, 0, sizeof(bo));
+			bo.type = B_OVERFLOW;
+			bo.tlen = child_bo->tlen;
+			memset(&hdr, 0, sizeof(hdr));
+			if ((ret = __db_goff(dbc, &hdr, child_bo->tlen,
+			     child_bo->pgno, &hdr.data, &hdr.size)) == 0)
+				ret = __db_poff(dbc, &hdr, &bo.pgno);
+
+			if (hdr.data != NULL)
+				__os_free(dbp->env, hdr.data);
+			if (ret != 0)
+				return (ret);
+
+			memset(&bi, 0, sizeof(bi));
+			bi.len = BOVERFLOW_SIZE;
+			B_TSET(bi.type, B_OVERFLOW);
+			bi.pgno = rchild->pgno;
+			bi.nrecs = nrecs;
+			DB_SET_DBT(hdr, &bi, SSZA(BINTERNAL, data));
+			DB_SET_DBT(data, &bo, BOVERFLOW_SIZE);
+			size = BINTERNAL_SIZE(BOVERFLOW_SIZE);
+
+			break;
+		case B_DUPLICATE:
+		default:
+			goto pgfmt;
+		}
+		break;
+	case P_IRECNO:
+	case P_LRECNO:
+		nbytes = RINTERNAL_PSIZE;
+
+		if (P_FREESPACE(dbp, ppage) + oldsize < nbytes)
+			return (DB_NEEDSPLIT);
+		if (LF_ISSET(BPI_SPACEONLY))
+			return (0);
+
+		/* Add a new record for the right page. */
+		DB_SET_DBT(hdr, &ri, RINTERNAL_SIZE);
+		ri.pgno = rchild->pgno;
+		ri.nrecs = nrecs;
+		size = RINTERNAL_SIZE;
+		data.size = 0;
+		/*
+		 * For now, we are locking internal recno nodes so
+		 * use two steps.
+		 */
+		if (LF_ISSET(BPI_REPLACE)) {
+			if ((ret = __bam_ditem(dbc, ppage, off)) != 0)
+				return (ret);
+			LF_CLR(BPI_REPLACE);
+		}
+		break;
+	default:
+pgfmt:		return (__db_pgfmt(dbp->env, PGNO(child->page)));
+	}
+
+	if (LF_ISSET(BPI_REPLACE)) {
+		DB_ASSERT(dbp->env, !LF_ISSET(BPI_NOLOGGING));
+		if ((ret = __bam_irep(dbc, ppage, off, &hdr, &data)) != 0)
+			return (ret);
+	} else {
+		if (LF_ISSET(BPI_NOLOGGING))
+			pitem = __db_pitem_nolog;
+		else
+			pitem = __db_pitem;
+
+		if ((ret = pitem(dbc, ppage,
+		    off, size, &hdr, data.size != 0 ? &data : NULL)) != 0)
+			return (ret);
+	}
+
+	/*
+	 * If a Recno or Btree with record numbers AM page, or an off-page
+	 * duplicates tree, adjust the parent page's left page record count.
+	 */
+	if (F_ISSET(cp, C_RECNUM) && !LF_ISSET(BPI_NORECNUM)) {
+		/* Log the change. */
+		if (DBC_LOGGING(dbc)) {
+			if ((ret = __bam_cadjust_log(dbp, dbc->txn,
+			    &LSN(ppage), 0, PGNO(ppage), &LSN(ppage),
+			    parent->indx, -(int32_t)nrecs, 0)) != 0)
+				return (ret);
+		} else
+			LSN_NOT_LOGGED(LSN(ppage));
+
+		/* Update the left page count. */
+		if (dbc->dbtype == DB_RECNO)
+			GET_RINTERNAL(dbp, ppage, parent->indx)->nrecs -= nrecs;
+		else
+			GET_BINTERNAL(dbp, ppage, parent->indx)->nrecs -= nrecs;
+	}
+
+	return (0);
+}
+
+/*
+ * __bam_psplit --
+ *	Do the real work of splitting the page.
+ */
+static int
+__bam_psplit(dbc, cp, lp, rp, splitret)
+	DBC *dbc;
+	EPG *cp;
+	PAGE *lp, *rp;
+	db_indx_t *splitret;
+{
+	DB *dbp;
+	PAGE *pp;
+	db_indx_t half, *inp, nbytes, off, splitp, top;
+	int adjust, cnt, iflag, isbigkey, ret;
+
+	dbp = dbc->dbp;
+	pp = cp->page;
+	inp = P_INP(dbp, pp);
+	adjust = TYPE(pp) == P_LBTREE ? P_INDX : O_INDX;
+
+	/*
+	 * If we're splitting the first (last) page on a level because we're
+	 * inserting (appending) a key to it, it's likely that the data is
+	 * sorted.  Moving a single item to the new page is less work and can
+	 * push the fill factor higher than normal.  This is trivial when we
+	 * are splitting a new page before the beginning of the tree, all of
+	 * the interesting tests are against values of 0.
+	 *
+	 * Catching appends to the tree is harder.  In a simple append, we're
+	 * inserting an item that sorts past the end of the tree; the cursor
+	 * will point past the last element on the page.  But, in trees with
+	 * duplicates, the cursor may point to the last entry on the page --
+	 * in this case, the entry will also be the last element of a duplicate
+	 * set (the last because the search call specified the SR_DUPLAST flag).
+	 * The only way to differentiate between an insert immediately before
+	 * the last item in a tree or an append after a duplicate set which is
+	 * also the last item in the tree is to call the comparison function.
+	 * When splitting internal pages during an append, the search code
+	 * guarantees the cursor always points to the largest page item less
+	 * than the new internal entry.  To summarize, we want to catch three
+	 * possible index values:
+	 *
+	 *	NUM_ENT(page)		Btree/Recno leaf insert past end-of-tree
+	 *	NUM_ENT(page) - O_INDX	Btree or Recno internal insert past EOT
+	 *	NUM_ENT(page) - P_INDX	Btree leaf insert past EOT after a set
+	 *				    of duplicates
+	 *
+	 * two of which, (NUM_ENT(page) - O_INDX or P_INDX) might be an insert
+	 * near the end of the tree, and not after the end of the tree at all.
+	 * Do a simple test which might be wrong because calling the comparison
+	 * functions is expensive.  Regardless, it's not a big deal if we're
+	 * wrong, we'll do the split the right way next time.
+	 */
+	off = 0;
+	if (NEXT_PGNO(pp) == PGNO_INVALID && cp->indx >= NUM_ENT(pp) - adjust)
+		off = NUM_ENT(pp) - adjust;
+	else if (PREV_PGNO(pp) == PGNO_INVALID && cp->indx == 0)
+		off = adjust;
+	if (off != 0)
+		goto sort;
+
+	/*
+	 * Split the data to the left and right pages.  Try not to split on
+	 * an overflow key.  (Overflow keys on internal pages will slow down
+	 * searches.)  Refuse to split in the middle of a set of duplicates.
+	 *
+	 * First, find the optimum place to split.
+	 *
+	 * It's possible to try and split past the last record on the page if
+	 * there's a very large record at the end of the page.  Make sure this
+	 * doesn't happen by bounding the check at the next-to-last entry on
+	 * the page.
+	 *
+	 * Note, we try and split half the data present on the page.  This is
+	 * because another process may have already split the page and left
+	 * it half empty.  We don't try and skip the split -- we don't know
+	 * how much space we're going to need on the page, and we may need up
+	 * to half the page for a big item, so there's no easy test to decide
+	 * if we need to split or not.  Besides, if two threads are inserting
+	 * data into the same place in the database, we're probably going to
+	 * need more space soon anyway.
+	 */
+	top = NUM_ENT(pp) - adjust;
+	half = (dbp->pgsize - HOFFSET(pp)) / 2;
+	for (nbytes = 0, off = 0; off < top && nbytes < half; ++off)
+		switch (TYPE(pp)) {
+		case P_IBTREE:
+			if (B_TYPE(
+			    GET_BINTERNAL(dbp, pp, off)->type) == B_KEYDATA)
+				nbytes += BINTERNAL_SIZE(
+				   GET_BINTERNAL(dbp, pp, off)->len);
+			else
+				nbytes += BINTERNAL_SIZE(BOVERFLOW_SIZE);
+			break;
+		case P_LBTREE:
+			if (B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) ==
+			    B_KEYDATA)
+				nbytes += BKEYDATA_SIZE(GET_BKEYDATA(dbp,
+				    pp, off)->len);
+			else
+				nbytes += BOVERFLOW_SIZE;
+
+			++off;
+			/* FALLTHROUGH */
+		case P_LDUP:
+		case P_LRECNO:
+			if (B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) ==
+			    B_KEYDATA)
+				nbytes += BKEYDATA_SIZE(GET_BKEYDATA(dbp,
+				    pp, off)->len);
+			else
+				nbytes += BOVERFLOW_SIZE;
+			break;
+		case P_IRECNO:
+			nbytes += RINTERNAL_SIZE;
+			break;
+		default:
+			return (__db_pgfmt(dbp->env, pp->pgno));
+		}
+sort:	splitp = off;
+
+	/*
+	 * Splitp is either at or just past the optimum split point.  If the
+	 * tree type is such that we're going to promote a key to an internal
+	 * page, and our current choice is an overflow key, look for something
+	 * close by that's smaller.
+	 */
+	switch (TYPE(pp)) {
+	case P_IBTREE:
+		iflag = 1;
+		isbigkey =
+		    B_TYPE(GET_BINTERNAL(dbp, pp, off)->type) != B_KEYDATA;
+		break;
+	case P_LBTREE:
+	case P_LDUP:
+		iflag = 0;
+		isbigkey = B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) !=
+		    B_KEYDATA;
+		break;
+	default:
+		iflag = isbigkey = 0;
+	}
+	if (isbigkey)
+		for (cnt = 1; cnt <= 3; ++cnt) {
+			off = splitp + cnt * adjust;
+			if (off < (db_indx_t)NUM_ENT(pp) &&
+			    ((iflag && B_TYPE(
+			    GET_BINTERNAL(dbp, pp,off)->type) == B_KEYDATA) ||
+			    B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) ==
+			    B_KEYDATA)) {
+				splitp = off;
+				break;
+			}
+			if (splitp <= (db_indx_t)(cnt * adjust))
+				continue;
+			off = splitp - cnt * adjust;
+			if (iflag ? B_TYPE(
+			    GET_BINTERNAL(dbp, pp, off)->type) == B_KEYDATA :
+			    B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) ==
+			    B_KEYDATA) {
+				splitp = off;
+				break;
+			}
+		}
+
+	/*
+	 * We can't split in the middle a set of duplicates.  We know that
+	 * no duplicate set can take up more than about 25% of the page,
+	 * because that's the point where we push it off onto a duplicate
+	 * page set.  So, this loop can't be unbounded.
+	 */
+	if (TYPE(pp) == P_LBTREE &&
+	    inp[splitp] == inp[splitp - adjust])
+		for (cnt = 1;; ++cnt) {
+			off = splitp + cnt * adjust;
+			if (off < NUM_ENT(pp) &&
+			    inp[splitp] != inp[off]) {
+				splitp = off;
+				break;
+			}
+			if (splitp <= (db_indx_t)(cnt * adjust))
+				continue;
+			off = splitp - cnt * adjust;
+			if (inp[splitp] != inp[off]) {
+				splitp = off + adjust;
+				break;
+			}
+		}
+
+	/* We're going to split at splitp. */
+	if ((ret = __bam_copy(dbp, pp, lp, 0, splitp)) != 0)
+		return (ret);
+	if ((ret = __bam_copy(dbp, pp, rp, splitp, NUM_ENT(pp))) != 0)
+		return (ret);
+
+	*splitret = splitp;
+	return (0);
+}
+
+/*
+ * __bam_copy --
+ *	Copy a set of records from one page to another.
+ *
+ * PUBLIC: int __bam_copy __P((DB *, PAGE *, PAGE *, u_int32_t, u_int32_t));
+ */
+int
+__bam_copy(dbp, pp, cp, nxt, stop)
+	DB *dbp;
+	PAGE *pp, *cp;
+	u_int32_t nxt, stop;
+{
+	BINTERNAL internal;
+	db_indx_t *cinp, nbytes, off, *pinp;
+
+	cinp = P_INP(dbp, cp);
+	pinp = P_INP(dbp, pp);
+	/*
+	 * Nxt is the offset of the next record to be placed on the target page.
+	 */
+	for (off = 0; nxt < stop; ++nxt, ++NUM_ENT(cp), ++off) {
+		switch (TYPE(pp)) {
+		case P_IBTREE:
+			if (off == 0 && nxt != 0)
+				nbytes = BINTERNAL_SIZE(0);
+			else if (B_TYPE(
+			    GET_BINTERNAL(dbp, pp, nxt)->type) == B_KEYDATA)
+				nbytes = BINTERNAL_SIZE(
+				    GET_BINTERNAL(dbp, pp, nxt)->len);
+			else
+				nbytes = BINTERNAL_SIZE(BOVERFLOW_SIZE);
+			break;
+		case P_LBTREE:
+			/*
+			 * If we're on a key and it's a duplicate, just copy
+			 * the offset.
+			 */
+			if (off != 0 && (nxt % P_INDX) == 0 &&
+			    pinp[nxt] == pinp[nxt - P_INDX]) {
+				cinp[off] = cinp[off - P_INDX];
+				continue;
+			}
+			/* FALLTHROUGH */
+		case P_LDUP:
+		case P_LRECNO:
+			if (B_TYPE(GET_BKEYDATA(dbp, pp, nxt)->type) ==
+			    B_KEYDATA)
+				nbytes = BKEYDATA_SIZE(GET_BKEYDATA(dbp,
+				    pp, nxt)->len);
+			else
+				nbytes = BOVERFLOW_SIZE;
+			break;
+		case P_IRECNO:
+			nbytes = RINTERNAL_SIZE;
+			break;
+		default:
+			return (__db_pgfmt(dbp->env, pp->pgno));
+		}
+		cinp[off] = HOFFSET(cp) -= nbytes;
+		if (off == 0 && nxt != 0 && TYPE(pp) == P_IBTREE) {
+			internal.len = 0;
+			UMRW_SET(internal.unused);
+			internal.type = B_KEYDATA;
+			internal.pgno = GET_BINTERNAL(dbp, pp, nxt)->pgno;
+			internal.nrecs = GET_BINTERNAL(dbp, pp, nxt)->nrecs;
+			memcpy(P_ENTRY(dbp, cp, off), &internal, nbytes);
+		}
+		else
+			memcpy(P_ENTRY(dbp, cp, off),
+			     P_ENTRY(dbp, pp, nxt), nbytes);
+	}
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_stat.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,691 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+
+#ifdef HAVE_STATISTICS
+/*
+ * __bam_stat --
+ *	Gather/print the btree statistics
+ *
+ * PUBLIC: int __bam_stat __P((DBC *, void *, u_int32_t));
+ */
+int
+__bam_stat(dbc, spp, flags)
+	DBC *dbc;
+	void *spp;
+	u_int32_t flags;
+{
+	BTMETA *meta;
+	BTREE *t;
+	DB *dbp;
+	DB_BTREE_STAT *sp;
+	DB_LOCK lock, metalock;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h;
+	db_pgno_t pgno;
+	int ret, t_ret, write_meta;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	meta = NULL;
+	t = dbp->bt_internal;
+	sp = NULL;
+	LOCK_INIT(metalock);
+	LOCK_INIT(lock);
+	mpf = dbp->mpf;
+	h = NULL;
+	ret = write_meta = 0;
+
+	/* Allocate and clear the structure. */
+	if ((ret = __os_umalloc(env, sizeof(*sp), &sp)) != 0)
+		goto err;
+	memset(sp, 0, sizeof(*sp));
+
+	/* Get the metadata page for the entire database. */
+	pgno = PGNO_BASE_MD;
+	if ((ret = __db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &metalock)) != 0)
+		goto err;
+	if ((ret = __memp_fget(mpf, &pgno,
+	     dbc->thread_info, dbc->txn, 0, &meta)) != 0)
+		goto err;
+
+	if (flags == DB_FAST_STAT)
+		goto meta_only;
+
+	/* Walk the metadata free list, counting pages. */
+	for (sp->bt_free = 0, pgno = meta->dbmeta.free; pgno != PGNO_INVALID;) {
+		++sp->bt_free;
+
+		if ((ret = __memp_fget(mpf, &pgno,
+		     dbc->thread_info, dbc->txn, 0, &h)) != 0)
+			goto err;
+
+		pgno = h->next_pgno;
+		if ((ret = __memp_fput(mpf,
+		    dbc->thread_info, h, dbc->priority)) != 0)
+			goto err;
+		h = NULL;
+	}
+
+	/* Get the root page. */
+	BAM_GET_ROOT(dbc, pgno, h, 0, DB_LOCK_READ, lock, ret);
+	if (ret != 0)
+		goto err;
+	DB_ASSERT(env, h != NULL);
+
+	/* Get the levels from the root page. */
+	sp->bt_levels = h->level;
+
+	/* Discard the root page. */
+	ret = __memp_fput(mpf, dbc->thread_info, h, dbc->priority);
+	h = NULL;
+	if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
+		ret = t_ret;
+	if (ret != 0)
+		goto err;
+
+	/* Discard the metadata page. */
+	ret = __memp_fput(mpf, dbc->thread_info, meta, dbc->priority);
+	meta = NULL;
+	if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
+		ret = t_ret;
+	if (ret != 0)
+		goto err;
+
+	/* Walk the tree. */
+	if ((ret = __bam_traverse(dbc,
+	    DB_LOCK_READ, PGNO_INVALID, __bam_stat_callback, sp)) != 0)
+		goto err;
+
+#ifdef HAVE_COMPRESSION
+	if (DB_IS_COMPRESSED(dbp) && (ret = __bam_compress_count(dbc,
+	    &sp->bt_nkeys, &sp->bt_ndata)) != 0)
+		goto err;
+#endif
+
+	/*
+	 * Get the subdatabase metadata page if it's not the same as the
+	 * one we already have.
+	 */
+	write_meta = !F_ISSET(dbp, DB_AM_RDONLY) &&
+	    (!MULTIVERSION(dbp) || dbc->txn != NULL);
+meta_only:
+	if (meta == NULL || t->bt_meta != PGNO_BASE_MD || write_meta) {
+		if (meta != NULL) {
+			ret = __memp_fput(mpf,
+			    dbc->thread_info, meta, dbc->priority);
+			meta = NULL;
+			if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
+				ret = t_ret;
+			if (ret != 0)
+				goto err;
+		}
+
+		if ((ret = __db_lget(dbc,
+		    0, t->bt_meta, write_meta ? DB_LOCK_WRITE : DB_LOCK_READ,
+		    0, &metalock)) != 0)
+			goto err;
+		if ((ret = __memp_fget(mpf, &t->bt_meta,
+		     dbc->thread_info, dbc->txn,
+		    write_meta ? DB_MPOOL_DIRTY : 0, &meta)) != 0)
+			goto err;
+	}
+	if (flags == DB_FAST_STAT) {
+		if (dbp->type == DB_RECNO ||
+		    (dbp->type == DB_BTREE && F_ISSET(dbp, DB_AM_RECNUM))) {
+			BAM_GET_ROOT(dbc, pgno, h, 0, DB_LOCK_READ, lock, ret);
+			if (ret != 0)
+				goto err;
+
+			sp->bt_nkeys = RE_NREC(h);
+		} else
+			sp->bt_nkeys = meta->dbmeta.key_count;
+
+		sp->bt_ndata = dbp->type == DB_RECNO ?
+		   sp->bt_nkeys : meta->dbmeta.record_count;
+	}
+
+	/* Get metadata page statistics. */
+	sp->bt_metaflags = meta->dbmeta.flags;
+	sp->bt_minkey = meta->minkey;
+	sp->bt_re_len = meta->re_len;
+	sp->bt_re_pad = meta->re_pad;
+	/*
+	 * Don't take the page number from the meta-data page -- that value is
+	 * only maintained in the primary database, we may have been called on
+	 * a subdatabase.  (Yes, I read the primary database meta-data page
+	 * earlier in this function, but I'm asking the underlying cache so the
+	 * code for the Hash and Btree methods is the same.)
+	 */
+	if ((ret = __memp_get_last_pgno(dbp->mpf, &pgno)) != 0)
+		goto err;
+	sp->bt_pagecnt = pgno + 1;
+	sp->bt_pagesize = meta->dbmeta.pagesize;
+	sp->bt_magic = meta->dbmeta.magic;
+	sp->bt_version = meta->dbmeta.version;
+
+	if (write_meta != 0) {
+		meta->dbmeta.key_count = sp->bt_nkeys;
+		meta->dbmeta.record_count = sp->bt_ndata;
+	}
+
+	*(DB_BTREE_STAT **)spp = sp;
+
+err:	/* Discard the second page. */
+	if (h != NULL && (t_ret = __memp_fput(mpf,
+	    dbc->thread_info, h, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Discard the metadata page. */
+	if (meta != NULL && (t_ret = __memp_fput(mpf,
+	    dbc->thread_info, meta, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (ret != 0 && sp != NULL) {
+		__os_ufree(env, sp);
+		*(DB_BTREE_STAT **)spp = NULL;
+	}
+
+	return (ret);
+}
+
+/*
+ * __bam_stat_print --
+ *	Display btree/recno statistics.
+ *
+ * PUBLIC: int __bam_stat_print __P((DBC *, u_int32_t));
+ */
+int
+__bam_stat_print(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	static const FN fn[] = {
+		{ BTM_DUP,	"duplicates" },
+		{ BTM_RECNO,	"recno" },
+		{ BTM_RECNUM,	"record-numbers" },
+		{ BTM_FIXEDLEN,	"fixed-length" },
+		{ BTM_RENUMBER,	"renumber" },
+		{ BTM_SUBDB,	"multiple-databases" },
+		{ BTM_DUPSORT,	"sorted duplicates" },
+		{ BTM_COMPRESS,	"compressed" },
+		{ 0,		NULL }
+	};
+	DB *dbp;
+	DB_BTREE_STAT *sp;
+	ENV *env;
+	int lorder, ret;
+	const char *s;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+#ifdef HAVE_PARTITION
+	if (DB_IS_PARTITIONED(dbp)) {
+		if ((ret = __partition_stat(dbc, &sp, flags)) != 0)
+			return (ret);
+	} else
+#endif
+	if ((ret = __bam_stat(dbc, &sp, LF_ISSET(DB_FAST_STAT))) != 0)
+		return (ret);
+
+	if (LF_ISSET(DB_STAT_ALL)) {
+		__db_msg(env, "%s", DB_GLOBAL(db_line));
+		__db_msg(env, "Default Btree/Recno database information:");
+	}
+
+	__db_msg(env, "%lx\tBtree magic number", (u_long)sp->bt_magic);
+	__db_msg(env, "%lu\tBtree version number", (u_long)sp->bt_version);
+
+	(void)__db_get_lorder(dbp, &lorder);
+	switch (lorder) {
+	case 1234:
+		s = "Little-endian";
+		break;
+	case 4321:
+		s = "Big-endian";
+		break;
+	default:
+		s = "Unrecognized byte order";
+		break;
+	}
+	__db_msg(env, "%s\tByte order", s);
+	__db_prflags(env, NULL, sp->bt_metaflags, fn, NULL, "\tFlags");
+	if (dbp->type == DB_BTREE)
+		__db_dl(env, "Minimum keys per-page", (u_long)sp->bt_minkey);
+	if (dbp->type == DB_RECNO) {
+		__db_dl(env,
+		    "Fixed-length record size", (u_long)sp->bt_re_len);
+		__db_msg(env,
+		    "%#x\tFixed-length record pad", (u_int)sp->bt_re_pad);
+	}
+	__db_dl(env,
+	    "Underlying database page size", (u_long)sp->bt_pagesize);
+	if (dbp->type == DB_BTREE)
+		__db_dl(env, "Overflow key/data size",
+		    ((BTREE_CURSOR *)dbc->internal)->ovflsize);
+	__db_dl(env, "Number of levels in the tree", (u_long)sp->bt_levels);
+	__db_dl(env, dbp->type == DB_BTREE ?
+	    "Number of unique keys in the tree" :
+	    "Number of records in the tree", (u_long)sp->bt_nkeys);
+	__db_dl(env,
+	    "Number of data items in the tree", (u_long)sp->bt_ndata);
+
+	__db_dl(env,
+	    "Number of tree internal pages", (u_long)sp->bt_int_pg);
+	__db_dl_pct(env,
+	    "Number of bytes free in tree internal pages",
+	    (u_long)sp->bt_int_pgfree,
+	    DB_PCT_PG(sp->bt_int_pgfree, sp->bt_int_pg, sp->bt_pagesize), "ff");
+
+	__db_dl(env,
+	    "Number of tree leaf pages", (u_long)sp->bt_leaf_pg);
+	__db_dl_pct(env, "Number of bytes free in tree leaf pages",
+	    (u_long)sp->bt_leaf_pgfree, DB_PCT_PG(
+	    sp->bt_leaf_pgfree, sp->bt_leaf_pg, sp->bt_pagesize), "ff");
+
+	__db_dl(env,
+	    "Number of tree duplicate pages", (u_long)sp->bt_dup_pg);
+	__db_dl_pct(env,
+	    "Number of bytes free in tree duplicate pages",
+	    (u_long)sp->bt_dup_pgfree,
+	    DB_PCT_PG(sp->bt_dup_pgfree, sp->bt_dup_pg, sp->bt_pagesize), "ff");
+
+	__db_dl(env,
+	    "Number of tree overflow pages", (u_long)sp->bt_over_pg);
+	__db_dl_pct(env, "Number of bytes free in tree overflow pages",
+	    (u_long)sp->bt_over_pgfree, DB_PCT_PG(
+	    sp->bt_over_pgfree, sp->bt_over_pg, sp->bt_pagesize), "ff");
+	__db_dl(env, "Number of empty pages", (u_long)sp->bt_empty_pg);
+
+	__db_dl(env, "Number of pages on the free list", (u_long)sp->bt_free);
+
+	__os_ufree(env, sp);
+
+	return (0);
+}
+
+/*
+ * __bam_stat_callback --
+ *	Statistics callback.
+ *
+ * PUBLIC: int __bam_stat_callback __P((DBC *, PAGE *, void *, int *));
+ */
+int
+__bam_stat_callback(dbc, h, cookie, putp)
+	DBC *dbc;
+	PAGE *h;
+	void *cookie;
+	int *putp;
+{
+	DB *dbp;
+	DB_BTREE_STAT *sp;
+	db_indx_t indx, *inp, top;
+	u_int8_t type;
+
+	dbp = dbc->dbp;
+	sp = cookie;
+	*putp = 0;
+	top = NUM_ENT(h);
+	inp = P_INP(dbp, h);
+
+	switch (TYPE(h)) {
+	case P_IBTREE:
+	case P_IRECNO:
+		++sp->bt_int_pg;
+		sp->bt_int_pgfree += P_FREESPACE(dbp, h);
+		break;
+	case P_LBTREE:
+		if (top == 0)
+			++sp->bt_empty_pg;
+
+		/* Correct for on-page duplicates and deleted items. */
+		for (indx = 0; indx < top; indx += P_INDX) {
+			type = GET_BKEYDATA(dbp, h, indx + O_INDX)->type;
+			/* Ignore deleted items. */
+			if (B_DISSET(type))
+				continue;
+
+			/* Ignore duplicate keys. */
+			if (indx + P_INDX >= top ||
+			    inp[indx] != inp[indx + P_INDX])
+				++sp->bt_nkeys;
+
+			/* Ignore off-page duplicates. */
+			if (B_TYPE(type) != B_DUPLICATE)
+				++sp->bt_ndata;
+		}
+
+		++sp->bt_leaf_pg;
+		sp->bt_leaf_pgfree += P_FREESPACE(dbp, h);
+		break;
+	case P_LRECNO:
+		if (top == 0)
+			++sp->bt_empty_pg;
+
+		/*
+		 * If walking a recno tree, then each of these items is a key.
+		 * Otherwise, we're walking an off-page duplicate set.
+		 */
+		if (dbp->type == DB_RECNO) {
+			/*
+			 * Correct for deleted items in non-renumbering Recno
+			 * databases.
+			 */
+			if (F_ISSET(dbp, DB_AM_RENUMBER)) {
+				sp->bt_nkeys += top;
+				sp->bt_ndata += top;
+			} else
+				for (indx = 0; indx < top; indx += O_INDX) {
+					type = GET_BKEYDATA(dbp, h, indx)->type;
+					if (!B_DISSET(type)) {
+						++sp->bt_ndata;
+						++sp->bt_nkeys;
+					}
+				}
+
+			++sp->bt_leaf_pg;
+			sp->bt_leaf_pgfree += P_FREESPACE(dbp, h);
+		} else {
+			sp->bt_ndata += top;
+
+			++sp->bt_dup_pg;
+			sp->bt_dup_pgfree += P_FREESPACE(dbp, h);
+		}
+		break;
+	case P_LDUP:
+		if (top == 0)
+			++sp->bt_empty_pg;
+
+		/* Correct for deleted items. */
+		for (indx = 0; indx < top; indx += O_INDX)
+			if (!B_DISSET(GET_BKEYDATA(dbp, h, indx)->type))
+				++sp->bt_ndata;
+
+		++sp->bt_dup_pg;
+		sp->bt_dup_pgfree += P_FREESPACE(dbp, h);
+		break;
+	case P_OVERFLOW:
+		++sp->bt_over_pg;
+		sp->bt_over_pgfree += P_OVFLSPACE(dbp, dbp->pgsize, h);
+		break;
+	default:
+		return (__db_pgfmt(dbp->env, h->pgno));
+	}
+	return (0);
+}
+
+/*
+ * __bam_print_cursor --
+ *	Display the current internal cursor.
+ *
+ * PUBLIC: void __bam_print_cursor __P((DBC *));
+ */
+void
+__bam_print_cursor(dbc)
+	DBC *dbc;
+{
+	static const FN fn[] = {
+		{ C_DELETED,	"C_DELETED" },
+		{ C_RECNUM,	"C_RECNUM" },
+		{ C_RENUMBER,	"C_RENUMBER" },
+		{ 0,		NULL }
+	};
+	ENV *env;
+	BTREE_CURSOR *cp;
+
+	env = dbc->env;
+	cp = (BTREE_CURSOR *)dbc->internal;
+
+	STAT_ULONG("Overflow size", cp->ovflsize);
+	if (dbc->dbtype == DB_RECNO)
+		STAT_ULONG("Recno", cp->recno);
+	STAT_ULONG("Order", cp->order);
+	__db_prflags(env, NULL, cp->flags, fn, NULL, "\tInternal Flags");
+}
+
+#else /* !HAVE_STATISTICS */
+
+int
+__bam_stat(dbc, spp, flags)
+	DBC *dbc;
+	void *spp;
+	u_int32_t flags;
+{
+	COMPQUIET(spp, NULL);
+	COMPQUIET(flags, 0);
+
+	return (__db_stat_not_built(dbc->env));
+}
+
+int
+__bam_stat_print(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+
+	return (__db_stat_not_built(dbc->env));
+}
+#endif
+
+/*
+ * __bam_key_range --
+ *	Return proportion of keys relative to given key.  The numbers are
+ *	slightly skewed due to on page duplicates.
+ *
+ * PUBLIC: int __bam_key_range __P((DBC *, DBT *, DB_KEY_RANGE *, u_int32_t));
+ */
+int
+__bam_key_range(dbc, dbt, kp, flags)
+	DBC *dbc;
+	DBT *dbt;
+	DB_KEY_RANGE *kp;
+	u_int32_t flags;
+{
+	BTREE_CURSOR *cp;
+	EPG *sp;
+	double factor;
+	int exact, ret;
+
+	COMPQUIET(flags, 0);
+
+	if ((ret = __bam_search(dbc, PGNO_INVALID,
+	    dbt, SR_STK_ONLY, 1, NULL, &exact)) != 0)
+		return (ret);
+
+	cp = (BTREE_CURSOR *)dbc->internal;
+	kp->less = kp->greater = 0.0;
+
+	factor = 1.0;
+
+	/* Correct the leaf page. */
+	cp->csp->entries /= 2;
+	cp->csp->indx /= 2;
+	for (sp = cp->sp; sp <= cp->csp; ++sp) {
+		/*
+		 * At each level we know that pages greater than indx contain
+		 * keys greater than what we are looking for and those less
+		 * than indx are less than.  The one pointed to by indx may
+		 * have some less, some greater or even equal.  If indx is
+		 * equal to the number of entries, then the key is out of range
+		 * and everything is less.
+		 */
+		if (sp->indx == 0)
+			kp->greater += factor * (sp->entries - 1)/sp->entries;
+		else if (sp->indx == sp->entries)
+			kp->less += factor;
+		else {
+			kp->less += factor * sp->indx / sp->entries;
+			kp->greater += factor *
+			    ((sp->entries - sp->indx) - 1) / sp->entries;
+		}
+		factor *= 1.0/sp->entries;
+	}
+
+	/*
+	 * If there was an exact match then assign 1 n'th to the key itself.
+	 * Otherwise that factor belongs to those greater than the key, unless
+	 * the key was out of range.
+	 */
+	if (exact)
+		kp->equal = factor;
+	else {
+		if (kp->less != 1)
+			kp->greater += factor;
+		kp->equal = 0;
+	}
+
+	if ((ret = __bam_stkrel(dbc, 0)) != 0)
+		return (ret);
+
+	return (0);
+}
+
+/*
+ * __bam_traverse --
+ *	Walk a Btree database.
+ *
+ * PUBLIC: int __bam_traverse __P((DBC *, db_lockmode_t,
+ * PUBLIC:     db_pgno_t, int (*)(DBC *, PAGE *, void *, int *), void *));
+ */
+int
+__bam_traverse(dbc, mode, root_pgno, callback, cookie)
+	DBC *dbc;
+	db_lockmode_t mode;
+	db_pgno_t root_pgno;
+	int (*callback)__P((DBC *, PAGE *, void *, int *));
+	void *cookie;
+{
+	BINTERNAL *bi;
+	BKEYDATA *bk;
+	DB *dbp;
+	DB_LOCK lock;
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	RINTERNAL *ri;
+	db_indx_t indx, *inp;
+	int already_put, ret, t_ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	already_put = 0;
+	LOCK_INIT(lock);
+
+	COMPQUIET(h, NULL);
+	BAM_GET_ROOT(dbc, root_pgno, h, 0, mode, lock, ret);
+	if (ret != 0)
+		goto err1;
+
+	switch (TYPE(h)) {
+	case P_IBTREE:
+		for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) {
+			bi = GET_BINTERNAL(dbp, h, indx);
+			if (B_TYPE(bi->type) == B_OVERFLOW &&
+			    (ret = __db_traverse_big(dbc,
+			    ((BOVERFLOW *)bi->data)->pgno,
+			    callback, cookie)) != 0)
+				goto err;
+			if ((ret = __bam_traverse(
+			    dbc, mode, bi->pgno, callback, cookie)) != 0)
+				goto err;
+		}
+		break;
+	case P_IRECNO:
+		for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) {
+			ri = GET_RINTERNAL(dbp, h, indx);
+			if ((ret = __bam_traverse(
+			    dbc, mode, ri->pgno, callback, cookie)) != 0)
+				goto err;
+		}
+		break;
+	case P_LBTREE:
+		inp = P_INP(dbp, h);
+		for (indx = 0; indx < NUM_ENT(h); indx += P_INDX) {
+			bk = GET_BKEYDATA(dbp, h, indx);
+			if (B_TYPE(bk->type) == B_OVERFLOW &&
+			    (indx + P_INDX >= NUM_ENT(h) ||
+			    inp[indx] != inp[indx + P_INDX])) {
+				if ((ret = __db_traverse_big(dbc,
+				    GET_BOVERFLOW(dbp, h, indx)->pgno,
+				    callback, cookie)) != 0)
+					goto err;
+			}
+			bk = GET_BKEYDATA(dbp, h, indx + O_INDX);
+			if (B_TYPE(bk->type) == B_DUPLICATE &&
+			    (ret = __bam_traverse(dbc, mode,
+			    GET_BOVERFLOW(dbp, h, indx + O_INDX)->pgno,
+			    callback, cookie)) != 0)
+				goto err;
+			if (B_TYPE(bk->type) == B_OVERFLOW &&
+			    (ret = __db_traverse_big(dbc,
+			    GET_BOVERFLOW(dbp, h, indx + O_INDX)->pgno,
+			    callback, cookie)) != 0)
+				goto err;
+		}
+		break;
+	case P_LDUP:
+	case P_LRECNO:
+		for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) {
+			bk = GET_BKEYDATA(dbp, h, indx);
+			if (B_TYPE(bk->type) == B_OVERFLOW &&
+			    (ret = __db_traverse_big(dbc,
+			    GET_BOVERFLOW(dbp, h, indx)->pgno,
+			    callback, cookie)) != 0)
+				goto err;
+		}
+		break;
+	default:
+		return (__db_pgfmt(dbp->env, h->pgno));
+	}
+
+	ret = callback(dbc, h, cookie, &already_put);
+
+err:	if (!already_put && (t_ret = __memp_fput(mpf,
+	    dbc->thread_info, h, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+err1:	if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/btree/bt_verify.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,2827 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_verify.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+
+static int __bam_safe_getdata __P((DB *, DB_THREAD_INFO *,
+    PAGE *, u_int32_t, int, DBT *, int *));
+static int __bam_vrfy_inp __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
+    db_indx_t *, u_int32_t));
+static int __bam_vrfy_treeorder __P((DB *, DB_THREAD_INFO *, PAGE *,
+    BINTERNAL *, BINTERNAL *, int (*)(DB *, const DBT *, const DBT *),
+    u_int32_t));
+static int __ram_vrfy_inp __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
+    db_indx_t *, u_int32_t));
+
+/*
+ * __bam_vrfy_meta --
+ *	Verify the btree-specific part of a metadata page.
+ *
+ * PUBLIC: int __bam_vrfy_meta __P((DB *, VRFY_DBINFO *, BTMETA *,
+ * PUBLIC:     db_pgno_t, u_int32_t));
+ */
+int
+__bam_vrfy_meta(dbp, vdp, meta, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	BTMETA *meta;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	int isbad, t_ret, ret;
+	db_indx_t ovflsize;
+
+	env = dbp->env;
+	isbad = 0;
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+
+	/*
+	 * If we came through __db_vrfy_pagezero, we have already checked the
+	 * common fields.  However, we used the on-disk metadata page, it may
+	 * have been stale.  We now have the page from mpool, so check that.
+	 */
+	if ((ret = __db_vrfy_meta(dbp, vdp, &meta->dbmeta, pgno, flags)) != 0) {
+		if (ret == DB_VERIFY_BAD)
+			isbad = 1;
+		else
+			goto err;
+	}
+
+	/* bt_minkey:  must be >= 2; must produce sensible ovflsize */
+
+	/* avoid division by zero */
+	ovflsize = meta->minkey > 0 ?
+	    B_MINKEY_TO_OVFLSIZE(dbp, meta->minkey, dbp->pgsize) : 0;
+
+	if (meta->minkey < 2 ||
+	    ovflsize > B_MINKEY_TO_OVFLSIZE(dbp, DEFMINKEYPAGE, dbp->pgsize)) {
+		pip->bt_minkey = 0;
+		isbad = 1;
+		EPRINT((env, DB_STR_A("1034",
+	    "Page %lu: nonsensical bt_minkey value %lu on metadata page",
+		    "%lu %lu"), (u_long)pgno, (u_long)meta->minkey));
+	} else
+		pip->bt_minkey = meta->minkey;
+
+	/* re_len: no constraints on this (may be zero or huge--we make rope) */
+	pip->re_pad = meta->re_pad;
+	pip->re_len = meta->re_len;
+
+	/*
+	 * The root must not be current page or 0 and it must be within
+	 * database.  If this metadata page is the master meta data page
+	 * of the file, then the root page had better be page 1.
+	 */
+	pip->root = 0;
+	if (meta->root == PGNO_INVALID ||
+	    meta->root == pgno || !IS_VALID_PGNO(meta->root) ||
+	    (pgno == PGNO_BASE_MD && meta->root != 1)) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("1035",
+		    "Page %lu: nonsensical root page %lu on metadata page",
+		    "%lu %lu"), (u_long)pgno, (u_long)meta->root));
+	} else
+		pip->root = meta->root;
+
+	/* Flags. */
+	if (F_ISSET(&meta->dbmeta, BTM_RENUMBER))
+		F_SET(pip, VRFY_IS_RRECNO);
+
+	if (F_ISSET(&meta->dbmeta, BTM_SUBDB)) {
+		/*
+		 * If this is a master db meta page, it had better not have
+		 * duplicates.
+		 */
+		if (F_ISSET(&meta->dbmeta, BTM_DUP) && pgno == PGNO_BASE_MD) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("1036",
+"Page %lu: Btree metadata page has both duplicates and multiple databases",
+			    "%lu"), (u_long)pgno));
+		}
+		F_SET(pip, VRFY_HAS_SUBDBS);
+	}
+
+	if (F_ISSET(&meta->dbmeta, BTM_DUP))
+		F_SET(pip, VRFY_HAS_DUPS);
+	if (F_ISSET(&meta->dbmeta, BTM_DUPSORT))
+		F_SET(pip, VRFY_HAS_DUPSORT);
+	if (F_ISSET(&meta->dbmeta, BTM_RECNUM))
+		F_SET(pip, VRFY_HAS_RECNUMS);
+	if (F_ISSET(pip, VRFY_HAS_RECNUMS) && F_ISSET(pip, VRFY_HAS_DUPS)) {
+		EPRINT((env, DB_STR_A("1037",
+    "Page %lu: Btree metadata page illegally has both recnums and dups",
+		    "%lu"), (u_long)pgno));
+		isbad = 1;
+	}
+
+	if (F_ISSET(&meta->dbmeta, BTM_RECNO)) {
+		F_SET(pip, VRFY_IS_RECNO);
+		dbp->type = DB_RECNO;
+	} else if (F_ISSET(pip, VRFY_IS_RRECNO)) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("1038",
+    "Page %lu: metadata page has renumber flag set but is not recno",
+		    "%lu"), (u_long)pgno));
+	}
+
+#ifdef HAVE_COMPRESSION
+	if (F_ISSET(&meta->dbmeta, BTM_COMPRESS)) {
+		F_SET(pip, VRFY_HAS_COMPRESS);
+		if (!DB_IS_COMPRESSED(dbp)) {
+			((BTREE *)dbp->bt_internal)->bt_compress =
+			    __bam_defcompress;
+			((BTREE *)dbp->bt_internal)->bt_decompress =
+			    __bam_defdecompress;
+		}
+		/*
+		 * Copy dup_compare to compress_dup_compare, and use the
+		 * compression duplicate compare.
+		 */
+		if (F_ISSET(pip, VRFY_HAS_DUPSORT)) {
+			if (dbp->dup_compare == NULL)
+				dbp->dup_compare = __bam_defcmp;
+			if (((BTREE *)dbp->bt_internal)->compress_dup_compare
+				== NULL) {
+				((BTREE *)dbp->bt_internal)->
+					compress_dup_compare = dbp->dup_compare;
+				dbp->dup_compare = __bam_compress_dupcmp;
+			}
+		}
+	}
+
+	if (F_ISSET(pip, VRFY_HAS_RECNUMS) && F_ISSET(pip, VRFY_HAS_COMPRESS)) {
+		EPRINT((env, DB_STR_A("1039",
+    "Page %lu: Btree metadata page illegally has both recnums and compression",
+		    "%lu"), (u_long)pgno));
+		isbad = 1;
+	}
+	if (F_ISSET(pip, VRFY_HAS_DUPS) && !F_ISSET(pip, VRFY_HAS_DUPSORT) &&
+	    F_ISSET(pip, VRFY_HAS_COMPRESS)) {
+		EPRINT((env, DB_STR_A("1040",
+		    "Page %lu: Btree metadata page illegally has both "
+		    "unsorted duplicates and compression",
+		    "%lu"), (u_long)pgno));
+		isbad = 1;
+	}
+#endif
+
+	if (F_ISSET(pip, VRFY_IS_RECNO) && F_ISSET(pip, VRFY_HAS_DUPS)) {
+		EPRINT((env, DB_STR_A("1041",
+		    "Page %lu: recno metadata page specifies duplicates",
+		    "%lu"), (u_long)pgno));
+		isbad = 1;
+	}
+
+	if (F_ISSET(&meta->dbmeta, BTM_FIXEDLEN))
+		F_SET(pip, VRFY_IS_FIXEDLEN);
+	else if (pip->re_len > 0) {
+		/*
+		 * It's wrong to have an re_len if it's not a fixed-length
+		 * database
+		 */
+		isbad = 1;
+		EPRINT((env, DB_STR_A("1042",
+		    "Page %lu: re_len of %lu in non-fixed-length database",
+		    "%lu %lu"), (u_long)pgno, (u_long)pip->re_len));
+	}
+
+	/*
+	 * We do not check that the rest of the page is 0, because it may
+	 * not be and may still be correct.
+	 */
+
+err:	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+	if (LF_ISSET(DB_SALVAGE) &&
+	   (t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0)
+		ret = t_ret;
+	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __ram_vrfy_leaf --
+ *	Verify a recno leaf page.
+ *
+ * PUBLIC: int __ram_vrfy_leaf __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
+ * PUBLIC:     u_int32_t));
+ */
+int
+__ram_vrfy_leaf(dbp, vdp, h, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	BKEYDATA *bk;
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	db_indx_t i;
+	int ret, t_ret, isbad;
+	u_int32_t re_len_guess, len;
+
+	env = dbp->env;
+	isbad = 0;
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+
+	if (TYPE(h) != P_LRECNO) {
+		ret = __db_unknown_path(env, "__ram_vrfy_leaf");
+		goto err;
+	}
+
+	/*
+	 * Verify (and, if relevant, save off) page fields common to
+	 * all PAGEs.
+	 */
+	if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) {
+		if (ret == DB_VERIFY_BAD)
+			isbad = 1;
+		else
+			goto err;
+	}
+
+	/*
+	 * Verify inp[].  Return immediately if it returns DB_VERIFY_BAD;
+	 * further checks are dangerous.
+	 */
+	if ((ret = __bam_vrfy_inp(dbp,
+	    vdp, h, pgno, &pip->entries, flags)) != 0)
+		goto err;
+
+	if (F_ISSET(pip, VRFY_HAS_DUPS)) {
+		EPRINT((env, DB_STR_A("1043",
+		    "Page %lu: Recno database has dups",
+		    "%lu"), (u_long)pgno));
+		ret = DB_VERIFY_BAD;
+		goto err;
+	}
+
+	/*
+	 * Walk through inp and see if the lengths of all the records are the
+	 * same--if so, this may be a fixed-length database, and we want to
+	 * save off this value.  We know inp to be safe if we've gotten this
+	 * far.
+	 */
+	re_len_guess = 0;
+	for (i = 0; i < NUM_ENT(h); i++) {
+		bk = GET_BKEYDATA(dbp, h, i);
+		/* KEYEMPTY.  Go on. */
+		if (B_DISSET(bk->type))
+			continue;
+		if (bk->type == B_OVERFLOW)
+			len = ((BOVERFLOW *)bk)->tlen;
+		else if (bk->type == B_KEYDATA)
+			len = bk->len;
+		else {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("1044",
+			    "Page %lu: nonsensical type for item %lu",
+			    "%lu %lu"), (u_long)pgno, (u_long)i));
+			continue;
+		}
+		if (re_len_guess == 0)
+			re_len_guess = len;
+
+		/*
+		 * Is this item's len the same as the last one's?  If not,
+		 * reset to 0 and break--we don't have a single re_len.
+		 * Otherwise, go on to the next item.
+		 */
+		if (re_len_guess != len) {
+			re_len_guess = 0;
+			break;
+		}
+	}
+	pip->re_len = re_len_guess;
+
+	/* Save off record count. */
+	pip->rec_cnt = NUM_ENT(h);
+
+err:	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __bam_vrfy --
+ *	Verify a btree leaf or internal page.
+ *
+ * PUBLIC: int __bam_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
+ * PUBLIC:     u_int32_t));
+ */
+int
+__bam_vrfy(dbp, vdp, h, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	int ret, t_ret, isbad;
+
+	env = dbp->env;
+	isbad = 0;
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+
+	switch (TYPE(h)) {
+	case P_IBTREE:
+	case P_IRECNO:
+	case P_LBTREE:
+	case P_LDUP:
+		break;
+	default:
+		ret = __db_unknown_path(env, "__bam_vrfy");
+		goto err;
+	}
+
+	/*
+	 * Verify (and, if relevant, save off) page fields common to
+	 * all PAGEs.
+	 */
+	if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) {
+		if (ret == DB_VERIFY_BAD)
+			isbad = 1;
+		else
+			goto err;
+	}
+
+	/*
+	 * The record count is, on internal pages, stored in an overloaded
+	 * next_pgno field.  Save it off;  we'll verify it when we check
+	 * overall database structure.  We could overload the field
+	 * in VRFY_PAGEINFO, too, but this seems gross, and space
+	 * is not at such a premium.
+	 */
+	pip->rec_cnt = RE_NREC(h);
+
+	/*
+	 * Verify inp[].
+	 */
+	if (TYPE(h) == P_IRECNO) {
+		if ((ret = __ram_vrfy_inp(dbp,
+		    vdp, h, pgno, &pip->entries, flags)) != 0)
+			goto err;
+	} else if ((ret = __bam_vrfy_inp(dbp,
+	    vdp, h, pgno, &pip->entries, flags)) != 0) {
+		if (ret == DB_VERIFY_BAD)
+			isbad = 1;
+		else
+			goto err;
+		EPRINT((env, DB_STR_A("1045",
+		    "Page %lu: item order check unsafe: skipping",
+		    "%lu"), (u_long)pgno));
+	} else if (!LF_ISSET(DB_NOORDERCHK) && (ret =
+	    __bam_vrfy_itemorder(dbp,
+	    vdp, vdp->thread_info, h, pgno, 0, 0, 0, flags)) != 0) {
+		/*
+		 * We know that the elements of inp are reasonable.
+		 *
+		 * Check that elements fall in the proper order.
+		 */
+		if (ret == DB_VERIFY_BAD)
+			isbad = 1;
+		else
+			goto err;
+	}
+
+err:	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __ram_vrfy_inp --
+ *	Verify that all entries in a P_IRECNO inp[] array are reasonable,
+ *	and count them.  Note that P_LRECNO uses __bam_vrfy_inp;
+ *	P_IRECNOs are a special, and simpler, case, since they have
+ *	RINTERNALs rather than BKEYDATA/BINTERNALs.
+ */
+static int
+__ram_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	PAGE *h;
+	db_pgno_t pgno;
+	db_indx_t *nentriesp;
+	u_int32_t flags;
+{
+	ENV *env;
+	RINTERNAL *ri;
+	VRFY_CHILDINFO child;
+	VRFY_PAGEINFO *pip;
+	int ret, t_ret, isbad;
+	u_int32_t himark, i, offset, nentries;
+	db_indx_t *inp;
+	u_int8_t *pagelayout, *p;
+
+	env = dbp->env;
+	isbad = 0;
+	memset(&child, 0, sizeof(VRFY_CHILDINFO));
+	nentries = 0;
+	pagelayout = NULL;
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+
+	if (TYPE(h) != P_IRECNO) {
+		ret = __db_unknown_path(env, "__ram_vrfy_inp");
+		goto err;
+	}
+
+	himark = dbp->pgsize;
+	if ((ret = __os_malloc(env, dbp->pgsize, &pagelayout)) != 0)
+		goto err;
+	memset(pagelayout, 0, dbp->pgsize);
+	inp = P_INP(dbp, h);
+	for (i = 0; i < NUM_ENT(h); i++) {
+		if ((u_int8_t *)inp + i >= (u_int8_t *)h + himark) {
+			EPRINT((env, DB_STR_A("1046",
+			    "Page %lu: entries listing %lu overlaps data",
+			    "%lu %lu"), (u_long)pgno, (u_long)i));
+			ret = DB_VERIFY_BAD;
+			goto err;
+		}
+		offset = inp[i];
+		/*
+		 * Check that the item offset is reasonable:  it points
+		 * somewhere after the inp array and before the end of the
+		 * page.
+		 */
+		if (offset <= (u_int32_t)((u_int8_t *)inp + i -
+		    (u_int8_t *)h) ||
+		    offset > (u_int32_t)(dbp->pgsize - RINTERNAL_SIZE)) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("1047",
+			    "Page %lu: bad offset %lu at index %lu",
+			    "%lu %lu %lu"), (u_long)pgno, (u_long)offset,
+			    (u_long)i));
+			continue;
+		}
+
+		/* Update the high-water mark (what HOFFSET should be) */
+		if (offset < himark)
+			himark = offset;
+
+		nentries++;
+
+		/* Make sure this RINTERNAL is not multiply referenced. */
+		ri = GET_RINTERNAL(dbp, h, i);
+		if (pagelayout[offset] == 0) {
+			pagelayout[offset] = 1;
+			child.pgno = ri->pgno;
+			child.type = V_RECNO;
+			child.nrecs = ri->nrecs;
+			if ((ret = __db_vrfy_childput(vdp, pgno, &child)) != 0)
+				goto err;
+		} else {
+			EPRINT((env, DB_STR_A("1048",
+		"Page %lu: RINTERNAL structure at offset %lu referenced twice",
+			    "%lu %lu"), (u_long)pgno, (u_long)offset));
+			isbad = 1;
+		}
+	}
+
+	for (p = pagelayout + himark;
+	    p < pagelayout + dbp->pgsize;
+	    p += RINTERNAL_SIZE)
+		if (*p != 1) {
+			EPRINT((env, DB_STR_A("1049",
+			    "Page %lu: gap between items at offset %lu",
+			    "%lu %lu"), (u_long)pgno,
+			    (u_long)(p - pagelayout)));
+			isbad = 1;
+		}
+
+	if ((db_indx_t)himark != HOFFSET(h)) {
+		EPRINT((env, DB_STR_A("1050",
+		    "Page %lu: bad HOFFSET %lu, appears to be %lu",
+		    "%lu %lu %lu"), (u_long)pgno, (u_long)(HOFFSET(h)),
+		    (u_long)himark));
+		isbad = 1;
+	}
+
+	*nentriesp = nentries;
+
+err:	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+	if (pagelayout != NULL)
+		__os_free(env, pagelayout);
+	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
+}
+
+typedef enum { VRFY_ITEM_NOTSET=0, VRFY_ITEM_BEGIN, VRFY_ITEM_END } VRFY_ITEM;
+
+/*
+ * __bam_vrfy_inp --
+ *	Verify that all entries in inp[] array are reasonable;
+ *	count them.
+ */
+static int
+__bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	PAGE *h;
+	db_pgno_t pgno;
+	db_indx_t *nentriesp;
+	u_int32_t flags;
+{
+	BKEYDATA *bk;
+	BOVERFLOW *bo;
+	ENV *env;
+	VRFY_CHILDINFO child;
+	VRFY_ITEM *pagelayout;
+	VRFY_PAGEINFO *pip;
+	u_int32_t himark, offset;		/*
+						 * These would be db_indx_ts
+						 * but for alignment.
+						 */
+	u_int32_t i, endoff, nentries;
+	int isbad, initem, isdupitem, ret, t_ret;
+
+	env = dbp->env;
+	isbad = isdupitem = 0;
+	nentries = 0;
+	memset(&child, 0, sizeof(VRFY_CHILDINFO));
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+
+	switch (TYPE(h)) {
+	case P_IBTREE:
+	case P_LBTREE:
+	case P_LDUP:
+	case P_LRECNO:
+		break;
+	default:
+		/*
+		 * In the salvager, we might call this from a page which
+		 * we merely suspect is a btree page.  Otherwise, it
+		 * shouldn't get called--if it is, that's a verifier bug.
+		 */
+		if (LF_ISSET(DB_SALVAGE))
+			break;
+		ret = __db_unknown_path(env, "__bam_vrfy_inp");
+		goto err;
+	}
+
+	/*
+	 * Loop through inp[], the array of items, until we either
+	 * run out of entries or collide with the data.  Keep track
+	 * of h_offset in himark.
+	 *
+	 * For each element in inp[i], make sure it references a region
+	 * that starts after the end of the inp array (as defined by
+	 * NUM_ENT(h)), ends before the beginning of the page, doesn't
+	 * overlap any other regions, and doesn't have a gap between
+	 * it and the region immediately after it.
+	 */
+	himark = dbp->pgsize;
+	if ((ret = __os_calloc(
+	    env, dbp->pgsize, sizeof(pagelayout[0]), &pagelayout)) != 0)
+		goto err;
+	for (i = 0; i < NUM_ENT(h); i++) {
+		switch (ret = __db_vrfy_inpitem(dbp,
+		    h, pgno, i, 1, flags, &himark, &offset)) {
+		case 0:
+			break;
+		case DB_VERIFY_BAD:
+			isbad = 1;
+			continue;
+		case DB_VERIFY_FATAL:
+			isbad = 1;
+			goto err;
+		default:
+			DB_ASSERT(env, ret != 0);
+			break;
+		}
+
+		/*
+		 * We now have a plausible beginning for the item, and we know
+		 * its length is safe.
+		 *
+		 * Mark the beginning and end in pagelayout so we can make sure
+		 * items have no overlaps or gaps.
+		 */
+		bk = GET_BKEYDATA(dbp, h, i);
+		if (pagelayout[offset] == VRFY_ITEM_NOTSET)
+			pagelayout[offset] = VRFY_ITEM_BEGIN;
+		else if (pagelayout[offset] == VRFY_ITEM_BEGIN) {
+			/*
+			 * Having two inp entries that point at the same patch
+			 * of page is legal if and only if the page is
+			 * a btree leaf and they're onpage duplicate keys--
+			 * that is, if (i % P_INDX) == 0.
+			 */
+			if ((i % P_INDX == 0) && (TYPE(h) == P_LBTREE)) {
+				/* Flag for later. */
+				F_SET(pip, VRFY_HAS_DUPS);
+
+				/* Bump up nentries so we don't undercount. */
+				nentries++;
+
+				/*
+				 * We'll check to make sure the end is
+				 * equal, too.
+				 */
+				isdupitem = 1;
+			} else {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1051",
+				    "Page %lu: duplicated item %lu",
+				    "%lu %lu"), (u_long)pgno, (u_long)i));
+			}
+		}
+
+		/*
+		 * Mark the end.  Its location varies with the page type
+		 * and the item type.
+		 *
+		 * If the end already has a sign other than 0, do nothing--
+		 * it's an overlap that we'll catch later.
+		 */
+		switch (B_TYPE(bk->type)) {
+		case B_KEYDATA:
+			if (TYPE(h) == P_IBTREE)
+				/* It's a BINTERNAL. */
+				endoff = offset + BINTERNAL_SIZE(bk->len) - 1;
+			else
+				endoff = offset + BKEYDATA_SIZE(bk->len) - 1;
+			break;
+		case B_DUPLICATE:
+			/*
+			 * Flag that we have dups; we'll check whether
+			 * that's okay during the structure check.
+			 */
+			F_SET(pip, VRFY_HAS_DUPS);
+			/* FALLTHROUGH */
+		case B_OVERFLOW:
+			/*
+			 * Overflow entries on internal pages are stored
+			 * as the _data_ of a BINTERNAL;  overflow entries
+			 * on leaf pages are stored as the entire entry.
+			 */
+			endoff = offset +
+			    ((TYPE(h) == P_IBTREE) ?
+			    BINTERNAL_SIZE(BOVERFLOW_SIZE) :
+			    BOVERFLOW_SIZE) - 1;
+			break;
+		default:
+			/*
+			 * We'll complain later;  for now, just mark
+			 * a minimum.
+			 */
+			endoff = offset + BKEYDATA_SIZE(0) - 1;
+			break;
+		}
+
+		/*
+		 * If this is an onpage duplicate key we've seen before,
+		 * the end had better coincide too.
+		 */
+		if (isdupitem && pagelayout[endoff] != VRFY_ITEM_END) {
+			EPRINT((env, DB_STR_A("1052",
+			    "Page %lu: duplicated item %lu",
+			    "%lu %lu"), (u_long)pgno, (u_long)i));
+			isbad = 1;
+		} else if (pagelayout[endoff] == VRFY_ITEM_NOTSET)
+			pagelayout[endoff] = VRFY_ITEM_END;
+		isdupitem = 0;
+
+		/*
+		 * There should be no deleted items in a quiescent tree,
+		 * except in recno.
+		 */
+		if (B_DISSET(bk->type) && TYPE(h) != P_LRECNO) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("1053",
+			    "Page %lu: item %lu marked deleted", "%lu %lu"),
+			    (u_long)pgno, (u_long)i));
+		}
+
+		/*
+		 * Check the type and such of bk--make sure it's reasonable
+		 * for the pagetype.
+		 */
+		switch (B_TYPE(bk->type)) {
+		case B_KEYDATA:
+			/*
+			 * This is a normal, non-overflow BKEYDATA or BINTERNAL.
+			 * The only thing to check is the len, and that's
+			 * already been done.
+			 */
+			break;
+		case B_DUPLICATE:
+			if (TYPE(h) == P_IBTREE) {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1054",
+    "Page %lu: duplicate page referenced by internal btree page at item %lu",
+				    "%lu %lu"), (u_long)pgno, (u_long)i));
+				break;
+			} else if (TYPE(h) == P_LRECNO) {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1055",
+	"Page %lu: duplicate page referenced by recno page at item %lu",
+				    "%lu %lu"), (u_long)pgno, (u_long)i));
+				break;
+			}
+			/* FALLTHROUGH */
+		case B_OVERFLOW:
+			bo = (TYPE(h) == P_IBTREE) ?
+			    (BOVERFLOW *)(((BINTERNAL *)bk)->data) :
+			    (BOVERFLOW *)bk;
+
+			if (B_TYPE(bk->type) == B_OVERFLOW)
+				/* Make sure tlen is reasonable. */
+				if (bo->tlen > dbp->pgsize * vdp->last_pgno) {
+					isbad = 1;
+					EPRINT((env, DB_STR_A("1056",
+				"Page %lu: impossible tlen %lu, item %lu",
+					    "%lu %lu %lu"), (u_long)pgno,
+					    (u_long)bo->tlen, (u_long)i));
+					/* Don't save as a child. */
+					break;
+				}
+
+			if (!IS_VALID_PGNO(bo->pgno) || bo->pgno == pgno ||
+			    bo->pgno == PGNO_INVALID) {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1057",
+			    "Page %lu: offpage item %lu has bad pgno %lu",
+				    "%lu %lu %lu"), (u_long)pgno, (u_long)i,
+				    (u_long)bo->pgno));
+				/* Don't save as a child. */
+				break;
+			}
+
+			child.pgno = bo->pgno;
+			child.type = (B_TYPE(bk->type) == B_OVERFLOW ?
+			    V_OVERFLOW : V_DUPLICATE);
+			child.tlen = bo->tlen;
+			if ((ret = __db_vrfy_childput(vdp, pgno, &child)) != 0)
+				goto err;
+			break;
+		default:
+			isbad = 1;
+			EPRINT((env, DB_STR_A("1058",
+			    "Page %lu: item %lu of invalid type %lu",
+			    "%lu %lu %lu"), (u_long)pgno, (u_long)i,
+			    (u_long)B_TYPE(bk->type)));
+			break;
+		}
+	}
+
+	/*
+	 * Now, loop through and make sure the items are contiguous and
+	 * non-overlapping.
+	 */
+	initem = 0;
+	for (i = himark; i < dbp->pgsize; i++)
+		if (initem == 0)
+			switch (pagelayout[i]) {
+			case VRFY_ITEM_NOTSET:
+				/* May be just for alignment. */
+				if (i != DB_ALIGN(i, sizeof(u_int32_t)))
+					continue;
+
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1059",
+				    "Page %lu: gap between items at offset %lu",
+				    "%lu %lu"), (u_long)pgno, (u_long)i));
+				/* Find the end of the gap */
+				for (; pagelayout[i + 1] == VRFY_ITEM_NOTSET &&
+				    (size_t)(i + 1) < dbp->pgsize; i++)
+					;
+				break;
+			case VRFY_ITEM_BEGIN:
+				/* We've found an item. Check its alignment. */
+				if (i != DB_ALIGN(i, sizeof(u_int32_t))) {
+					isbad = 1;
+					EPRINT((env, DB_STR_A("1060",
+					    "Page %lu: offset %lu unaligned",
+					    "%lu %lu"), (u_long)pgno,
+					    (u_long)i));
+				}
+				initem = 1;
+				nentries++;
+				break;
+			case VRFY_ITEM_END:
+				/*
+				 * We've hit the end of an item even though
+				 * we don't think we're in one;  must
+				 * be an overlap.
+				 */
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1061",
+				    "Page %lu: overlapping items at offset %lu",
+				    "%lu %lu"), (u_long)pgno, (u_long)i));
+				break;
+			}
+		else
+			switch (pagelayout[i]) {
+			case VRFY_ITEM_NOTSET:
+				/* In the middle of an item somewhere. Okay. */
+				break;
+			case VRFY_ITEM_END:
+				/* End of an item; switch to out-of-item mode.*/
+				initem = 0;
+				break;
+			case VRFY_ITEM_BEGIN:
+				/*
+				 * Hit a second item beginning without an
+				 * end.  Overlap.
+				 */
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1062",
+				    "Page %lu: overlapping items at offset %lu",
+				    "%lu %lu"), (u_long)pgno, (u_long)i));
+				break;
+			}
+
+	__os_free(env, pagelayout);
+
+	/* Verify HOFFSET. */
+	if ((db_indx_t)himark != HOFFSET(h)) {
+		EPRINT((env, DB_STR_A("1063",
+		    "Page %lu: bad HOFFSET %lu, appears to be %lu",
+		    "%lu %lu %lu"), (u_long)pgno, (u_long)HOFFSET(h),
+		    (u_long)himark));
+		isbad = 1;
+	}
+
+err:	if (nentriesp != NULL)
+		*nentriesp = nentries;
+
+	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __bam_vrfy_itemorder --
+ *	Make sure the items on a page sort correctly.
+ *
+ *	Assumes that NUM_ENT(h) and inp[0]..inp[NUM_ENT(h) - 1] are
+ *	reasonable;  be sure that __bam_vrfy_inp has been called first.
+ *
+ *	If ovflok is set, it also assumes that overflow page chains
+ *	hanging off the current page have been sanity-checked, and so we
+ *	can use __bam_cmp to verify their ordering.  If it is not set,
+ *	and we run into an overflow page, carp and return DB_VERIFY_BAD;
+ *	we shouldn't be called if any exist.
+ *
+ * PUBLIC: int __bam_vrfy_itemorder __P((DB *, VRFY_DBINFO *, DB_THREAD_INFO *,
+ * PUBLIC:      PAGE *, db_pgno_t, u_int32_t, int, int, u_int32_t));
+ */
+int
+__bam_vrfy_itemorder(dbp, vdp, ip, h, pgno, nentries, ovflok, hasdups, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	DB_THREAD_INFO *ip;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int32_t nentries;
+	int ovflok, hasdups;
+	u_int32_t flags;
+{
+	BINTERNAL *bi;
+	BKEYDATA *bk;
+	BOVERFLOW *bo;
+	BTREE *bt;
+	DB_MPOOLFILE *mpf;
+	DBC *dbc;
+	DBT dbta, dbtb, dup_1, dup_2, *p1, *p2, *tmp;
+	ENV *env;
+	PAGE *child;
+	db_pgno_t cpgno;
+	VRFY_PAGEINFO *pip;
+	db_indx_t i, *inp;
+	int adj, cmp, freedup_1, freedup_2, isbad, ret, t_ret;
+	int (*dupfunc) __P((DB *, const DBT *, const DBT *));
+	int (*func) __P((DB *, const DBT *, const DBT *));
+	void *buf1, *buf2, *tmpbuf;
+
+	/*
+	 * We need to work in the ORDERCHKONLY environment where we might
+	 * not have a pip, but we also may need to work in contexts where
+	 * NUM_ENT isn't safe.
+	 */
+	if (vdp != NULL) {
+		if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+			return (ret);
+		nentries = pip->entries;
+	} else
+		pip = NULL;
+
+	env = dbp->env;
+	ret = isbad = 0;
+	bo = NULL;			/* Shut up compiler. */
+
+	memset(&dbta, 0, sizeof(DBT));
+	F_SET(&dbta, DB_DBT_REALLOC);
+
+	memset(&dbtb, 0, sizeof(DBT));
+	F_SET(&dbtb, DB_DBT_REALLOC);
+
+	buf1 = buf2 = NULL;
+
+	DB_ASSERT(env, !LF_ISSET(DB_NOORDERCHK));
+
+	dupfunc = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare;
+	if (TYPE(h) == P_LDUP)
+		func = dupfunc;
+	else {
+		func = __bam_defcmp;
+		if (dbp->bt_internal != NULL) {
+			bt = (BTREE *)dbp->bt_internal;
+			if (TYPE(h) == P_IBTREE && (bt->bt_compare != NULL ||
+			    dupfunc != __bam_defcmp)) {
+				/*
+				 * The problem here is that we cannot
+				 * tell the difference between an off
+				 * page duplicate internal page and
+				 * a main database internal page.
+				 * Walk down the tree to figure it out.
+				 */
+				mpf = dbp->mpf;
+				child = h;
+				while (TYPE(child) == P_IBTREE) {
+					bi = GET_BINTERNAL(dbp, child, 0);
+					cpgno = bi->pgno;
+					if (child != h &&
+					    (ret = __memp_fput(mpf,
+					    vdp->thread_info, child,
+					    DB_PRIORITY_UNCHANGED)) != 0)
+						goto err;
+					if ((ret = __memp_fget(mpf,
+					    &cpgno, vdp->thread_info,
+					    NULL, 0, &child)) != 0)
+						goto err;
+				}
+				if (TYPE(child) == P_LDUP)
+					func = dupfunc;
+				else if (bt->bt_compare != NULL)
+					func = bt->bt_compare;
+				if ((ret = __memp_fput(mpf, vdp->thread_info,
+				    child, DB_PRIORITY_UNCHANGED)) != 0)
+					goto err;
+			} else if (bt->bt_compare != NULL)
+				func = bt->bt_compare;
+		}
+	}
+
+	/*
+	 * We alternate our use of dbta and dbtb so that we can walk
+	 * through the page key-by-key without copying a dbt twice.
+	 * p1 is always the dbt for index i - 1, and p2 for index i.
+	 * Reset the data pointers in case we are retrying.
+	 */
+retry:	p1 = &dbta;
+	p1->data = NULL;
+	p2 = &dbtb;
+	p2->data = NULL;
+
+	/*
+	 * Loop through the entries.  nentries ought to contain the
+	 * actual count, and so is a safe way to terminate the loop;  whether
+	 * we inc. by one or two depends on whether we're a leaf page--
+	 * on a leaf page, we care only about keys.  On internal pages
+	 * and LDUP pages, we want to check the order of all entries.
+	 *
+	 * Note that on IBTREE pages or the index page of a partitioned
+	 * database, we start with item 1, since item 0 doesn't get looked
+	 * at by __bam_cmp.
+	 */
+	inp = P_INP(dbp, h);
+	adj = (TYPE(h) == P_LBTREE) ? P_INDX : O_INDX;
+	for (i = (TYPE(h) == P_IBTREE || dbp->p_internal != NULL) ? adj : 0;
+	    i < nentries; i += adj) {
+		/*
+		 * Put key i-1, now in p2, into p1, by swapping DBTs and bufs.
+		 */
+		tmp = p1;
+		p1 = p2;
+		p2 = tmp;
+		tmpbuf = buf1;
+		buf1 = buf2;
+		buf2 = tmpbuf;
+
+		/*
+		 * Get key i into p2.
+		 */
+		switch (TYPE(h)) {
+		case P_IBTREE:
+			bi = GET_BINTERNAL(dbp, h, i);
+			if (B_TYPE(bi->type) == B_OVERFLOW) {
+				bo = (BOVERFLOW *)(bi->data);
+				goto overflow;
+			} else {
+				p2->data = bi->data;
+				p2->size = bi->len;
+			}
+
+			/*
+			 * The leftmost key on an internal page must be
+			 * len 0, since it's just a placeholder and
+			 * automatically sorts less than all keys.
+			 *
+			 * XXX
+			 * This criterion does not currently hold!
+			 * See todo list item #1686.  Meanwhile, it's harmless
+			 * to just not check for it.
+			 */
+#if 0
+			if (i == 0 && bi->len != 0) {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1064",
+		"Page %lu: lowest key on internal page of nonzero length",
+				    "%lu"), (u_long)pgno));
+			}
+#endif
+			break;
+		case P_LBTREE:
+		case P_LDUP:
+			bk = GET_BKEYDATA(dbp, h, i);
+			if (B_TYPE(bk->type) == B_OVERFLOW) {
+				bo = (BOVERFLOW *)bk;
+				goto overflow;
+			} else {
+				p2->data = bk->data;
+				p2->size = bk->len;
+			}
+			break;
+		default:
+			/*
+			 * This means our caller screwed up and sent us
+			 * an inappropriate page.
+			 */
+			ret = __db_unknown_path(env, "__bam_vrfy_itemorder");
+			goto err;
+		}
+
+		if (0) {
+			/*
+			 * If ovflok != 1, we can't safely go chasing
+			 * overflow pages with the normal routines now;
+			 * they might be unsafe or nonexistent.  Mark this
+			 * page as incomplete and return.
+			 *
+			 * Note that we don't need to worry about freeing
+			 * buffers, since they can't have been allocated
+			 * if overflow items are unsafe.
+			 */
+overflow:		if (!ovflok) {
+				if (pip != NULL)
+					F_SET(pip, VRFY_INCOMPLETE);
+				goto err;
+			}
+
+			/*
+			 * Overflow items are safe to chase.  Do so.
+			 * Fetch the overflow item into p2->data,
+			 * NULLing it or reallocing it as appropriate.
+			 *
+			 * (We set p2->data to buf2 before the call
+			 * so we're sure to realloc if we can and if p2
+			 * was just pointing at a non-overflow item.)
+			 */
+			p2->data = buf2;
+			if ((ret = __db_cursor_int(dbp, ip, NULL, DB_BTREE,
+			    PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0)
+				goto err;
+			if ((ret = __db_goff(dbc,
+			    p2, bo->tlen, bo->pgno, NULL, NULL)) != 0) {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1065",
+			    "Page %lu: error %lu in fetching overflow item %lu",
+				    "%lu %lu %lu"), (u_long)pgno, (u_long)ret,
+				    (u_long)i));
+			}
+			/* In case it got realloc'ed and thus changed. */
+			buf2 = p2->data;
+		}
+
+		/* Compare with the last key. */
+		if (p1->data != NULL && p2->data != NULL) {
+			cmp = inp[i] == inp[i - adj] ? 0 : func(dbp, p1, p2);
+
+			/* comparison succeeded */
+			if (cmp > 0) {
+				/*
+				 * If we are looking at an internal page, we
+				 * don't know whether it is part of the main
+				 * database or in an off-page-duplicate tree.
+				 * If the main comparator fails, retry with
+				 * the duplicate comparator.
+				 */
+				if (TYPE(h) == P_IBTREE && func != dupfunc) {
+					func = dupfunc;
+					goto retry;
+				}
+
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1066",
+				    "Page %lu: out-of-order key at entry %lu",
+				    "%lu %lu"), (u_long)pgno, (u_long)i));
+				/* proceed */
+			} else if (cmp == 0) {
+				if (inp[i] != inp[i - adj]) {
+					/* See above. */
+					if (TYPE(h) == P_IBTREE &&
+					    func != dupfunc) {
+						func = dupfunc;
+						goto retry;
+					}
+					isbad = 1;
+					EPRINT((env, DB_STR_A("1067",
+				     "Page %lu: non-dup dup key at entry %lu",
+					   "%lu %lu"), (u_long)pgno,
+					    (u_long)i));
+				}
+				/*
+				 * If they compared equally, this
+				 * had better be a (sub)database with dups.
+				 * Mark it so we can check during the
+				 * structure check.
+				 */
+				if (pip != NULL)
+					F_SET(pip, VRFY_HAS_DUPS);
+				else if (hasdups == 0) {
+					/* See above. */
+					if (TYPE(h) == P_IBTREE &&
+					    func != dupfunc) {
+						func = dupfunc;
+						goto retry;
+					}
+					isbad = 1;
+					EPRINT((env, DB_STR_A("1068",
+	"Page %lu: database with no duplicates has duplicated keys",
+					    "%lu"), (u_long)pgno));
+				}
+
+				/*
+				 * If we're a btree leaf, check to see
+				 * if the data items of these on-page dups are
+				 * in sorted order.  If not, flag this, so
+				 * that we can make sure during the
+				 * structure checks that the DUPSORT flag
+				 * is unset.
+				 *
+				 * At this point i points to a duplicate key.
+				 * Compare the datum before it (same key)
+				 * to the datum after it, i.e. i-1 to i+1.
+				 */
+				if (TYPE(h) == P_LBTREE) {
+					/*
+					 * Unsafe;  continue and we'll pick
+					 * up the bogus nentries later.
+					 */
+					if (i + 1 >= (db_indx_t)nentries)
+						continue;
+
+					/*
+					 * We don't bother with clever memory
+					 * management with on-page dups,
+					 * as it's only really a big win
+					 * in the overflow case, and overflow
+					 * dups are probably (?) rare.
+					 */
+					if (((ret = __bam_safe_getdata(dbp,
+					    ip, h, i - 1, ovflok,
+					    &dup_1, &freedup_1)) != 0) ||
+					    ((ret = __bam_safe_getdata(dbp,
+					    ip, h, i + 1, ovflok,
+					    &dup_2, &freedup_2)) != 0))
+						goto err;
+
+					/*
+					 * If either of the data are NULL,
+					 * it's because they're overflows and
+					 * it's not safe to chase them now.
+					 * Mark an incomplete and return.
+					 */
+					if (dup_1.data == NULL ||
+					    dup_2.data == NULL) {
+						DB_ASSERT(env, !ovflok);
+						if (pip != NULL)
+							F_SET(pip,
+							    VRFY_INCOMPLETE);
+						goto err;
+					}
+
+					/*
+					 * If the dups are out of order,
+					 * flag this.  It's not an error
+					 * until we do the structure check
+					 * and see whether DUPSORT is set.
+					 */
+					if (dupfunc(dbp, &dup_1, &dup_2) > 0 &&
+					    pip != NULL)
+						F_SET(pip, VRFY_DUPS_UNSORTED);
+
+					if (freedup_1)
+						__os_ufree(env, dup_1.data);
+					if (freedup_2)
+						__os_ufree(env, dup_2.data);
+				}
+			}
+		}
+	}
+
+err:	if (pip != NULL && ((t_ret =
+	    __db_vrfy_putpageinfo(env, vdp, pip)) != 0) && ret == 0)
+		ret = t_ret;
+
+	if (buf1 != NULL)
+		__os_ufree(env, buf1);
+	if (buf2 != NULL)
+		__os_ufree(env, buf2);
+
+	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __bam_vrfy_structure --
+ *	Verify the tree structure of a btree database (including the master
+ *	database containing subdbs).
+ *
+ * PUBLIC: int __bam_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t,
+ * PUBLIC:     void *, void *, u_int32_t));
+ */
+int
+__bam_vrfy_structure(dbp, vdp, meta_pgno, lp, rp, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t meta_pgno;
+	void *lp, *rp;
+	u_int32_t flags;
+{
+	DB *pgset;
+	ENV *env;
+	VRFY_PAGEINFO *mip, *rip;
+	db_pgno_t root, p;
+	int t_ret, ret;
+	u_int32_t nrecs, level, relen, stflags;
+
+	env = dbp->env;
+	mip = rip = 0;
+	pgset = vdp->pgset;
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &mip)) != 0)
+		return (ret);
+
+	if ((ret = __db_vrfy_pgset_get(pgset,
+	    vdp->thread_info, vdp->txn, meta_pgno, (int *)&p)) != 0)
+		goto err;
+	if (p != 0) {
+		EPRINT((env, DB_STR_A("1069",
+		    "Page %lu: btree metadata page observed twice",
+		    "%lu"), (u_long)meta_pgno));
+		ret = DB_VERIFY_BAD;
+		goto err;
+	}
+	if ((ret = __db_vrfy_pgset_inc(
+	    pgset, vdp->thread_info, vdp->txn, meta_pgno)) != 0)
+		goto err;
+
+	root = mip->root;
+
+	if (root == 0) {
+		EPRINT((env, DB_STR_A("1070",
+		    "Page %lu: btree metadata page has no root",
+		    "%lu"), (u_long)meta_pgno));
+		ret = DB_VERIFY_BAD;
+		goto err;
+	}
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, root, &rip)) != 0)
+		goto err;
+
+	switch (rip->type) {
+	case P_IBTREE:
+	case P_LBTREE:
+		stflags = flags | DB_ST_TOPLEVEL;
+		if (F_ISSET(mip, VRFY_HAS_DUPS))
+			stflags |= DB_ST_DUPOK;
+		if (F_ISSET(mip, VRFY_HAS_DUPSORT))
+			stflags |= DB_ST_DUPSORT;
+		if (F_ISSET(mip, VRFY_HAS_RECNUMS))
+			stflags |= DB_ST_RECNUM;
+		ret = __bam_vrfy_subtree(dbp,
+		    vdp, root, lp, rp, stflags, NULL, NULL, NULL);
+		break;
+	case P_IRECNO:
+	case P_LRECNO:
+		stflags =
+		    flags | DB_ST_RECNUM | DB_ST_IS_RECNO | DB_ST_TOPLEVEL;
+		if (mip->re_len > 0)
+			stflags |= DB_ST_RELEN;
+		if ((ret = __bam_vrfy_subtree(dbp, vdp,
+		    root, NULL, NULL, stflags, &level, &nrecs, &relen)) != 0)
+			goto err;
+		/*
+		 * Even if mip->re_len > 0, re_len may come back zero if the
+		 * tree is empty.  It should be okay to just skip the check in
+		 * this case, as if there are any non-deleted keys at all,
+		 * that should never happen.
+		 */
+		if (mip->re_len > 0 && relen > 0 && mip->re_len != relen) {
+			EPRINT((env, DB_STR_A("1071",
+			    "Page %lu: recno database has bad re_len %lu",
+			    "%lu %lu"), (u_long)meta_pgno, (u_long)relen));
+			ret = DB_VERIFY_BAD;
+			goto err;
+		}
+		ret = 0;
+		break;
+	case P_LDUP:
+		EPRINT((env, DB_STR_A("1072",
+		    "Page %lu: duplicate tree referenced from metadata page",
+		    "%lu"), (u_long)meta_pgno));
+		ret = DB_VERIFY_BAD;
+		break;
+	default:
+		EPRINT((env, DB_STR_A("1073",
+	    "Page %lu: btree root of incorrect type %lu on metadata page",
+		    "%lu %lu"), (u_long)meta_pgno, (u_long)rip->type));
+		ret = DB_VERIFY_BAD;
+		break;
+	}
+
+err:	if (mip != NULL && ((t_ret =
+	    __db_vrfy_putpageinfo(env, vdp, mip)) != 0) && ret == 0)
+		ret = t_ret;
+	if (rip != NULL && ((t_ret =
+	    __db_vrfy_putpageinfo(env, vdp, rip)) != 0) && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+/*
+ * __bam_vrfy_subtree--
+ *	Verify a subtree (or entire) btree with specified root.
+ *
+ *	Note that this is public because it must be called to verify
+ *	offpage dup trees, including from hash.
+ *
+ * PUBLIC: int __bam_vrfy_subtree __P((DB *, VRFY_DBINFO *, db_pgno_t, void *,
+ * PUBLIC:     void *, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *));
+ */
+int
+__bam_vrfy_subtree(dbp, vdp, pgno, l, r, flags, levelp, nrecsp, relenp)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	void *l, *r;
+	u_int32_t flags, *levelp, *nrecsp, *relenp;
+{
+	BINTERNAL *li, *ri;
+	DB *pgset;
+	DBC *cc;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h;
+	VRFY_CHILDINFO *child;
+	VRFY_PAGEINFO *pip;
+	db_indx_t i;
+	db_pgno_t next_pgno, prev_pgno;
+	db_recno_t child_nrecs, nrecs;
+	u_int32_t child_level, child_relen, j, level, relen, stflags;
+	u_int8_t leaf_type;
+	int (*func) __P((DB *, const DBT *, const DBT *));
+	int isbad, p, ret, t_ret, toplevel;
+
+	if (levelp != NULL)	/* Don't leave uninitialized on error. */
+		*levelp = 0;
+	if (nrecsp != NULL)
+		*nrecsp = 0;
+
+	env = dbp->env;
+	mpf = dbp->mpf;
+	h = NULL;
+	next_pgno = prev_pgno = PGNO_INVALID;
+	nrecs = 0;
+	relen = 0;
+	leaf_type = P_INVALID;
+	isbad = ret = 0;
+
+	/* Provide feedback on our progress to the application. */
+	if (!LF_ISSET(DB_SALVAGE))
+		__db_vrfy_struct_feedback(dbp, vdp);
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+
+	cc = NULL;
+	level = pip->bt_level;
+
+	toplevel = LF_ISSET(DB_ST_TOPLEVEL) ? 1 : 0;
+	LF_CLR(DB_ST_TOPLEVEL);
+
+	/*
+	 * If this is the root, initialize the vdp's prev- and next-pgno
+	 * accounting.
+	 *
+	 * For each leaf page we hit, we'll want to make sure that
+	 * vdp->prev_pgno is the same as pip->prev_pgno and vdp->next_pgno is
+	 * our page number.  Then, we'll set vdp->next_pgno to pip->next_pgno
+	 * and vdp->prev_pgno to our page number, and the next leaf page in
+	 * line should be able to do the same verification.
+	 */
+	if (toplevel) {
+		/*
+		 * Cache the values stored in the vdp so that if we're an
+		 * auxiliary tree such as an off-page duplicate set, our
+		 * caller's leaf page chain doesn't get lost.
+		 */
+		prev_pgno = vdp->prev_pgno;
+		next_pgno = vdp->next_pgno;
+		leaf_type = vdp->leaf_type;
+		vdp->next_pgno = vdp->prev_pgno = PGNO_INVALID;
+		vdp->leaf_type = P_INVALID;
+	}
+
+	/*
+	 * We are recursively descending a btree, starting from the root
+	 * and working our way out to the leaves.
+	 *
+	 * There are four cases we need to deal with:
+	 *	1. pgno is a recno leaf page.  Any children are overflows.
+	 *	2. pgno is a duplicate leaf page.  Any children
+	 *	   are overflow pages;  traverse them, and then return
+	 *	   level and nrecs.
+	 *	3. pgno is an ordinary leaf page.  Check whether dups are
+	 *	   allowed, and if so, traverse any off-page dups or
+	 *	   overflows.  Then return nrecs and level.
+	 *	4. pgno is a recno internal page.  Recursively check any
+	 *	   child pages, making sure their levels are one lower
+	 *	   and their nrecs sum to ours.
+	 *	5. pgno is a btree internal page.  Same as #4, plus we
+	 *	   must verify that for each pair of BINTERNAL entries
+	 *	   N and N+1, the leftmost item on N's child sorts
+	 *	   greater than N, and the rightmost item on N's child
+	 *	   sorts less than N+1.
+	 *
+	 * Furthermore, in any sorted page type (P_LDUP, P_LBTREE, P_IBTREE),
+	 * we need to verify the internal sort order is correct if,
+	 * due to overflow items, we were not able to do so earlier.
+	 */
+	switch (pip->type) {
+	case P_LRECNO:
+	case P_LDUP:
+	case P_LBTREE:
+		/*
+		 * Cases 1, 2 and 3.
+		 *
+		 * We're some sort of leaf page;  verify
+		 * that our linked list of leaves is consistent.
+		 */
+		if (vdp->leaf_type == P_INVALID) {
+			/*
+			 * First leaf page.  Set the type that all its
+			 * successors should be, and verify that our prev_pgno
+			 * is PGNO_INVALID.
+			 */
+			vdp->leaf_type = pip->type;
+			if (pip->prev_pgno != PGNO_INVALID)
+				goto bad_prev;
+		} else {
+			/*
+			 * Successor leaf page. Check our type, the previous
+			 * page's next_pgno, and our prev_pgno.
+			 */
+			if (pip->type != vdp->leaf_type) {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1074",
+	"Page %lu: unexpected page type %lu found in leaf chain (expected %lu)",
+				    "%lu %lu %lu"), (u_long)pip->pgno,
+				    (u_long)pip->type,
+				    (u_long)vdp->leaf_type));
+			}
+
+			/*
+			 * Don't do the prev/next_pgno checks if we've lost
+			 * leaf pages due to another corruption.
+			 */
+			if (!F_ISSET(vdp, VRFY_LEAFCHAIN_BROKEN)) {
+				if (pip->pgno != vdp->next_pgno) {
+					isbad = 1;
+					EPRINT((env, DB_STR_A("1075",
+	"Page %lu: incorrect next_pgno %lu found in leaf chain (should be %lu)",
+					    "%lu %lu %lu"),
+					    (u_long)vdp->prev_pgno,
+					    (u_long)vdp->next_pgno,
+					    (u_long)pip->pgno));
+				}
+				if (pip->prev_pgno != vdp->prev_pgno) {
+bad_prev:				isbad = 1;
+					EPRINT((env, DB_STR_A("1076",
+    "Page %lu: incorrect prev_pgno %lu found in leaf chain (should be %lu)",
+					    "%lu %lu %lu"),
+					    (u_long)pip->pgno,
+					    (u_long)pip->prev_pgno,
+					    (u_long)vdp->prev_pgno));
+				}
+			}
+		}
+		vdp->prev_pgno = pip->pgno;
+		vdp->next_pgno = pip->next_pgno;
+		F_CLR(vdp, VRFY_LEAFCHAIN_BROKEN);
+
+		/*
+		 * Overflow pages are common to all three leaf types;
+		 * traverse the child list, looking for overflows.
+		 */
+		if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0)
+			goto err;
+		for (ret = __db_vrfy_ccset(cc, pgno, &child); ret == 0;
+		    ret = __db_vrfy_ccnext(cc, &child))
+			if (child->type == V_OVERFLOW &&
+			    (ret = __db_vrfy_ovfl_structure(dbp, vdp,
+			    child->pgno, child->tlen,
+			    flags | DB_ST_OVFL_LEAF)) != 0) {
+				if (ret == DB_VERIFY_BAD)
+					isbad = 1;
+				else
+					goto done;
+			}
+
+		if ((ret = __db_vrfy_ccclose(cc)) != 0)
+			goto err;
+		cc = NULL;
+
+		/* Case 1 */
+		if (pip->type == P_LRECNO) {
+			if (!LF_ISSET(DB_ST_IS_RECNO) &&
+			    !(LF_ISSET(DB_ST_DUPOK) &&
+			    !LF_ISSET(DB_ST_DUPSORT))) {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1077",
+				    "Page %lu: recno leaf page non-recno tree",
+				    "%lu"), (u_long)pgno));
+				goto done;
+			}
+			goto leaf;
+		} else if (LF_ISSET(DB_ST_IS_RECNO)) {
+			/*
+			 * It's a non-recno leaf.  Had better not be a recno
+			 * subtree.
+			 */
+			isbad = 1;
+			EPRINT((env, DB_STR_A("1078",
+			    "Page %lu: non-recno leaf page in recno tree",
+			    "%lu"), (u_long)pgno));
+			goto done;
+		}
+
+		/* Case 2--no more work. */
+		if (pip->type == P_LDUP)
+			goto leaf;
+
+		/* Case 3 */
+
+		/* Check if we have any dups. */
+		if (F_ISSET(pip, VRFY_HAS_DUPS)) {
+			/* If dups aren't allowed in this btree, trouble. */
+			if (!LF_ISSET(DB_ST_DUPOK)) {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1079",
+				    "Page %lu: duplicates in non-dup btree",
+				    "%lu"), (u_long)pgno));
+			} else {
+				/*
+				 * We correctly have dups.  If any are off-page,
+				 * traverse those btrees recursively.
+				 */
+				if ((ret =
+				    __db_vrfy_childcursor(vdp, &cc)) != 0)
+					goto err;
+				for (ret = __db_vrfy_ccset(cc, pgno, &child);
+				    ret == 0;
+				    ret = __db_vrfy_ccnext(cc, &child)) {
+					stflags =
+					    flags | DB_ST_RECNUM | DB_ST_DUPSET;
+					/* Skip any overflow entries. */
+					if (child->type == V_DUPLICATE) {
+						if ((ret = __db_vrfy_duptype(
+						    dbp, vdp, child->pgno,
+						    stflags)) != 0) {
+							isbad = 1;
+							/* Next child. */
+							continue;
+						}
+						if ((ret = __bam_vrfy_subtree(
+						    dbp, vdp, child->pgno,
+						    NULL, NULL,
+						    stflags | DB_ST_TOPLEVEL,
+						    NULL, NULL, NULL)) != 0) {
+							if (ret ==
+							    DB_VERIFY_BAD)
+								isbad = 1;
+							else
+								goto err;
+						}
+					}
+				}
+
+				if ((ret = __db_vrfy_ccclose(cc)) != 0)
+					goto err;
+				cc = NULL;
+
+				/*
+				 * If VRFY_DUPS_UNSORTED is set,
+				 * DB_ST_DUPSORT had better not be.
+				 */
+				if (F_ISSET(pip, VRFY_DUPS_UNSORTED) &&
+				    LF_ISSET(DB_ST_DUPSORT)) {
+					isbad = 1;
+					EPRINT((env, DB_STR_A("1080",
+		    "Page %lu: unsorted duplicate set in sorted-dup database",
+					    "%lu"), (u_long)pgno));
+				}
+			}
+		}
+		goto leaf;
+	case P_IBTREE:
+	case P_IRECNO:
+		/* We handle these below. */
+		break;
+	default:
+		/*
+		 * If a P_IBTREE or P_IRECNO contains a reference to an
+		 * invalid page, we'll wind up here;  handle it gracefully.
+		 * Note that the code at the "done" label assumes that the
+		 * current page is a btree/recno one of some sort;  this
+		 * is not the case here, so we goto err.
+		 *
+		 * If the page is entirely zeroed, its pip->type will be a lie
+		 * (we assumed it was a hash page, as they're allowed to be
+		 * zeroed);  handle this case specially.
+		 */
+		if (F_ISSET(pip, VRFY_IS_ALLZEROES))
+			ZEROPG_ERR_PRINT(env, pgno, DB_STR_P(
+			    "btree or recno page"));
+		else
+			EPRINT((env, DB_STR_A("1081",
+	    "Page %lu: btree or recno page is of inappropriate type %lu",
+			    "%lu %lu"), (u_long)pgno, (u_long)pip->type));
+
+		/*
+		 * We probably lost a leaf page (or more if this was an
+		 * internal page) from our prev/next_pgno chain.  Flag
+		 * that this is expected;  we don't want or need to
+		 * spew error messages about erroneous prev/next_pgnos,
+		 * since that's probably not the real problem.
+		 */
+		F_SET(vdp, VRFY_LEAFCHAIN_BROKEN);
+
+		ret = DB_VERIFY_BAD;
+		goto err;
+	}
+
+	/*
+	 * Cases 4 & 5: This is a btree or recno internal page.  For each child,
+	 * recurse, keeping a running count of nrecs and making sure the level
+	 * is always reasonable.
+	 */
+	if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0)
+		goto err;
+	for (ret = __db_vrfy_ccset(cc, pgno, &child); ret == 0;
+	    ret = __db_vrfy_ccnext(cc, &child))
+		if (child->type == V_RECNO) {
+			if (pip->type != P_IRECNO) {
+				ret = __db_unknown_path(
+				    env, "__bam_vrfy_subtree");
+				goto err;
+			}
+			if ((ret = __bam_vrfy_subtree(dbp, vdp, child->pgno,
+			    NULL, NULL, flags, &child_level, &child_nrecs,
+			    &child_relen)) != 0) {
+				if (ret == DB_VERIFY_BAD)
+					isbad = 1;
+				else
+					goto done;
+			}
+
+			if (LF_ISSET(DB_ST_RELEN)) {
+				if (relen == 0)
+					relen = child_relen;
+				/*
+				 * child_relen may be zero if the child subtree
+				 * is empty.
+				 */
+				else if (child_relen > 0 &&
+				    relen != child_relen) {
+					isbad = 1;
+					EPRINT((env, DB_STR_A("1082",
+			   "Page %lu: recno page returned bad re_len %lu",
+					    "%lu %lu"), (u_long)child->pgno,
+					    (u_long)child_relen));
+				}
+				if (relenp)
+					*relenp = relen;
+			}
+			if (LF_ISSET(DB_ST_RECNUM)) {
+				if (child->nrecs != child_nrecs) {
+					isbad = 1;
+					EPRINT((env, DB_STR_A("1083",
+		"Page %lu: record count incorrect: actual %lu, in record %lu",
+					    "%lu %lu %lu"),
+					    (u_long)child->pgno,
+					    (u_long)child_nrecs,
+					    (u_long)child->nrecs));
+				}
+				nrecs += child_nrecs;
+			}
+			if (isbad == 0 && level != child_level + 1) {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1084",
+		"Page %lu: recno level incorrect: got %lu, expected %lu",
+				    "%lu %lu %lu"),
+				    (u_long)child->pgno, (u_long)child_level,
+				    (u_long)(level - 1)));
+			}
+		} else if (child->type == V_OVERFLOW) {
+			/*
+			 * It is possible for one internal page to reference
+			 * a single overflow page twice, if all the items
+			 * in the subtree referenced by slot 0 are deleted,
+			 * then a similar number of items are put back
+			 * before the key that formerly had been in slot 1.
+			 *
+			 * (Btree doesn't look at the key in slot 0, so the
+			 * fact that the key formerly at slot 1 is the "wrong"
+			 * parent of the stuff in the slot 0 subtree isn't
+			 * really incorrect.)
+			 *
+			 * __db_vrfy_ovfl_structure is designed to be
+			 * efficiently called multiple times for multiple
+			 * references;  call it here as many times as is
+			 * appropriate.
+			 */
+
+			/* Otherwise, __db_vrfy_childput would be broken. */
+			DB_ASSERT(env, child->refcnt >= 1);
+
+			/*
+			 * An overflow referenced more than twice here
+			 * shouldn't happen.
+			 */
+			if (child->refcnt > 2) {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1085",
+    "Page %lu: overflow page %lu referenced more than twice from internal page",
+				    "%lu %lu"), (u_long)pgno,
+				    (u_long)child->pgno));
+			} else
+				for (j = 0; j < child->refcnt; j++)
+					if ((ret = __db_vrfy_ovfl_structure(dbp,
+					    vdp, child->pgno, child->tlen,
+					    flags)) != 0) {
+						if (ret == DB_VERIFY_BAD)
+							isbad = 1;
+						else
+							goto done;
+					}
+		}
+
+	if ((ret = __db_vrfy_ccclose(cc)) != 0)
+		goto err;
+	cc = NULL;
+
+	/* We're done with case 4. */
+	if (pip->type == P_IRECNO)
+		goto done;
+
+	/*
+	 * Case 5.  Btree internal pages.
+	 * As described above, we need to iterate through all the
+	 * items on the page and make sure that our children sort appropriately
+	 * with respect to them.
+	 *
+	 * For each entry, li will be the "left-hand" key for the entry
+	 * itself, which must sort lower than all entries on its child;
+	 * ri will be the key to its right, which must sort greater.
+	 */
+	if (h == NULL &&
+	    (ret = __memp_fget(mpf, &pgno, vdp->thread_info, NULL, 0, &h)) != 0)
+		goto err;
+	for (i = 0; i < pip->entries; i += O_INDX) {
+		li = GET_BINTERNAL(dbp, h, i);
+		ri = (i + O_INDX < pip->entries) ?
+		    GET_BINTERNAL(dbp, h, i + O_INDX) : r;
+
+		/*
+		 * The leftmost key is forcibly sorted less than all entries,
+		 * so don't bother passing it.
+		 */
+		if ((ret = __bam_vrfy_subtree(dbp, vdp, li->pgno,
+		    i == 0 ? NULL : li, ri, flags, &child_level,
+		    &child_nrecs, NULL)) != 0) {
+			if (ret == DB_VERIFY_BAD)
+				isbad = 1;
+			else
+				goto done;
+		}
+
+		if (LF_ISSET(DB_ST_RECNUM)) {
+			/*
+			 * Keep a running tally on the actual record count so
+			 * we can return it to our parent (if we have one) or
+			 * compare it to the NRECS field if we're a root page.
+			 */
+			nrecs += child_nrecs;
+
+			/*
+			 * Make sure the actual record count of the child
+			 * is equal to the value in the BINTERNAL structure.
+			 */
+			if (li->nrecs != child_nrecs) {
+				isbad = 1;
+				EPRINT((env, DB_STR_A("1086",
+	"Page %lu: item %lu has incorrect record count of %lu, should be %lu",
+				    "%lu %lu %lu %lu"), (u_long)pgno,
+				    (u_long)i, (u_long)li->nrecs,
+				    (u_long)child_nrecs));
+			}
+		}
+
+		if (level != child_level + 1) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("1087",
+		"Page %lu: Btree level incorrect: got %lu, expected %lu",
+			    "%lu %lu %lu"), (u_long)li->pgno,
+			    (u_long)child_level, (u_long)(level - 1)));
+		}
+	}
+
+	if (0) {
+leaf:		level = LEAFLEVEL;
+		if (LF_ISSET(DB_ST_RECNUM))
+			nrecs = pip->rec_cnt;
+
+		/* XXX
+		 * We should verify that the record count on a leaf page
+		 * is the sum of the number of keys and the number of
+		 * records in its off-page dups.  This requires looking
+		 * at the page again, however, and it may all be changing
+		 * soon, so for now we don't bother.
+		 */
+
+		if (LF_ISSET(DB_ST_RELEN) && relenp)
+			*relenp = pip->re_len;
+	}
+done:	if (F_ISSET(pip, VRFY_INCOMPLETE) && isbad == 0 && ret == 0) {
+		/*
+		 * During the page-by-page pass, item order verification was
+		 * not finished due to the presence of overflow items.  If
+		 * isbad == 0, though, it's now safe to do so, as we've
+		 * traversed any child overflow pages.  Do it.
+		 */
+		if (h == NULL && (ret = __memp_fget(mpf, &pgno,
+		    vdp->thread_info, NULL, 0, &h)) != 0)
+			goto err;
+		if ((ret = __bam_vrfy_itemorder(dbp,
+		    vdp, vdp->thread_info, h, pgno, 0, 1, 0, flags)) != 0)
+			goto err;
+		F_CLR(pip, VRFY_INCOMPLETE);
+	}
+
+	/*
+	 * It's possible to get to this point with a page that has no
+	 * items, but without having detected any sort of failure yet.
+	 * Having zero items is legal if it's a leaf--it may be the
+	 * root page in an empty tree, or the tree may have been
+	 * modified with the DB_REVSPLITOFF flag set (there's no way
+	 * to tell from what's on disk).  For an internal page,
+	 * though, having no items is a problem (all internal pages
+	 * must have children).
+	 */
+	if (isbad == 0 && ret == 0) {
+		if (h == NULL && (ret = __memp_fget(mpf, &pgno,
+		    vdp->thread_info, NULL, 0, &h)) != 0)
+			goto err;
+
+		if (NUM_ENT(h) == 0 && ISINTERNAL(h)) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("1088",
+		    "Page %lu: internal page is empty and should not be",
+			    "%lu"), (u_long)pgno));
+			goto err;
+		}
+	}
+
+	/*
+	 * Our parent has sent us BINTERNAL pointers to parent records
+	 * so that we can verify our place with respect to them.  If it's
+	 * appropriate--we have a default sort function--verify this.
+	 */
+	if (isbad == 0 && ret == 0 && !LF_ISSET(DB_NOORDERCHK) &&
+	    pip->type != P_IRECNO && pip->type != P_LRECNO) {
+		if (h == NULL && (ret = __memp_fget(mpf, &pgno,
+		    vdp->thread_info, NULL, 0, &h)) != 0)
+			goto err;
+
+		/*
+		 * __bam_vrfy_treeorder needs to know what comparison function
+		 * to use.  If DB_ST_DUPSET is set, we're in a duplicate tree
+		 * and we use the duplicate comparison function;  otherwise,
+		 * use the btree one.  If unset, use the default, of course.
+		 */
+		func = LF_ISSET(DB_ST_DUPSET) ? dbp->dup_compare :
+		    ((BTREE *)dbp->bt_internal)->bt_compare;
+		if (func == NULL)
+			func = __bam_defcmp;
+
+		if ((ret = __bam_vrfy_treeorder(dbp,
+		    vdp->thread_info, h, l, r, func, flags)) != 0) {
+			if (ret == DB_VERIFY_BAD)
+				isbad = 1;
+			else
+				goto err;
+		}
+	}
+
+	/*
+	 * This is guaranteed to succeed for leaf pages, but no harm done.
+	 *
+	 * Internal pages below the top level do not store their own
+	 * record numbers, so we skip them.
+	 */
+	if (LF_ISSET(DB_ST_RECNUM) && nrecs != pip->rec_cnt && toplevel) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("1089",
+		    "Page %lu: bad record count: has %lu records, claims %lu",
+		    "%lu %lu %lu"), (u_long)pgno, (u_long)nrecs,
+		    (u_long)pip->rec_cnt));
+	}
+
+	if (levelp)
+		*levelp = level;
+	if (nrecsp)
+		*nrecsp = nrecs;
+
+	pgset = vdp->pgset;
+	if ((ret = __db_vrfy_pgset_get(pgset,
+	    vdp->thread_info, vdp->txn, pgno, &p)) != 0)
+		goto err;
+	if (p != 0) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("1090",
+		    "Page %lu: linked twice", "%lu"), (u_long)pgno));
+	} else if ((ret =
+	    __db_vrfy_pgset_inc(pgset, vdp->thread_info, vdp->txn, pgno)) != 0)
+		goto err;
+
+	if (toplevel)
+		/*
+		 * The last page's next_pgno in the leaf chain should have been
+		 * PGNO_INVALID.
+		 */
+		if (vdp->next_pgno != PGNO_INVALID) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("1091",
+			    "Page %lu: unterminated leaf chain",
+			    "%lu"), (u_long)vdp->prev_pgno));
+		}
+
+err:	if (toplevel) {
+		/* Restore our caller's settings. */
+		vdp->next_pgno = next_pgno;
+		vdp->prev_pgno = prev_pgno;
+		vdp->leaf_type = leaf_type;
+	}
+
+	if (h != NULL && (t_ret = __memp_fput(mpf,
+	    vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+	if (cc != NULL && ((t_ret = __db_vrfy_ccclose(cc)) != 0) && ret == 0)
+		ret = t_ret;
+	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __bam_vrfy_treeorder --
+ *	Verify that the lowest key on a page sorts greater than the
+ *	BINTERNAL which points to it (lp), and the highest key
+ *	sorts less than the BINTERNAL above that (rp).
+ *
+ *	If lp is NULL, this means that it was the leftmost key on the
+ *	parent, which (regardless of sort function) sorts less than
+ *	all keys.  No need to check it.
+ *
+ *	If rp is NULL, lp was the highest key on the parent, so there's
+ *	no higher key we must sort less than.
+ */
+static int
+__bam_vrfy_treeorder(dbp, ip, h, lp, rp, func, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	PAGE *h;
+	BINTERNAL *lp, *rp;
+	int (*func) __P((DB *, const DBT *, const DBT *));
+	u_int32_t flags;
+{
+	BOVERFLOW *bo;
+	DBC *dbc;
+	DBT dbt;
+	ENV *env;
+	db_indx_t last;
+	int ret, cmp;
+
+	env = dbp->env;
+	memset(&dbt, 0, sizeof(DBT));
+	F_SET(&dbt, DB_DBT_MALLOC);
+	ret = 0;
+
+	/*
+	 * Empty pages are sorted correctly by definition.  We check
+	 * to see whether they ought to be empty elsewhere;  leaf
+	 * pages legally may be.
+	 */
+	if (NUM_ENT(h) == 0)
+		return (0);
+
+	switch (TYPE(h)) {
+	case P_IBTREE:
+	case P_LDUP:
+		last = NUM_ENT(h) - O_INDX;
+		break;
+	case P_LBTREE:
+		last = NUM_ENT(h) - P_INDX;
+		break;
+	default:
+		return (__db_unknown_path(env, "__bam_vrfy_treeorder"));
+	}
+
+	/* Populate a dummy cursor. */
+	if ((ret = __db_cursor_int(dbp, ip, NULL, DB_BTREE,
+	    PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0)
+		return (ret);
+	/*
+	 * The key on page h, the child page, is more likely to be
+	 * an overflow page, so we pass its offset, rather than lp/rp's,
+	 * into __bam_cmp.  This will take advantage of __db_moff.
+	 */
+
+	/*
+	 * Skip first-item check if we're an internal page--the first
+	 * entry on an internal page is treated specially by __bam_cmp,
+	 * so what's on the page shouldn't matter.  (Plus, since we're passing
+	 * our page and item 0 as to __bam_cmp, we'll sort before our
+	 * parent and falsely report a failure.)
+	 */
+	if (lp != NULL && TYPE(h) != P_IBTREE) {
+		if ((ret = __db_cursor_int(dbp, ip, NULL, DB_BTREE,
+		    PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0)
+			return (ret);
+		if (lp->type == B_KEYDATA) {
+			dbt.data = lp->data;
+			dbt.size = lp->len;
+		} else if (lp->type == B_OVERFLOW) {
+			bo = (BOVERFLOW *)lp->data;
+			if ((ret = __db_goff(dbc, &dbt,
+			    bo->tlen, bo->pgno, NULL, NULL)) != 0)
+				return (ret);
+		} else
+			return (
+			    __db_unknown_path(env, "__bam_vrfy_treeorder"));
+
+		/* On error, fall through, free if needed, and return. */
+		if ((ret = __bam_cmp(dbc, &dbt, h, 0, func, &cmp)) == 0) {
+			if (cmp > 0) {
+				EPRINT((env, DB_STR_A("1092",
+	    "Page %lu: first item on page sorted greater than parent entry",
+				    "%lu"), (u_long)PGNO(h)));
+				ret = DB_VERIFY_BAD;
+			}
+		} else
+			EPRINT((env, DB_STR_A("1093",
+			    "Page %lu: first item on page had comparison error",
+			    "%lu"), (u_long)PGNO(h)));
+
+		if (dbt.data != lp->data)
+			__os_ufree(env, dbt.data);
+		if (ret != 0)
+			return (ret);
+	}
+
+	if (rp != NULL) {
+		if (rp->type == B_KEYDATA) {
+			dbt.data = rp->data;
+			dbt.size = rp->len;
+		} else if (rp->type == B_OVERFLOW) {
+			bo = (BOVERFLOW *)rp->data;
+			if ((ret = __db_goff(dbc, &dbt,
+			    bo->tlen, bo->pgno, NULL, NULL)) != 0)
+				return (ret);
+		} else
+			return (
+			    __db_unknown_path(env, "__bam_vrfy_treeorder"));
+
+		/* On error, fall through, free if needed, and return. */
+		if ((ret = __bam_cmp(dbc, &dbt, h, last, func, &cmp)) == 0) {
+			if (cmp < 0) {
+				EPRINT((env, DB_STR_A("1094",
+	    "Page %lu: last item on page sorted greater than parent entry",
+				    "%lu"), (u_long)PGNO(h)));
+				ret = DB_VERIFY_BAD;
+			}
+		} else
+			EPRINT((env, DB_STR_A("1095",
+			    "Page %lu: last item on page had comparison error",
+			    "%lu"), (u_long)PGNO(h)));
+
+		if (dbt.data != rp->data)
+			__os_ufree(env, dbt.data);
+	}
+
+	return (ret);
+}
+
+/*
+ * __bam_salvage --
+ *	Safely dump out anything that looks like a key on an alleged
+ *	btree leaf page, also mark overflow pages as seen.  For internal btree
+ *	pages, just mark any overflow pages as seen.
+ *
+ * PUBLIC: int __bam_salvage __P((DB *, VRFY_DBINFO *,
+ * PUBLIC:     db_pgno_t, u_int32_t, PAGE *, void *,
+ * PUBLIC:     int (*)(void *, const void *), DBT *, u_int32_t));
+ */
+int
+__bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	u_int32_t pgtype;
+	PAGE *h;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	DBT *key;
+	u_int32_t flags;
+{
+	BKEYDATA *bk;
+	BOVERFLOW *bo;
+	DBT dbt, repldbt, unknown_key, unknown_data;
+	ENV *env;
+	VRFY_ITEM *pgmap;
+	db_indx_t i, last, beg, end, *inp;
+	db_pgno_t ovflpg;
+	u_int32_t himark, ovfl_bufsz;
+	void *ovflbuf;
+	int adj, ret, t_ret, t2_ret;
+#ifdef HAVE_COMPRESSION
+	DBT kcpy, *last_key;
+	int unknown_dup_key;
+#endif
+
+	env = dbp->env;
+	ovflbuf = pgmap = NULL;
+	inp = P_INP(dbp, h);
+
+	memset(&dbt, 0, sizeof(DBT));
+	dbt.flags = DB_DBT_REALLOC;
+	memset(&repldbt, 0, sizeof(DBT));
+
+#ifdef HAVE_COMPRESSION
+	memset(&kcpy, 0, sizeof(DBT));
+	unknown_dup_key = LF_ISSET(DB_SA_UNKNOWNKEY);
+	last_key = unknown_dup_key ? NULL : key;
+#endif
+	LF_CLR(DB_SA_UNKNOWNKEY);
+
+	DB_INIT_DBT(unknown_key, "UNKNOWN_KEY", sizeof("UNKNOWN_KEY") - 1);
+	DB_INIT_DBT(unknown_data, "UNKNOWN_DATA", sizeof("UNKNOWN_DATA") - 1);
+
+	/*
+	 * Allocate a buffer for overflow items.  Start at one page;
+	 * __db_safe_goff will realloc as needed.
+	 */
+	if ((ret = __os_malloc(env, dbp->pgsize, &ovflbuf)) != 0)
+		goto err;
+	ovfl_bufsz = dbp->pgsize;
+
+	if (LF_ISSET(DB_AGGRESSIVE) && (ret =
+	    __os_calloc(env, dbp->pgsize, sizeof(pgmap[0]), &pgmap)) != 0)
+		goto err;
+
+	/*
+	 * Loop through the inp array, spitting out key/data pairs.
+	 *
+	 * If we're salvaging normally, loop from 0 through NUM_ENT(h).  If
+	 * we're being aggressive, loop until we hit the end of the page --
+	 * NUM_ENT() may be bogus.
+	 */
+	himark = dbp->pgsize;
+	for (i = 0, last = UINT16_MAX;; i += O_INDX) {
+		/*
+		 * If we're not aggressive, or if we're on an internal page,
+		 * break when we hit NUM_ENT(h).
+		 */
+		if ((!LF_ISSET(DB_AGGRESSIVE) ||
+		    pgtype == P_IBTREE) && i >= NUM_ENT(h))
+			break;
+
+		/* Verify the current item. */
+		t_ret =
+		    __db_vrfy_inpitem(dbp, h, pgno, i, 1, flags, &himark, NULL);
+
+		if (t_ret != 0) {
+			/*
+			 * If this is a btree leaf and we've printed out a key
+			 * but not its associated data item, fix this imbalance
+			 * by printing an "UNKNOWN_DATA".
+			 */
+			if (pgtype == P_LBTREE && i % P_INDX == 1 &&
+			    last == i - 1 && (t2_ret = __db_vrfy_prdbt(
+			    &unknown_data,
+			    0, " ", handle, callback, 0, 0, vdp)) != 0) {
+				if (ret == 0)
+					ret = t2_ret;
+				goto err;
+			}
+
+			/*
+			 * Don't return DB_VERIFY_FATAL; it's private and means
+			 * only that we can't go on with this page, not with
+			 * the whole database.  It's not even an error if we've
+			 * run into it after NUM_ENT(h).
+			 */
+			if (t_ret == DB_VERIFY_FATAL) {
+				if (i < NUM_ENT(h) && ret == 0)
+					ret = DB_VERIFY_BAD;
+				break;
+			}
+			continue;
+		}
+
+		/*
+		 * If this returned 0, it's safe to print or (carefully)
+		 * try to fetch.
+		 *
+		 * We only print deleted items if DB_AGGRESSIVE is set.
+		 */
+		bk = GET_BKEYDATA(dbp, h, i);
+		if (!LF_ISSET(DB_AGGRESSIVE) && B_DISSET(bk->type))
+			continue;
+
+		/*
+		 * If this is a btree leaf and we're about to print out a data
+		 * item for which we didn't print out a key, fix this imbalance
+		 * by printing an "UNKNOWN_KEY".
+		 */
+		if (pgtype == P_LBTREE && i % P_INDX == 1 && last != i - 1) {
+#ifdef HAVE_COMPRESSION
+			last_key = NULL;
+#endif
+			if ((t_ret = __db_vrfy_prdbt(&unknown_key,
+			    0, " ", handle, callback, 0, 0, vdp)) != 0) {
+				if (ret == 0)
+					ret = t_ret;
+				goto err;
+			}
+		}
+		last = i;
+
+		/*
+		 * We're going to go try to print the next item.  If key is
+		 * non-NULL, we're a dup page, so we've got to print the key
+		 * first, unless DB_SA_SKIPFIRSTKEY is set and we're on the
+		 * first entry.
+		 */
+		if (key != NULL && (i != 0 || !LF_ISSET(DB_SA_SKIPFIRSTKEY))) {
+#ifdef HAVE_COMPRESSION
+			last_key = unknown_dup_key ? NULL : key;
+#endif
+			if ((t_ret = __db_vrfy_prdbt(key,
+			    0, " ", handle, callback, 0, 0, vdp)) != 0) {
+				if (ret == 0)
+					ret = t_ret;
+				goto err;
+			}
+		}
+
+		beg = end = inp[i];
+		switch (B_TYPE(bk->type)) {
+		case B_DUPLICATE:
+			if (pgtype == P_IBTREE)
+				break;
+
+			end = beg + BOVERFLOW_SIZE - 1;
+			/*
+			 * If we're not on a normal btree leaf page, there
+			 * shouldn't be off-page dup sets.  Something's
+			 * confused; just drop it, and the code to pick up
+			 * unlinked offpage dup sets will print it out
+			 * with key "UNKNOWN" later.
+			 */
+			if (pgtype != P_LBTREE)
+				break;
+
+			bo = (BOVERFLOW *)bk;
+
+			/*
+			 * If the page number is unreasonable, or if this is
+			 * supposed to be a key item, output "UNKNOWN_KEY" --
+			 * the best we can do is run into the data items in
+			 * the unlinked offpage dup pass.
+			 */
+			if (!IS_VALID_PGNO(bo->pgno) || (i % P_INDX == 0)) {
+				/* Not much to do on failure. */
+#ifdef HAVE_COMPRESSION
+				if (key == NULL && i % P_INDX == 0)
+					last_key = NULL;
+#endif
+				if ((t_ret = __db_vrfy_prdbt(
+				 i % P_INDX == 0 ? &unknown_key : &unknown_data,
+				   0, " ", handle, callback, 0, 0,vdp)) != 0) {
+					if (ret == 0)
+						ret = t_ret;
+					goto err;
+				}
+				break;
+			}
+
+			/* Don't stop on error. */
+			if ((t_ret = __db_salvage_duptree(dbp,
+			    vdp, bo->pgno, &dbt, handle, callback,
+			    flags | DB_SA_SKIPFIRSTKEY
+#ifdef HAVE_COMPRESSION
+			    | (last_key == NULL ? DB_SA_UNKNOWNKEY : 0)
+#endif
+			    )) != 0 && ret == 0)
+				ret = t_ret;
+
+			break;
+		case B_KEYDATA:
+			if (pgtype == P_IBTREE)
+				break;
+
+			end = (db_indx_t)DB_ALIGN(
+			    beg + bk->len, sizeof(u_int32_t)) - 1;
+
+			dbt.data = bk->data;
+			dbt.size = bk->len;
+
+#ifdef HAVE_COMPRESSION
+			if (DB_IS_COMPRESSED(dbp) && last_key != NULL &&
+			    (key != NULL || (i % P_INDX == 1))) {
+				/* Decompress the key/data pair  - the key
+				   is in last_key, and the data is in dbt */
+				if ((t_ret = __bam_compress_salvage(dbp, vdp,
+				    handle, callback, last_key, &dbt)) != 0) {
+					if (t_ret == DB_VERIFY_FATAL) {
+						if (ret == 0)
+							ret = DB_VERIFY_BAD;
+						if (!LF_ISSET(DB_AGGRESSIVE))
+							goto err;
+					} else if (ret == 0) {
+						ret = t_ret;
+						goto err;
+					}
+				}
+			} else {
+				if (key == NULL && i % P_INDX == 0) {
+					if ((ret = __os_realloc(
+					    env, dbt.size, &kcpy.data)) != 0)
+						goto err;
+					memcpy(kcpy.data, dbt.data, dbt.size);
+					kcpy.size = dbt.size;
+					last_key = &kcpy;
+				}
+#endif
+
+				if ((t_ret = __db_vrfy_prdbt(&dbt,
+				   0, " ", handle, callback, 0, 0, vdp)) != 0) {
+					if (ret == 0)
+						ret = t_ret;
+					goto err;
+				}
+#ifdef HAVE_COMPRESSION
+			}
+#endif
+			break;
+		case B_OVERFLOW:
+			if (pgtype != P_IBTREE)
+				end = beg + BOVERFLOW_SIZE - 1;
+			bo = (BOVERFLOW *)bk;
+
+			/*
+			 * Check for replicated overflow keys, so that we only
+			 * call __db_safe_goff once per overflow page.  If we
+			 * get the same offset as the previous key just re-use
+			 * the previous dbt.
+			 *
+			 * P_IBTREE pages will never have replicated overflow
+			 * keys.
+			 */
+			adj = pgtype == P_IBTREE ? O_INDX : P_INDX;
+			if (pgtype == P_IBTREE) {
+				/*
+				 * If we're looking at a P_IBTREE, we just want
+				 * to mark the overflow page as seen.
+				 *
+				 * Note that this call to __db_safe_goff differs
+				 * from the non-P_IBTREE call.
+				 *
+				 * Only call __db_safe_goff if the overflow page
+				 * hasn't been seen.
+				 */
+				ovflpg = ((BOVERFLOW *)
+				    ((BINTERNAL *)bk)->data)->pgno;
+				if (__db_salvage_isdone(vdp, ovflpg) == 0 &&
+				    (t_ret =__db_safe_goff(dbp, vdp, ovflpg,
+					&dbt, &ovflbuf,
+					&ovfl_bufsz, flags)) != 0 && ret == 0)
+					ret = t_ret;
+				break;
+			} else if (i > adj - 1 &&
+			    i % adj == 0 && inp[i] == inp[i - adj])
+				dbt = repldbt;
+			else {
+				/* Don't stop on error. */
+				if ((t_ret = __db_safe_goff(dbp, vdp,
+				    bo->pgno, &dbt, &ovflbuf,
+				    &ovfl_bufsz, flags)) != 0 && ret == 0)
+					ret = t_ret;
+
+				/*
+				 * If this is a key, save it in case the next
+				 * key is a replicated overflow, so we don't
+				 * call __db_safe_goff again.  Copy out dbt.data
+				 * in case that pointer gets realloc'd when
+				 * getting a data item.
+				 */
+				if (i % P_INDX == 0) {
+					if (t_ret == 0) {
+						if ((t_ret = __os_realloc(env,
+							dbt.size,
+							&repldbt.data)) != 0) {
+							if (ret == 0)
+								ret = t_ret;
+							goto err;
+						}
+						memcpy(repldbt.data,
+						    dbt.data, dbt.size);
+						repldbt.size = dbt.size;
+					} else {
+						if (__os_realloc(env,
+						    unknown_key.size,
+						    &repldbt.data) != 0)
+							goto err;
+						memcpy(repldbt.data,
+						    unknown_key.data,
+						    unknown_key.size);
+						repldbt.size = unknown_key.size;
+					}
+				}
+
+			}
+
+#ifdef HAVE_COMPRESSION
+			if (DB_IS_COMPRESSED(dbp) && last_key && t_ret == 0 &&
+			    (key != NULL || (i % P_INDX == 1))) {
+				/* Decompress the key/data pair  - the key
+				   is in last_key, and the data is in dbt */
+				if ((t_ret = __bam_compress_salvage(dbp, vdp,
+				    handle, callback, last_key, &dbt)) != 0) {
+					if (t_ret == DB_VERIFY_FATAL) {
+						if (ret == 0)
+							ret = DB_VERIFY_BAD;
+						if (!LF_ISSET(DB_AGGRESSIVE))
+							goto err;
+					} else if (ret == 0) {
+						ret = t_ret;
+						goto err;
+					}
+				}
+			} else {
+				if (key == NULL && i % P_INDX == 0) {
+					if (t_ret == 0) {
+						if ((ret = __os_realloc(env,
+						    dbt.size, &kcpy.data)) != 0)
+							goto err;
+						memcpy(kcpy.data, dbt.data,
+							dbt.size);
+						kcpy.size = dbt.size;
+						last_key = &kcpy;
+					} else
+						last_key = NULL;
+				}
+#endif
+
+				if ((t_ret = __db_vrfy_prdbt(
+					   t_ret == 0 ? &dbt : &unknown_key,
+					   0, " ", handle, callback, 0, 0, vdp))
+					!= 0 && ret == 0)
+					ret = t_ret;
+#ifdef HAVE_COMPRESSION
+			}
+#endif
+			break;
+		default:
+			/*
+			 * We should never get here; __db_vrfy_inpitem should
+			 * not be returning 0 if bk->type is unrecognizable.
+			 */
+			t_ret = __db_unknown_path(env, "__bam_salvage");
+			if (ret == 0)
+				ret = t_ret;
+			goto err;
+		}
+
+		/*
+		 * If we're being aggressive, mark the beginning and end of
+		 * the item; we'll come back and print whatever "junk" is in
+		 * the gaps in case we had any bogus inp elements and thereby
+		 * missed stuff.
+		 */
+		if (LF_ISSET(DB_AGGRESSIVE) && pgtype != P_IBTREE) {
+			pgmap[beg] = VRFY_ITEM_BEGIN;
+			pgmap[end] = VRFY_ITEM_END;
+		}
+	}
+
+err:	if (pgmap != NULL)
+		__os_free(env, pgmap);
+	if (ovflbuf != NULL)
+		__os_free(env, ovflbuf);
+	if (repldbt.data != NULL)
+		__os_free(env, repldbt.data);
+#ifdef HAVE_COMPRESSION
+	if (kcpy.data != NULL)
+		__os_free(env, kcpy.data);
+#endif
+
+	/* Mark this page as done. */
+	if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __bam_salvage_walkdupint --
+ *	Walk a known-good btree or recno internal page which is part of
+ *	a dup tree, calling __db_salvage_duptree on each child page.
+ *
+ * PUBLIC: int __bam_salvage_walkdupint __P((DB *, VRFY_DBINFO *, PAGE *,
+ * PUBLIC:     DBT *, void *, int (*)(void *, const void *), u_int32_t));
+ */
+int
+__bam_salvage_walkdupint(dbp, vdp, h, key, handle, callback, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	PAGE *h;
+	DBT *key;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	BINTERNAL *bi;
+	ENV *env;
+	RINTERNAL *ri;
+	int ret, t_ret;
+	db_indx_t i;
+
+	env = dbp->env;
+	ret = 0;
+
+	for (i = 0; i < NUM_ENT(h); i++) {
+		switch (TYPE(h)) {
+		case P_IBTREE:
+			bi = GET_BINTERNAL(dbp, h, i);
+			if ((t_ret = __db_salvage_duptree(dbp,
+			    vdp, bi->pgno, key, handle, callback, flags)) != 0)
+				ret = t_ret;
+			break;
+		case P_IRECNO:
+			ri = GET_RINTERNAL(dbp, h, i);
+			if ((t_ret = __db_salvage_duptree(dbp,
+			    vdp, ri->pgno, key, handle, callback, flags)) != 0)
+				ret = t_ret;
+			break;
+		default:
+			return (__db_unknown_path(
+			    env, "__bam_salvage_walkdupint"));
+		}
+		/* Pass DB_SA_SKIPFIRSTKEY, if set, on to the 0th child only. */
+		flags &= ~LF_ISSET(DB_SA_SKIPFIRSTKEY);
+	}
+
+	return (ret);
+}
+
+/*
+ * __bam_meta2pgset --
+ *	Given a known-good meta page, return in pgsetp a 0-terminated list of
+ *	db_pgno_t's corresponding to the pages in the btree.
+ *
+ *	We do this by a somewhat sleazy method, to avoid having to traverse the
+ *	btree structure neatly:  we walk down the left side to the very
+ *	first leaf page, then we mark all the pages in the chain of
+ *	NEXT_PGNOs (being wary of cycles and invalid ones), then we
+ *	consolidate our scratch array into a nice list, and return.  This
+ *	avoids the memory management hassles of recursion and the
+ *	trouble of walking internal pages--they just don't matter, except
+ *	for the left branch.
+ *
+ * PUBLIC: int __bam_meta2pgset __P((DB *, VRFY_DBINFO *, BTMETA *,
+ * PUBLIC:     u_int32_t, DB *));
+ */
+int
+__bam_meta2pgset(dbp, vdp, btmeta, flags, pgset)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	BTMETA *btmeta;
+	u_int32_t flags;
+	DB *pgset;
+{
+	BINTERNAL *bi;
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	RINTERNAL *ri;
+	db_pgno_t current, p;
+	int err_ret, ret;
+
+	DB_ASSERT(dbp->env, pgset != NULL);
+
+	mpf = dbp->mpf;
+	h = NULL;
+	ret = err_ret = 0;
+
+	for (current = btmeta->root;;) {
+		if (!IS_VALID_PGNO(current) || current == PGNO(btmeta)) {
+			err_ret = DB_VERIFY_BAD;
+			goto err;
+		}
+		if ((ret = __memp_fget(mpf, &current,
+		     vdp->thread_info, NULL, 0, &h)) != 0) {
+			err_ret = ret;
+			goto err;
+		}
+
+		switch (TYPE(h)) {
+		case P_IBTREE:
+		case P_IRECNO:
+			if ((ret = __bam_vrfy(dbp,
+			    vdp, h, current, flags | DB_NOORDERCHK)) != 0) {
+				err_ret = ret;
+				goto err;
+			}
+			if (TYPE(h) == P_IBTREE) {
+				bi = GET_BINTERNAL(dbp, h, 0);
+				current = bi->pgno;
+			} else {	/* P_IRECNO */
+				ri = GET_RINTERNAL(dbp, h, 0);
+				current = ri->pgno;
+			}
+			break;
+		case P_LBTREE:
+		case P_LRECNO:
+			goto traverse;
+		default:
+			err_ret = DB_VERIFY_BAD;
+			goto err;
+		}
+
+		if ((ret = __memp_fput(mpf,
+		     vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0)
+			err_ret = ret;
+		h = NULL;
+	}
+
+	/*
+	 * At this point, current is the pgno of leaf page h, the 0th in the
+	 * tree we're concerned with.
+	 */
+traverse:
+	while (IS_VALID_PGNO(current) && current != PGNO_INVALID) {
+		if (h == NULL && (ret = __memp_fget(mpf,
+		    &current, vdp->thread_info, NULL, 0, &h)) != 0) {
+			err_ret = ret;
+			break;
+		}
+
+		if ((ret = __db_vrfy_pgset_get(pgset,
+		    vdp->thread_info, vdp->txn, current, (int *)&p)) != 0)
+			goto err;
+
+		if (p != 0) {
+			/*
+			 * We've found a cycle.  Return success anyway--
+			 * our caller may as well use however much of
+			 * the pgset we've come up with.
+			 */
+			break;
+		}
+		if ((ret = __db_vrfy_pgset_inc(
+		    pgset, vdp->thread_info, vdp->txn, current)) != 0)
+			goto err;
+
+		current = NEXT_PGNO(h);
+		if ((ret = __memp_fput(mpf,
+		     vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0)
+			err_ret = ret;
+		h = NULL;
+	}
+
+err:	if (h != NULL)
+		(void)__memp_fput(mpf,
+		    vdp->thread_info, h, DB_PRIORITY_UNCHANGED);
+
+	return (ret == 0 ? err_ret : ret);
+}
+
+/*
+ * __bam_safe_getdata --
+ *
+ *	Utility function for __bam_vrfy_itemorder.  Safely gets the datum at
+ *	index i, page h, and sticks it in DBT dbt.  If ovflok is 1 and i's an
+ *	overflow item, we do a safe_goff to get the item and signal that we need
+ *	to free dbt->data;  if ovflok is 0, we leaves the DBT zeroed.
+ */
+static int
+__bam_safe_getdata(dbp, ip, h, i, ovflok, dbt, freedbtp)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	PAGE *h;
+	u_int32_t i;
+	int ovflok;
+	DBT *dbt;
+	int *freedbtp;
+{
+	BKEYDATA *bk;
+	BOVERFLOW *bo;
+	DBC *dbc;
+	int ret;
+
+	memset(dbt, 0, sizeof(DBT));
+	*freedbtp = 0;
+
+	bk = GET_BKEYDATA(dbp, h, i);
+	if (B_TYPE(bk->type) == B_OVERFLOW) {
+		if (!ovflok)
+			return (0);
+
+		if ((ret = __db_cursor_int(dbp, ip, NULL, DB_BTREE,
+		    PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0)
+			return (ret);
+		bo = (BOVERFLOW *)bk;
+		F_SET(dbt, DB_DBT_MALLOC);
+
+		*freedbtp = 1;
+		return (__db_goff(dbc, dbt, bo->tlen, bo->pgno, NULL, NULL));
+	} else {
+		dbt->data = bk->data;
+		dbt->size = bk->len;
+	}
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/clib/getopt.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,175 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1987, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * Avoid inclusion of internal header files as this
+ * file is used by example code.
+ *
+ * Unconditional inclusion of stdio and string are
+ * OK in this file.  It will work on all platforms
+ * for which this file is used
+ */
+extern char *__db_rpath(const char *);
+#include <stdio.h>
+#include <string.h>
+
+int	__db_getopt_reset;	/* global reset for VxWorks. */
+
+int	opterr = 1,		/* if error message should be printed */
+	optind = 1,		/* index into parent argv vector */
+	optopt,			/* character checked for validity */
+	optreset;		/* reset getopt */
+char	*optarg;		/* argument associated with option */
+
+#undef	BADCH
+#define	BADCH	(int)'?'
+#undef	BADARG
+#define	BADARG	(int)':'
+#undef	EMSG
+#define	EMSG	""
+
+/*
+ * getopt --
+ *	Parse argc/argv argument vector.
+ *
+ * PUBLIC: #ifndef HAVE_GETOPT
+ * PUBLIC: int getopt __P((int, char * const *, const char *));
+ * PUBLIC: #endif
+ */
+int
+getopt(nargc, nargv, ostr)
+	int nargc;
+	char * const *nargv;
+	const char *ostr;
+{
+	static char *progname;
+	static char *place = EMSG;		/* option letter processing */
+	char *oli;				/* option letter list index */
+
+	/*
+	 * VxWorks needs to be able to repeatedly call getopt from multiple
+	 * programs within its global name space.
+	 */
+	if (__db_getopt_reset) {
+		__db_getopt_reset = 0;
+
+		opterr = optind = 1;
+		optopt = optreset = 0;
+		optarg = NULL;
+		progname = NULL;
+		place = EMSG;
+	}
+	if (!progname) {
+		if ((progname = __db_rpath(*nargv)) == NULL)
+			progname = *nargv;
+		else
+			++progname;
+	}
+
+	if (optreset || !*place) {		/* update scanning pointer */
+		optreset = 0;
+		if (optind >= nargc || *(place = nargv[optind]) != '-') {
+			place = EMSG;
+			return (EOF);
+		}
+		if (place[1] && *++place == '-') {	/* found "--" */
+			++optind;
+			place = EMSG;
+			return (EOF);
+		}
+	}					/* option letter okay? */
+	if ((optopt = (int)*place++) == (int)':' ||
+	    !(oli = strchr(ostr, optopt))) {
+		/*
+		 * if the user didn't specify '-' as an option,
+		 * assume it means EOF.
+		 */
+		if (optopt == (int)'-')
+			return (EOF);
+		if (!*place)
+			++optind;
+		if (opterr && *ostr != ':')
+			(void)fprintf(stderr,
+			    "%s: illegal option -- %c\n", progname, optopt);
+		return (BADCH);
+	}
+	if (*++oli != ':') {			/* don't need argument */
+		optarg = NULL;
+		if (!*place)
+			++optind;
+	}
+	else {					/* need an argument */
+		if (*place)			/* no white space */
+			optarg = place;
+		else if (nargc <= ++optind) {	/* no arg */
+			place = EMSG;
+			if (*ostr == ':')
+				return (BADARG);
+			if (opterr)
+				(void)fprintf(stderr,
+				    "%s: option requires an argument -- %c\n",
+				    progname, optopt);
+			return (BADCH);
+		}
+		else				/* white space */
+			optarg = nargv[optind];
+		place = EMSG;
+		++optind;
+	}
+	return (optopt);			/* dump back option letter */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/clib/isalpha.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,50 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2005, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * isalpha --
+ *
+ * PUBLIC: #ifndef HAVE_ISALPHA
+ * PUBLIC: int isalpha __P((int));
+ * PUBLIC: #endif
+ */
+int
+isalpha(c)
+	int c;
+{
+	/*
+	 * Depends on ASCII-like character ordering.
+	 */
+	return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ? 1 : 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/clib/snprintf.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,171 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
+static void sprintf_overflow __P((void));
+static int  sprintf_retcharpnt __P((void));
+#endif
+
+/*
+ * snprintf --
+ *	Bounded version of sprintf.
+ *
+ * PUBLIC: #ifndef HAVE_SNPRINTF
+ * PUBLIC: int snprintf __P((char *, size_t, const char *, ...));
+ * PUBLIC: #endif
+ */
+#ifndef HAVE_SNPRINTF
+int
+#ifdef STDC_HEADERS
+snprintf(char *str, size_t n, const char *fmt, ...)
+#else
+snprintf(str, n, fmt, va_alist)
+	char *str;
+	size_t n;
+	const char *fmt;
+	va_dcl
+#endif
+{
+	static int ret_charpnt = -1;
+	va_list ap;
+	size_t len;
+
+	if (ret_charpnt == -1)
+		ret_charpnt = sprintf_retcharpnt();
+
+#ifdef STDC_HEADERS
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	len = (size_t)vsprintf(str, fmt, ap);
+	if (ret_charpnt)
+		len = strlen(str);
+
+	va_end(ap);
+
+	if (len >= n) {
+		sprintf_overflow();
+		/* NOTREACHED */
+	}
+	return ((int)len);
+}
+#endif
+
+/*
+ * vsnprintf --
+ *	Bounded version of vsprintf.
+ *
+ * PUBLIC: #ifndef HAVE_VSNPRINTF
+ * PUBLIC: int vsnprintf __P((char *, size_t, const char *, va_list));
+ * PUBLIC: #endif
+ */
+#ifndef HAVE_VSNPRINTF
+int
+vsnprintf(str, n, fmt, ap)
+	char *str;
+	size_t n;
+	const char *fmt;
+	va_list ap;
+{
+	static int ret_charpnt = -1;
+	size_t len;
+
+	if (ret_charpnt == -1)
+		ret_charpnt = sprintf_retcharpnt();
+
+	len = (size_t)vsprintf(str, fmt, ap);
+	if (ret_charpnt)
+		len = strlen(str);
+
+	if (len >= n) {
+		sprintf_overflow();
+		/* NOTREACHED */
+	}
+	return ((int)len);
+}
+#endif
+
+#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
+static void
+sprintf_overflow()
+{
+	/*
+	 * !!!
+	 * We're potentially manipulating strings handed us by the application,
+	 * and on systems without a real snprintf() the sprintf() calls could
+	 * have overflowed the buffer.  We can't do anything about it now, but
+	 * we don't want to return control to the application, we might have
+	 * overwritten the stack with a Trojan horse.  We're not trying to do
+	 * anything recoverable here because systems without snprintf support
+	 * are pretty rare anymore.
+	 */
+#define	OVERFLOW_ERROR	"internal buffer overflow, process ended\n"
+#ifndef	STDERR_FILENO
+#define	STDERR_FILENO	2
+#endif
+	(void)write(STDERR_FILENO, OVERFLOW_ERROR, sizeof(OVERFLOW_ERROR) - 1);
+
+	/* Be polite. */
+	exit(1);
+
+	/* But firm. */
+	__os_abort(NULL);
+
+	/* NOTREACHED */
+}
+
+static int
+sprintf_retcharpnt()
+{
+	int ret_charpnt;
+	char buf[10];
+
+	/*
+	 * Some old versions of sprintf return a pointer to the first argument
+	 * instead of a character count.  Assume the return value of snprintf,
+	 * vsprintf, etc. will be the same as sprintf, and check the easy one.
+	 *
+	 * We do this test at run-time because it's not a test we can do in a
+	 * cross-compilation environment.
+	 */
+
+	ret_charpnt =
+	    (int)sprintf(buf, "123") != 3 ||
+	    (int)sprintf(buf, "123456789") != 9 ||
+	    (int)sprintf(buf, "1234") != 4;
+
+	return (ret_charpnt);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/clib/strsep.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,105 @@
+/*-
+ *
+ * Copyright (c) 2006, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * Get next token from string *stringp, where tokens are possibly-empty
+ * strings separated by characters from delim.
+ *
+ * Writes NULs into the string at *stringp to end tokens.
+ * delim need not remain constant from call to call.
+ * On return, *stringp points past the last NUL written (if there might
+ * be further tokens), or is NULL (if there are definitely no more tokens).
+ *
+ * If *stringp is NULL, strsep returns NULL.
+ *
+ * PUBLIC: #ifndef HAVE_STRSEP
+ * PUBLIC: char *strsep __P((char **, const char *));
+ * PUBLIC: #endif
+ */
+char *
+strsep(stringp, delim)
+	char **stringp;
+	const char *delim;
+{
+	char *s;
+	const char *spanp;
+	int c, sc;
+	char *tok;
+
+	if ((s = *stringp) == NULL)
+		return (NULL);
+	for (tok = s;;) {
+		c = *s++;
+		spanp = delim;
+		do {
+			if ((sc = *spanp++) == c) {
+				if (c == 0)
+					s = NULL;
+				else
+					s[-1] = 0;
+				*stringp = s;
+				return (tok);
+			}
+		} while (sc != 0);
+	}
+	/* NOTREACHED */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/clock.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,79 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+/*
+ * __clock_set_expires --
+ *	Set the expire time given the time to live.
+ *
+ * PUBLIC: void __clock_set_expires __P((ENV *, db_timespec *, db_timeout_t));
+ */
+void
+__clock_set_expires(env, timespecp, timeout)
+	ENV *env;
+	db_timespec *timespecp;
+	db_timeout_t timeout;
+{
+	db_timespec v;
+
+	/*
+	 * If timespecp is set then it contains "now".  This avoids repeated
+	 * system calls to get the time.
+	 */
+	if (!timespecisset(timespecp))
+		__os_gettime(env, timespecp, 1);
+
+	/* Convert the microsecond timeout argument to a timespec. */
+	DB_TIMEOUT_TO_TIMESPEC(timeout, &v);
+
+	/* Add the timeout to "now". */
+	timespecadd(timespecp, &v);
+}
+
+/*
+ * __clock_expired -- determine if a timeout has expired.
+ *
+ * PUBLIC: int __clock_expired __P((ENV *, db_timespec *, db_timespec *));
+ */
+int
+__clock_expired(env, now, timespecp)
+	ENV *env;
+	db_timespec *now, *timespecp;
+{
+	if (!timespecisset(timespecp))
+		return (0);
+
+	if (!timespecisset(now))
+		__os_gettime(env, now, 1);
+
+	return (timespeccmp(now, timespecp, >=));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/crypto_stub.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,66 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __crypto_region_init --
+ *	Initialize crypto.
+ *
+ *
+ * !!!
+ * We don't put this stub file in the crypto/ directory of the distribution
+ * because that entire directory is removed for non-crypto distributions.
+ *
+ * PUBLIC: int __crypto_region_init __P((ENV *));
+ */
+int
+__crypto_region_init(env)
+	ENV *env;
+{
+	REGENV *renv;
+	REGINFO *infop;
+	int ret;
+
+	infop = env->reginfo;
+	renv = infop->primary;
+	MUTEX_LOCK(env, renv->mtx_regenv);
+	ret = !(renv->cipher_off == INVALID_ROFF);
+	MUTEX_UNLOCK(env, renv->mtx_regenv);
+
+	if (ret == 0)
+		return (0);
+
+	__db_errx(env, DB_STR("0040",
+"Encrypted environment: library build did not include cryptography support"));
+	return (DB_OPNOTSUP);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/db_byteorder.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,85 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __db_isbigendian --
+ *	Return 1 if big-endian (Motorola and Sparc), not little-endian
+ *	(Intel and Vax).  We do this work at run-time, rather than at
+ *	configuration time so cross-compilation and general embedded
+ *	system support is simpler.
+ *
+ * PUBLIC: int __db_isbigendian __P((void));
+ */
+int
+__db_isbigendian()
+{
+	union {					/* From Harbison & Steele.  */
+		long l;
+		char c[sizeof(long)];
+	} u;
+
+	u.l = 1;
+	return (u.c[sizeof(long) - 1] == 1);
+}
+
+/*
+ * __db_byteorder --
+ *	Return if we need to do byte swapping, checking for illegal
+ *	values.
+ *
+ * PUBLIC: int __db_byteorder __P((ENV *, int));
+ */
+int
+__db_byteorder(env, lorder)
+	ENV *env;
+	int lorder;
+{
+	switch (lorder) {
+	case 0:
+		break;
+	case 1234:
+		if (!F_ISSET(env, ENV_LITTLEENDIAN))
+			return (DB_SWAPBYTES);
+		break;
+	case 4321:
+		if (F_ISSET(env, ENV_LITTLEENDIAN))
+			return (DB_SWAPBYTES);
+		break;
+	default:
+		__db_errx(env, DB_STR("0041",
+	    "unsupported byte order, only big and little-endian supported"));
+		return (EINVAL);
+	}
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/db_err.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,996 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+static void __db_msgcall __P((const DB_ENV *, const char *, va_list));
+static void __db_msgfile __P((const DB_ENV *, const char *, va_list));
+
+/*
+ * __db_fchk --
+ *	General flags checking routine.
+ *
+ * PUBLIC: int __db_fchk __P((ENV *, const char *, u_int32_t, u_int32_t));
+ */
+int
+__db_fchk(env, name, flags, ok_flags)
+	ENV *env;
+	const char *name;
+	u_int32_t flags, ok_flags;
+{
+	return (LF_ISSET(~ok_flags) ? __db_ferr(env, name, 0) : 0);
+}
+
+/*
+ * __db_fcchk --
+ *	General combination flags checking routine.
+ *
+ * PUBLIC: int __db_fcchk
+ * PUBLIC:    __P((ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
+ */
+int
+__db_fcchk(env, name, flags, flag1, flag2)
+	ENV *env;
+	const char *name;
+	u_int32_t flags, flag1, flag2;
+{
+	return (LF_ISSET(flag1) &&
+	    LF_ISSET(flag2) ? __db_ferr(env, name, 1) : 0);
+}
+
+/*
+ * __db_ferr --
+ *	Common flag errors.
+ *
+ * PUBLIC: int __db_ferr __P((const ENV *, const char *, int));
+ */
+int
+__db_ferr(env, name, iscombo)
+	const ENV *env;
+	const char *name;
+	int iscombo;
+{
+	if (iscombo)
+		__db_errx(env, DB_STR_A("0054",
+		    "illegal flag combination specified to %s", "%s"), name);
+	else
+		__db_errx(env, DB_STR_A("0055",
+		    "illegal flag specified to %s", "%s"), name);
+
+	return (EINVAL);
+}
+
+/*
+ * __db_fnl --
+ *	Common flag-needs-locking message.
+ *
+ * PUBLIC: int __db_fnl __P((const ENV *, const char *));
+ */
+int
+__db_fnl(env, name)
+	const ENV *env;
+	const char *name;
+{
+	__db_errx(env, DB_STR_A("0056",
+    "%s: DB_READ_COMMITTED, DB_READ_UNCOMMITTED and DB_RMW require locking",
+	    "%s"), name);
+	return (EINVAL);
+}
+
+/*
+ * __db_pgerr --
+ *	Error when unable to retrieve a specified page.
+ *
+ * PUBLIC: int __db_pgerr __P((DB *, db_pgno_t, int));
+ */
+int
+__db_pgerr(dbp, pgno, errval)
+	DB *dbp;
+	db_pgno_t pgno;
+	int errval;
+{
+	/*
+	 * Three things are certain:
+	 * Death, taxes, and lost data.
+	 * Guess which has occurred.
+	 */
+	__db_errx(dbp->env, DB_STR_A("0057",
+	    "unable to create/retrieve page %lu", "%lu"), (u_long)pgno);
+	return (__env_panic(dbp->env, errval));
+}
+
+/*
+ * __db_pgfmt --
+ *	Error when a page has the wrong format.
+ *
+ * PUBLIC: int __db_pgfmt __P((ENV *, db_pgno_t));
+ */
+int
+__db_pgfmt(env, pgno)
+	ENV *env;
+	db_pgno_t pgno;
+{
+	__db_errx(env, DB_STR_A("0058",
+	    "page %lu: illegal page type or format", "%lu"), (u_long)pgno);
+	return (__env_panic(env, EINVAL));
+}
+
+#ifdef DIAGNOSTIC
+/*
+ * __db_assert --
+ *	Error when an assertion fails.  Only checked if #DIAGNOSTIC defined.
+ *
+ * PUBLIC: #ifdef DIAGNOSTIC
+ * PUBLIC: void __db_assert __P((ENV *, const char *, const char *, int));
+ * PUBLIC: #endif
+ */
+void
+__db_assert(env, e, file, line)
+	ENV *env;
+	const char *e, *file;
+	int line;
+{
+	if (DB_GLOBAL(j_assert) != NULL)
+		DB_GLOBAL(j_assert)(e, file, line);
+	else {
+		__db_errx(env, DB_STR_A("0059",
+		    "assert failure: %s/%d: \"%s\"",
+		    "%s %d %s"), file, line, e);
+
+		__os_abort(env);
+		/* NOTREACHED */
+	}
+}
+#endif
+
+/*
+ * __env_panic_msg --
+ *	Just report that someone else paniced.
+ *
+ * PUBLIC: int __env_panic_msg __P((ENV *));
+ */
+int
+__env_panic_msg(env)
+	ENV *env;
+{
+	DB_ENV *dbenv;
+	int ret;
+
+	dbenv = env->dbenv;
+
+	ret = DB_RUNRECOVERY;
+
+	__db_errx(env, DB_STR("0060",
+	    "PANIC: fatal region error detected; run recovery"));
+
+	if (dbenv->db_paniccall != NULL)		/* Deprecated */
+		dbenv->db_paniccall(dbenv, ret);
+
+	/* Must check for DB_EVENT_REG_PANIC panic first because it is never
+	 * set by itself.  If set, it means panic came from DB_REGISTER code
+	 * only, otherwise it could be from many possible places in the code.
+	 */
+	if ((env->reginfo != NULL) &&
+	    (((REGENV *)env->reginfo->primary)->reg_panic))
+		DB_EVENT(env, DB_EVENT_REG_PANIC, &ret);
+	else
+		DB_EVENT(env, DB_EVENT_PANIC, &ret);
+
+	return (ret);
+}
+
+/*
+ * __env_panic --
+ *	Lock out the database environment due to unrecoverable error.
+ *
+ * PUBLIC: int __env_panic __P((ENV *, int));
+ */
+int
+__env_panic(env, errval)
+	ENV *env;
+	int errval;
+{
+	DB_ENV *dbenv;
+
+	dbenv = env->dbenv;
+
+	if (env != NULL) {
+		__env_panic_set(env, 1);
+
+		__db_err(env, errval, DB_STR("0061", "PANIC"));
+
+		if (dbenv->db_paniccall != NULL)	/* Deprecated */
+			dbenv->db_paniccall(dbenv, errval);
+
+		/* Must check for DB_EVENT_REG_PANIC first because it is never
+		 * set by itself.  If set, it means panic came from DB_REGISTER
+		 * code only, otherwise it could be from many possible places
+		 * in the code.
+		 */
+		if ((env->reginfo != NULL) &&
+		    (((REGENV *)env->reginfo->primary)->reg_panic))
+			DB_EVENT(env, DB_EVENT_REG_PANIC, &errval);
+		else
+			DB_EVENT(env, DB_EVENT_PANIC, &errval);
+	}
+
+#if defined(DIAGNOSTIC) && !defined(CONFIG_TEST)
+	/*
+	 * We want a stack trace of how this could possibly happen.
+	 *
+	 * Don't drop core if it's the test suite -- it's reasonable for the
+	 * test suite to check to make sure that DB_RUNRECOVERY is returned
+	 * under certain conditions.
+	 */
+	__os_abort(env);
+	/* NOTREACHED */
+#endif
+
+	/*
+	 * Chaos reigns within.
+	 * Reflect, repent, and reboot.
+	 * Order shall return.
+	 */
+	return (DB_RUNRECOVERY);
+}
+
+/*
+ * db_strerror --
+ *	ANSI C strerror(3) for DB.
+ *
+ * EXTERN: char *db_strerror __P((int));
+ */
+char *
+db_strerror(error)
+	int error;
+{
+	char *p;
+
+	if (error == 0)
+		return (DB_STR("0062", "Successful return: 0"));
+	if (error > 0) {
+		if ((p = strerror(error)) != NULL)
+			return (p);
+		return (__db_unknown_error(error));
+	}
+
+	/*
+	 * !!!
+	 * The Tcl API requires that some of these return strings be compared
+	 * against strings stored in application scripts.  So, any of these
+	 * errors that do not invariably result in a Tcl exception may not be
+	 * altered.
+	 */
+	switch (error) {
+	case DB_BUFFER_SMALL:
+		return (DB_STR("0063",
+		    "DB_BUFFER_SMALL: User memory too small for return value"));
+	case DB_DONOTINDEX:
+		return (DB_STR("0064",
+		    "DB_DONOTINDEX: Secondary index callback returns null"));
+	case DB_FOREIGN_CONFLICT:
+		return (DB_STR("0065",
+       "DB_FOREIGN_CONFLICT: A foreign database constraint has been violated"));
+	case DB_HEAP_FULL:
+		return (DB_STR("0208","DB_HEAP_FULL: no free space in db"));
+	case DB_KEYEMPTY:
+		return (DB_STR("0066",
+		    "DB_KEYEMPTY: Non-existent key/data pair"));
+	case DB_KEYEXIST:
+		return (DB_STR("0067",
+		    "DB_KEYEXIST: Key/data pair already exists"));
+	case DB_LOCK_DEADLOCK:
+		return (DB_STR("0068",
+		    "DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock"));
+	case DB_LOCK_NOTGRANTED:
+		return (DB_STR("0069", "DB_LOCK_NOTGRANTED: Lock not granted"));
+	case DB_LOG_BUFFER_FULL:
+		return (DB_STR("0070",
+		    "DB_LOG_BUFFER_FULL: In-memory log buffer is full"));
+	case DB_LOG_VERIFY_BAD:
+		return (DB_STR("0071",
+		    "DB_LOG_VERIFY_BAD: Log verification failed"));
+	case DB_NOSERVER:
+		return (DB_STR("0072",
+    "DB_NOSERVER: No message dispatch call-back function has been configured"));
+	case DB_NOTFOUND:
+		return (DB_STR("0073",
+		    "DB_NOTFOUND: No matching key/data pair found"));
+	case DB_OLD_VERSION:
+		return (DB_STR("0074",
+		    "DB_OLDVERSION: Database requires a version upgrade"));
+	case DB_PAGE_NOTFOUND:
+		return (DB_STR("0075",
+		    "DB_PAGE_NOTFOUND: Requested page not found"));
+	case DB_REP_DUPMASTER:
+		return (DB_STR("0076",
+		    "DB_REP_DUPMASTER: A second master site appeared"));
+	case DB_REP_HANDLE_DEAD:
+		return (DB_STR("0077",
+		    "DB_REP_HANDLE_DEAD: Handle is no longer valid"));
+	case DB_REP_HOLDELECTION:
+		return (DB_STR("0078",
+		    "DB_REP_HOLDELECTION: Need to hold an election"));
+	case DB_REP_IGNORE:
+		return (DB_STR("0079",
+		    "DB_REP_IGNORE: Replication record/operation ignored"));
+	case DB_REP_ISPERM:
+		return (DB_STR("0080",
+		    "DB_REP_ISPERM: Permanent record written"));
+	case DB_REP_JOIN_FAILURE:
+		return (DB_STR("0081",
+		    "DB_REP_JOIN_FAILURE: Unable to join replication group"));
+	case DB_REP_LEASE_EXPIRED:
+		return (DB_STR("0082",
+		    "DB_REP_LEASE_EXPIRED: Replication leases have expired"));
+	case DB_REP_LOCKOUT:
+		return (DB_STR("0083",
+	    "DB_REP_LOCKOUT: Waiting for replication recovery to complete"));
+	case DB_REP_NEWSITE:
+		return (DB_STR("0084",
+		    "DB_REP_NEWSITE: A new site has entered the system"));
+	case DB_REP_NOTPERM:
+		return (DB_STR("0085",
+		    "DB_REP_NOTPERM: Permanent log record not written"));
+	case DB_REP_UNAVAIL:
+		return (DB_STR("0086",
+	    "DB_REP_UNAVAIL: Too few remote sites to complete operation"));
+	case DB_REP_WOULDROLLBACK:	/* Undocumented; C API only. */
+		return (DB_STR("0207",
+			"DB_REP_WOULDROLLBACK: Client data has diverged"));
+	case DB_RUNRECOVERY:
+		return (DB_STR("0087",
+		    "DB_RUNRECOVERY: Fatal error, run database recovery"));
+	case DB_SECONDARY_BAD:
+		return (DB_STR("0088",
+	    "DB_SECONDARY_BAD: Secondary index inconsistent with primary"));
+	case DB_TIMEOUT:
+		return (DB_STR("0089", "DB_TIMEOUT: Operation timed out"));
+	case DB_VERIFY_BAD:
+		return (DB_STR("0090",
+		    "DB_VERIFY_BAD: Database verification failed"));
+	case DB_VERSION_MISMATCH:
+		return (DB_STR("0091",
+	    "DB_VERSION_MISMATCH: Database environment version mismatch"));
+	default:
+		break;
+	}
+
+	return (__db_unknown_error(error));
+}
+
+/*
+ * __db_unknown_error --
+ *	Format an unknown error value into a static buffer.
+ *
+ * PUBLIC: char *__db_unknown_error __P((int));
+ */
+char *
+__db_unknown_error(error)
+	int error;
+{
+	/*
+	 * !!!
+	 * Room for a 64-bit number + slop.  This buffer is only used
+	 * if we're given an unknown error number, which should never
+	 * happen.
+	 *
+	 * We're no longer thread-safe if it does happen, but the worst
+	 * result is a corrupted error string because there will always
+	 * be a trailing nul byte since the error buffer is nul filled
+	 * and longer than any error message.
+	 */
+	(void)snprintf(DB_GLOBAL(error_buf),
+	    sizeof(DB_GLOBAL(error_buf)), DB_STR_A("0092",
+	    "Unknown error: %d", "%d"), error);
+	return (DB_GLOBAL(error_buf));
+}
+
+/*
+ * __db_syserr --
+ *	Standard error routine.
+ *
+ * PUBLIC: void __db_syserr __P((const ENV *, int, const char *, ...))
+ * PUBLIC:    __attribute__ ((__format__ (__printf__, 3, 4)));
+ */
+void
+#ifdef STDC_HEADERS
+__db_syserr(const ENV *env, int error, const char *fmt, ...)
+#else
+__db_syserr(env, error, fmt, va_alist)
+	const ENV *env;
+	int error;
+	const char *fmt;
+	va_dcl
+#endif
+{
+	DB_ENV *dbenv;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	/*
+	 * The same as DB->err, except we don't default to writing to stderr
+	 * after any output channel has been configured, and we use a system-
+	 * specific function to translate errors to strings.
+	 */
+	DB_REAL_ERR(dbenv, error, DB_ERROR_SYSTEM, 0, fmt);
+}
+
+/*
+ * __db_err --
+ *	Standard error routine.
+ *
+ * PUBLIC: void __db_err __P((const ENV *, int, const char *, ...))
+ * PUBLIC:    __attribute__ ((__format__ (__printf__, 3, 4)));
+ */
+void
+#ifdef STDC_HEADERS
+__db_err(const ENV *env, int error, const char *fmt, ...)
+#else
+__db_err(env, error, fmt, va_alist)
+	const ENV *env;
+	int error;
+	const char *fmt;
+	va_dcl
+#endif
+{
+	DB_ENV *dbenv;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	/*
+	 * The same as DB->err, except we don't default to writing to stderr
+	 * once an output channel has been configured.
+	 */
+	DB_REAL_ERR(dbenv, error, DB_ERROR_SET, 0, fmt);
+}
+
+/*
+ * __db_errx --
+ *	Standard error routine.
+ *
+ * PUBLIC: void __db_errx __P((const ENV *, const char *, ...))
+ * PUBLIC:    __attribute__ ((__format__ (__printf__, 2, 3)));
+ */
+void
+#ifdef STDC_HEADERS
+__db_errx(const ENV *env, const char *fmt, ...)
+#else
+__db_errx(env, fmt, va_alist)
+	const ENV *env;
+	const char *fmt;
+	va_dcl
+#endif
+{
+	DB_ENV *dbenv;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	/*
+	 * The same as DB->errx, except we don't default to writing to stderr
+	 * once an output channel has been configured.
+	 */
+	DB_REAL_ERR(dbenv, 0, DB_ERROR_NOT_SET, 0, fmt);
+}
+
+/*
+ * __db_errcall --
+ *	Do the error message work for callback functions.
+ *
+ * PUBLIC: void __db_errcall
+ * PUBLIC:    __P((const DB_ENV *, int, db_error_set_t, const char *, va_list));
+ */
+void
+__db_errcall(dbenv, error, error_set, fmt, ap)
+	const DB_ENV *dbenv;
+	int error;
+	db_error_set_t error_set;
+	const char *fmt;
+	va_list ap;
+{
+	char *p;
+	char buf[2048];		/* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
+	char sysbuf[1024];	/* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
+
+	p = buf;
+	if (fmt != NULL)
+		p += vsnprintf(buf, sizeof(buf), fmt, ap);
+	if (error_set != DB_ERROR_NOT_SET)
+		p += snprintf(p,
+		    sizeof(buf) - (size_t)(p - buf), ": %s",
+		    error_set == DB_ERROR_SET ? db_strerror(error) :
+		    __os_strerror(error, sysbuf, sizeof(sysbuf)));
+
+	dbenv->db_errcall(dbenv, dbenv->db_errpfx, buf);
+}
+
+/*
+ * __db_errfile --
+ *	Do the error message work for FILE *s.
+ *
+ * PUBLIC: void __db_errfile
+ * PUBLIC:    __P((const DB_ENV *, int, db_error_set_t, const char *, va_list));
+ */
+void
+__db_errfile(dbenv, error, error_set, fmt, ap)
+	const DB_ENV *dbenv;
+	int error;
+	db_error_set_t error_set;
+	const char *fmt;
+	va_list ap;
+{
+	FILE *fp;
+	int need_sep;
+	char sysbuf[1024];	/* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
+
+	fp = dbenv == NULL ||
+	    dbenv->db_errfile == NULL ? stderr : dbenv->db_errfile;
+	need_sep = 0;
+
+	if (dbenv != NULL && dbenv->db_errpfx != NULL) {
+		(void)fprintf(fp, "%s", dbenv->db_errpfx);
+		need_sep = 1;
+	}
+	if (fmt != NULL && fmt[0] != '\0') {
+		if (need_sep)
+			(void)fprintf(fp, ": ");
+		need_sep = 1;
+		(void)vfprintf(fp, fmt, ap);
+	}
+	if (error_set != DB_ERROR_NOT_SET)
+		(void)fprintf(fp, "%s%s",
+		    need_sep ? ": " : "",
+		    error_set == DB_ERROR_SET ? db_strerror(error) :
+		    __os_strerror(error, sysbuf, sizeof(sysbuf)));
+	(void)fprintf(fp, "\n");
+	(void)fflush(fp);
+}
+
+/*
+ * __db_msgadd --
+ *	Aggregate a set of strings into a buffer for the callback API.
+ *
+ * PUBLIC: void __db_msgadd __P((ENV *, DB_MSGBUF *, const char *, ...))
+ * PUBLIC:    __attribute__ ((__format__ (__printf__, 3, 4)));
+ */
+void
+#ifdef STDC_HEADERS
+__db_msgadd(ENV *env, DB_MSGBUF *mbp, const char *fmt, ...)
+#else
+__db_msgadd(env, mbp, fmt, va_alist)
+	ENV *env;
+	DB_MSGBUF *mbp;
+	const char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+
+#ifdef STDC_HEADERS
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	__db_msgadd_ap(env, mbp, fmt, ap);
+	va_end(ap);
+}
+
+/*
+ * __db_msgadd_ap --
+ *	Aggregate a set of strings into a buffer for the callback API.
+ *
+ * PUBLIC: void __db_msgadd_ap
+ * PUBLIC:     __P((ENV *, DB_MSGBUF *, const char *, va_list));
+ */
+void
+__db_msgadd_ap(env, mbp, fmt, ap)
+	ENV *env;
+	DB_MSGBUF *mbp;
+	const char *fmt;
+	va_list ap;
+{
+	size_t len, olen;
+	char buf[2048];		/* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
+
+	len = (size_t)vsnprintf(buf, sizeof(buf), fmt, ap);
+
+	/*
+	 * There's a heap buffer in the ENV handle we use to aggregate the
+	 * message chunks.  We maintain a pointer to the buffer, the next slot
+	 * to be filled in in the buffer, and a total buffer length.
+	 */
+	olen = (size_t)(mbp->cur - mbp->buf);
+	if (olen + len >= mbp->len) {
+		if (__os_realloc(env, mbp->len + len + 256, &mbp->buf))
+			return;
+		mbp->len += (len + 256);
+		mbp->cur = mbp->buf + olen;
+	}
+
+	memcpy(mbp->cur, buf, len + 1);
+	mbp->cur += len;
+}
+
+/*
+ * __db_msg --
+ *	Standard DB stat message routine.
+ *
+ * PUBLIC: void __db_msg __P((const ENV *, const char *, ...))
+ * PUBLIC:    __attribute__ ((__format__ (__printf__, 2, 3)));
+ */
+void
+#ifdef STDC_HEADERS
+__db_msg(const ENV *env, const char *fmt, ...)
+#else
+__db_msg(env, fmt, va_alist)
+	const ENV *env;
+	const char *fmt;
+	va_dcl
+#endif
+{
+	DB_ENV *dbenv;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	DB_REAL_MSG(dbenv, fmt);
+}
+
+/*
+ * __db_repmsg --
+ *	Replication system message routine.
+ *
+ * PUBLIC: void __db_repmsg __P((const ENV *, const char *, ...))
+ * PUBLIC:    __attribute__ ((__format__ (__printf__, 2, 3)));
+ */
+void
+#ifdef STDC_HEADERS
+__db_repmsg(const ENV *env, const char *fmt, ...)
+#else
+__db_repmsg(env, fmt, va_alist)
+	const ENV *env;
+	const char *fmt;
+	va_dcl
+#endif
+{
+	va_list ap;
+	char buf[2048];		/* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
+
+#ifdef STDC_HEADERS
+	va_start(ap, fmt);
+#else
+	va_start(ap);
+#endif
+	(void)vsnprintf(buf, sizeof(buf), fmt, ap);
+	__rep_msg(env, buf);
+	va_end(ap);
+}
+
+/*
+ * __db_msgcall --
+ *	Do the message work for callback functions.
+ */
+static void
+__db_msgcall(dbenv, fmt, ap)
+	const DB_ENV *dbenv;
+	const char *fmt;
+	va_list ap;
+{
+	char buf[2048];		/* !!!: END OF THE STACK DON'T TRUST SPRINTF. */
+
+	(void)vsnprintf(buf, sizeof(buf), fmt, ap);
+
+	dbenv->db_msgcall(dbenv, buf);
+}
+
+/*
+ * __db_msgfile --
+ *	Do the message work for FILE *s.
+ */
+static void
+__db_msgfile(dbenv, fmt, ap)
+	const DB_ENV *dbenv;
+	const char *fmt;
+	va_list ap;
+{
+	FILE *fp;
+
+	fp = dbenv == NULL ||
+	    dbenv->db_msgfile == NULL ? stdout : dbenv->db_msgfile;
+	(void)vfprintf(fp, fmt, ap);
+
+	(void)fprintf(fp, "\n");
+	(void)fflush(fp);
+}
+
+/*
+ * __db_unknown_flag -- report internal error
+ *
+ * PUBLIC: int __db_unknown_flag __P((ENV *, char *, u_int32_t));
+ */
+int
+__db_unknown_flag(env, routine, flag)
+	ENV *env;
+	char *routine;
+	u_int32_t flag;
+{
+	__db_errx(env, DB_STR_A("0093", "%s: Unknown flag: %#x", "%s %#x"),
+	    routine, (u_int)flag);
+
+#ifdef DIAGNOSTIC
+	__os_abort(env);
+	/* NOTREACHED */
+#endif
+	return (EINVAL);
+}
+
+/*
+ * __db_unknown_type -- report internal database type error
+ *
+ * PUBLIC: int __db_unknown_type __P((ENV *, char *, DBTYPE));
+ */
+int
+__db_unknown_type(env, routine, type)
+	ENV *env;
+	char *routine;
+	DBTYPE type;
+{
+	__db_errx(env, DB_STR_A("0094", "%s: Unexpected database type: %s",
+	    "%s %s"), routine, __db_dbtype_to_string(type));
+
+#ifdef DIAGNOSTIC
+	__os_abort(env);
+	/* NOTREACHED */
+#endif
+	return (EINVAL);
+}
+
+/*
+ * __db_unknown_path -- report unexpected database code path error.
+ *
+ * PUBLIC: int __db_unknown_path __P((ENV *, char *));
+ */
+int
+__db_unknown_path(env, routine)
+	ENV *env;
+	char *routine;
+{
+	__db_errx(env, DB_STR_A("0095", "%s: Unexpected code path error",
+	    "%s"), routine);
+
+#ifdef DIAGNOSTIC
+	__os_abort(env);
+	/* NOTREACHED */
+#endif
+	return (EINVAL);
+}
+
+/*
+ * __db_not_txn_env --
+ *	DB handle must be in an environment that supports transactions.
+ *
+ * PUBLIC: int __db_not_txn_env __P((ENV *));
+ */
+int
+__db_not_txn_env(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("0103",
+	    "DB environment not configured for transactions"));
+	return (EINVAL);
+}
+
+/*
+ * __db_rec_toobig --
+ *	Fixed record length exceeded error message.
+ *
+ * PUBLIC: int __db_rec_toobig __P((ENV *, u_int32_t, u_int32_t));
+ */
+int
+__db_rec_toobig(env, data_len, fixed_rec_len)
+	ENV *env;
+	u_int32_t data_len, fixed_rec_len;
+{
+	__db_errx(env, DB_STR_A("0104",
+	    "%lu larger than database's maximum record length %lu",
+	    "%lu %lu"), (u_long)data_len, (u_long)fixed_rec_len);
+	return (EINVAL);
+}
+
+/*
+ * __db_rec_repl --
+ *	Fixed record replacement length error message.
+ *
+ * PUBLIC: int __db_rec_repl __P((ENV *, u_int32_t, u_int32_t));
+ */
+int
+__db_rec_repl(env, data_size, data_dlen)
+	ENV *env;
+	u_int32_t data_size, data_dlen;
+{
+	__db_errx(env, DB_STR_A("0105",
+	    "Record length error: "
+	    "replacement length %lu differs from replaced length %lu",
+	    "%lu %lu"), (u_long)data_size, (u_long)data_dlen);
+	return (EINVAL);
+}
+
+#if defined(DIAGNOSTIC) || defined(DEBUG_ROP)  || defined(DEBUG_WOP)
+/*
+ * __dbc_logging --
+ *	In DIAGNOSTIC mode, check for bad replication combinations.
+ *
+ * PUBLIC: int __dbc_logging __P((DBC *));
+ */
+int
+__dbc_logging(dbc)
+	DBC *dbc;
+{
+	DB_REP *db_rep;
+	ENV *env;
+	int ret;
+
+	env = dbc->env;
+	db_rep = env->rep_handle;
+
+	ret = LOGGING_ON(env) &&
+	    !F_ISSET(dbc, DBC_RECOVER) && !IS_REP_CLIENT(env);
+
+	/*
+	 * If we're not using replication or running recovery, return.
+	 */
+	if (db_rep == NULL || F_ISSET(dbc, DBC_RECOVER))
+		return (ret);
+
+#ifndef	DEBUG_ROP
+	/*
+	 *  Only check when DEBUG_ROP is not configured.  People often do
+	 * non-transactional reads, and debug_rop is going to write
+	 * a log record.
+	 */
+	{
+	REP *rep;
+
+	rep = db_rep->region;
+
+	/*
+	 * If we're a client and not running recovery or non durably, error.
+	 */
+	if (IS_REP_CLIENT(env) && !F_ISSET(dbc->dbp, DB_AM_NOT_DURABLE)) {
+		__db_errx(env, DB_STR("0106",
+		    "dbc_logging: Client update"));
+		goto err;
+	}
+
+#ifndef DEBUG_WOP
+	/*
+	 * If DEBUG_WOP is enabled, then we'll generate debugging log records
+	 * that are non-transactional.  This is OK.
+	 */
+	if (IS_REP_MASTER(env) &&
+	    dbc->txn == NULL && !F_ISSET(dbc->dbp, DB_AM_NOT_DURABLE)) {
+		__db_errx(env, DB_STR("0107",
+		    "Dbc_logging: Master non-txn update"));
+		goto err;
+	}
+#endif
+
+	if (0) {
+err:		__db_errx(env, DB_STR_A("0108", "Rep: flags 0x%lx msg_th %lu",
+		    "%lx %lu"), (u_long)rep->flags, (u_long)rep->msg_th);
+		__db_errx(env, DB_STR_A("0109", "Rep: handle %lu, opcnt %lu",
+		    "%lu %lu"), (u_long)rep->handle_cnt, (u_long)rep->op_cnt);
+		__os_abort(env);
+		/* NOTREACHED */
+	}
+	}
+#endif
+	return (ret);
+}
+#endif
+
+/*
+ * __db_check_lsn --
+ *	Display the log sequence error message.
+ *
+ * PUBLIC: int __db_check_lsn __P((ENV *, DB_LSN *, DB_LSN *));
+ */
+int
+__db_check_lsn(env, lsn, prev)
+	ENV *env;
+	DB_LSN *lsn, *prev;
+{
+	__db_errx(env, DB_STR_A("0110",
+	    "Log sequence error: page LSN %lu %lu; previous LSN %lu %lu",
+	    "%lu %lu %lu %lu"), (u_long)(lsn)->file,
+	    (u_long)(lsn)->offset, (u_long)(prev)->file,
+	    (u_long)(prev)->offset);
+	return (EINVAL);
+}
+
+/*
+ * __db_rdonly --
+ *	Common readonly message.
+ * PUBLIC: int __db_rdonly __P((const ENV *, const char *));
+ */
+int
+__db_rdonly(env, name)
+	const ENV *env;
+	const char *name;
+{
+	__db_errx(env, DB_STR_A("0111",
+	    "%s: attempt to modify a read-only database", "%s"), name);
+	return (EACCES);
+}
+
+/*
+ * __db_space_err --
+ *	Common out of space message.
+ * PUBLIC: int __db_space_err __P((const DB *));
+ */
+int
+__db_space_err(dbp)
+	const DB *dbp;
+{
+	__db_errx(dbp->env, DB_STR_A("0112",
+	    "%s: file limited to %lu pages", "%s %lu"),
+	    dbp->fname, (u_long)dbp->mpf->mfp->maxpgno);
+	return (ENOSPC);
+}
+
+/*
+ * __db_failed --
+ *	Common failed thread  message.
+ *
+ * PUBLIC: int __db_failed __P((const ENV *,
+ * PUBLIC:      const char *, pid_t, db_threadid_t));
+ */
+int
+__db_failed(env, msg, pid, tid)
+	const ENV *env;
+	const char *msg;
+	pid_t pid;
+	db_threadid_t tid;
+{
+	DB_ENV *dbenv;
+	char buf[DB_THREADID_STRLEN];
+
+	dbenv = env->dbenv;
+
+	__db_errx(env, DB_STR_A("0113", "Thread/process %s failed: %s",
+	    "%s %s"), dbenv->thread_id_string(dbenv, pid, tid, buf),  msg);
+	return (DB_RUNRECOVERY);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/db_getlong.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,170 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __db_getlong --
+ *	Return a long value inside of basic parameters.
+ *
+ * PUBLIC: int __db_getlong
+ * PUBLIC:     __P((DB_ENV *, const char *, char *, long, long, long *));
+ */
+int
+__db_getlong(dbenv, progname, p, min, max, storep)
+	DB_ENV *dbenv;
+	const char *progname;
+	char *p;
+	long min, max, *storep;
+{
+	long val;
+	char *end;
+
+	__os_set_errno(0);
+	val = strtol(p, &end, 10);
+	if ((val == LONG_MIN || val == LONG_MAX) &&
+	    __os_get_errno() == ERANGE) {
+		if (dbenv != NULL)
+			dbenv->err(dbenv, ERANGE, "%s", p);
+		else
+			fprintf(stderr, "%s: %s: %s\n",
+			    progname, p, strerror(ERANGE));
+		return (ERANGE);
+	}
+	if (p[0] == '\0' || (end[0] != '\0' && end[0] != '\n')) {
+		if (dbenv != NULL)
+			dbenv->errx(dbenv, DB_STR_A("0043",
+			    "%s: Invalid numeric argument", "%s"), p);
+		else
+			fprintf(stderr, DB_STR_A("0042",
+			    "%s: %s: Invalid numeric argument\n",
+			    "%s %s\n"), progname, p);
+		return (EINVAL);
+	}
+	if (val < min) {
+		if (dbenv != NULL)
+			dbenv->errx(dbenv, DB_STR_A("0045",
+			    "%s: Less than minimum value (%ld)",
+			    "%s %ld"), p, min);
+		else
+			fprintf(stderr, DB_STR_A("0044",
+			    "%s: %s: Less than minimum value (%ld)\n",
+			    "%s %s %ld\n"), progname, p, min);
+		return (ERANGE);
+	}
+	if (val > max) {
+		if (dbenv != NULL)
+			dbenv->errx(dbenv, DB_STR_A("0047",
+			    "%s: Greater than maximum value (%ld)",
+			    "%s %ld"), p, max);
+		else
+			fprintf(stderr, DB_STR_A("0046",
+			    "%s: %s: Greater than maximum value (%ld)\n",
+			    "%s %s %ld\n"), progname, p, max);
+		return (ERANGE);
+	}
+	*storep = val;
+	return (0);
+}
+
+/*
+ * __db_getulong --
+ *	Return an unsigned long value inside of basic parameters.
+ *
+ * PUBLIC: int __db_getulong
+ * PUBLIC:     __P((DB_ENV *, const char *, char *, u_long, u_long, u_long *));
+ */
+int
+__db_getulong(dbenv, progname, p, min, max, storep)
+	DB_ENV *dbenv;
+	const char *progname;
+	char *p;
+	u_long min, max, *storep;
+{
+	u_long val;
+	char *end;
+
+	__os_set_errno(0);
+	val = strtoul(p, &end, 10);
+	if (val == ULONG_MAX && __os_get_errno() == ERANGE) {
+#ifndef HAVE_RDS_BUILD
+		if (dbenv != NULL)
+			dbenv->err(dbenv, ERANGE, "%s", p);
+		else
+#endif
+			fprintf(stderr, "%s: %s: %s\n",
+			    progname, p, strerror(ERANGE));
+		return (ERANGE);
+	}
+	if (p[0] == '\0' || (end[0] != '\0' && end[0] != '\n')) {
+		if (dbenv != NULL)
+			dbenv->errx(dbenv, DB_STR_A("0049",
+			    "%s: Invalid numeric argument",
+			    "%s"), p);
+		else
+			fprintf(stderr, DB_STR_A("0048",
+			    "%s: %s: Invalid numeric argument\n",
+			    "%s %s\n"), progname, p);
+		return (EINVAL);
+	}
+	if (val < min) {
+		if (dbenv != NULL)
+			dbenv->errx(dbenv, DB_STR_A("0051",
+			    "%s: Less than minimum value (%lu)",
+			    "%s %lu"), p, min);
+		else
+			fprintf(stderr, DB_STR_A("0050",
+			    "%s: %s: Less than minimum value (%lu)\n",
+			    "%s %s %lu\n"), progname, p, min);
+		return (ERANGE);
+	}
+
+	/*
+	 * We allow a 0 to substitute as a max value for ULONG_MAX because
+	 * 1) accepting only a 0 value is unlikely to be necessary, and 2)
+	 * we don't want callers to have to use ULONG_MAX explicitly, as it
+	 * may not exist on all platforms.
+	 */
+	if (max != 0 && val > max) {
+		if (dbenv != NULL)
+			dbenv->errx(dbenv, DB_STR_A("0053",
+			    "%s: Greater than maximum value (%lu)",
+			    "%s %lu"), p, max);
+		else
+			fprintf(stderr, DB_STR_A("0052",
+			    "%s: %s: Greater than maximum value (%lu)\n",
+			    "%s %s %lu\n"), progname, p, max);
+		return (ERANGE);
+	}
+	*storep = val;
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/db_idspace.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,107 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+static int __db_idcmp __P((const void *, const void *));
+
+static int
+__db_idcmp(a, b)
+	const void *a;
+	const void *b;
+{
+	u_int32_t i, j;
+
+	i = *(u_int32_t *)a;
+	j = *(u_int32_t *)b;
+
+	if (i < j)
+		return (-1);
+	else if (i > j)
+		return (1);
+	else
+		return (0);
+}
+
+/*
+ * __db_idspace --
+ *
+ * On input, minp and maxp contain the minimum and maximum valid values for
+ * the name space and on return, they contain the minimum and maximum ids
+ * available (by finding the biggest gap).  The minimum can be an inuse
+ * value, but the maximum cannot be.
+ *
+ * PUBLIC: void __db_idspace __P((u_int32_t *, int, u_int32_t *, u_int32_t *));
+ */
+void
+__db_idspace(inuse, n, minp, maxp)
+	u_int32_t *inuse;
+	int n;
+	u_int32_t *minp, *maxp;
+{
+	int i, low;
+	u_int32_t gap, t;
+
+	/* A single locker ID is a special case. */
+	if (n == 1) {
+		/*
+		 * If the single item in use is the last one in the range,
+		 * then we've got to perform wrap which means that we set
+		 * the min to the minimum ID, which is what we came in with,
+		 * so we don't do anything.
+		 */
+		if (inuse[0] != *maxp)
+			*minp = inuse[0];
+		*maxp = inuse[0] - 1;
+		return;
+	}
+
+	gap = 0;
+	low = 0;
+	qsort(inuse, (size_t)n, sizeof(u_int32_t), __db_idcmp);
+	for (i = 0; i < n - 1; i++)
+		if ((t = (inuse[i + 1] - inuse[i])) > gap) {
+			gap = t;
+			low = i;
+		}
+
+	/* Check for largest gap at the end of the space. */
+	if ((*maxp - inuse[n - 1]) + (inuse[0] - *minp) > gap) {
+		/* Do same check as we do in the n == 1 case. */
+		if (inuse[n - 1] != *maxp)
+			*minp = inuse[n - 1];
+		*maxp = inuse[0] - 1;
+	} else {
+		*minp = inuse[low];
+		*maxp = inuse[low + 1] - 1;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/db_log2.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,79 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1995, 1996
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * PUBLIC: u_int32_t __db_log2 __P((u_int32_t));
+ */
+u_int32_t
+__db_log2(num)
+	u_int32_t num;
+{
+	u_int32_t i, limit;
+
+	limit = 1;
+	for (i = 0; limit < num; limit = limit << 1)
+		++i;
+	return (i);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/db_shash.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,126 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __db_tablesize --
+ *	Choose a size for the hash table.
+ *
+ * PUBLIC: u_int32_t __db_tablesize __P((u_int32_t));
+ */
+u_int32_t
+__db_tablesize(n_buckets)
+	u_int32_t n_buckets;
+{
+	/*
+	 * We try to be clever about how big we make the hash tables.  Use a
+	 * prime number close to the "suggested" number of elements that will
+	 * be in the hash table.  Use 32 as the minimum hash table size.
+	 *
+	 * Ref: Sedgewick, Algorithms in C, "Hash Functions"
+	 *
+	 * Up to ~250,000 buckets, we use powers of 2.  After that, we slow
+	 * the rate of increase by half.  For each choice, we then use a
+	 * nearby prime number as the hash value.
+	 *
+	 * If a terabyte is the maximum cache we'll see, and we assume there
+	 * are 10 1K buckets on each hash chain, then 107374182 is the maximum
+	 * number of buckets we'll ever need.
+	 *
+	 * We don't use the obvious static data structure because some C
+	 * compilers (and I use the term loosely), can't handle them.
+	 */
+#define	HASH_SIZE(power, prime) {					\
+	if ((power) >= n_buckets)					\
+		return (prime);						\
+}
+	HASH_SIZE(32, 37);			/* 2^5 */
+	HASH_SIZE(64, 67);			/* 2^6 */
+	HASH_SIZE(128, 131);			/* 2^7 */
+	HASH_SIZE(256, 257);			/* 2^8 */
+	HASH_SIZE(512, 521);			/* 2^9 */
+	HASH_SIZE(1024, 1031);			/* 2^10 */
+	HASH_SIZE(2048, 2053);			/* 2^11 */
+	HASH_SIZE(4096, 4099);			/* 2^12 */
+	HASH_SIZE(8192, 8191);			/* 2^13 */
+	HASH_SIZE(16384, 16381);		/* 2^14 */
+	HASH_SIZE(32768, 32771);		/* 2^15 */
+	HASH_SIZE(65536, 65537);		/* 2^16 */
+	HASH_SIZE(131072, 131071);		/* 2^17 */
+	HASH_SIZE(262144, 262147);		/* 2^18 */
+	HASH_SIZE(393216, 393209);		/* 2^18 + 2^18/2 */
+	HASH_SIZE(524288, 524287);		/* 2^19 */
+	HASH_SIZE(786432, 786431);		/* 2^19 + 2^19/2 */
+	HASH_SIZE(1048576, 1048573);		/* 2^20 */
+	HASH_SIZE(1572864, 1572869);		/* 2^20 + 2^20/2 */
+	HASH_SIZE(2097152, 2097169);		/* 2^21 */
+	HASH_SIZE(3145728, 3145721);		/* 2^21 + 2^21/2 */
+	HASH_SIZE(4194304, 4194301);		/* 2^22 */
+	HASH_SIZE(6291456, 6291449);		/* 2^22 + 2^22/2 */
+	HASH_SIZE(8388608, 8388617);		/* 2^23 */
+	HASH_SIZE(12582912, 12582917);		/* 2^23 + 2^23/2 */
+	HASH_SIZE(16777216, 16777213);		/* 2^24 */
+	HASH_SIZE(25165824, 25165813);		/* 2^24 + 2^24/2 */
+	HASH_SIZE(33554432, 33554393);		/* 2^25 */
+	HASH_SIZE(50331648, 50331653);		/* 2^25 + 2^25/2 */
+	HASH_SIZE(67108864, 67108859);		/* 2^26 */
+	HASH_SIZE(100663296, 100663291);	/* 2^26 + 2^26/2 */
+	HASH_SIZE(134217728, 134217757);	/* 2^27 */
+	HASH_SIZE(201326592, 201326611);	/* 2^27 + 2^27/2 */
+	HASH_SIZE(268435456, 268435459);	/* 2^28 */
+	HASH_SIZE(402653184, 402653189);	/* 2^28 + 2^28/2 */
+	HASH_SIZE(536870912, 536870909);	/* 2^29 */
+	HASH_SIZE(805306368, 805306357);	/* 2^29 + 2^29/2 */
+	HASH_SIZE(1073741824, 1073741827);	/* 2^30 */
+	return (1073741827);
+}
+
+/*
+ * __db_hashinit --
+ *	Initialize a hash table that resides in shared memory.
+ *
+ * PUBLIC: void __db_hashinit __P((void *, u_int32_t));
+ */
+void
+__db_hashinit(begin, nelements)
+	void *begin;
+	u_int32_t nelements;
+{
+	u_int32_t i;
+	SH_TAILQ_HEAD(hash_head) *headp;
+
+	headp = (struct hash_head *)begin;
+
+	for (i = 0; i < nelements; i++, headp++)
+		SH_TAILQ_INIT(headp);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/dbt.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,96 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __dbt_usercopy --
+ *	Take a copy of the user's data, if a callback is supplied.
+ *
+ * PUBLIC: int __dbt_usercopy __P((ENV *, DBT *));
+ */
+int
+__dbt_usercopy(env, dbt)
+	ENV *env;
+	DBT *dbt;
+{
+	void *buf;
+	int ret;
+
+	if (dbt == NULL || !F_ISSET(dbt, DB_DBT_USERCOPY) || dbt->size == 0 ||
+	    dbt->data != NULL)
+		return (0);
+
+	buf = NULL;
+	if ((ret = __os_umalloc(env, dbt->size, &buf)) != 0 ||
+	    (ret = env->dbt_usercopy(dbt, 0, buf, dbt->size,
+	    DB_USERCOPY_GETDATA)) != 0)
+		goto err;
+	dbt->data = buf;
+
+	return (0);
+
+err:	if (buf != NULL) {
+		__os_ufree(env, buf);
+		dbt->data = NULL;
+	}
+
+	return (ret);
+}
+
+/*
+ * __dbt_userfree --
+ *	Free a copy of the user's data, if necessary.
+ *
+ * PUBLIC: void __dbt_userfree __P((ENV *, DBT *, DBT *, DBT *));
+ */
+void
+__dbt_userfree(env, key, pkey, data)
+	ENV *env;
+	DBT *key, *pkey, *data;
+{
+	if (key != NULL &&
+	    F_ISSET(key, DB_DBT_USERCOPY) && key->data != NULL) {
+		__os_ufree(env, key->data);
+		key->data = NULL;
+	}
+	if (pkey != NULL &&
+	    F_ISSET(pkey, DB_DBT_USERCOPY) && pkey->data != NULL) {
+		__os_ufree(env, pkey->data);
+		pkey->data = NULL;
+	}
+	if (data != NULL &&
+	    F_ISSET(data, DB_DBT_USERCOPY) && data->data != NULL) {
+		__os_ufree(env, data->data);
+		data->data = NULL;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/mkpath.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,90 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __db_mkpath -- --
+ *	Create intermediate directories.
+ *
+ * PUBLIC: int __db_mkpath __P((ENV *, const char *));
+ */
+int
+__db_mkpath(env, name)
+	ENV *env;
+	const char *name;
+{
+	size_t len;
+	int ret;
+	char *p, *t, savech;
+
+	/*
+	 * Get a copy so we can modify the string.  It's a path and potentially
+	 * quite long, so don't allocate the space on the stack.
+	 */
+	len = strlen(name) + 1;
+	if ((ret = __os_malloc(env, len, &t)) != 0)
+		return (ret);
+	memcpy(t, name, len);
+
+	/*
+	 * Cycle through the path, creating intermediate directories.
+	 *
+	 * Skip the first byte if it's a path separator, it's the start of an
+	 * absolute pathname.
+	 */
+	if (PATH_SEPARATOR[1] == '\0') {
+		for (p = t + 1; p[0] != '\0'; ++p)
+			if (p[0] == PATH_SEPARATOR[0]) {
+				savech = *p;
+				*p = '\0';
+				if (__os_exists(env, t, NULL) &&
+				    (ret = __os_mkdir(
+					env, t, env->dir_mode)) != 0)
+					break;
+				*p = savech;
+			}
+	} else
+		for (p = t + 1; p[0] != '\0'; ++p)
+			if (strchr(PATH_SEPARATOR, p[0]) != NULL) {
+				savech = *p;
+				*p = '\0';
+				if (__os_exists(env, t, NULL) &&
+				    (ret = __os_mkdir(
+					env, t, env->dir_mode)) != 0)
+					break;
+				*p = savech;
+			}
+
+	__os_free(env, t);
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/os_method.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,292 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * EXTERN: int db_env_set_func_assert
+ * EXTERN:     __P((void (*)(const char *, const char *, int)));
+ */
+int
+db_env_set_func_assert(func_assert)
+	void (*func_assert) __P((const char *, const char *, int));
+{
+	DB_GLOBAL(j_assert) = func_assert;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_close __P((int (*)(int)));
+ */
+int
+db_env_set_func_close(func_close)
+	int (*func_close) __P((int));
+{
+	DB_GLOBAL(j_close) = func_close;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_dirfree __P((void (*)(char **, int)));
+ */
+int
+db_env_set_func_dirfree(func_dirfree)
+	void (*func_dirfree) __P((char **, int));
+{
+	DB_GLOBAL(j_dirfree) = func_dirfree;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_dirlist
+ * EXTERN:     __P((int (*)(const char *, char ***, int *)));
+ */
+int
+db_env_set_func_dirlist(func_dirlist)
+	int (*func_dirlist) __P((const char *, char ***, int *));
+{
+	DB_GLOBAL(j_dirlist) = func_dirlist;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_exists __P((int (*)(const char *, int *)));
+ */
+int
+db_env_set_func_exists(func_exists)
+	int (*func_exists) __P((const char *, int *));
+{
+	DB_GLOBAL(j_exists) = func_exists;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_free __P((void (*)(void *)));
+ */
+int
+db_env_set_func_free(func_free)
+	void (*func_free) __P((void *));
+{
+	DB_GLOBAL(j_free) = func_free;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_fsync __P((int (*)(int)));
+ */
+int
+db_env_set_func_fsync(func_fsync)
+	int (*func_fsync) __P((int));
+{
+	DB_GLOBAL(j_fsync) = func_fsync;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_ftruncate __P((int (*)(int, off_t)));
+ */
+int
+db_env_set_func_ftruncate(func_ftruncate)
+	int (*func_ftruncate) __P((int, off_t));
+{
+	DB_GLOBAL(j_ftruncate) = func_ftruncate;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_ioinfo __P((int (*)(const char *,
+ * EXTERN:     int, u_int32_t *, u_int32_t *, u_int32_t *)));
+ */
+int
+db_env_set_func_ioinfo(func_ioinfo)
+	int (*func_ioinfo)
+	    __P((const char *, int, u_int32_t *, u_int32_t *, u_int32_t *));
+{
+	DB_GLOBAL(j_ioinfo) = func_ioinfo;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_malloc __P((void *(*)(size_t)));
+ */
+int
+db_env_set_func_malloc(func_malloc)
+	void *(*func_malloc) __P((size_t));
+{
+	DB_GLOBAL(j_malloc) = func_malloc;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_file_map
+ * EXTERN:    __P((int (*)(DB_ENV *, char *, size_t, int, void **),
+ * EXTERN:    int (*)(DB_ENV *, void *)));
+ */
+int
+db_env_set_func_file_map(func_file_map, func_file_unmap)
+	int (*func_file_map) __P((DB_ENV *, char *, size_t, int, void **));
+	int (*func_file_unmap) __P((DB_ENV *, void *));
+{
+	DB_GLOBAL(j_file_map) = func_file_map;
+	DB_GLOBAL(j_file_unmap) = func_file_unmap;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_region_map
+ * EXTERN:    __P((int (*)(DB_ENV *, char *, size_t, int *, void **),
+ * EXTERN:    int (*)(DB_ENV *, void *)));
+ */
+int
+db_env_set_func_region_map(func_region_map, func_region_unmap)
+	int (*func_region_map) __P((DB_ENV *, char *, size_t, int *, void **));
+	int (*func_region_unmap) __P((DB_ENV *, void *));
+{
+	DB_GLOBAL(j_region_map) = func_region_map;
+	DB_GLOBAL(j_region_unmap) = func_region_unmap;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_pread
+ * EXTERN:    __P((ssize_t (*)(int, void *, size_t, off_t)));
+ */
+int
+db_env_set_func_pread(func_pread)
+	ssize_t (*func_pread) __P((int, void *, size_t, off_t));
+{
+	DB_GLOBAL(j_pread) = func_pread;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_pwrite
+ * EXTERN:    __P((ssize_t (*)(int, const void *, size_t, off_t)));
+ */
+int
+db_env_set_func_pwrite(func_pwrite)
+	ssize_t (*func_pwrite) __P((int, const void *, size_t, off_t));
+{
+	DB_GLOBAL(j_pwrite) = func_pwrite;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_open __P((int (*)(const char *, int, ...)));
+ */
+int
+db_env_set_func_open(func_open)
+	int (*func_open) __P((const char *, int, ...));
+{
+	DB_GLOBAL(j_open) = func_open;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_read __P((ssize_t (*)(int, void *, size_t)));
+ */
+int
+db_env_set_func_read(func_read)
+	ssize_t (*func_read) __P((int, void *, size_t));
+{
+	DB_GLOBAL(j_read) = func_read;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_realloc __P((void *(*)(void *, size_t)));
+ */
+int
+db_env_set_func_realloc(func_realloc)
+	void *(*func_realloc) __P((void *, size_t));
+{
+	DB_GLOBAL(j_realloc) = func_realloc;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_rename
+ * EXTERN:     __P((int (*)(const char *, const char *)));
+ */
+int
+db_env_set_func_rename(func_rename)
+	int (*func_rename) __P((const char *, const char *));
+{
+	DB_GLOBAL(j_rename) = func_rename;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_seek
+ * EXTERN:     __P((int (*)(int, off_t, int)));
+ */
+int
+db_env_set_func_seek(func_seek)
+	int (*func_seek) __P((int, off_t, int));
+{
+	DB_GLOBAL(j_seek) = func_seek;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_unlink __P((int (*)(const char *)));
+ */
+int
+db_env_set_func_unlink(func_unlink)
+	int (*func_unlink) __P((const char *));
+{
+	DB_GLOBAL(j_unlink) = func_unlink;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_write
+ * EXTERN:     __P((ssize_t (*)(int, const void *, size_t)));
+ */
+int
+db_env_set_func_write(func_write)
+	ssize_t (*func_write) __P((int, const void *, size_t));
+{
+	DB_GLOBAL(j_write) = func_write;
+	return (0);
+}
+
+/*
+ * EXTERN: int db_env_set_func_yield __P((int (*)(u_long, u_long)));
+ */
+int
+db_env_set_func_yield(func_yield)
+	int (*func_yield) __P((u_long, u_long));
+{
+	DB_GLOBAL(j_yield) = func_yield;
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/rds_stub.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1417 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/log.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+/*
+ * If the library was built in the 'lite' version, various routines
+ * aren't available.  Stub them here, returning an appropriate error.
+ */
+static int __db_rds __P((ENV *));
+static int __db_notransactions __P((ENV *));
+
+
+
+/*
+ * __dbreg_get_name	- a non-trival 'stub' function!
+ *
+ * Interface to get name of registered files.  This is mainly diagnostic
+ * and the name passed could be transient unless there is something
+ * ensuring that the file cannot be closed.
+ *
+ *	It is used in __lock_stat_print().
+ */
+int
+__dbreg_get_name(env, fid, fnamep, dnamep)
+	ENV *env;
+	u_int8_t *fid;
+	char **fnamep, **dnamep;
+{
+	*fnamep = "<Some File>";
+	*dnamep = NULL;
+	COMPQUIET(env, NULL);
+	COMPQUIET(fid, NULL);
+	return (-1);
+}
+
+/*
+ * __db_rds --
+ *	Error when a restricted distribution invokes a full Berkeley DB feature.
+ *
+ * PUBLIC: 
+ */
+static int
+__db_rds(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("0750",
+	    "This RDS build does not include support for this function"));
+	__os_stack(env);
+	return (DB_OPNOTSUP);
+}
+
+/*
+ * __db_notransactions --
+ *	Error when a Berkeley DB build doesn't include transaction support.
+ */
+static int
+__db_notransactions(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("0751",
+	    "library build did not include support for transactions"));
+	__os_stack(env);
+	return (DB_OPNOTSUP);
+}
+
+int
+__db_check_chksum(env, hdr, db_cipher, chksum, data, data_len, is_hmac)
+	ENV *env;
+	void *hdr;
+	DB_CIPHER *db_cipher;
+	u_int8_t *chksum;
+	void *data;
+	size_t data_len;
+	int is_hmac;
+{
+	COMPQUIET(hdr, NULL);
+	COMPQUIET(db_cipher, NULL);
+	COMPQUIET(chksum, NULL);
+	COMPQUIET(data, NULL);
+	COMPQUIET(data_len, 0);
+	COMPQUIET(is_hmac, 0);
+	return (__db_rds(env));
+}
+
+int
+__db_relink_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, db_pgno_t new_pgno, db_pgno_t prev_pgno, DB_LSN * lsn_prev,
+    db_pgno_t next_pgno, DB_LSN * lsn_next)
+{
+	COMPQUIET(txnp, NULL);
+	COMPQUIET(ret_lsnp, NULL);
+	COMPQUIET(flags, 0);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(new_pgno, 0);
+	COMPQUIET(prev_pgno, 0);
+	COMPQUIET(lsn_prev, NULL);
+	COMPQUIET(next_pgno, 0);
+	COMPQUIET(lsn_next, NULL);
+	return (__db_rds(dbp->env));
+}
+
+int
+__db_relink_42_print(env, dbtp, lsnp, notused2, info)
+	ENV *env;
+	DBT *dbtp;
+	DB_LSN *lsnp;
+	db_recops notused2;
+	void *info;
+{
+	COMPQUIET(dbtp, NULL);
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(notused2, 0);
+	COMPQUIET(info, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__db_relink_print(env, dbtp, lsnp, notused2, info)
+	ENV *env;
+	DBT *dbtp;
+	DB_LSN *lsnp;
+	db_recops notused2;
+	void *info;
+{
+	COMPQUIET(dbtp, NULL);
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(notused2, 0);
+	COMPQUIET(info, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__db_relink_42_recover(env, dbtp, lsnp, op, info)
+	ENV *env;
+	DBT *dbtp;
+	DB_LSN *lsnp;
+	db_recops op;
+	void *info;
+{
+	COMPQUIET(dbtp, NULL);
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(op, 0);
+	COMPQUIET(info, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__db_relink_recover(env, dbtp, lsnp, op, info)
+	ENV *env;
+	DBT *dbtp;
+	DB_LSN *lsnp;
+	db_recops op;
+	void *info;
+{
+	COMPQUIET(dbtp, NULL);
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(op, 0);
+	COMPQUIET(info, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__db_upgrade_pp(dbp, fname, flags)
+	DB *dbp;
+	const char *fname;
+	u_int32_t flags;
+{
+	COMPQUIET(fname, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_rds(dbp->env));
+}
+
+int
+__dbreg_log_id(dbp, txn, id, needlock)
+	DB *dbp;
+	DB_TXN *txn;
+	int32_t id;
+	int needlock;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(id, 0);
+	COMPQUIET(needlock, 0);
+	return (__db_notransactions(dbp->env));
+}
+
+void
+__dbreg_print_fname(env, fnp)
+	ENV *env;
+	FNAME *fnp;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(fnp, NULL);
+}
+
+int
+__env_get_backup_config(dbenv, config, valuep)
+	DB_ENV *dbenv;
+	DB_BACKUP_CONFIG config;
+	u_int32_t *valuep;
+{
+	COMPQUIET(config, 0);
+	COMPQUIET(valuep, 0);
+	return (__db_rds(dbenv->env));
+}
+
+int
+__env_set_backup_config(dbenv, config, value)
+	DB_ENV *dbenv;
+	DB_BACKUP_CONFIG config;
+	u_int32_t value;
+{
+	COMPQUIET(config, 0);
+	COMPQUIET(value, 0);
+	return (__db_rds(dbenv->env));
+}
+
+int
+__env_get_backup_callbacks(dbenv, openp, writep, closep)
+	DB_ENV *dbenv;
+	int (**openp)(DB_ENV *, const char *, const char *, void **);
+	int (**writep)(DB_ENV *,
+		    u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *);
+	int (**closep)(DB_ENV *, const char *, void *);
+{
+	COMPQUIET(openp, NULL);
+	COMPQUIET(writep, NULL);
+	COMPQUIET(closep, NULL);
+	return (__db_rds(dbenv->env));
+}
+
+int
+__env_set_backup_callbacks(dbenv, open_func, write_func, close_func)
+	DB_ENV *dbenv;
+	int (*open_func)(DB_ENV *, const char *, const char *, void **);
+	int (*write_func)(DB_ENV *,
+	    u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *);
+	int (*close_func)(DB_ENV *, const char *, void *);
+{
+	COMPQUIET(open_func, NULL);
+	COMPQUIET(write_func, NULL);
+	COMPQUIET(close_func, NULL);
+	return (__db_rds(dbenv->env));
+}
+
+int
+__env_failchk_pp(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_rds(dbenv->env));
+}
+
+int
+__env_failchk_int(dbenv)
+	DB_ENV *dbenv;
+{
+	return (__db_rds(dbenv->env));
+}
+
+size_t
+__env_thread_size(env, other_alloc)
+	ENV *env;
+	size_t other_alloc;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(other_alloc, 0);
+	return (0);
+}
+
+size_t
+__env_thread_max(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+int
+__env_thread_init(env, during_creation)
+	ENV *env;
+	int during_creation;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(during_creation, 0);
+	return (0);
+}
+
+void
+__env_thread_destroy(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+}
+
+int
+__env_set_state(env, ipp, state)
+	ENV *env;
+	DB_THREAD_INFO **ipp;
+	DB_THREAD_STATE state;
+{
+	COMPQUIET(ipp, NULL);
+	COMPQUIET(state, 0);
+	return (__db_rds(env));
+}
+
+int
+__env_init_rec(env, version)
+	ENV *env;
+	u_int32_t version;
+{
+	COMPQUIET(version, 0);
+	return (__db_rds(env));
+}
+
+int
+__env_init_rec_42(env)
+	ENV *env;
+{
+	return (__db_rds(env));
+}
+
+int
+__env_init_rec_43(env)
+	ENV *env;
+{
+	return (__db_rds(env));
+}
+
+int
+__env_init_rec_46(env)
+	ENV *env;
+{
+	return (__db_rds(env));
+}
+
+int
+__env_init_rec_47(env)
+	ENV *env;
+{
+	return (__db_rds(env));
+}
+
+int
+__env_init_rec_48(env)
+	ENV *env;
+{
+	return (__db_rds(env));
+}
+
+int
+__envreg_register(env, need_recoveryp, flags)
+	ENV *env;
+	int *need_recoveryp;
+	u_int32_t flags;
+{
+	COMPQUIET(need_recoveryp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_rds(env));
+}
+
+int
+__envreg_unregister(env, recovery_failed)
+	ENV *env;
+	int recovery_failed;
+{
+	COMPQUIET(recovery_failed, 0);
+	return (__db_rds(env));
+}
+
+int
+__envreg_xunlock(env)
+	ENV *env;
+{
+	return (__db_rds(env));
+}
+
+int
+__envreg_isalive(dbenv, pid, tid, flags )
+	DB_ENV *dbenv;
+	pid_t pid;
+	db_threadid_t tid;
+	u_int32_t flags;
+{
+	COMPQUIET(pid, 0);
+	DB_THREADID_INIT(tid);
+	COMPQUIET(flags, 0);
+	return (__db_rds(dbenv->env));
+}
+
+int
+__log_open(env)
+	ENV *env;
+{
+	return (__db_notransactions(env));
+}
+
+size_t
+__log_region_size(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+size_t
+__log_region_max(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+u_int32_t
+__log_region_mutex_count(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+u_int32_t
+__log_region_mutex_max(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+int
+__log_archive_pp(dbenv, listp, flags)
+	DB_ENV *dbenv;
+	char ***listp;
+	u_int32_t flags;
+{
+	COMPQUIET(listp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__log_archive(env, listp, flags)
+	ENV *env;
+	char ***listp;
+	u_int32_t flags;
+{
+	COMPQUIET(listp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_notransactions(env));
+}
+
+int
+__log_env_create(dbenv)
+	DB_ENV *dbenv;
+{
+	COMPQUIET(dbenv, NULL);
+	return (0);
+}
+
+void
+__log_env_destroy(dbenv)
+	DB_ENV *dbenv;
+{
+	COMPQUIET(dbenv, NULL);
+}
+
+int
+__log_get_config(dbenv, which, onp)
+	DB_ENV *dbenv;
+	u_int32_t which;
+	int *onp;
+{
+	COMPQUIET(which, 0);
+	COMPQUIET(onp, NULL);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__log_set_lg_bsize(dbenv, lg_bsize)
+	DB_ENV *dbenv;
+	u_int32_t lg_bsize;
+{
+	COMPQUIET(lg_bsize, 0);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__log_set_lg_filemode(dbenv, lg_mode)
+	DB_ENV *dbenv;
+	int lg_mode;
+{
+	COMPQUIET(lg_mode, 0);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__log_set_lg_max(dbenv, lg_max)
+	DB_ENV *dbenv;
+	u_int32_t lg_max;
+{
+	COMPQUIET(lg_max, 0);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__log_set_lg_regionmax(dbenv, lg_regionmax)
+	DB_ENV *dbenv;
+	u_int32_t lg_regionmax;
+{
+	COMPQUIET(lg_regionmax, 0);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__log_set_lg_dir(dbenv, dir)
+	DB_ENV *dbenv;
+	const char *dir;
+{
+	COMPQUIET(dir, NULL);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__log_set_config(dbenv, flags, on)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+	int on;
+{
+	COMPQUIET(flags, 0);
+	COMPQUIET(on, 0);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__log_set_config_int(dbenv, flags, on, in_open)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+	int on;
+	int in_open;
+{
+	COMPQUIET(flags, 0);
+	COMPQUIET(on, 0);
+	COMPQUIET(in_open, 0);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__log_flush_commit(env, lsnp, flags)
+	ENV *env;
+	const DB_LSN *lsnp;
+	u_int32_t flags;
+{
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_notransactions(env));
+}
+
+int
+__log_flush_pp(dbenv, lsn)
+	DB_ENV *dbenv;
+	const DB_LSN *lsn;
+{
+	COMPQUIET(lsn, NULL);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__log_flush(env, lsn)
+	ENV *env;
+	const DB_LSN *lsn;
+{
+	COMPQUIET(lsn, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__log_flush_int(dblp, lsnp, release)
+	DB_LOG *dblp;
+	const DB_LSN *lsnp;
+	int release;
+{
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(release, 0);
+	return (__db_notransactions(dblp->env));
+}
+
+int
+__log_stat_print(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_notransactions(env));
+}
+
+
+int
+log_compare(lsn0, lsn1)
+	const DB_LSN *lsn0, *lsn1;
+{
+	COMPQUIET(lsn0, NULL);
+	COMPQUIET(lsn1, NULL);
+	return (__db_notransactions(NULL));
+}
+
+int
+__log_check_page_lsn(env, dbp, lsnp)
+	ENV *env;
+	DB *dbp;
+	DB_LSN *lsnp;
+{
+	COMPQUIET(dbp, NULL);
+	COMPQUIET(lsnp, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__log_current_lsn_int(env, lsnp, mbytesp, bytesp)
+	ENV *env;
+	DB_LSN *lsnp;
+	u_int32_t *mbytesp, *bytesp;
+{
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(mbytesp, NULL);
+	COMPQUIET(bytesp, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__log_env_refresh(env)
+	ENV *env;
+{
+	return (__db_notransactions(env));
+}
+
+#ifdef STDC_HEADERS
+int
+__log_put_record(ENV *env, DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp,
+    u_int32_t flags, u_int32_t rectype, u_int32_t has_data, u_int32_t size,
+    DB_LOG_RECSPEC *spec, ...)
+#else
+int
+__log_put_record(env, dbp, txnp, ret_lsnp,
+    flags, rectype, has_data, size, spec, va_alist);
+	ENV *env;
+	DB *dbp;
+	DB_TXN *txnp;
+	DB_LSN *ret_lsnp;
+	u_int32_t flags;
+	u_int32_t rectype;
+	u_int32_t has_data;
+	u_int32_t size;
+	DB_LOG_RECSPEC *spec;
+	va_dcl
+#endif
+{
+	COMPQUIET(dbp, NULL);
+	COMPQUIET(txnp, NULL);
+	COMPQUIET(ret_lsnp, NULL);
+	COMPQUIET(flags, 0);
+	COMPQUIET(rectype, 0);
+	COMPQUIET(has_data, 0);
+	COMPQUIET(size, 0);
+	COMPQUIET(spec, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__log_read_record(env, dbpp, td, recbuf, spec, size, argpp)
+	ENV *env;
+	DB **dbpp;
+	void *td;
+	void *recbuf;
+	DB_LOG_RECSPEC *spec;
+	u_int32_t size;
+	void **argpp;
+{
+	COMPQUIET(dbpp, NULL);
+	COMPQUIET(td, NULL);
+	COMPQUIET(recbuf, NULL);
+	COMPQUIET(spec, NULL);
+	COMPQUIET(size, 0);
+	COMPQUIET(argpp, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__db_relink_42_verify(env, dbtp, lsnp, notused2, lvhp)
+	ENV *env;
+	DBT *dbtp;
+	DB_LSN *lsnp;
+	db_recops notused2;
+	void *lvhp;
+{
+	COMPQUIET(dbtp, NULL);
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(notused2, 0);
+	COMPQUIET(lvhp, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__db_relink_verify(env, dbtp, lsnp, notused2, lvhp)
+	ENV *env;
+	DBT *dbtp;
+	DB_LSN *lsnp;
+	db_recops notused2;
+	void *lvhp;
+{
+	COMPQUIET(dbtp, NULL);
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(notused2, 0);
+	COMPQUIET(lvhp, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__db_dbtxn_remove(dbp, ip, txn, name, subdb)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name, *subdb;
+{
+	COMPQUIET(ip, NULL);
+	COMPQUIET(txn, NULL);
+	COMPQUIET(name, NULL);
+	COMPQUIET(subdb, NULL);
+
+	return (__db_notransactions(dbp->env));
+}
+
+void
+__db_chksum(hdr, data, data_len, mac_key, store)
+	void *hdr;
+	u_int8_t *data;
+	size_t data_len;
+	u_int8_t *mac_key;
+	u_int8_t *store;
+{
+	COMPQUIET(hdr, NULL);
+	COMPQUIET(data, NULL);
+	COMPQUIET(data_len, 0);
+	COMPQUIET(mac_key, NULL);
+	COMPQUIET(store, NULL);
+	(void)__db_rds(NULL);
+}
+
+int
+__fop_subdb_setup(dbp, ip, txn, mname, name, mode, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *mname, *name;
+	int mode;
+	u_int32_t flags;
+{
+	COMPQUIET(dbp, NULL);
+	COMPQUIET(ip, NULL);
+	COMPQUIET(mname, NULL);
+	COMPQUIET(name, NULL);
+	COMPQUIET(mode, 0);
+	COMPQUIET(flags, 0);
+	return (__db_rds(NULL));
+}
+
+int
+__fop_dummy(dbp, txn, old, new)
+	DB *dbp;
+	DB_TXN *txn;
+	const char *old, *new;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(old, NULL);
+	COMPQUIET(new, NULL);
+	return (__db_notransactions(dbp->env));
+}
+
+int
+__memp_backup_open(env, mpf, dbfile, target, flags, fpp, handlep)
+	ENV *env;
+	DB_MPOOLFILE *mpf;
+	const char *dbfile;
+	const char *target;
+	u_int32_t flags;
+	DB_FH **fpp;
+	void **handlep;
+{
+	COMPQUIET(mpf, NULL);
+	COMPQUIET(dbfile, NULL);
+	COMPQUIET(target, NULL);
+	COMPQUIET(flags, 0);
+	COMPQUIET(fpp, NULL);
+	COMPQUIET(handlep, NULL);
+	return (__db_rds(env));
+}
+
+int
+__memp_backup_mpf(env, mpf, ip, first_pgno, last_pgno, fp, handle, flags)
+	ENV *env;
+	DB_MPOOLFILE *mpf;
+	DB_THREAD_INFO *ip;
+	db_pgno_t first_pgno, last_pgno;
+	DB_FH *fp;
+	void *handle;
+	u_int32_t flags;
+{
+	COMPQUIET(mpf, NULL);
+	COMPQUIET(ip, NULL);
+	COMPQUIET(first_pgno, 0);
+	COMPQUIET(last_pgno, 0);
+	COMPQUIET(fp, NULL);
+	COMPQUIET(handle, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_rds(env));
+}
+
+int
+__memp_backup_close(env, mpf, dbfile, fp, handle)
+	ENV *env;
+	DB_MPOOLFILE *mpf;
+	const char *dbfile;
+	DB_FH *fp;
+	void *handle;
+{
+	COMPQUIET(mpf, NULL);
+	COMPQUIET(dbfile, NULL);
+	COMPQUIET(fp, NULL);
+	COMPQUIET(handle, NULL);
+	return (__db_rds(env));
+}
+
+int
+__memp_bh_freeze(dbmp, infop, hp, bhp, need_frozenp)
+	DB_MPOOL *dbmp;
+	REGINFO *infop;
+	DB_MPOOL_HASH *hp;
+	BH *bhp;
+	int *need_frozenp;
+{
+	COMPQUIET(infop, NULL);
+	COMPQUIET(hp, NULL);
+	COMPQUIET(bhp, NULL);
+	COMPQUIET(need_frozenp, NULL);
+	return (__db_rds(dbmp->env));
+}
+
+int
+__memp_bh_thaw(dbmp, infop, hp, frozen_bhp, alloc_bhp)
+	DB_MPOOL *dbmp;
+	REGINFO *infop;
+	DB_MPOOL_HASH *hp;
+	BH *frozen_bhp, *alloc_bhp;
+{
+	COMPQUIET(infop, NULL);
+	COMPQUIET(hp, NULL);
+	COMPQUIET(frozen_bhp, NULL);
+	COMPQUIET(alloc_bhp, NULL);
+	return (__db_rds(dbmp->env));
+}
+
+int
+__memp_bh_settxn(dbmp, mfp, bhp, vtd)
+	DB_MPOOL *dbmp;
+	MPOOLFILE *mfp;
+	BH *bhp;
+	void *vtd;
+{
+	COMPQUIET(mfp, NULL);
+	COMPQUIET(bhp, NULL);
+	COMPQUIET(vtd, NULL);
+	return (__db_notransactions(dbmp->env));
+}
+
+int
+__memp_skip_curadj(dbc, pgno)
+	DBC *dbc;
+	db_pgno_t pgno;
+{
+	COMPQUIET(dbc, NULL);
+	COMPQUIET(pgno, 0);
+	return (FALSE);
+}
+
+int
+__txn_checkpoint_pp(dbenv, kbytes, minutes, flags)
+	DB_ENV *dbenv;
+	u_int32_t kbytes, minutes, flags;
+{
+	COMPQUIET(kbytes, 0);
+	COMPQUIET(minutes, 0);
+	COMPQUIET(flags, 0);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__txn_checkpoint(env, kbytes, minutes, flags)
+	ENV *env;
+	u_int32_t kbytes, minutes, flags;
+{
+	COMPQUIET(kbytes, 0);
+	COMPQUIET(minutes, 0);
+	COMPQUIET(flags, 0);
+	return (__db_notransactions(env));
+}
+
+int
+__txn_env_create(dbenv)
+	DB_ENV *dbenv;
+{
+	COMPQUIET(dbenv, NULL);
+	return (0);
+}
+
+void
+__txn_env_destroy(dbenv)
+	DB_ENV *dbenv;
+{
+	COMPQUIET(dbenv, NULL);
+}
+
+int
+__txn_set_timeout(txn, timeout, op)
+	DB_TXN *txn;
+	db_timeout_t timeout;
+	u_int32_t op;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(timeout, 0);
+	COMPQUIET(op, 0);
+	return (0);
+}
+
+int
+__txn_set_tx_max(dbenv, tx_max)
+	DB_ENV *dbenv;
+	u_int32_t tx_max;
+{
+	COMPQUIET(tx_max, 0);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__txn_set_tx_timestamp(dbenv, timestamp)
+	DB_ENV *dbenv;
+	time_t *timestamp;
+{
+	COMPQUIET(timestamp, NULL);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__txn_begin(env, ip, parent, txnpp, flags)
+	ENV *env;
+	DB_THREAD_INFO *ip;
+	DB_TXN *parent, **txnpp;
+	u_int32_t flags;
+{
+	COMPQUIET(ip, NULL);
+	COMPQUIET(parent, NULL);
+	COMPQUIET(txnpp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_notransactions(env));
+}
+
+int
+__txn_commit(txn, flags)
+	DB_TXN *txn;
+	u_int32_t flags;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_notransactions(NULL));
+	
+}
+
+int
+__txn_abort(txn)
+	DB_TXN *txn;
+{
+	COMPQUIET(txn, NULL);
+	return (__db_notransactions(NULL));
+}
+
+int
+__txn_preclose(env)
+	ENV *env;
+{
+	return (__db_notransactions(env));
+}
+
+int
+__dbreg_setup(dbp, fname, dname, create_txnid)
+	DB *dbp;
+	const char *fname, *dname;
+	u_int32_t create_txnid;
+{
+	COMPQUIET(fname, NULL);
+	COMPQUIET(dname, NULL);
+	COMPQUIET(create_txnid, 0);
+
+	return (__db_notransactions(dbp->env));
+}
+
+int
+__dbreg_new_id(dbp, txn)
+	DB *dbp;
+	DB_TXN *txn;
+{
+	COMPQUIET(txn, NULL);
+	return (__db_notransactions(dbp->env));
+}
+
+int
+__dbreg_revoke_id(dbp, have_lock, force_id)
+	DB *dbp;
+	int have_lock;
+	int32_t force_id;
+{
+	COMPQUIET(have_lock, 0);
+	COMPQUIET(force_id, 0);
+	return (__db_notransactions(dbp->env));
+}
+
+int
+__dbreg_teardown(dbp)
+	DB *dbp;
+{
+	return (__db_notransactions(dbp->env));
+}
+
+int
+__dbreg_close_id(dbp, txn, op)
+	DB *dbp;
+	DB_TXN *txn;
+	u_int32_t op;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(op, 0);
+	return (__db_notransactions(dbp->env));
+}
+
+int
+__dbreg_stat_print(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_notransactions(env));
+}
+
+/* txn_util.c */
+int
+__txn_closeevent(env, txn, dbp)
+	ENV *env;
+	DB_TXN *txn;
+	DB *dbp;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(dbp, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__txn_remevent(env, txn, name, fileid, inmem)
+	ENV *env;
+	DB_TXN *txn;
+	const char *name;
+	u_int8_t *fileid;
+	int inmem;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(name, NULL);
+	COMPQUIET(fileid, NULL);
+	COMPQUIET(inmem, 0);
+	return (__db_notransactions(env));
+}
+
+void
+__txn_remrem(env, txn, name)
+	ENV *env;
+	DB_TXN *txn;
+	const char *name;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(name, NULL);
+	(void) __db_notransactions(env);
+}
+
+int
+__txn_lockevent(env, txn, dbp, lock, locker)
+	ENV *env;
+	DB_TXN *txn;
+	DB *dbp;
+	DB_LOCK *lock;
+	DB_LOCKER *locker;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(dbp, NULL);
+	COMPQUIET(lock, NULL);
+	COMPQUIET(locker, NULL);
+	return (__db_notransactions(env));
+}
+
+void
+__txn_remlock(env, txn, lock, locker)
+	ENV *env;
+	DB_TXN *txn;
+	DB_LOCK *lock;
+	DB_LOCKER *locker;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(lock, NULL);
+	COMPQUIET(locker, NULL);
+	(void) __db_notransactions(env);
+}
+
+int
+__txn_record_fname(env, txn, fname)
+	ENV *env;
+	DB_TXN *txn;
+	FNAME *fname;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(fname, NULL);
+	return (__db_notransactions(env));
+}
+
+void
+__txn_remove_fe_watermark(txn, db)
+     DB_TXN *txn;
+     DB *db;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(db, NULL);
+}
+
+void
+__txn_add_fe_watermark(txn, db, pgno)
+     DB_TXN *txn;
+     DB *db;
+     db_pgno_t pgno;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(db, NULL);
+	COMPQUIET(pgno, 0);
+    	return;
+}
+
+int
+__txn_pg_above_fe_watermark(txn, mpf, pgno)
+     DB_TXN *txn;
+     MPOOLFILE *mpf;
+     db_pgno_t pgno;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(mpf, NULL);
+	COMPQUIET(pgno, 0);
+	return (0);
+}
+
+int
+__txn_stat_print(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_notransactions(env));
+}
+
+/* txn_region.c */
+int
+__txn_open(env)
+	ENV *env;
+{
+	return (__db_notransactions(env));
+}
+
+int
+__txn_env_refresh(env)
+	ENV *env;
+{
+	return (__db_notransactions(env));
+}
+
+int
+__txn_id_set(env, cur_txnid, max_txnid)
+	ENV *env;
+	u_int32_t cur_txnid, max_txnid;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(cur_txnid, 0);
+	COMPQUIET(max_txnid, 0);
+	return (0);
+}
+
+size_t
+__txn_region_max(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+size_t
+__txn_region_size(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+int
+__txn_oldest_reader(env, lsnp)
+	ENV *env;
+	DB_LSN *lsnp;
+{
+	COMPQUIET(lsnp, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__txn_add_buffer(env, td)
+	ENV *env;
+	TXN_DETAIL *td;
+{
+	COMPQUIET(td, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__txn_remove_buffer(env, td, hash_mtx)
+	ENV *env;
+	TXN_DETAIL *td;
+	db_mutex_t hash_mtx;
+{
+	COMPQUIET(td, NULL);
+	COMPQUIET(hash_mtx, 0);
+	return (__db_notransactions(env));
+}
+
+u_int32_t
+__txn_region_mutex_count(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	/*
+	 * We need  a mutex for DB_TXNMGR structure, two mutexes for
+	 * the DB_TXNREGION structure.
+	 */
+	return (1 + 2);
+}
+
+u_int32_t
+__txn_region_mutex_max(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+int
+__cdsgroup_begin_pp(dbenv, txnpp)
+	DB_ENV *dbenv;
+	DB_TXN **txnpp;
+{
+	COMPQUIET(txnpp, NULL);
+	return (__db_notransactions(dbenv->env));
+}
+
+int
+__cdsgroup_begin(env, txnpp)
+	ENV *env;
+	DB_TXN **txnpp;
+{
+	COMPQUIET(txnpp, NULL);
+	return (__db_notransactions(env));
+}
+
+int
+__db_check_txn(dbp, txn, assoc_locker, read_op)
+	DB *dbp;
+	DB_TXN *txn;
+	DB_LOCKER *assoc_locker;
+	int read_op;
+{
+	COMPQUIET(dbp, NULL);
+	COMPQUIET(txn, NULL);
+	COMPQUIET(assoc_locker, NULL);
+	COMPQUIET(read_op, 0);
+	return (0);
+}
+
+int
+__db_join_close(dbc)
+	DBC *dbc;
+{
+	return (__db_rds(dbc->env));
+}
+
+DB_LOG_RECSPEC __bam_split_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_split_48_desc[] = {  { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_split_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_rsplit_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_adj_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_cadjust_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_cdel_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_repl_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_irep_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_root_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_curadj_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_rcuradj_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_relink_43_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __bam_merge_44_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __crdel_metasub_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __crdel_inmem_create_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __crdel_inmem_rename_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __crdel_inmem_remove_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_addrem_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_addrem_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_big_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_big_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_ovref_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_relink_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_debug_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_noop_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_pg_alloc_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_pg_alloc_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_pg_free_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_pg_free_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_cksum_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_pg_freedata_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_pg_freedata_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_pg_init_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_pg_sort_44_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_pg_trunc_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_realloc_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_relink_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_merge_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __db_pgno_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __dbreg_register_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __fop_create_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __fop_create_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __fop_remove_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __fop_write_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __fop_write_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __fop_rename_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __fop_rename_noundo_46_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __fop_rename_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __fop_rename_noundo_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __fop_file_remove_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_insdel_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_insdel_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_newpage_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_splitdata_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_replace_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_replace_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_copypage_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_metagroup_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_metagroup_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_groupalloc_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_groupalloc_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_changeslot_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_contract_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_curadj_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __ham_chgpg_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __heap_addrem_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __heap_addrem_50_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __heap_pg_alloc_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __heap_trunc_meta_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __heap_trunc_page_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __qam_incfirst_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __qam_mvptr_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __qam_del_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __qam_add_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __qam_delext_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __repmgr_member_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __txn_regop_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __txn_regop_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __txn_ckp_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __txn_ckp_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __txn_child_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __txn_xa_regop_42_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __txn_prepare_desc[] = { { 0 , 0, NULL,  { '\0' } } };
+DB_LOG_RECSPEC __txn_recycle_desc[] = { { 0 , 0, NULL,  { '\0' } } };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/util_cache.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,69 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2000, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __db_util_cache --
+ *	Compute if we have enough cache.
+ *
+ * PUBLIC: int __db_util_cache __P((DB *, u_int32_t *, int *));
+ */
+int
+__db_util_cache(dbp, cachep, resizep)
+	DB *dbp;
+	u_int32_t *cachep;
+	int *resizep;
+{
+	u_int32_t pgsize;
+	int ret;
+
+	/* Get the current page size. */
+	if ((ret = dbp->get_pagesize(dbp, &pgsize)) != 0)
+		return (ret);
+
+	/*
+	 * The current cache size is in cachep.  If it's insufficient, set the
+	 * the memory referenced by resizep to 1 and set cachep to the minimum
+	 * size needed.
+	 *
+	 * Make sure our current cache is big enough.  We want at least
+	 * DB_MINPAGECACHE pages in the cache.
+	 */
+	if ((*cachep / pgsize) < DB_MINPAGECACHE) {
+		*resizep = 1;
+		*cachep = pgsize * DB_MINPAGECACHE;
+	} else
+		*resizep = 0;
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/util_log.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,67 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2000, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __db_util_logset --
+ *	Log that we're running.
+ *
+ * PUBLIC: int __db_util_logset __P((const char *, char *));
+ */
+int
+__db_util_logset(progname, fname)
+	const char *progname;
+	char *fname;
+{
+	pid_t pid;
+	FILE *fp;
+	time_t now;
+	char time_buf[CTIME_BUFLEN];
+
+	if ((fp = fopen(fname, "w")) == NULL)
+		goto err;
+
+	(void)time(&now);
+
+	__os_id(NULL, &pid, NULL);
+	fprintf(fp,
+	    "%s: %lu %s", progname, (u_long)pid, __os_ctime(&now, time_buf));
+
+	if (fclose(fp) == EOF)
+		goto err;
+
+	return (0);
+
+err:	fprintf(stderr, "%s: %s: %s\n", progname, fname, strerror(errno));
+	return (1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/util_sig.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,132 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2000, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+static int	interrupt;
+static void	set_signal __P((int, int));
+static void	signal_handler __P((int));
+
+/*
+ * signal_handler --
+ *	Interrupt signal handler.
+ */
+static void
+signal_handler(signo)
+	int signo;
+{
+#ifndef HAVE_SIGACTION
+	/* Assume signal() is unreliable and reset it, first thing. */
+	set_signal(signo, 0);
+#endif
+	/* Some systems don't pass in the correct signal value -- check. */
+	if ((interrupt = signo) == 0)
+		interrupt = SIGINT;
+}
+
+/*
+ * set_signal
+ */
+static void
+set_signal(s, is_dflt)
+	int s, is_dflt;
+{
+	/*
+	 * Use sigaction if it's available, otherwise use signal().
+	 */
+#ifdef HAVE_SIGACTION
+	struct sigaction sa, osa;
+
+	sa.sa_handler = is_dflt ? SIG_DFL : signal_handler;
+	(void)sigemptyset(&sa.sa_mask);
+	sa.sa_flags = 0;
+	(void)sigaction(s, &sa, &osa);
+#else
+	(void)signal(s, is_dflt ? SIG_DFL : signal_handler);
+#endif
+}
+
+/*
+ * __db_util_siginit --
+ *
+ * PUBLIC: void __db_util_siginit __P((void));
+ */
+void
+__db_util_siginit()
+{
+	/*
+	 * Initialize the set of signals for which we want to clean up.
+	 * Generally, we try not to leave the shared regions locked if
+	 * we can.
+	 */
+#ifdef SIGHUP
+	set_signal(SIGHUP, 0);
+#endif
+#ifdef SIGINT
+	set_signal(SIGINT, 0);
+#endif
+#ifdef SIGPIPE
+	set_signal(SIGPIPE, 0);
+#endif
+#ifdef SIGTERM
+	set_signal(SIGTERM, 0);
+#endif
+}
+
+/*
+ * __db_util_interrupted --
+ *	Return if interrupted.
+ *
+ * PUBLIC: int __db_util_interrupted __P((void));
+ */
+int
+__db_util_interrupted()
+{
+	return (interrupt != 0);
+}
+
+/*
+ * __db_util_sigresend --
+ *
+ * PUBLIC: void __db_util_sigresend __P((void));
+ */
+void
+__db_util_sigresend()
+{
+	/* Resend any caught signal. */
+	if (interrupt != 0) {
+		set_signal(interrupt, 1);
+
+		(void)raise(interrupt);
+		/* NOTREACHED */
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/zerofill.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,151 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __db_zero_fill --
+ *	Zero out bytes in the file.
+ *
+ *	Pages allocated by writing pages past end-of-file are not zeroed,
+ *	on some systems.  Recovery could theoretically be fooled by a page
+ *	showing up that contained garbage.  In order to avoid this, we
+ *	have to write the pages out to disk, and flush them.  The reason
+ *	for the flush is because if we don't sync, the allocation of another
+ *	page subsequent to this one might reach the disk first, and if we
+ *	crashed at the right moment, leave us with this page as the one
+ *	allocated by writing a page past it in the file.
+ *
+ * PUBLIC: int __db_zero_fill __P((ENV *, DB_FH *));
+ */
+int
+__db_zero_fill(env, fhp)
+	ENV *env;
+	DB_FH *fhp;
+{
+#ifdef HAVE_FILESYSTEM_NOTZERO
+	off_t stat_offset, write_offset;
+	size_t blen, nw;
+	u_int32_t bytes, mbytes;
+	int group_sync, ret;
+	u_int8_t *bp;
+
+	/* Calculate the byte offset of the next write. */
+	write_offset = (off_t)fhp->pgno * fhp->pgsize + fhp->offset;
+
+	/* Stat the file. */
+	if ((ret = __os_ioinfo(env, NULL, fhp, &mbytes, &bytes, NULL)) != 0)
+		return (ret);
+	stat_offset = (off_t)mbytes * MEGABYTE + bytes;
+
+	/* Check if the file is large enough. */
+	if (stat_offset >= write_offset)
+		return (0);
+
+	/* Get a large buffer if we're writing lots of data. */
+#undef	ZF_LARGE_WRITE
+#define	ZF_LARGE_WRITE	(64 * 1024)
+	if ((ret = __os_calloc(env, 1, ZF_LARGE_WRITE, &bp)) != 0)
+		return (ret);
+	blen = ZF_LARGE_WRITE;
+
+	/* Seek to the current end of the file. */
+	if ((ret = __os_seek(env, fhp, mbytes, MEGABYTE, bytes)) != 0)
+		goto err;
+
+	/*
+	 * Hash is the only access method that allocates groups of pages.  Hash
+	 * uses the existence of the last page in a group to signify the entire
+	 * group is OK; so, write all the pages but the last one in the group,
+	 * flush them to disk, then write the last one to disk and flush it.
+	 */
+	for (group_sync = 0; stat_offset < write_offset; group_sync = 1) {
+		if (write_offset - stat_offset <= (off_t)blen) {
+			blen = (size_t)(write_offset - stat_offset);
+			if (group_sync && (ret = __os_fsync(env, fhp)) != 0)
+				goto err;
+		}
+		if ((ret = __os_physwrite(env, fhp, bp, blen, &nw)) != 0)
+			goto err;
+		stat_offset += blen;
+	}
+	if ((ret = __os_fsync(env, fhp)) != 0)
+		goto err;
+
+	/* Seek back to where we started. */
+	mbytes = (u_int32_t)(write_offset / MEGABYTE);
+	bytes = (u_int32_t)(write_offset % MEGABYTE);
+	ret = __os_seek(env, fhp, mbytes, MEGABYTE, bytes);
+
+err:	 __os_free(env, bp);
+	return (ret);
+#else
+	COMPQUIET(env, NULL);
+	COMPQUIET(fhp, NULL);
+	return (0);
+#endif /* HAVE_FILESYSTEM_NOTZERO */
+}
+
+/*
+ * __db_zero --
+ *	Zero to the end of the file.
+ *
+ * PUBLIC: int __db_zero_extend __P((ENV *,
+ * PUBLIC:     DB_FH *, db_pgno_t, db_pgno_t, u_int32_t));
+ */
+int
+__db_zero_extend(env, fhp, pgno, last_pgno, pgsize)
+	ENV *env;
+	DB_FH *fhp;
+	db_pgno_t pgno, last_pgno;
+	u_int32_t pgsize;
+{
+	int ret;
+	size_t nwrote;
+	u_int8_t *buf;
+
+	if ((ret = __os_calloc(env, 1, pgsize, &buf)) != 0)
+		return (ret);
+	memset(buf, 0, pgsize);
+	for (; pgno <= last_pgno; pgno++)
+		if ((ret = __os_io(env, DB_IO_WRITE,
+		    fhp, pgno, pgsize, 0, pgsize, buf, &nwrote)) != 0) {
+			if (ret == 0) {
+				ret = EIO;
+				goto err;
+			}
+			goto err;
+		}
+
+err:	__os_free(env, buf);
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1681 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_swap.h"
+#include "dbinc/btree.h"
+#include "dbinc/fop.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+#include "dbinc/qam.h"
+#include "dbinc/txn.h"
+
+static int __db_disassociate __P((DB *));
+static int __db_disassociate_foreign __P ((DB *));
+
+#ifdef CONFIG_TEST
+static int __db_makecopy __P((ENV *, const char *, const char *));
+static int __qam_testdocopy __P((DB *, const char *));
+#endif
+
+/*
+ * DB.C --
+ *	This file contains the utility functions for the DBP layer.
+ */
+
+/*
+ * __db_master_open --
+ *	Open up a handle on a master database.
+ *
+ * PUBLIC: int __db_master_open __P((DB *, DB_THREAD_INFO *,
+ * PUBLIC:     DB_TXN *, const char *, u_int32_t, int, DB **));
+ */
+int
+__db_master_open(subdbp, ip, txn, name, flags, mode, dbpp)
+	DB *subdbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name;
+	u_int32_t flags;
+	int mode;
+	DB **dbpp;
+{
+	DB *dbp;
+	int ret;
+
+	*dbpp = NULL;
+
+	/* Open up a handle on the main database. */
+	if ((ret = __db_create_internal(&dbp, subdbp->env, 0)) != 0)
+		return (ret);
+
+	/*
+	 * It's always a btree.
+	 * Run in the transaction we've created.
+	 * Set the pagesize in case we're creating a new database.
+	 * Flag that we're creating a database with subdatabases.
+	 */
+	dbp->pgsize = subdbp->pgsize;
+	F_SET(dbp, DB_AM_SUBDB);
+	F_SET(dbp, F_ISSET(subdbp,
+	    DB_AM_RECOVER | DB_AM_SWAP |
+	    DB_AM_ENCRYPT | DB_AM_CHKSUM | DB_AM_NOT_DURABLE));
+
+	/*
+	 * If there was a subdb specified, then we only want to apply
+	 * DB_EXCL to the subdb, not the actual file.  We only got here
+	 * because there was a subdb specified.
+	 */
+	LF_CLR(DB_EXCL);
+	LF_SET(DB_RDWRMASTER);
+	if ((ret = __db_open(dbp, ip, txn,
+	    name, NULL, DB_BTREE, flags, mode, PGNO_BASE_MD)) != 0)
+		goto err;
+
+	/*
+	 * The items in dbp are initialized from the master file's meta page.
+	 * Other items such as checksum and encryption are checked when we
+	 * read the meta-page, so we do not check those here.  However, if
+	 * the meta-page caused checksumming to be turned on and it wasn't
+	 * already, set it here.
+	 */
+	if (F_ISSET(dbp, DB_AM_CHKSUM))
+		F_SET(subdbp, DB_AM_CHKSUM);
+
+	/*
+	 * The user may have specified a page size for an existing file,
+	 * which we want to ignore.
+	 */
+	subdbp->pgsize = dbp->pgsize;
+	*dbpp = dbp;
+
+	if (0) {
+err:		if (!F_ISSET(dbp, DB_AM_DISCARD))
+			(void)__db_close(dbp, txn, DB_NOSYNC);
+	}
+
+	return (ret);
+}
+
+/*
+ * __db_master_update --
+ *	Add/Open/Remove a subdatabase from a master database.
+ *
+ * PUBLIC: int __db_master_update __P((DB *, DB *, DB_THREAD_INFO *, DB_TXN *,
+ * PUBLIC:      const char *, DBTYPE, mu_action, const char *, u_int32_t));
+ */
+int
+__db_master_update(mdbp, sdbp, ip, txn, subdb, type, action, newname, flags)
+	DB *mdbp, *sdbp;
+	DB_TXN *txn;
+	DB_THREAD_INFO *ip;
+	const char *subdb;
+	DBTYPE type;
+	mu_action action;
+	const char *newname;
+	u_int32_t flags;
+{
+	DBC *dbc, *ndbc;
+	DBT key, data, ndata;
+	ENV *env;
+	PAGE *p, *r;
+	db_pgno_t t_pgno;
+	int modify, ret, t_ret;
+
+	env = mdbp->env;
+	dbc = ndbc = NULL;
+	p = NULL;
+
+	/*
+	 * Open up a cursor.  If this is CDB and we're creating the database,
+	 * make it an update cursor.
+	 *
+	 * Might we modify the master database?  If so, we'll need to lock.
+	 */
+	modify = (!F_ISSET(mdbp, DB_AM_RDONLY) &&
+	    (action != MU_OPEN || LF_ISSET(DB_CREATE))) ? 1 : 0;
+
+	if ((ret = __db_cursor(mdbp, ip, txn, &dbc,
+	    (CDB_LOCKING(env) && modify) ? DB_WRITECURSOR : 0)) != 0)
+		return (ret);
+
+	/*
+	 * Point the cursor at the record.
+	 *
+	 * If we're removing or potentially creating an entry, lock the page
+	 * with DB_RMW.
+	 *
+	 * We do multiple cursor operations with the cursor in some cases and
+	 * subsequently access the data DBT information.  Set DB_DBT_MALLOC so
+	 * we don't risk modification of the data between our uses of it.
+	 *
+	 * !!!
+	 * We don't include the name's nul termination in the database.
+	 */
+	DB_INIT_DBT(key, subdb, strlen(subdb));
+	memset(&data, 0, sizeof(data));
+	F_SET(&data, DB_DBT_MALLOC);
+
+	ret = __dbc_get(dbc, &key, &data,
+	    DB_SET | ((STD_LOCKING(dbc) && modify) ? DB_RMW : 0));
+
+	/*
+	 * What we do next--whether or not we found a record for the
+	 * specified subdatabase--depends on what the specified action is.
+	 * Handle ret appropriately as the first statement of each case.
+	 */
+	switch (action) {
+	case MU_REMOVE:
+		/*
+		 * We should have found something if we're removing it.  Note
+		 * that in the common case where the DB we're asking to remove
+		 * doesn't exist, we won't get this far;  __db_subdb_remove
+		 * will already have returned an error from __db_open.
+		 */
+		if (ret != 0)
+			goto err;
+
+		/*
+		 * Delete the subdatabase entry first;  if this fails,
+		 * we don't want to touch the actual subdb pages.
+		 */
+		if ((ret = __dbc_del(dbc, 0)) != 0)
+			goto err;
+
+		/*
+		 * We're handling actual data, not on-page meta-data,
+		 * so it hasn't been converted to/from opposite
+		 * endian architectures.  Do it explicitly, now.
+		 */
+		memcpy(&sdbp->meta_pgno, data.data, sizeof(db_pgno_t));
+		DB_NTOHL_SWAP(env, &sdbp->meta_pgno);
+		if ((ret = __memp_fget(mdbp->mpf, &sdbp->meta_pgno,
+		    ip, dbc->txn, DB_MPOOL_DIRTY, &p)) != 0)
+			goto err;
+
+		/* Free the root on the master db if it was created. */
+		if (TYPE(p) == P_BTREEMETA &&
+		    ((BTMETA *)p)->root != PGNO_INVALID) {
+			if ((ret = __memp_fget(mdbp->mpf,
+			    &((BTMETA *)p)->root, ip, dbc->txn,
+			    DB_MPOOL_DIRTY, &r)) != 0)
+				goto err;
+
+			/* Free and put the page. */
+			if ((ret = __db_free(dbc, r, 0)) != 0) {
+				r = NULL;
+				goto err;
+			}
+		}
+		/* Free and put the page. */
+		if ((ret = __db_free(dbc, p, 0)) != 0) {
+			p = NULL;
+			goto err;
+		}
+		p = NULL;
+		break;
+	case MU_RENAME:
+		/* We should have found something if we're renaming it. */
+		if (ret != 0)
+			goto err;
+
+		/*
+		 * Before we rename, we need to make sure we're not
+		 * overwriting another subdatabase, or else this operation
+		 * won't be undoable.  Open a second cursor and check
+		 * for the existence of newname;  it shouldn't appear under
+		 * us since we hold the metadata lock.
+		 */
+		if ((ret = __db_cursor(mdbp, ip, txn, &ndbc,
+		    CDB_LOCKING(env) ? DB_WRITECURSOR : 0)) != 0)
+			goto err;
+		DB_SET_DBT(key, newname, strlen(newname));
+
+		/*
+		 * We don't actually care what the meta page of the potentially-
+		 * overwritten DB is; we just care about existence.
+		 */
+		memset(&ndata, 0, sizeof(ndata));
+		F_SET(&ndata, DB_DBT_USERMEM | DB_DBT_PARTIAL);
+
+		if ((ret = __dbc_get(ndbc, &key, &ndata, DB_SET)) == 0) {
+			/* A subdb called newname exists.  Bail. */
+			ret = EEXIST;
+			__db_errx(env, DB_STR_A("0673",
+			    "rename: database %s exists", "%s"), newname);
+			goto err;
+		} else if (ret != DB_NOTFOUND)
+			goto err;
+
+		/*
+		 * Now do the put first; we don't want to lose our only
+		 * reference to the subdb.  Use the second cursor so the
+		 * first one continues to point to the old record.
+		 */
+		if ((ret = __dbc_put(ndbc, &key, &data, DB_KEYFIRST)) != 0)
+			goto err;
+		if ((ret = __dbc_del(dbc, 0)) != 0) {
+			/*
+			 * If the delete fails, try to delete the record
+			 * we just put, in case we're not txn-protected.
+			 */
+			(void)__dbc_del(ndbc, 0);
+			goto err;
+		}
+
+		break;
+	case MU_OPEN:
+		/*
+		 * Get the subdatabase information.  If it already exists,
+		 * copy out the page number and we're done.
+		 */
+		switch (ret) {
+		case 0:
+			if (LF_ISSET(DB_CREATE) && LF_ISSET(DB_EXCL)) {
+				ret = EEXIST;
+				goto err;
+			}
+			memcpy(&sdbp->meta_pgno, data.data, sizeof(db_pgno_t));
+			DB_NTOHL_SWAP(env, &sdbp->meta_pgno);
+			goto done;
+		case DB_NOTFOUND:
+			if (LF_ISSET(DB_CREATE))
+				break;
+			/*
+			 * No db_err, it is reasonable to remove a
+			 * nonexistent db.
+			 */
+			ret = ENOENT;
+			goto err;
+		default:
+			goto err;
+		}
+
+		/* Create a subdatabase. */
+		if (F_ISSET(mdbp, DB_AM_RDONLY)) {
+			ret = EBADF;
+			goto err;
+		}
+		if ((ret = __db_new(dbc,
+		    type == DB_HASH ? P_HASHMETA : P_BTREEMETA, NULL, &p)) != 0)
+			goto err;
+		sdbp->meta_pgno = PGNO(p);
+
+		/*
+		 * XXX
+		 * We're handling actual data, not on-page meta-data, so it
+		 * hasn't been converted to/from opposite endian architectures.
+		 * Do it explicitly, now.
+		 */
+		t_pgno = PGNO(p);
+		DB_HTONL_SWAP(env, &t_pgno);
+		memset(&ndata, 0, sizeof(ndata));
+		ndata.data = &t_pgno;
+		ndata.size = sizeof(db_pgno_t);
+		if ((ret = __dbc_put(dbc, &key, &ndata, 0)) != 0)
+			goto err;
+		F_SET(sdbp, DB_AM_CREATED);
+		break;
+
+	case MU_MOVE:
+		/* We should have found something if we're moving it. */
+		if (ret != 0)
+			goto err;
+		t_pgno = sdbp->meta_pgno;
+		DB_HTONL_SWAP(env, &t_pgno);
+		memset(&ndata, 0, sizeof(ndata));
+		ndata.data = &t_pgno;
+		ndata.size = sizeof(db_pgno_t);
+		if ((ret = __dbc_put(dbc, &key, &ndata, 0)) != 0)
+			goto err;
+		mdbp->mpf->mfp->revision++;
+	}
+
+err:
+done:	/*
+	 * If we allocated a page: if we're successful, mark the page dirty
+	 * and return it to the cache, otherwise, discard/free it.
+	 */
+	if (p != NULL && (t_ret = __memp_fput(mdbp->mpf,
+	     dbc->thread_info, p, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Discard the cursor(s) and data. */
+	if (data.data != NULL)
+		__os_ufree(env, data.data);
+	if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+	if (ndbc != NULL && (t_ret = __dbc_close(ndbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __env_dbreg_setup --
+ *
+ * PUBLIC: int __env_dbreg_setup __P((DB *,
+ * PUBLIC:      DB_TXN *, const char *, const char *, u_int32_t));
+ */
+int
+__env_dbreg_setup(dbp, txn, fname, dname, id)
+	DB *dbp;
+	DB_TXN *txn;
+	const char *fname, *dname;
+	u_int32_t id;
+{
+	ENV *env;
+	int ret;
+
+	env = dbp->env;
+	if (dbp->log_filename == NULL
+#if !defined(DEBUG_ROP) && !defined(DEBUG_WOP) && !defined(DIAGNOSTIC)
+	    && (txn != NULL || F_ISSET(dbp, DB_AM_RECOVER))
+#endif
+#if !defined(DEBUG_ROP)
+	    && !F_ISSET(dbp, DB_AM_RDONLY)
+#endif
+	    ) {
+		if ((ret = __dbreg_setup(dbp,
+		    F_ISSET(dbp, DB_AM_INMEM) ? dname: fname,
+		    F_ISSET(dbp, DB_AM_INMEM) ? NULL : dname, id)) != 0)
+			return (ret);
+
+		/*
+		 * If we're actively logging and our caller isn't a
+		 * recovery function that already did so, then assign
+		 * this dbp a log fileid.
+		 */
+		if (DBENV_LOGGING(env) && !F_ISSET(dbp, DB_AM_RECOVER) &&
+		    (ret = __dbreg_new_id(dbp, txn)) != 0)
+			return (ret);
+	}
+	return (0);
+}
+
+/*
+ * __env_setup --
+ *	Set up the underlying environment during a db_open.
+ *
+ * PUBLIC: int __env_setup __P((DB *,
+ * PUBLIC:     DB_TXN *, const char *, const char *, u_int32_t, u_int32_t));
+ */
+int
+__env_setup(dbp, txn, fname, dname, id, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	const char *fname, *dname;
+	u_int32_t id, flags;
+{
+	DB *ldbp;
+	DB_ENV *dbenv;
+	ENV *env;
+	u_int32_t maxid;
+	int ret;
+
+	env = dbp->env;
+	dbenv = env->dbenv;
+
+	/*
+	 * When verifying an in-memory db, we need to pass dname to
+	 * __env_mpool.  That is the only time fname will be used.
+	 */
+	if (F_ISSET(dbp, DB_AM_INMEM) && F_ISSET(dbp, DB_AM_VERIFYING))
+		fname = dname;
+
+	/* If we don't yet have an environment, it's time to create it. */
+	if (!F_ISSET(env, ENV_OPEN_CALLED)) {
+#if defined(HAVE_MIXED_SIZE_ADDRESSING) && (SIZEOF_CHAR_P == 8)
+		__db_errx(env, DB_STR("0701", "DB_PRIVATE is not supported by"
+		    " 64-bit applications in mixed-size-addressing mode"));
+	       return (EINVAL);
+#endif
+		/* Make sure we have at least DB_MINCACHE pages in our cache. */
+		if (dbenv->mp_gbytes == 0 &&
+		    dbenv->mp_bytes < dbp->pgsize * DB_MINPAGECACHE &&
+		    (ret = __memp_set_cachesize(
+		    dbenv, 0, dbp->pgsize * DB_MINPAGECACHE, 0)) != 0)
+			return (ret);
+
+		if ((ret = __env_open(dbenv, NULL, DB_CREATE |
+		    DB_INIT_MPOOL | DB_PRIVATE | LF_ISSET(DB_THREAD), 0)) != 0)
+			return (ret);
+	}
+
+	/* Join the underlying cache. */
+	if ((!F_ISSET(dbp, DB_AM_INMEM) || F_ISSET(dbp, DB_AM_VERIFYING) ||
+	    dname == NULL) && (ret = __env_mpool(dbp, fname, flags)) != 0)
+		return (ret);
+
+	/* We may need a per-thread mutex. */
+	if (LF_ISSET(DB_THREAD) && (ret = __mutex_alloc(
+	    env, MTX_DB_HANDLE, DB_MUTEX_PROCESS_ONLY, &dbp->mutex)) != 0)
+		return (ret);
+
+	/*
+	 * Set up a bookkeeping entry for this database in the log region,
+	 * if such a region exists.  Note that even if we're in recovery
+	 * or a replication client, where we won't log registries, we'll
+	 * still need an FNAME struct, so LOGGING_ON is the correct macro.
+	 */
+	if (LOGGING_ON(env) &&
+	    (!F_ISSET(dbp, DB_AM_INMEM) || dname == NULL) &&
+	    (ret = __env_dbreg_setup(dbp, txn, fname, dname, id)) != 0)
+		return (ret);
+
+	/*
+	 * Insert ourselves into the ENV's dblist.  We allocate a
+	 * unique ID to each {fileid, meta page number} pair, and to
+	 * each temporary file (since they all have a zero fileid).
+	 * This ID gives us something to use to tell which DB handles
+	 * go with which databases in all the cursor adjustment
+	 * routines, where we don't want to do a lot of ugly and
+	 * expensive memcmps.
+	 */
+	MUTEX_LOCK(env, env->mtx_dblist);
+	maxid = 0;
+	TAILQ_FOREACH(ldbp, &env->dblist, dblistlinks) {
+		/*
+		 * There are three cases: on-disk database (first clause),
+		 * named in-memory database (second clause), temporary database
+		 * (never matches; no clause).
+		 */
+		if (!F_ISSET(dbp, DB_AM_INMEM)) {
+			if (memcmp(ldbp->fileid, dbp->fileid, DB_FILE_ID_LEN)
+			    == 0 && ldbp->meta_pgno == dbp->meta_pgno)
+				break;
+		} else if (dname != NULL) {
+			if (F_ISSET(ldbp, DB_AM_INMEM) &&
+			    ldbp->dname != NULL &&
+			    strcmp(ldbp->dname, dname) == 0)
+				break;
+		}
+		if (ldbp->adj_fileid > maxid)
+			maxid = ldbp->adj_fileid;
+	}
+
+	/*
+	 * If ldbp is NULL, we didn't find a match. Assign the dbp an
+	 * adj_fileid one higher than the largest we found, and
+	 * insert it at the head of the master dbp list.
+	 *
+	 * If ldbp is not NULL, it is a match for our dbp.  Give dbp
+	 * the same ID that ldbp has, and add it after ldbp so they're
+	 * together in the list.
+	 */
+	if (ldbp == NULL) {
+		dbp->adj_fileid = maxid + 1;
+		TAILQ_INSERT_HEAD(&env->dblist, dbp, dblistlinks);
+	} else {
+		dbp->adj_fileid = ldbp->adj_fileid;
+		TAILQ_INSERT_AFTER(&env->dblist, ldbp, dbp, dblistlinks);
+	}
+	MUTEX_UNLOCK(env, env->mtx_dblist);
+
+	return (0);
+}
+
+/*
+ * __env_mpool --
+ *	Set up the underlying environment cache during a db_open.
+ *
+ * PUBLIC: int __env_mpool __P((DB *, const char *, u_int32_t));
+ */
+int
+__env_mpool(dbp, fname, flags)
+	DB *dbp;
+	const char *fname;
+	u_int32_t flags;
+{
+	DBT pgcookie;
+	DB_MPOOLFILE *mpf;
+	DB_PGINFO pginfo;
+	ENV *env;
+	int fidset, ftype, ret;
+	int32_t lsn_off;
+	u_int8_t nullfid[DB_FILE_ID_LEN];
+	u_int32_t clear_len;
+
+	env = dbp->env;
+
+	/* The LSN is the first entry on a DB page, byte offset 0. */
+	lsn_off = F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LSN_OFF_NOTSET : 0;
+
+	/* It's possible that this database is already open. */
+	if (F_ISSET(dbp, DB_AM_OPEN_CALLED))
+		return (0);
+
+	/*
+	 * If we need to pre- or post-process a file's pages on I/O, set the
+	 * file type.  If it's a hash file, always call the pgin and pgout
+	 * routines.  This means that hash files can never be mapped into
+	 * process memory.  If it's a btree file and requires swapping, we
+	 * need to page the file in and out.  This has to be right -- we can't
+	 * mmap files that are being paged in and out.
+	 */
+	switch (dbp->type) {
+	case DB_BTREE:
+	case DB_HEAP:
+	case DB_RECNO:
+		ftype = F_ISSET(dbp, DB_AM_SWAP | DB_AM_ENCRYPT | DB_AM_CHKSUM)
+		    ? DB_FTYPE_SET : DB_FTYPE_NOTSET;
+		clear_len = CRYPTO_ON(env) ?
+		    (dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET) :
+		    DB_PAGE_DB_LEN;
+		break;
+	case DB_HASH:
+		ftype = DB_FTYPE_SET;
+		clear_len = CRYPTO_ON(env) ?
+		    (dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET) :
+		    DB_PAGE_DB_LEN;
+		break;
+	case DB_QUEUE:
+		ftype = F_ISSET(dbp,
+		    DB_AM_SWAP | DB_AM_ENCRYPT | DB_AM_CHKSUM) ?
+		    DB_FTYPE_SET : DB_FTYPE_NOTSET;
+
+		/*
+		 * If we came in here without a pagesize set, then we need
+		 * to mark the in-memory handle as having clear_len not
+		 * set, because we don't really know the clear length or
+		 * the page size yet (since the file doesn't yet exist).
+		 */
+		clear_len = dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET;
+		break;
+	case DB_UNKNOWN:
+		/*
+		 * If we're running in the verifier, our database might
+		 * be corrupt and we might not know its type--but we may
+		 * still want to be able to verify and salvage.
+		 *
+		 * If we can't identify the type, it's not going to be safe
+		 * to call __db_pgin--we pretty much have to give up all
+		 * hope of salvaging cross-endianness.  Proceed anyway;
+		 * at worst, the database will just appear more corrupt
+		 * than it actually is, but at best, we may be able
+		 * to salvage some data even with no metadata page.
+		 */
+		if (F_ISSET(dbp, DB_AM_VERIFYING)) {
+			ftype = DB_FTYPE_NOTSET;
+			clear_len = DB_PAGE_DB_LEN;
+			break;
+		}
+
+		/*
+		 * This might be an in-memory file and we won't know its
+		 * file type until after we open it and read the meta-data
+		 * page.
+		 */
+		if (F_ISSET(dbp, DB_AM_INMEM)) {
+			clear_len = DB_CLEARLEN_NOTSET;
+			ftype = DB_FTYPE_NOTSET;
+			lsn_off = DB_LSN_OFF_NOTSET;
+			break;
+		}
+		/* FALLTHROUGH */
+	default:
+		return (__db_unknown_type(env, "DB->open", dbp->type));
+	}
+
+	mpf = dbp->mpf;
+
+	memset(nullfid, 0, DB_FILE_ID_LEN);
+	fidset = memcmp(nullfid, dbp->fileid, DB_FILE_ID_LEN);
+	if (fidset)
+		(void)__memp_set_fileid(mpf, dbp->fileid);
+
+	(void)__memp_set_clear_len(mpf, clear_len);
+	(void)__memp_set_ftype(mpf, ftype);
+	(void)__memp_set_lsn_offset(mpf, lsn_off);
+
+	pginfo.db_pagesize = dbp->pgsize;
+	pginfo.flags =
+	    F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP));
+	pginfo.type = dbp->type;
+	pgcookie.data = &pginfo;
+	pgcookie.size = sizeof(DB_PGINFO);
+	(void)__memp_set_pgcookie(mpf, &pgcookie);
+
+#ifndef DIAG_MVCC
+	if (F_ISSET(env->dbenv, DB_ENV_MULTIVERSION))
+#endif
+		if (F_ISSET(dbp, DB_AM_TXN) &&
+		    dbp->type != DB_QUEUE && dbp->type != DB_UNKNOWN)
+			LF_SET(DB_MULTIVERSION);
+
+	if ((ret = __memp_fopen(mpf, NULL, fname, &dbp->dirname,
+	    LF_ISSET(DB_CREATE | DB_DURABLE_UNKNOWN | DB_MULTIVERSION |
+		DB_NOMMAP | DB_ODDFILESIZE | DB_RDONLY | DB_TRUNCATE) |
+	    (F_ISSET(env->dbenv, DB_ENV_DIRECT_DB) ? DB_DIRECT : 0) |
+	    (F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_TXN_NOT_DURABLE : 0),
+	    0, dbp->pgsize)) != 0) {
+		/*
+		 * The open didn't work; we need to reset the mpf,
+		 * retaining the in-memory semantics (if any).
+		 */
+		(void)__memp_fclose(dbp->mpf, 0);
+		(void)__memp_fcreate(env, &dbp->mpf);
+		if (F_ISSET(dbp, DB_AM_INMEM))
+			MAKE_INMEM(dbp);
+		return (ret);
+	}
+
+	/*
+	 * Set the open flag.  We use it to mean that the dbp has gone
+	 * through mpf setup, including dbreg_register.  Also, below,
+	 * the underlying access method open functions may want to do
+	 * things like acquire cursors, so the open flag has to be set
+	 * before calling them.
+	 */
+	F_SET(dbp, DB_AM_OPEN_CALLED);
+	if (!fidset && fname != NULL) {
+		(void)__memp_get_fileid(dbp->mpf, dbp->fileid);
+		dbp->preserve_fid = 1;
+	}
+
+	return (0);
+}
+
+/*
+ * __db_close --
+ *	DB->close method.
+ *
+ * PUBLIC: int __db_close __P((DB *, DB_TXN *, u_int32_t));
+ */
+int
+__db_close(dbp, txn, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	u_int32_t flags;
+{
+	ENV *env;
+	int db_ref, deferred_close, ret, t_ret;
+
+	env = dbp->env;
+	deferred_close = 0;
+
+	PERFMON4(env, db, close,
+	    dbp->fname, dbp->dname, flags, &dbp->fileid[0]);
+
+	/* Refresh the structure and close any underlying resources. */
+	ret = __db_refresh(dbp, txn, flags, &deferred_close, 0);
+
+	/*
+	 * If we've deferred the close because the logging of the close failed,
+	 * return our failure right away without destroying the handle.
+	 */
+	if (deferred_close)
+		return (ret);
+
+	/* !!!
+	 * This code has an apparent race between the moment we read and
+	 * decrement env->db_ref and the moment we check whether it's 0.
+	 * However, if the environment is DBLOCAL, the user shouldn't have a
+	 * reference to the env handle anyway;  the only way we can get
+	 * multiple dbps sharing a local env is if we open them internally
+	 * during something like a subdatabase open.  If any such thing is
+	 * going on while the user is closing the original dbp with a local
+	 * env, someone's already badly screwed up, so there's no reason
+	 * to bother engineering around this possibility.
+	 */
+	MUTEX_LOCK(env, env->mtx_dblist);
+	db_ref = --env->db_ref;
+	MUTEX_UNLOCK(env, env->mtx_dblist);
+	if (F_ISSET(env, ENV_DBLOCAL) && db_ref == 0 &&
+	    (t_ret = __env_close(env->dbenv, 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Free the database handle. */
+	memset(dbp, CLEAR_BYTE, sizeof(*dbp));
+	__os_free(env, dbp);
+
+	return (ret);
+}
+
+/*
+ * __db_refresh --
+ *	Refresh the DB structure, releasing any allocated resources.
+ * This does most of the work of closing files now because refresh
+ * is what is used during abort processing (since we can't destroy
+ * the actual handle) and during abort processing, we may have a
+ * fully opened handle.
+ *
+ * PUBLIC: int __db_refresh __P((DB *, DB_TXN *, u_int32_t, int *, int));
+ */
+int
+__db_refresh(dbp, txn, flags, deferred_closep, reuse)
+	DB *dbp;
+	DB_TXN *txn;
+	u_int32_t flags;
+	int *deferred_closep, reuse;
+{
+	DB *sdbp;
+	DBC *dbc;
+	DB_FOREIGN_INFO *f_info, *tmp;
+	DB_LOCKER *locker;
+	DB_LOCKREQ lreq;
+	ENV *env;
+	REGENV *renv;
+	REGINFO *infop;
+	u_int32_t save_flags;
+	int resync, ret, t_ret;
+
+	ret = 0;
+
+	env = dbp->env;
+	infop = env->reginfo;
+	if (infop != NULL)
+		renv = infop->primary;
+	else
+		renv = NULL;
+
+	/*
+	 * If this dbp is not completely open, avoid trapping by trying to
+	 * sync without an mpool file.
+	 */
+	if (dbp->mpf == NULL)
+		LF_SET(DB_NOSYNC);
+
+	/* If never opened, or not currently open, it's easy. */
+	if (!F_ISSET(dbp, DB_AM_OPEN_CALLED))
+		goto never_opened;
+
+	/*
+	 * If we have any secondary indices, disassociate them from us.
+	 * We don't bother with the mutex here;  it only protects some
+	 * of the ops that will make us core-dump mid-close anyway, and
+	 * if you're trying to do something with a secondary *while* you're
+	 * closing the primary, you deserve what you get.  The disassociation
+	 * is mostly done just so we can close primaries and secondaries in
+	 * any order--but within one thread of control.
+	 */
+	LIST_FOREACH(sdbp, &dbp->s_secondaries, s_links) {
+		LIST_REMOVE(sdbp, s_links);
+		if ((t_ret = __db_disassociate(sdbp)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+	if (F_ISSET(dbp, DB_AM_SECONDARY))
+		LIST_REMOVE(dbp, s_links);
+
+	/*
+	 * Disassociate ourself from any databases using us as a foreign key
+	 * database by clearing the referring db's pointer.  Reclaim memory.
+	 */
+	f_info = LIST_FIRST(&dbp->f_primaries);
+	while (f_info != NULL) {
+		tmp = LIST_NEXT(f_info, f_links);
+		LIST_REMOVE(f_info, f_links);
+		f_info->dbp->s_foreign = NULL;
+		__os_free(env, f_info);
+		f_info = tmp;
+	}
+
+	if (dbp->s_foreign != NULL &&
+	    (t_ret = __db_disassociate_foreign(dbp)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * Sync the underlying access method.  Do before closing the cursors
+	 * because DB->sync allocates cursors in order to write Recno backing
+	 * source text files.
+	 *
+	 * Sync is slow on some systems, notably Solaris filesystems where the
+	 * entire buffer cache is searched.  If we're in recovery, don't flush
+	 * the file, it's not necessary.
+	 */
+	if (!LF_ISSET(DB_NOSYNC) &&
+	    !F_ISSET(dbp, DB_AM_DISCARD | DB_AM_RECOVER) &&
+	    (t_ret = __db_sync(dbp)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * Go through the active cursors, unregister each cursor from its
+	 * transaction if any, and call the cursor recycle routine,
+	 * which resolves pending operations and moves the cursors onto the
+	 * free list.  Then, walk the free list and call the cursor destroy
+	 * routine.  Note that any failure on a close is considered "really
+	 * bad" and we just break out of the loop and force forward.
+	 */
+	resync = TAILQ_FIRST(&dbp->active_queue) == NULL ? 0 : 1;
+	while ((dbc = TAILQ_FIRST(&dbp->active_queue)) != NULL) {
+		if (dbc->txn != NULL)
+			TAILQ_REMOVE(&(dbc->txn->my_cursors), dbc, txn_cursors);
+
+		if ((t_ret = __dbc_close(dbc)) != 0) {
+			if (ret == 0)
+				ret = t_ret;
+			break;
+		}
+	}
+
+	while ((dbc = TAILQ_FIRST(&dbp->free_queue)) != NULL)
+		if ((t_ret = __dbc_destroy(dbc)) != 0) {
+			if (ret == 0)
+				ret = t_ret;
+			break;
+		}
+
+	/*
+	 * Close any outstanding join cursors.  Join cursors destroy themselves
+	 * on close and have no separate destroy routine.  We don't have to set
+	 * the resync flag here, because join cursors aren't write cursors.
+	 */
+	while ((dbc = TAILQ_FIRST(&dbp->join_queue)) != NULL)
+		if ((t_ret = __db_join_close(dbc)) != 0) {
+			if (ret == 0)
+				ret = t_ret;
+			break;
+		}
+
+	/*
+	 * Sync the memory pool, even though we've already called DB->sync,
+	 * because closing cursors can dirty pages by deleting items they
+	 * referenced.
+	 *
+	 * Sync is slow on some systems, notably Solaris filesystems where the
+	 * entire buffer cache is searched.  If we're in recovery, don't flush
+	 * the file, it's not necessary.
+	 */
+	if (resync && !LF_ISSET(DB_NOSYNC) &&
+	    !F_ISSET(dbp, DB_AM_DISCARD | DB_AM_RECOVER) &&
+	    (t_ret = __memp_fsync(dbp->mpf)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * If there is a file extension watermark associated with this
+	 * database, we don't need it any more.
+	 */
+	__txn_remove_fe_watermark(txn, dbp);
+
+never_opened:
+	MUTEX_LOCK(env, env->mtx_dblist);
+	/*
+	 * At this point, we haven't done anything to render the DB handle
+	 * unusable, at least by a transaction abort.  Take the opportunity
+	 * now to log the file close if we have initialized the logging
+	 * information.  If this log fails and we're in a transaction,
+	 * we have to bail out of the attempted close; we'll need a dbp in
+	 * order to successfully abort the transaction, and we can't conjure
+	 * a new one up because we haven't gotten out the dbreg_register
+	 * record that represents the close.  In this case, we put off
+	 * actually closing the dbp until we've performed the abort.
+	 */
+	if (!reuse && LOGGING_ON(dbp->env) && dbp->log_filename != NULL) {
+		/*
+		 * Discard the log file id, if any.  We want to log the close
+		 * if and only if this is not a recovery dbp or a client dbp,
+		 * or a dead dbp handle.
+		 */
+		DB_ASSERT(env, renv != NULL);
+		if (F_ISSET(dbp, DB_AM_RECOVER) || IS_REP_CLIENT(env) ||
+		    dbp->timestamp != renv->rep_timestamp) {
+			if ((t_ret = __dbreg_revoke_id(dbp,
+			    0, DB_LOGFILEID_INVALID)) == 0 && ret == 0)
+				ret = t_ret;
+			if ((t_ret = __dbreg_teardown(dbp)) != 0 && ret == 0)
+				ret = t_ret;
+		} else {
+			if ((t_ret = __dbreg_close_id(dbp,
+			    txn, DBREG_CLOSE)) != 0 && txn != NULL) {
+				MUTEX_UNLOCK(env, env->mtx_dblist);
+				/*
+				 * We're in a txn and the attempt to log the
+				 * close failed;  let the txn subsystem know
+				 * that we need to destroy this dbp once we're
+				 * done with the abort, then bail from the
+				 * close.
+				 *
+				 * Note that if the attempt to put off the
+				 * close -also- fails--which it won't unless
+				 * we're out of heap memory--we're really
+				 * screwed.  Panic.
+				 */
+				if ((ret =
+				    __txn_closeevent(env, txn, dbp)) != 0)
+					return (__env_panic(env, ret));
+				if (deferred_closep != NULL)
+					*deferred_closep = 1;
+				return (t_ret);
+			}
+			/*
+			 * If dbreg_close_id failed and we were not in a
+			 * transaction, then we need to finish this close
+			 * because the caller can't do anything with the
+			 * handle after we return an error.  We rely on
+			 * dbreg_close_id to mark the entry in some manner
+			 * so that we do not do a clean shutdown of this
+			 * environment.  If shutdown isn't clean, then the
+			 * application *must* run recovery and that will
+			 * generate the RCLOSE record.
+			 */
+		}
+
+	}
+
+	/* Close any handle we've been holding since the open.  */
+	if (dbp->saved_open_fhp != NULL &&
+	    (t_ret = __os_closehandle(env, dbp->saved_open_fhp)) != 0 &&
+	    ret == 0)
+		ret = t_ret;
+
+	/*
+	 * Remove this DB handle from the ENV's dblist, if it's been added.
+	 *
+	 * Close our reference to the underlying cache while locked, we don't
+	 * want to race with a thread searching for our underlying cache link
+	 * while opening a DB handle.
+	 *
+	 * The DB handle may not yet have been added to the ENV list, don't
+	 * blindly call the underlying TAILQ_REMOVE macro.  Explicitly reset
+	 * the field values to NULL so that we can't call TAILQ_REMOVE twice.
+	 */
+	if (!reuse &&
+	    (dbp->dblistlinks.tqe_next != NULL ||
+	    dbp->dblistlinks.tqe_prev != NULL)) {
+		TAILQ_REMOVE(&env->dblist, dbp, dblistlinks);
+		dbp->dblistlinks.tqe_next = NULL;
+		dbp->dblistlinks.tqe_prev = NULL;
+	}
+
+	/* Close the memory pool file handle. */
+	if (dbp->mpf != NULL) {
+		if ((t_ret = __memp_fclose(dbp->mpf,
+		    F_ISSET(dbp, DB_AM_DISCARD) ? DB_MPOOL_DISCARD : 0)) != 0 &&
+		    ret == 0)
+			ret = t_ret;
+		dbp->mpf = NULL;
+		if (reuse &&
+		    (t_ret = __memp_fcreate(env, &dbp->mpf)) != 0 &&
+		    ret == 0)
+			ret = t_ret;
+	}
+
+	MUTEX_UNLOCK(env, env->mtx_dblist);
+
+	/*
+	 * Call the access specific close function.
+	 *
+	 * We do this here rather than in __db_close as we need to do this when
+	 * aborting an open so that file descriptors are closed and abort of
+	 * renames can succeed on platforms that lock open files (such as
+	 * Windows).  In particular, we need to ensure that all the extents
+	 * associated with a queue are closed so that queue renames can be
+	 * aborted.
+	 *
+	 * It is also important that we do this before releasing the handle
+	 * lock, because dbremove and dbrename assume that once they have the
+	 * handle lock, it is safe to modify the underlying file(s).
+	 *
+	 * !!!
+	 * Because of where these functions are called in the DB handle close
+	 * process, these routines can't do anything that would dirty pages or
+	 * otherwise affect closing down the database.  Specifically, we can't
+	 * abort and recover any of the information they control.
+	 */
+#ifdef HAVE_PARTITION
+	if (dbp->p_internal != NULL &&
+	    (t_ret = __partition_close(dbp, txn, flags)) != 0 && ret == 0)
+		ret = t_ret;
+#endif
+	if ((t_ret = __bam_db_close(dbp)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __ham_db_close(dbp)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __heap_db_close(dbp)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __qam_db_close(dbp, dbp->flags)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * !!!
+	 * At this point, the access-method specific information has been
+	 * freed.  From now on, we can use the dbp, but not touch any
+	 * access-method specific data.
+	 */
+
+	if (!reuse && dbp->locker != NULL) {
+		/* We may have pending trade operations on this dbp. */
+		if (txn == NULL)
+			txn = dbp->cur_txn;
+		if (IS_REAL_TXN(txn))
+			__txn_remlock(env,
+			     txn, &dbp->handle_lock, dbp->locker);
+
+		/* We may be holding the handle lock; release it. */
+		lreq.op = DB_LOCK_PUT_ALL;
+		lreq.obj = NULL;
+		if ((t_ret = __lock_vec(env,
+		    dbp->locker, 0, &lreq, 1, NULL)) != 0 && ret == 0)
+			ret = t_ret;
+
+		if ((t_ret =
+		     __lock_id_free(env, dbp->locker)) != 0 && ret == 0)
+			ret = t_ret;
+		dbp->locker = NULL;
+		LOCK_INIT(dbp->handle_lock);
+	}
+
+	/*
+	 * If this is a temporary file (un-named in-memory file), then
+	 * discard the locker ID allocated as the fileid.
+	 */
+	if (LOCKING_ON(env) &&
+	    F_ISSET(dbp, DB_AM_INMEM) && !dbp->preserve_fid &&
+	    *(u_int32_t *)dbp->fileid != DB_LOCK_INVALIDID) {
+		if ((t_ret = __lock_getlocker(env->lk_handle,
+		     *(u_int32_t *)dbp->fileid, 0, &locker)) == 0)
+			t_ret = __lock_id_free(env, locker);
+		if (ret == 0)
+			ret = t_ret;
+	}
+
+	if (reuse) {
+		/*
+		 * If we are reusing this dbp, then we're done now. Re-init
+		 * the handle, preserving important flags, and then return.
+		 * This code is borrowed from __db_init, which does more
+		 * than we can do here.
+		 */
+		save_flags = F_ISSET(dbp, DB_AM_INMEM |
+		    DB_AM_RDONLY | DB_AM_TXN);
+
+		if ((ret = __bam_db_create(dbp)) != 0)
+			return (ret);
+		if ((ret = __ham_db_create(dbp)) != 0)
+			return (ret);
+		if ((ret = __heap_db_create(dbp)) != 0)
+			return (ret);
+		if ((ret = __qam_db_create(dbp)) != 0)
+			return (ret);
+
+		/* Restore flags */
+		dbp->flags = dbp->orig_flags | save_flags;
+
+		if (FLD_ISSET(save_flags, DB_AM_INMEM)) {
+			/*
+			 * If this is inmem, then it may have a fileid
+			 * even if it was never opened, and we need to
+			 * clear out that fileid.
+			 */
+			memset(dbp->fileid, 0, sizeof(dbp->fileid));
+			MAKE_INMEM(dbp);
+		}
+		return (ret);
+	}
+
+	dbp->type = DB_UNKNOWN;
+
+	/*
+	 * The thread mutex may have been invalidated in __dbreg_close_id if the
+	 * fname refcount did not go to 0. If not, discard the thread mutex.
+	 */
+	if ((t_ret = __mutex_free(env, &dbp->mutex)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Discard any memory allocated for the file and database names. */
+	if (dbp->fname != NULL) {
+		__os_free(dbp->env, dbp->fname);
+		dbp->fname = NULL;
+	}
+	if (dbp->dname != NULL) {
+		__os_free(dbp->env, dbp->dname);
+		dbp->dname = NULL;
+	}
+
+	/* Discard any memory used to store returned data. */
+	if (dbp->my_rskey.data != NULL)
+		__os_free(dbp->env, dbp->my_rskey.data);
+	if (dbp->my_rkey.data != NULL)
+		__os_free(dbp->env, dbp->my_rkey.data);
+	if (dbp->my_rdata.data != NULL)
+		__os_free(dbp->env, dbp->my_rdata.data);
+
+	/* For safety's sake;  we may refresh twice. */
+	memset(&dbp->my_rskey, 0, sizeof(DBT));
+	memset(&dbp->my_rkey, 0, sizeof(DBT));
+	memset(&dbp->my_rdata, 0, sizeof(DBT));
+
+	/* Clear out fields that normally get set during open. */
+	memset(dbp->fileid, 0, sizeof(dbp->fileid));
+	dbp->adj_fileid = 0;
+	dbp->meta_pgno = 0;
+	dbp->cur_locker = NULL;
+	dbp->cur_txn = NULL;
+	dbp->associate_locker = NULL;
+	dbp->open_flags = 0;
+
+	/*
+	 * If we are being refreshed with a txn specified, then we need
+	 * to make sure that we clear out the lock handle field, because
+	 * releasing all the locks for this transaction will release this
+	 * lock and we don't want close to stumble upon this handle and
+	 * try to close it.
+	 */
+	if (txn != NULL)
+		LOCK_INIT(dbp->handle_lock);
+
+	/* Reset flags to whatever the user configured. */
+	dbp->flags = dbp->orig_flags;
+
+	return (ret);
+}
+
+/*
+ * __db_disassociate --
+ *	Destroy the association between a given secondary and its primary.
+ */
+static int
+__db_disassociate(sdbp)
+	DB *sdbp;
+{
+	DBC *dbc;
+	int ret, t_ret;
+
+	ret = 0;
+
+	sdbp->s_callback = NULL;
+	sdbp->s_primary = NULL;
+	sdbp->get = sdbp->stored_get;
+	sdbp->close = sdbp->stored_close;
+
+	/*
+	 * Complain, but proceed, if we have any active cursors.  (We're in
+	 * the middle of a close, so there's really no turning back.)
+	 */
+	if (sdbp->s_refcnt != 1 ||
+	    TAILQ_FIRST(&sdbp->active_queue) != NULL ||
+	    TAILQ_FIRST(&sdbp->join_queue) != NULL) {
+		__db_errx(sdbp->env, DB_STR("0674",
+"Closing a primary DB while a secondary DB has active cursors is unsafe"));
+		ret = EINVAL;
+	}
+	sdbp->s_refcnt = 0;
+
+	while ((dbc = TAILQ_FIRST(&sdbp->free_queue)) != NULL)
+		if ((t_ret = __dbc_destroy(dbc)) != 0 && ret == 0)
+			ret = t_ret;
+
+	F_CLR(sdbp, DB_AM_SECONDARY);
+	return (ret);
+}
+
+/*
+ * __db_disassociate_foreign --
+ *     Destroy the association between a given secondary and its foreign.
+ */
+static int
+__db_disassociate_foreign(sdbp)
+	DB *sdbp;
+{
+	DB *fdbp;
+	DB_FOREIGN_INFO *f_info, *tmp;
+	int ret;
+
+	if (sdbp->s_foreign == NULL)
+		return (0);
+	if ((ret = __os_malloc(sdbp->env, sizeof(DB_FOREIGN_INFO), &tmp)) != 0)
+		return (ret);
+
+	fdbp = sdbp->s_foreign;
+	ret = 0;
+	f_info = LIST_FIRST(&fdbp->f_primaries);
+	while (f_info != NULL) {
+		tmp = LIST_NEXT(f_info, f_links);
+		if (f_info ->dbp == sdbp) {
+			LIST_REMOVE(f_info, f_links);
+			__os_free(sdbp->env, f_info);
+		}
+		f_info = tmp;
+	}
+
+	return (ret);
+}
+
+/*
+ * __db_log_page
+ *	Log a meta-data or root page during a subdatabase create operation.
+ *
+ * PUBLIC: int __db_log_page __P((DB *, DB_TXN *, DB_LSN *, db_pgno_t, PAGE *));
+ */
+int
+__db_log_page(dbp, txn, lsn, pgno, page)
+	DB *dbp;
+	DB_TXN *txn;
+	DB_LSN *lsn;
+	db_pgno_t pgno;
+	PAGE *page;
+{
+	DBT page_dbt;
+	DB_LSN new_lsn;
+	int ret;
+
+	if (!LOGGING_ON(dbp->env) || txn == NULL)
+		return (0);
+
+	memset(&page_dbt, 0, sizeof(page_dbt));
+	page_dbt.size = dbp->pgsize;
+	page_dbt.data = page;
+
+	ret = __crdel_metasub_log(dbp, txn, &new_lsn, F_ISSET(dbp,
+	    DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0, pgno, &page_dbt, lsn);
+
+	if (ret == 0)
+		page->lsn = new_lsn;
+	return (ret);
+}
+
+/*
+ * __db_walk_cursors
+ *	Walk all cursors for a database.
+ *
+ * PUBLIC: int __db_walk_cursors __P((DB *, DBC *,
+ * PUBLIC:	int (*) __P((DBC *, DBC *,
+ * PUBLIC:      u_int32_t *, db_pgno_t, u_int32_t, void *)),
+ * PUBLIC:      u_int32_t *, db_pgno_t, u_int32_t, void *));
+ */
+ int
+ __db_walk_cursors(dbp, my_dbc, func, countp, pgno, indx, args)
+	DB *dbp;
+	DBC *my_dbc;
+	int (*func)__P((DBC *, DBC *,
+	    u_int32_t *, db_pgno_t, u_int32_t, void *));
+	u_int32_t *countp;
+	db_pgno_t pgno;
+	u_int32_t indx;
+	void *args;
+{
+	ENV *env;
+	DB *ldbp;
+	DBC *dbc;
+	int ret;
+
+	env = dbp->env;
+	ret = 0;
+
+	MUTEX_LOCK(env, env->mtx_dblist);
+	FIND_FIRST_DB_MATCH(env, dbp, ldbp);
+	for (*countp = 0;
+	    ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;
+	    ldbp = TAILQ_NEXT(ldbp, dblistlinks)) {
+loop:		MUTEX_LOCK(env, ldbp->mutex);
+		TAILQ_FOREACH(dbc, &ldbp->active_queue, links)
+			if ((ret = (func)(dbc, my_dbc,
+			    countp, pgno, indx, args)) != 0)
+				break;
+		/*
+		 * We use the error to communicate that function
+		 * dropped the mutex.
+		 */
+		if (ret == DB_LOCK_NOTGRANTED)
+			goto loop;
+		MUTEX_UNLOCK(env, ldbp->mutex);
+		if (ret != 0)
+			break;
+	}
+	MUTEX_UNLOCK(env, env->mtx_dblist);
+	return (ret);
+}
+
+/*
+ * __db_backup_name
+ *	Create the backup file name for a given file.
+ *
+ * PUBLIC: int __db_backup_name __P((ENV *, const char *, DB_TXN *, char **));
+ */
+#undef	BACKUP_PREFIX
+#define	BACKUP_PREFIX	"__db."
+
+#undef	MAX_INT_TO_HEX
+#define	MAX_INT_TO_HEX	8
+
+int
+__db_backup_name(env, name, txn, backup)
+	ENV *env;
+	const char *name;
+	DB_TXN *txn;
+	char **backup;
+{
+	u_int32_t id;
+	size_t len;
+	int ret;
+	char *p, *retp;
+
+	*backup = NULL;
+
+	/*
+	 * Part of the name may be a full path, so we need to make sure that
+	 * we allocate enough space for it, even in the case where we don't
+	 * use the entire filename for the backup name.
+	 */
+	len = strlen(name) + strlen(BACKUP_PREFIX) + 2 * MAX_INT_TO_HEX + 1;
+	if ((ret = __os_malloc(env, len, &retp)) != 0)
+		return (ret);
+
+	/*
+	 * Create the name.  Backup file names are in one of 2 forms: in a
+	 * transactional env "__db.TXNID.ID", where ID is a random number,
+	 * and in any other env "__db.FILENAME".
+	 *
+	 * In addition, the name passed may contain an env-relative path.
+	 * In that case, put the "__db." in the right place (in the last
+	 * component of the pathname).
+	 *
+	 * There are four cases here:
+	 *	1. simple path w/out transaction
+	 *	2. simple path + transaction
+	 *	3. multi-component path w/out transaction
+	 *	4. multi-component path + transaction
+	 */
+	p = __db_rpath(name);
+	if (IS_REAL_TXN(txn)) {
+		__os_unique_id(env, &id);
+		if (p == NULL)				/* Case 2. */
+			snprintf(retp, len, "%s%x.%x",
+			    BACKUP_PREFIX, txn->txnid, id);
+		else					/* Case 4. */
+			snprintf(retp, len, "%.*s%x.%x",
+			    (int)(p - name) + 1, name, txn->txnid, id);
+	} else
+		{
+		if (p == NULL)				/* Case 1. */
+			snprintf(retp, len, "%s%s", BACKUP_PREFIX, name);
+		else					/* Case 3. */
+			snprintf(retp, len, "%.*s%s%s",
+			    (int)(p - name) + 1, name, BACKUP_PREFIX, p + 1);
+	}
+
+	*backup = retp;
+	return (0);
+}
+
+#ifdef CONFIG_TEST
+/*
+ * __db_testcopy
+ *	Create a copy of all backup files and our "main" DB.
+ *
+ * PUBLIC: #ifdef CONFIG_TEST
+ * PUBLIC: int __db_testcopy __P((ENV *, DB *, const char *));
+ * PUBLIC: #endif
+ */
+int
+__db_testcopy(env, dbp, name)
+	ENV *env;
+	DB *dbp;
+	const char *name;
+{
+	DB_MPOOL *dbmp;
+	DB_MPOOLFILE *mpf;
+
+	DB_ASSERT(env, dbp != NULL || name != NULL);
+
+	if (name == NULL) {
+		dbmp = env->mp_handle;
+		mpf = dbp->mpf;
+		name = R_ADDR(dbmp->reginfo, mpf->mfp->path_off);
+	}
+
+	if (dbp != NULL && dbp->type == DB_QUEUE)
+		return (__qam_testdocopy(dbp, name));
+	else
+#ifdef HAVE_PARTITION
+	if (dbp != NULL && DB_IS_PARTITIONED(dbp))
+		return (__part_testdocopy(dbp, name));
+	else
+#endif
+		return (__db_testdocopy(env, name));
+}
+
+static int
+__qam_testdocopy(dbp, name)
+	DB *dbp;
+	const char *name;
+{
+	DB_THREAD_INFO *ip;
+	QUEUE_FILELIST *filelist, *fp;
+	int ret;
+	char buf[DB_MAXPATHLEN], *dir;
+
+	filelist = NULL;
+	if ((ret = __db_testdocopy(dbp->env, name)) != 0)
+		return (ret);
+
+	/* Call ENV_GET_THREAD_INFO to get a valid DB_THREAD_INFO */
+	ENV_GET_THREAD_INFO(dbp->env, ip);
+	if (dbp->mpf != NULL &&
+	    (ret = __qam_gen_filelist(dbp, ip, &filelist)) != 0)
+		goto done;
+
+	if (filelist == NULL)
+		return (0);
+	dir = ((QUEUE *)dbp->q_internal)->dir;
+	for (fp = filelist; fp->mpf != NULL; fp++) {
+		snprintf(buf, sizeof(buf),
+		    QUEUE_EXTENT, dir, PATH_SEPARATOR[0], name, fp->id);
+		if ((ret = __db_testdocopy(dbp->env, buf)) != 0)
+			return (ret);
+	}
+
+done:	__os_free(dbp->env, filelist);
+	return (0);
+}
+
+/*
+ * __db_testdocopy
+ *	Create a copy of all backup files and our "main" DB.
+ * PUBLIC: int __db_testdocopy __P((ENV *, const char *));
+ */
+int
+__db_testdocopy(env, name)
+	ENV *env;
+	const char *name;
+{
+	size_t len;
+	int dircnt, i, ret;
+	char *copy, **namesp, *p, *real_name;
+
+	dircnt = 0;
+	copy = NULL;
+	namesp = NULL;
+
+	/* Create the real backing file name. */
+	if ((ret = __db_appname(env,
+	    DB_APP_DATA, name, NULL, &real_name)) != 0)
+		return (ret);
+
+	/*
+	 * !!!
+	 * There are tests that attempt to copy non-existent files.  I'd guess
+	 * it's a testing bug, but I don't have time to figure it out.  Block
+	 * the case here.
+	 */
+	if (__os_exists(env, real_name, NULL) != 0) {
+		__os_free(env, real_name);
+		return (0);
+	}
+
+	/*
+	 * Copy the file itself.
+	 *
+	 * Allocate space for the file name, including adding an ".afterop" and
+	 * trailing nul byte.
+	 */
+	len = strlen(real_name) + sizeof(".afterop");
+	if ((ret = __os_malloc(env, len, &copy)) != 0)
+		goto err;
+	snprintf(copy, len, "%s.afterop", real_name);
+	if ((ret = __db_makecopy(env, real_name, copy)) != 0)
+		goto err;
+
+	/*
+	 * Get the directory path to call __os_dirlist().
+	 */
+	if ((p = __db_rpath(real_name)) != NULL)
+		*p = '\0';
+	if ((ret = __os_dirlist(env, real_name, 0, &namesp, &dircnt)) != 0)
+		goto err;
+
+	/*
+	 * Walk the directory looking for backup files.  Backup file names in
+	 * transactional environments are of the form:
+	 *
+	 *	BACKUP_PREFIX.TXNID.ID
+	 */
+	for (i = 0; i < dircnt; i++) {
+		/* Check for a related backup file name. */
+		if (strncmp(
+		    namesp[i], BACKUP_PREFIX, sizeof(BACKUP_PREFIX) - 1) != 0)
+			continue;
+		p = namesp[i] + sizeof(BACKUP_PREFIX);
+		p += strspn(p, "0123456789ABCDEFabcdef");
+		if (*p != '.')
+			continue;
+		++p;
+		p += strspn(p, "0123456789ABCDEFabcdef");
+		if (*p != '\0')
+			continue;
+
+		/*
+		 * Copy the backup file.
+		 *
+		 * Allocate space for the file name, including adding a
+		 * ".afterop" and trailing nul byte.
+		 */
+		if (real_name != NULL) {
+			__os_free(env, real_name);
+			real_name = NULL;
+		}
+		if ((ret = __db_appname(env,
+		    DB_APP_DATA, namesp[i], NULL, &real_name)) != 0)
+			goto err;
+		if (copy != NULL) {
+			__os_free(env, copy);
+			copy = NULL;
+		}
+		len = strlen(real_name) + sizeof(".afterop");
+		if ((ret = __os_malloc(env, len, &copy)) != 0)
+			goto err;
+		snprintf(copy, len, "%s.afterop", real_name);
+		if ((ret = __db_makecopy(env, real_name, copy)) != 0)
+			goto err;
+	}
+
+err:	if (namesp != NULL)
+		__os_dirfree(env, namesp, dircnt);
+	if (copy != NULL)
+		__os_free(env, copy);
+	if (real_name != NULL)
+		__os_free(env, real_name);
+	return (ret);
+}
+
+static int
+__db_makecopy(env, src, dest)
+	ENV *env;
+	const char *src, *dest;
+{
+	DB_FH *rfhp, *wfhp;
+	size_t rcnt, wcnt;
+	int ret;
+	char *buf;
+
+	rfhp = wfhp = NULL;
+
+	if ((ret = __os_malloc(env, 64 * 1024, &buf)) != 0)
+		goto err;
+
+	if ((ret = __os_open(env, src, 0,
+	    DB_OSO_RDONLY, DB_MODE_600, &rfhp)) != 0)
+		goto err;
+	if ((ret = __os_open(env, dest, 0,
+	    DB_OSO_CREATE | DB_OSO_TRUNC, DB_MODE_600, &wfhp)) != 0)
+		goto err;
+
+	for (;;) {
+		if ((ret =
+		    __os_read(env, rfhp, buf, sizeof(buf), &rcnt)) != 0)
+			goto err;
+		if (rcnt == 0)
+			break;
+		if ((ret =
+		    __os_write(env, wfhp, buf, sizeof(buf), &wcnt)) != 0)
+			goto err;
+	}
+
+	if (0) {
+err:		__db_err(env, ret, "__db_makecopy: %s -> %s", src, dest);
+	}
+
+	if (buf != NULL)
+		__os_free(env, buf);
+	if (rfhp != NULL)
+		(void)__os_closehandle(env, rfhp);
+	if (wfhp != NULL)
+		(void)__os_closehandle(env, wfhp);
+	return (ret);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_am.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1172 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+#include "dbinc/qam.h"
+#include "dbinc/txn.h"
+
+static int __db_secondary_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
+static int __dbc_set_priority __P((DBC *, DB_CACHE_PRIORITY));
+static int __dbc_get_priority __P((DBC *, DB_CACHE_PRIORITY* ));
+
+/*
+ * __db_cursor_int --
+ *	Internal routine to create a cursor.
+ *
+ * PUBLIC: int __db_cursor_int __P((DB *, DB_THREAD_INFO *,
+ * PUBLIC:     DB_TXN *, DBTYPE, db_pgno_t, int, DB_LOCKER *, DBC **));
+ */
+int
+__db_cursor_int(dbp, ip, txn, dbtype, root, flags, locker, dbcp)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DBTYPE dbtype;
+	db_pgno_t root;
+	int flags;
+	DB_LOCKER *locker;
+	DBC **dbcp;
+{
+	DBC *dbc;
+	DBC_INTERNAL *cp;
+	DB_LOCKREQ req;
+	ENV *env;
+	db_threadid_t tid;
+	int allocated, envlid, ret;
+	pid_t pid;
+
+	env = dbp->env;
+	allocated = envlid = 0;
+
+	/*
+	 * If dbcp is non-NULL it is assumed to point to an area to initialize
+	 * as a cursor.
+	 *
+	 * Take one from the free list if it's available.  Take only the
+	 * right type.  With off page dups we may have different kinds
+	 * of cursors on the queue for a single database.
+	 */
+	MUTEX_LOCK(env, dbp->mutex);
+
+#ifndef HAVE_NO_DB_REFCOUNT
+	/*
+	 * If this DBP is being logged then refcount the log filename
+	 * relative to this transaction. We do this here because we have
+	 * the dbp->mutex which protects the refcount.  We want to avoid
+	 * calling the function if the transaction handle has a shared parent
+	 * locker or we are duplicating a cursor.  This includes the case of
+	 * creating an off page duplicate cursor.
+	 * If we knew this cursor will not be used in an update, we could avoid
+	 * this, but we don't have that information.
+	 */
+	if (IS_REAL_TXN(txn) &&
+	    !LF_ISSET(DBC_OPD | DBC_DUPLICATE) &&
+	    !F_ISSET(dbp, DB_AM_RECOVER) &&
+	    dbp->log_filename != NULL && !IS_REP_CLIENT(env) &&
+	    (ret = __txn_record_fname(env, txn, dbp->log_filename)) != 0) {
+		MUTEX_UNLOCK(env, dbp->mutex);
+		return (ret);
+	}
+
+#endif
+
+	TAILQ_FOREACH(dbc, &dbp->free_queue, links)
+		if (dbtype == dbc->dbtype) {
+			TAILQ_REMOVE(&dbp->free_queue, dbc, links);
+			F_CLR(dbc, ~DBC_OWN_LID);
+			break;
+		}
+	MUTEX_UNLOCK(env, dbp->mutex);
+
+	if (dbc == NULL) {
+		if ((ret = __os_calloc(env, 1, sizeof(DBC), &dbc)) != 0)
+			return (ret);
+		allocated = 1;
+		dbc->flags = 0;
+
+		dbc->dbp = dbp;
+		dbc->dbenv = dbp->dbenv;
+		dbc->env = dbp->env;
+
+		/* Set up locking information. */
+		if (LOCKING_ON(env)) {
+			/*
+			 * If we are not threaded, we share a locker ID among
+			 * all cursors opened in the environment handle,
+			 * allocating one if this is the first cursor.
+			 *
+			 * This relies on the fact that non-threaded DB handles
+			 * always have non-threaded environment handles, since
+			 * we set DB_THREAD on DB handles created with threaded
+			 * environment handles.
+			 */
+			if (!DB_IS_THREADED(dbp)) {
+				if (env->env_lref == NULL) {
+					if ((ret = __lock_id(env,
+					    NULL, &env->env_lref)) != 0)
+						goto err;
+				       envlid = 1;
+				}
+				dbc->lref = env->env_lref;
+			}
+
+			/*
+			 * In CDB, secondary indices should share a lock file
+			 * ID with the primary;  otherwise we're susceptible
+			 * to deadlocks.  We also use __db_cursor_int rather
+			 * than __db_cursor to create secondary update cursors
+			 * in c_put and c_del; these won't acquire a new lock.
+			 *
+			 * !!!
+			 * Since this is in the one-time cursor allocation
+			 * code, we need to be sure to destroy, not just
+			 * close, all cursors in the secondary when we
+			 * associate.
+			 */
+			if (CDB_LOCKING(env) &&
+			    F_ISSET(dbp, DB_AM_SECONDARY))
+				memcpy(dbc->lock.fileid,
+				    dbp->s_primary->fileid, DB_FILE_ID_LEN);
+			else
+				memcpy(dbc->lock.fileid,
+				    dbp->fileid, DB_FILE_ID_LEN);
+
+			if (CDB_LOCKING(env)) {
+				if (F_ISSET(env->dbenv, DB_ENV_CDB_ALLDB)) {
+					/*
+					 * If we are doing a single lock per
+					 * environment, set up the global
+					 * lock object just like we do to
+					 * single thread creates.
+					 */
+					DB_ASSERT(env, sizeof(db_pgno_t) ==
+					    sizeof(u_int32_t));
+					dbc->lock_dbt.size = sizeof(u_int32_t);
+					dbc->lock_dbt.data = &dbc->lock.pgno;
+					dbc->lock.pgno = 0;
+				} else {
+					dbc->lock_dbt.size = DB_FILE_ID_LEN;
+					dbc->lock_dbt.data = dbc->lock.fileid;
+				}
+			} else {
+				dbc->lock.type = DB_PAGE_LOCK;
+				dbc->lock_dbt.size = sizeof(dbc->lock);
+				dbc->lock_dbt.data = &dbc->lock;
+			}
+		}
+		/* Init the DBC internal structure. */
+#ifdef HAVE_PARTITION
+		if (DB_IS_PARTITIONED(dbp)) {
+			if ((ret = __partc_init(dbc)) != 0)
+				goto err;
+		} else
+#endif
+		switch (dbtype) {
+		case DB_BTREE:
+		case DB_RECNO:
+			if ((ret = __bamc_init(dbc, dbtype)) != 0)
+				goto err;
+			break;
+		case DB_HASH:
+			if ((ret = __hamc_init(dbc)) != 0)
+				goto err;
+			break;
+		case DB_HEAP:
+			if ((ret = __heapc_init(dbc)) != 0)
+				goto err;
+			break;
+		case DB_QUEUE:
+			if ((ret = __qamc_init(dbc)) != 0)
+				goto err;
+			break;
+		case DB_UNKNOWN:
+		default:
+			ret = __db_unknown_type(env, "DB->cursor", dbtype);
+			goto err;
+		}
+
+		cp = dbc->internal;
+	}
+
+	/* Refresh the DBC structure. */
+	dbc->dbtype = dbtype;
+	RESET_RET_MEM(dbc);
+	dbc->set_priority = __dbc_set_priority;
+	dbc->get_priority = __dbc_get_priority;
+	dbc->priority = dbp->priority;
+	dbc->txn_cursors.tqe_next = NULL;
+	dbc->txn_cursors.tqe_prev = NULL;
+
+	/*
+	 * If the DB handle is not threaded, there is one locker ID for the
+	 * whole environment.  There should only one family transaction active
+	 * as well.  This doesn't apply to CDS group transactions, where the
+	 * cursor can simply use the transaction's locker directly.
+	 */
+	if (!CDB_LOCKING(env) && txn != NULL && F_ISSET(txn, TXN_FAMILY) &&
+	    (F_ISSET(dbc, DBC_OWN_LID) || dbc->lref == NULL || envlid))  {
+		if (LOCKING_ON(env)) {
+			if (dbc->lref == NULL) {
+				if ((ret =
+				    __lock_id(env, NULL, &dbc->lref)) != 0)
+					goto err;
+				F_SET(dbc, DBC_OWN_LID);
+			}
+			if ((ret = __lock_addfamilylocker(env,
+			    txn->txnid, dbc->lref->id, 1)) != 0)
+				goto err;
+		}
+		F_SET(dbc, DBC_FAMILY);
+		txn = NULL;
+	}
+
+	if ((dbc->txn = txn) != NULL)
+		dbc->locker = txn->locker;
+	else if (LOCKING_ON(env)) {
+		/*
+		 * There are certain cases in which we want to create a
+		 * new cursor with a particular locker ID that is known
+		 * to be the same as (and thus not conflict with) an
+		 * open cursor.
+		 *
+		 * The most obvious case is cursor duplication;  when we
+		 * call DBC->dup or __dbc_idup, we want to use the original
+		 * cursor's locker ID.
+		 *
+		 * Another case is when updating secondary indices.  Standard
+		 * CDB locking would mean that we might block ourself:  we need
+		 * to open an update cursor in the secondary while an update
+		 * cursor in the primary is open, and when the secondary and
+		 * primary are subdatabases or we're using env-wide locking,
+		 * this is disastrous.
+		 *
+		 * In these cases, our caller will pass a nonzero locker
+		 * ID into this function.  Use this locker ID instead of
+		 * the default as the locker ID for our new cursor.
+		 */
+		if (locker != NULL)
+			dbc->locker = locker;
+		else if (LF_ISSET(DB_RECOVER))
+			dbc->locker = NULL;
+		else {
+			if (dbc->lref == NULL) {
+				if ((ret =
+				    __lock_id(env, NULL, &dbc->lref)) != 0)
+					goto err;
+				F_SET(dbc, DBC_OWN_LID);
+			}
+			/*
+			 * If we are threaded then we need to set the
+			 * proper thread id into the locker.
+			 */
+			if (DB_IS_THREADED(dbp)) {
+				env->dbenv->thread_id(env->dbenv, &pid, &tid);
+				__lock_set_thread_id(dbc->lref, pid, tid);
+			}
+			dbc->locker = dbc->lref;
+		}
+	}
+
+	/*
+	 * These fields change when we are used as a secondary index, so
+	 * if the DB is a secondary, make sure they're set properly just
+	 * in case we opened some cursors before we were associated.
+	 *
+	 * __dbc_get is used by all access methods, so this should be safe.
+	 */
+	if (F_ISSET(dbp, DB_AM_SECONDARY))
+		dbc->get = dbc->c_get = __dbc_secondary_get_pp;
+
+	/*
+	 * Don't enable bulk for btrees with record numbering, since avoiding
+	 * a full search avoids taking write locks necessary to maintain
+	 * consistent numbering.
+	 */
+	if (LF_ISSET(DB_CURSOR_BULK) && dbtype == DB_BTREE &&
+	    !F_ISSET(dbp, DB_AM_RECNUM))
+		F_SET(dbc, DBC_BULK);
+	if (LF_ISSET(DB_CURSOR_TRANSIENT))
+		F_SET(dbc, DBC_TRANSIENT);
+	if (LF_ISSET(DBC_OPD))
+		F_SET(dbc, DBC_OPD);
+	if (F_ISSET(dbp, DB_AM_RECOVER) || LF_ISSET(DB_RECOVER))
+		F_SET(dbc, DBC_RECOVER);
+	if (F_ISSET(dbp, DB_AM_COMPENSATE))
+		F_SET(dbc, DBC_DONTLOCK);
+	/*
+	* If this database is exclusive then the cursor
+	* does not need to get locks.
+	*/
+	if (F2_ISSET(dbp, DB2_AM_EXCL)) {
+		F_SET(dbc, DBC_DONTLOCK);
+		if (IS_REAL_TXN(txn) && !LF_ISSET(DBC_OPD | DBC_DUPLICATE)) {
+			/* 
+			 * Exclusive databases can only have one active 
+			 * transaction at a time since there are no internal 
+			 * locks to prevent one transaction from reading and
+			 * writing another's uncommitted changes. 
+			 */
+			if (dbp->cur_txn != NULL && dbp->cur_txn != txn) {
+			    __db_errx(env, DB_STR("0749",
+"Exclusive database handles can only have one active transaction at a time."));
+				ret = EINVAL;
+				goto err;
+			}
+			/* Do not trade a second time. */
+			if (dbp->cur_txn != txn) {
+				/* Trade the handle lock to the txn locker. */
+				memset(&req, 0, sizeof(req));
+				req.lock = dbp->handle_lock;
+				req.op = DB_LOCK_TRADE;
+				if ((ret = __lock_vec(env, txn->locker, 0, 
+				    &req, 1, 0)) != 0)
+					goto err;
+				dbp->cur_txn = txn;
+				dbp->cur_locker = txn->locker;
+				if ((ret = __txn_lockevent(env, txn, dbp,
+				    &dbp->handle_lock, dbp->locker)) != 0)
+					goto err;
+			}
+		}
+	}
+#ifdef HAVE_REPLICATION
+	/*
+	 * If we are replicating from a down rev version then we must
+	 * use old locking protocols.
+	 */
+	if (LOGGING_ON(env) &&
+	     ((LOG *)env->lg_handle->
+	     reginfo.primary)->persist.version < DB_LOGVERSION_LATCHING)
+		F_SET(dbc, DBC_DOWNREV);
+#endif
+
+	/* Refresh the DBC internal structure. */
+	cp = dbc->internal;
+	cp->opd = NULL;
+	cp->pdbc = NULL;
+
+	cp->indx = 0;
+	cp->page = NULL;
+	cp->pgno = PGNO_INVALID;
+	cp->root = root;
+	cp->stream_start_pgno = cp->stream_curr_pgno = PGNO_INVALID;
+	cp->stream_off = 0;
+
+	if (DB_IS_PARTITIONED(dbp)) {
+		DBC_PART_REFRESH(dbc);
+	} else switch (dbtype) {
+	case DB_BTREE:
+	case DB_RECNO:
+		if ((ret = __bamc_refresh(dbc)) != 0)
+			goto err;
+		break;
+	case DB_HEAP:
+		if ((ret = __heapc_refresh(dbc)) != 0)
+			goto err;
+		break;
+	case DB_HASH:
+	case DB_QUEUE:
+		break;
+	case DB_UNKNOWN:
+	default:
+		ret = __db_unknown_type(env, "DB->cursor", dbp->type);
+		goto err;
+	}
+
+	/*
+	 * The transaction keeps track of how many cursors were opened within
+	 * it to catch application errors where the cursor isn't closed when
+	 * the transaction is resolved.
+	 */
+	if (txn != NULL)
+		++txn->cursors;
+	if (ip != NULL) {
+		dbc->thread_info = ip;
+#ifdef DIAGNOSTIC
+		if (dbc->locker != NULL)
+			ip->dbth_locker =
+			    R_OFFSET(&(env->lk_handle->reginfo), dbc->locker);
+		else
+			ip->dbth_locker = INVALID_ROFF;
+#endif
+	} else if (txn != NULL)
+		dbc->thread_info = txn->thread_info;
+	else
+		ENV_GET_THREAD_INFO(env, dbc->thread_info);
+
+	MUTEX_LOCK(env, dbp->mutex);
+	TAILQ_INSERT_TAIL(&dbp->active_queue, dbc, links);
+	F_SET(dbc, DBC_ACTIVE);
+	MUTEX_UNLOCK(env, dbp->mutex);
+
+	*dbcp = dbc;
+	return (0);
+
+err:	if (allocated)
+		__os_free(env, dbc);
+	return (ret);
+}
+
+/*
+ * __db_put --
+ *	Store a key/data pair.
+ *
+ * PUBLIC: int __db_put __P((DB *,
+ * PUBLIC:      DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, u_int32_t));
+ */
+int
+__db_put(dbp, ip, txn, key, data, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DB_HEAP_RID rid;
+	DBC *dbc;
+	DBT tdata, tkey;
+	ENV *env;
+	void *bulk_kptr, *bulk_ptr;
+	db_recno_t recno;
+	u_int32_t cursor_flags;
+	int ret, t_ret;
+
+	env = dbp->env;
+
+	/*
+	 * See the comment in __db_get() regarding DB_CURSOR_TRANSIENT.
+	 *
+	 * Note that the get in the DB_NOOVERWRITE case is safe to do with this
+	 * flag set;  if it errors in any way other than DB_NOTFOUND, we're
+	 * going to close the cursor without doing anything else, and if it
+	 * returns DB_NOTFOUND then it's safe to do a c_put(DB_KEYLAST) even if
+	 * an access method moved the cursor, since that's not
+	 * position-dependent.
+	 */
+	cursor_flags = DB_WRITELOCK;
+	if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY))
+		cursor_flags |= DB_CURSOR_BULK;
+	else
+		cursor_flags |= DB_CURSOR_TRANSIENT;
+	if ((ret = __db_cursor(dbp, ip, txn, &dbc, cursor_flags)) != 0)
+		return (ret);
+
+	DEBUG_LWRITE(dbc, txn, "DB->put", key, data, flags);
+	PERFMON6(env, db, put, dbp->fname,
+	    dbp->dname, txn == NULL ? 0 : txn->txnid, key, data, flags);
+
+	SET_RET_MEM(dbc, dbp);
+
+	if (flags == DB_APPEND && !DB_IS_PRIMARY(dbp)) {
+		/*
+		 * If there is an append callback, the value stored in
+		 * data->data may be replaced and then freed.  To avoid
+		 * passing a freed pointer back to the user, just operate
+		 * on a copy of the data DBT.
+		 */
+		tdata = *data;
+
+		/*
+		 * Append isn't a normal put operation;  call the appropriate
+		 * access method's append function.
+		 */
+		switch (dbp->type) {
+		case DB_HEAP:
+			if ((ret = __heap_append(dbc, key, &tdata)) != 0)
+				goto err;
+			break;
+		case DB_QUEUE:
+			if ((ret = __qam_append(dbc, key, &tdata)) != 0)
+				goto err;
+			break;
+		case DB_RECNO:
+			if ((ret = __ram_append(dbc, key, &tdata)) != 0)
+				goto err;
+			break;
+		case DB_BTREE:
+		case DB_HASH:
+		case DB_UNKNOWN:
+		default:
+			/* The interface should prevent this. */
+			DB_ASSERT(env,
+			    dbp->type == DB_QUEUE || dbp->type == DB_RECNO);
+
+			ret = __db_ferr(env, "DB->put", 0);
+			goto err;
+		}
+
+		/*
+		 * The append callback, if one exists, may have allocated
+		 * a new tdata.data buffer.  If so, free it.
+		 */
+		FREE_IF_NEEDED(env, &tdata);
+
+		/* No need for a cursor put;  we're done. */
+#ifdef HAVE_COMPRESSION
+	} else if (DB_IS_COMPRESSED(dbp) && !F_ISSET(dbp, DB_AM_SECONDARY) &&
+	    !DB_IS_PRIMARY(dbp) && LIST_FIRST(&dbp->f_primaries) == NULL) {
+		ret = __dbc_put(dbc, key, data, flags);
+#endif
+	} else if (LF_ISSET(DB_MULTIPLE)) {
+		ret = 0;
+		memset(&tkey, 0, sizeof(tkey));
+		if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO) {
+			tkey.data = &recno;
+			tkey.size = sizeof(recno);
+		}
+		memset(&tdata, 0, sizeof(tdata));
+		DB_MULTIPLE_INIT(bulk_kptr, key);
+		DB_MULTIPLE_INIT(bulk_ptr, data);
+		key->doff = 0;
+		while (ret == 0) {
+			if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO)
+				DB_MULTIPLE_RECNO_NEXT(bulk_kptr, key,
+				    recno, tdata.data, tdata.size);
+			else
+				DB_MULTIPLE_NEXT(bulk_kptr, key,
+				    tkey.data, tkey.size);
+			DB_MULTIPLE_NEXT(bulk_ptr, data,
+			    tdata.data, tdata.size);
+			if (bulk_kptr == NULL || bulk_ptr == NULL)
+				break;
+			if (dbp->type == DB_HEAP) {
+				memcpy(&rid, tkey.data, sizeof(DB_HEAP_RID));
+				tkey.data = &rid;
+			}
+			ret = __dbc_put(dbc, &tkey, &tdata,
+			    LF_ISSET(DB_OPFLAGS_MASK));
+			if (ret == 0)
+				++key->doff;
+		}
+	} else if (LF_ISSET(DB_MULTIPLE_KEY)) {
+		ret = 0;
+		memset(&tkey, 0, sizeof(tkey));
+		if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO) {
+			tkey.data = &recno;
+			tkey.size = sizeof(recno);
+		}
+		memset(&tdata, 0, sizeof(tdata));
+		DB_MULTIPLE_INIT(bulk_ptr, key);
+		while (ret == 0) {
+			if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO)
+				DB_MULTIPLE_RECNO_NEXT(bulk_ptr, key, recno,
+				    tdata.data, tdata.size);
+			else
+				DB_MULTIPLE_KEY_NEXT(bulk_ptr, key, tkey.data,
+				    tkey.size, tdata.data, tdata.size);
+			if (bulk_ptr == NULL)
+				break;
+			if (dbp->type == DB_HEAP) {
+				memcpy(&rid, tkey.data, sizeof(DB_HEAP_RID));
+				tkey.data = &rid;
+			}
+			ret = __dbc_put(dbc, &tkey, &tdata,
+			    LF_ISSET(DB_OPFLAGS_MASK));
+			if (ret == 0)
+				++key->doff;
+		}
+	} else
+		ret = __dbc_put(dbc, key, data, flags);
+
+err:	/* Close the cursor. */
+	if (!DB_RETOK_DBPUT(ret))
+		F_SET(dbc, DBC_ERROR);
+	if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __db_del --
+ *	Delete the items referenced by a key.
+ *
+ * PUBLIC: int __db_del __P((DB *,
+ * PUBLIC:      DB_THREAD_INFO *, DB_TXN *, DBT *, u_int32_t));
+ */
+int
+__db_del(dbp, ip, txn, key, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DBT *key;
+	u_int32_t flags;
+{
+	DB_HEAP_RID rid;
+	DBC *dbc;
+	DBT data, tkey;
+	void *bulk_ptr;
+	db_recno_t recno;
+	u_int32_t cursor_flags, f_init, f_next;
+	int ret, t_ret;
+
+	COMPQUIET(bulk_ptr, NULL);
+	/* Allocate a cursor. */
+	cursor_flags = DB_WRITELOCK;
+	if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY))
+		cursor_flags |= DB_CURSOR_BULK;
+	if ((ret = __db_cursor(dbp, ip, txn, &dbc, cursor_flags)) != 0)
+		return (ret);
+
+	DEBUG_LWRITE(dbc, txn, "DB->del", key, NULL, flags);
+	PERFMON5(env, db, del,
+	    dbp->fname, dbp->dname, txn == NULL ? 0 : txn->txnid, key, flags);
+
+#ifdef HAVE_COMPRESSION
+	if (DB_IS_COMPRESSED(dbp) && !F_ISSET(dbp, DB_AM_SECONDARY) &&
+	    !DB_IS_PRIMARY(dbp) && LIST_FIRST(&dbp->f_primaries) == NULL) {
+		F_SET(dbc, DBC_TRANSIENT);
+		ret = __dbc_bulk_del(dbc, key, flags);
+		goto err;
+	}
+#endif
+
+	/*
+	 * Walk a cursor through the key/data pairs, deleting as we go.  Set
+	 * the DB_DBT_USERMEM flag, as this might be a threaded application
+	 * and the flags checking will catch us.  We don't actually want the
+	 * keys or data, set DB_DBT_ISSET.  We rely on __dbc_get to clear
+	 * this.
+	 */
+	memset(&data, 0, sizeof(data));
+	F_SET(&data, DB_DBT_USERMEM);
+	tkey = *key;
+
+	f_init = LF_ISSET(DB_MULTIPLE_KEY) ? DB_GET_BOTH : DB_SET;
+	f_next = DB_NEXT_DUP;
+
+	/*
+	 * If locking (and we haven't already acquired CDB locks), set the
+	 * read-modify-write flag.
+	 */
+	if (STD_LOCKING(dbc)) {
+		f_init |= DB_RMW;
+		f_next |= DB_RMW;
+	}
+
+	if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {
+		if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO) {
+			memset(&tkey, 0, sizeof(tkey));
+			tkey.data = &recno;
+			tkey.size = sizeof(recno);
+		}
+		DB_MULTIPLE_INIT(bulk_ptr, key);
+		/* We return the number of keys deleted in doff. */
+		key->doff = 0;
+bulk_next:	if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO)
+			DB_MULTIPLE_RECNO_NEXT(bulk_ptr, key,
+			    recno, data.data, data.size);
+		else if (LF_ISSET(DB_MULTIPLE))
+			DB_MULTIPLE_NEXT(bulk_ptr, key, tkey.data, tkey.size);
+		else
+			DB_MULTIPLE_KEY_NEXT(bulk_ptr, key,
+			    tkey.data, tkey.size, data.data, data.size);
+		if (bulk_ptr == NULL)
+			goto err;
+		if (dbp->type == DB_HEAP) {
+			memcpy(&rid, tkey.data, sizeof(DB_HEAP_RID));
+			tkey.data = &rid;
+		}
+
+	}
+
+	/* We're not interested in the data -- do not return it. */
+	F_SET(&tkey, DB_DBT_ISSET);
+	F_SET(&data, DB_DBT_ISSET);
+
+	/*
+	 * Optimize the simple cases.  For all AMs if we don't have secondaries
+	 * and are not a secondary and we aren't a foreign database and there
+	 * are no dups then we can avoid a bunch of overhead.  For queue we
+	 * don't need to fetch the record since we delete by direct calculation
+	 * from the record number.
+	 *
+	 * Hash permits an optimization in DB->del: since on-page duplicates are
+	 * stored in a single HKEYDATA structure, it's possible to delete an
+	 * entire set of them at once, and as the HKEYDATA has to be rebuilt
+	 * and re-put each time it changes, this is much faster than deleting
+	 * the duplicates one by one.  Thus, if not pointing at an off-page
+	 * duplicate set, and we're not using secondary indices (in which case
+	 * we'd have to examine the items one by one anyway), let hash do this
+	 * "quick delete".
+	 *
+	 * !!!
+	 * Note that this is the only application-executed delete call in
+	 * Berkeley DB that does not go through the __dbc_del function.
+	 * If anything other than the delete itself (like a secondary index
+	 * update) has to happen there in a particular situation, the
+	 * conditions here should be modified not to use these optimizations.
+	 * The ordinary AM-independent alternative will work just fine;
+	 * it'll just be slower.
+	 */
+	if (!F_ISSET(dbp, DB_AM_SECONDARY) && !DB_IS_PRIMARY(dbp) &&
+	    LIST_FIRST(&dbp->f_primaries) == NULL) {
+#ifdef HAVE_QUEUE
+		if (dbp->type == DB_QUEUE) {
+			ret = __qam_delete(dbc, &tkey, flags);
+			goto next;
+		}
+#endif
+
+		/* Fetch the first record. */
+		if ((ret = __dbc_get(dbc, &tkey, &data, f_init)) != 0)
+			goto err;
+
+#ifdef HAVE_HASH
+		/*
+		 * Hash "quick delete" removes all on-page duplicates.  We
+		 * can't do that if deleting specific key/data pairs.
+		 */
+		if (dbp->type == DB_HASH && !LF_ISSET(DB_MULTIPLE_KEY)) {
+			DBC *sdbc;
+			sdbc = dbc;
+#ifdef HAVE_PARTITION
+			if (F_ISSET(dbc, DBC_PARTITIONED))
+				sdbc =
+				    ((PART_CURSOR*)dbc->internal)->sub_cursor;
+#endif
+			if (sdbc->internal->opd == NULL) {
+				ret = __ham_quick_delete(sdbc);
+				goto next;
+			}
+		}
+#endif
+
+		if (!F_ISSET(dbp, DB_AM_DUP)) {
+			ret = dbc->am_del(dbc, 0);
+			goto next;
+		}
+	} else if ((ret = __dbc_get(dbc, &tkey, &data, f_init)) != 0)
+		goto err;
+
+	/* Walk through the set of key/data pairs, deleting as we go. */
+	for (;;) {
+		if ((ret = __dbc_del(dbc, flags)) != 0)
+			break;
+		/*
+		 * With DB_MULTIPLE_KEY, the application has specified the
+		 * exact records they want deleted.  We don't need to walk
+		 * through a set of duplicates.
+		 */
+		if (LF_ISSET(DB_MULTIPLE_KEY))
+			break;
+
+		F_SET(&tkey, DB_DBT_ISSET);
+		F_SET(&data, DB_DBT_ISSET);
+		if ((ret = __dbc_get(dbc, &tkey, &data, f_next)) != 0) {
+			if (ret == DB_NOTFOUND)
+				ret = 0;
+			break;
+		}
+	}
+
+next:	if (ret == 0 && LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {
+		++key->doff;
+		goto bulk_next;
+	}
+err:	/* Discard the cursor. */
+	if (!DB_RETOK_DBDEL(ret))
+		F_SET(dbc, DBC_ERROR);
+	if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __db_sync --
+ *	Flush the database cache.
+ *
+ * PUBLIC: int __db_sync __P((DB *));
+ */
+int
+__db_sync(dbp)
+	DB *dbp;
+{
+	int ret, t_ret;
+
+	ret = 0;
+
+	/* If the database was read-only, we're done. */
+	if (F_ISSET(dbp, DB_AM_RDONLY))
+		return (0);
+
+	/* If it's a Recno tree, write the backing source text file. */
+	if (dbp->type == DB_RECNO)
+		ret = __ram_writeback(dbp);
+
+	/* If the database was never backed by a database file, we're done. */
+	if (F_ISSET(dbp, DB_AM_INMEM))
+		return (ret);
+#ifdef HAVE_PARTITION
+	if (DB_IS_PARTITIONED(dbp))
+		ret = __partition_sync(dbp);
+	else
+#endif
+	if (dbp->type == DB_QUEUE)
+		ret = __qam_sync(dbp);
+	else
+		/* Flush any dirty pages from the cache to the backing file. */
+		if ((t_ret = __memp_fsync(dbp->mpf)) != 0 && ret == 0)
+			ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __db_associate --
+ *	Associate another database as a secondary index to this one.
+ *
+ * PUBLIC: int __db_associate __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB *,
+ * PUBLIC:     int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t));
+ */
+int
+__db_associate(dbp, ip, txn, sdbp, callback, flags)
+	DB *dbp, *sdbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	int (*callback) __P((DB *, const DBT *, const DBT *, DBT *));
+	u_int32_t flags;
+{
+	DBC *pdbc, *sdbc;
+	DBT key, data, skey, *tskeyp;
+	ENV *env;
+	int build, ret, t_ret;
+	u_int32_t nskey;
+
+	env = dbp->env;
+	pdbc = sdbc = NULL;
+	ret = 0;
+
+	memset(&skey, 0, sizeof(DBT));
+	nskey = 0;
+	tskeyp = NULL;
+
+	/*
+	 * Check to see if the secondary is empty -- and thus if we should
+	 * build it -- before we link it in and risk making it show up in other
+	 * threads.  Do this first so that the databases remain unassociated on
+	 * error.
+	 */
+	build = 0;
+	if (LF_ISSET(DB_CREATE)) {
+		FLD_SET(sdbp->s_assoc_flags, DB_ASSOC_CREATE);
+
+		if ((ret = __db_cursor(sdbp, ip, txn, &sdbc, 0)) != 0)
+			goto err;
+
+		/*
+		 * We don't care about key or data;  we're just doing
+		 * an existence check.
+		 */
+		memset(&key, 0, sizeof(DBT));
+		memset(&data, 0, sizeof(DBT));
+		F_SET(&key, DB_DBT_PARTIAL | DB_DBT_USERMEM);
+		F_SET(&data, DB_DBT_PARTIAL | DB_DBT_USERMEM);
+		if ((ret = __dbc_get(sdbc, &key, &data,
+		    (STD_LOCKING(sdbc) ? DB_RMW : 0) |
+		    DB_FIRST)) == DB_NOTFOUND) {
+			build = 1;
+			ret = 0;
+		}
+
+		if (ret != 0)
+			F_SET(sdbc, DBC_ERROR);
+		if ((t_ret = __dbc_close(sdbc)) != 0 && ret == 0)
+			ret = t_ret;
+
+		/* Reset for later error check. */
+		sdbc = NULL;
+
+		if (ret != 0)
+			goto err;
+	}
+
+	/*
+	 * Set up the database handle as a secondary.
+	 */
+	sdbp->s_callback = callback;
+	sdbp->s_primary = dbp;
+
+	sdbp->stored_get = sdbp->get;
+	sdbp->get = __db_secondary_get;
+
+	sdbp->stored_close = sdbp->close;
+	sdbp->close = __db_secondary_close_pp;
+
+	F_SET(sdbp, DB_AM_SECONDARY);
+
+	if (LF_ISSET(DB_IMMUTABLE_KEY))
+		FLD_SET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY);
+
+	/*
+	 * Add the secondary to the list on the primary.  Do it here
+	 * so that we see any updates that occur while we're walking
+	 * the primary.
+	 */
+	MUTEX_LOCK(env, dbp->mutex);
+
+	/* See __db_s_next for an explanation of secondary refcounting. */
+	DB_ASSERT(env, sdbp->s_refcnt == 0);
+	sdbp->s_refcnt = 1;
+	LIST_INSERT_HEAD(&dbp->s_secondaries, sdbp, s_links);
+	MUTEX_UNLOCK(env, dbp->mutex);
+
+	if (build) {
+		/*
+		 * We loop through the primary, putting each item we
+		 * find into the new secondary.
+		 *
+		 * If we're using CDB, opening these two cursors puts us
+		 * in a bit of a locking tangle:  CDB locks are done on the
+		 * primary, so that we stay deadlock-free, but that means
+		 * that updating the secondary while we have a read cursor
+		 * open on the primary will self-block.  To get around this,
+		 * we force the primary cursor to use the same locker ID
+		 * as the secondary, so they won't conflict.  This should
+		 * be harmless even if we're not using CDB.
+		 */
+		if ((ret = __db_cursor(sdbp, ip, txn, &sdbc,
+		    CDB_LOCKING(sdbp->env) ? DB_WRITECURSOR : 0)) != 0)
+			goto err;
+		if ((ret = __db_cursor_int(dbp, ip,
+		    txn, dbp->type, PGNO_INVALID, 0, sdbc->locker, &pdbc)) != 0)
+			goto err;
+
+		/* Lock out other threads, now that we have a locker. */
+		dbp->associate_locker = sdbc->locker;
+
+		memset(&key, 0, sizeof(DBT));
+		memset(&data, 0, sizeof(DBT));
+		while ((ret = __dbc_get(pdbc, &key, &data, DB_NEXT)) == 0) {
+			if ((ret = callback(sdbp, &key, &data, &skey)) != 0) {
+				if (ret == DB_DONOTINDEX)
+					continue;
+				goto err;
+			}
+			if (F_ISSET(&skey, DB_DBT_MULTIPLE)) {
+#ifdef DIAGNOSTIC
+				__db_check_skeyset(sdbp, &skey);
+#endif
+				nskey = skey.size;
+				tskeyp = (DBT *)skey.data;
+			} else {
+				nskey = 1;
+				tskeyp = &skey;
+			}
+			SWAP_IF_NEEDED(sdbp, &key);
+			for (; nskey > 0; nskey--, tskeyp++) {
+				if ((ret = __dbc_put(sdbc,
+				    tskeyp, &key, DB_UPDATE_SECONDARY)) != 0)
+					goto err;
+				FREE_IF_NEEDED(env, tskeyp);
+			}
+			SWAP_IF_NEEDED(sdbp, &key);
+			FREE_IF_NEEDED(env, &skey);
+		}
+		if (ret == DB_NOTFOUND)
+			ret = 0;
+	}
+
+err:	if (sdbc != NULL && (t_ret = __dbc_close(sdbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (pdbc != NULL && (t_ret = __dbc_close(pdbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	dbp->associate_locker = NULL;
+
+	for (; nskey > 0; nskey--, tskeyp++)
+		FREE_IF_NEEDED(env, tskeyp);
+	FREE_IF_NEEDED(env, &skey);
+
+	return (ret);
+}
+
+/*
+ * __db_secondary_get --
+ *	This wrapper function for DB->pget() is the DB->get() function
+ *	on a database which has been made into a secondary index.
+ */
+static int
+__db_secondary_get(sdbp, txn, skey, data, flags)
+	DB *sdbp;
+	DB_TXN *txn;
+	DBT *skey, *data;
+	u_int32_t flags;
+{
+	DB_ASSERT(sdbp->env, F_ISSET(sdbp, DB_AM_SECONDARY));
+	return (__db_pget_pp(sdbp, txn, skey, NULL, data, flags));
+}
+
+/*
+ * __db_secondary_close --
+ *	Wrapper function for DB->close() which we use on secondaries to
+ *	manage refcounting and make sure we don't close them underneath
+ *	a primary that is updating.
+ *
+ * PUBLIC: int __db_secondary_close __P((DB *, u_int32_t));
+ */
+int
+__db_secondary_close(sdbp, flags)
+	DB *sdbp;
+	u_int32_t flags;
+{
+	DB *primary;
+	ENV *env;
+	int doclose;
+
+	/*
+	 * If the opening transaction is rolled back then the db handle
+	 * will have already been refreshed, we just need to call
+	 * __db_close to free the data.
+	 */
+	if (!F_ISSET(sdbp, DB_AM_OPEN_CALLED)) {
+		doclose = 1;
+		goto done;
+	}
+	doclose = 0;
+	primary = sdbp->s_primary;
+	env = primary->env;
+
+	MUTEX_LOCK(env, primary->mutex);
+	/*
+	 * Check the refcount--if it was at 1 when we were called, no
+	 * thread is currently updating this secondary through the primary,
+	 * so it's safe to close it for real.
+	 *
+	 * If it's not safe to do the close now, we do nothing;  the
+	 * database will actually be closed when the refcount is decremented,
+	 * which can happen in either __db_s_next or __db_s_done.
+	 */
+	DB_ASSERT(env, sdbp->s_refcnt != 0);
+	if (--sdbp->s_refcnt == 0) {
+		LIST_REMOVE(sdbp, s_links);
+		/* We don't want to call close while the mutex is held. */
+		doclose = 1;
+	}
+	MUTEX_UNLOCK(env, primary->mutex);
+
+	/*
+	 * sdbp->close is this function;  call the real one explicitly if
+	 * need be.
+	 */
+done:	return (doclose ? __db_close(sdbp, NULL, flags) : 0);
+}
+
+/*
+ * __db_associate_foreign --
+ *	Associate this database (fdbp) as a foreign constraint to another
+ *	database (pdbp).  That is, dbp's keys appear as foreign key values in
+ *	pdbp.
+ *
+ * PUBLIC: int __db_associate_foreign __P((DB *, DB *,
+ * PUBLIC:     int (*)(DB *, const DBT *, DBT *, const DBT *, int *),
+ * PUBLIC:     u_int32_t));
+ */
+int
+__db_associate_foreign(fdbp, pdbp, callback, flags)
+	DB *fdbp, *pdbp;
+	int (*callback)(DB *, const DBT *, DBT *, const DBT *, int *);
+	u_int32_t flags;
+{
+	DB_FOREIGN_INFO *f_info;
+	ENV *env;
+	int ret;
+
+	env = fdbp->env;
+	ret = 0;
+
+	if ((ret = __os_malloc(env, sizeof(DB_FOREIGN_INFO), &f_info)) != 0) {
+		return (ret);
+	}
+	memset(f_info, 0, sizeof(DB_FOREIGN_INFO));
+
+	f_info->dbp = pdbp;
+	f_info->callback = callback;
+
+	/*
+	 * It might be wise to filter this, but for now the flags only
+	 * set the delete action type.
+	 */
+	FLD_SET(f_info->flags, flags);
+
+	/*
+	 * Add f_info to the foreign database's list of primaries.  That is to
+	 * say, fdbp->f_primaries lists all databases for which fdbp is a
+	 * foreign constraint.
+	 */
+	MUTEX_LOCK(env, fdbp->mutex);
+	LIST_INSERT_HEAD(&fdbp->f_primaries, f_info, f_links);
+	MUTEX_UNLOCK(env, fdbp->mutex);
+
+	/*
+	* Associate fdbp as pdbp's foreign db, for referential integrity
+	* checks.  We don't allow the foreign db to be changed, because we
+	* currently have no way of removing pdbp from the old foreign db's list
+	* of primaries.
+	*/
+	if (pdbp->s_foreign != NULL)
+		return (EINVAL);
+	pdbp->s_foreign = fdbp;
+
+	return (ret);
+}
+
+static int
+__dbc_set_priority(dbc, priority)
+	DBC *dbc;
+	DB_CACHE_PRIORITY priority;
+{
+	dbc->priority = priority;
+	return (0);
+}
+
+static int
+__dbc_get_priority(dbc, priority)
+	DBC *dbc;
+	DB_CACHE_PRIORITY *priority;
+{
+	if (dbc->priority == DB_PRIORITY_UNCHANGED)
+		return (__memp_get_priority(dbc->dbp->mpf, priority));
+	else
+		*priority = dbc->priority;
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_backup.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,797 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2011, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/heap.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+
+#ifdef HAVE_QUEUE
+#include "dbinc/qam.h"
+#endif
+
+static void save_error __P((const DB_ENV *, const char *, const char *));
+static int backup_read_log_dir __P((DB_ENV *, const char *, int *, u_int32_t));
+static int backup_read_data_dir
+    __P((DB_ENV *, DB_THREAD_INFO *, const char *, const char *, u_int32_t));
+static int backup_dir_clean
+    __P((DB_ENV *, const char *, const char *, int *, u_int32_t));
+static int backup_data_copy
+    __P((DB_ENV *, const char *, const char *, const char *, int));
+
+/*
+ * __db_dbbackup_pp --
+ *	Copy a database file coordinated with mpool.
+ *
+ * PUBLIC: int __db_dbbackup_pp __P((DB_ENV *,
+ * PUBLIC:     const char *, const char *, u_int32_t));
+ */
+int
+__db_dbbackup_pp(dbenv, dbfile, target, flags)
+	DB_ENV *dbenv;
+	const char *dbfile, *target;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	int ret;
+
+	if ((ret = __db_fchk(dbenv->env,
+	    "DB_ENV->dbbackup", flags, DB_EXCL)) != 0)
+		return (ret);
+	ENV_ENTER(dbenv->env, ip);
+
+	ret = __db_dbbackup(dbenv, ip, dbfile, target, flags);
+
+	ENV_LEAVE(dbenv->env, ip);
+	return (ret);
+}
+
+/*
+ * __db_dbbackup --
+ *	Copy a database file coordinated with mpool.
+ *
+ * PUBLIC: int __db_dbbackup __P((DB_ENV *, DB_THREAD_INFO *,
+ * PUBLIC:     const char *, const char *, u_int32_t));
+ */
+int
+__db_dbbackup(dbenv, ip, dbfile, target, flags)
+	DB_ENV *dbenv;
+	DB_THREAD_INFO *ip;
+	const char *dbfile, *target;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DB_FH *fp;
+	void *handle;
+	int ret, retry_count, t_ret;
+
+	dbp = NULL;
+	retry_count = 0;
+
+retry:	if ((ret = __db_create_internal(&dbp, dbenv->env, 0)) == 0 &&
+	    (ret = __db_open(dbp, ip, NULL, dbfile, NULL,
+	    DB_UNKNOWN, DB_AUTO_COMMIT | DB_RDONLY, 0, PGNO_BASE_MD)) != 0) {
+		if (ret == DB_LOCK_DEADLOCK || ret == DB_LOCK_NOTGRANTED) {
+			(void)__db_close(dbp, NULL, DB_NOSYNC);
+			dbp = NULL;
+			if (++retry_count > 100)
+				return (ret);
+			__db_errx(dbenv->env, DB_STR_A("0702",
+		    "Deadlock while opening %s, retrying", "%s"), dbfile);
+			__os_yield(dbenv->env, 1, 0);
+			goto retry;
+		}
+	}
+
+	if (ret == 0) {
+		if ((ret = __memp_backup_open(dbenv->env,
+		    dbp->mpf, dbfile, target, flags, &fp, &handle)) == 0) {
+			if (dbp->type == DB_HEAP)
+				ret = __heap_backup(
+				    dbenv, dbp, ip, fp, handle, flags);
+			else
+				ret = __memp_backup_mpf(
+				    dbenv->env, dbp->mpf,
+				    ip, 0, dbp->mpf->mfp->last_pgno,
+				    fp, handle, flags);
+		}
+		if ((t_ret = __memp_backup_close(dbenv->env,
+		    dbp->mpf, dbfile, fp, handle)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+
+#ifdef HAVE_QUEUE
+	/*
+	 * For compatibility with the 5.2 and patch versions of db_copy
+	 * dump the queue extents here.
+	 */
+	if (ret == 0 && dbp->type == DB_QUEUE)
+		ret = __qam_backup_extents(dbp, ip, target, flags);
+#endif
+
+	if (dbp != NULL &&
+	    (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (ret != 0)
+		__db_err(dbenv->env, ret, "Backup Failed");
+	return (ret);
+}
+
+/*
+ * backup_dir_clean --
+ *	Clean out the backup directory.
+ */
+static int
+backup_dir_clean(dbenv, backup_dir, log_dir, remove_maxp, flags)
+	DB_ENV *dbenv;
+	const char *backup_dir, *log_dir;
+	int *remove_maxp;
+	u_int32_t flags;
+{
+	ENV *env;
+	int cnt, fcnt, ret, v;
+	const char *dir;
+	char **names, buf[DB_MAXPATHLEN], path[DB_MAXPATHLEN];
+
+	env = dbenv->env;
+
+	/* We may be cleaning a log directory separate from the target. */
+	if (log_dir != NULL) {
+		if ((ret = __os_concat_path(buf,
+		    sizeof(buf), backup_dir, log_dir)) != 0) {
+			buf[sizeof(buf) - 1] = '\0';
+			__db_errx(env,  DB_STR_A("0717",
+			    "%s: path too long", "%s"), buf);
+			return (EINVAL);
+		}
+		dir = buf;
+	} else
+		dir = backup_dir;
+
+	/* Get a list of file names. */
+	if ((ret = __os_dirlist(env, dir, 0, &names, &fcnt)) != 0) {
+		if (log_dir != NULL && !LF_ISSET(DB_BACKUP_UPDATE))
+			return (0);
+		__db_err(env,
+		    ret, DB_STR_A("0718", "%s: directory read", "%s"), dir);
+		return (ret);
+	}
+	for (cnt = fcnt; --cnt >= 0;) {
+		/*
+		 * Skip non-log files (if update was specified).
+		 */
+		if (!IS_LOG_FILE(names[cnt])) {
+			if (LF_ISSET(DB_BACKUP_UPDATE))
+				continue;
+		} else {
+			/* Track the highest-numbered log file removed. */
+			v = atoi(names[cnt] + sizeof(LFPREFIX) - 1);
+			if (*remove_maxp < v)
+				*remove_maxp = v;
+		}
+		if ((ret = __os_concat_path(path,
+		    sizeof(path), dir, names[cnt])) != 0) {
+			path[sizeof(path) - 1] = '\0';
+			__db_errx(env, DB_STR_A("0714",
+			    "%s: path too long", "%s"), path);
+			return (EINVAL);
+		}
+		if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP))
+			__db_msg(env, DB_STR_A("0715", "removing %s",
+			    "%s"),  path);
+		if ((ret = __os_unlink(env, path, 0)) != 0)
+			return (ret);
+	}
+
+	__os_dirfree(env, names, fcnt);
+
+	if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP) && *remove_maxp != 0)
+		__db_msg(env, DB_STR_A("0719",
+		    "highest numbered log file removed: %d", "%d"),
+		    *remove_maxp);
+
+	return (0);
+}
+
+/*
+ * backup_data_copy --
+ *	Copy a non-database file into the backup directory.
+ */
+static int
+backup_data_copy(dbenv, file, from_dir, to_dir, log)
+	DB_ENV *dbenv;
+	const char *file, *from_dir, *to_dir;
+	int log;
+{
+	DB_BACKUP *backup;
+	DB_FH *rfhp, *wfhp;
+	ENV *env;
+	u_int32_t gigs, off;
+	size_t nr, nw;
+	int ret, t_ret;
+	char *buf;
+	void *handle;
+	char from[DB_MAXPATHLEN], to[DB_MAXPATHLEN];
+
+	rfhp = wfhp = NULL;
+	handle = NULL;
+	buf = NULL;
+	env = dbenv->env;
+	backup = env->backup_handle;
+
+	if ((ret = __os_concat_path(from,
+	    sizeof(from), from_dir, file)) != 0) {
+		from[sizeof(from) - 1] = '\0';
+		__db_errx(env, DB_STR_A("0728",
+		     "%s: path too long", "%s"), from);
+		goto err;
+	}
+	if ((ret = __os_concat_path(to,
+	    sizeof(to), to_dir, file)) != 0) {
+		to[sizeof(to) - 1] = '\0';
+		__db_errx(env, DB_STR_A("0729",
+		     "%s: path too long", "%s"), to);
+		goto err;
+	}
+	if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP))
+		__db_msg(env, DB_STR_A("0726",
+		    "copying %s to %s", "%s %s"), from, to);
+
+	if ((ret = __os_malloc(env, MEGABYTE, &buf)) != 0) {
+		__db_err(env, ret, DB_STR_A("0727",
+		    "%lu buffer allocation", "%lu"), (u_long)MEGABYTE);
+		return (ret);
+	}
+
+	/* Open the input file. */
+	if ((ret = __os_open(env, from, 0, DB_OSO_RDONLY, 0, &rfhp)) != 0) {
+		if (ret == ENOENT && !log) {
+			ret = 0;
+			if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP))
+				__db_msg(env, DB_STR_A("0730",
+				    "%s%c%s not present", "%s %c %s"),
+				    from_dir, PATH_SEPARATOR[0], file);
+			goto done;
+		}
+		__db_err(env, ret, "%s", buf);
+		goto err;
+	}
+
+	/* Open the output file. */
+	if (backup != NULL && backup->open != NULL)
+		ret = backup->open(env->dbenv, file, to_dir, &handle);
+	else {
+		if ((ret = __os_open(env, to, 0,
+		    DB_OSO_CREATE | DB_OSO_TRUNC, DB_MODE_600, &wfhp)) != 0) {
+			__db_err(env, ret, "%s", to);
+			goto err;
+		}
+	}
+
+	off = 0;
+	gigs = 0;
+	/* Copy the data. */
+	while ((ret = __os_read(env, rfhp, buf, MEGABYTE, &nr)) == 0 &&
+	    nr > 0) {
+		if (backup != NULL && backup->write != NULL) {
+			if ((ret = backup->write(env->dbenv, gigs,
+			     off, (u_int32_t)nr, (u_int8_t *)buf, handle)) != 0)
+				break;
+		} else {
+			if ((ret = __os_write(env, wfhp, buf, nr, &nw)) != 0)
+				break;
+			if (nr != nw) {
+				ret = EIO;
+				break;
+			}
+		}
+		off += (u_int32_t)nr;
+		if (off >= GIGABYTE) {
+			gigs++;
+			off -= GIGABYTE;
+		}
+	}
+	if (ret != 0)
+		__db_err(env, ret, DB_STR("0748", "Write failed."));
+
+err:
+done:	if (buf != NULL)
+		__os_free(env, buf);
+
+	if (backup != NULL && backup->close != NULL &&
+	    (t_ret = backup->close(env->dbenv, file, handle)) != 0 && ret != 0)
+		ret = t_ret;
+	if (rfhp != NULL &&
+	    (t_ret = __os_closehandle(env, rfhp)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* We may be running on a remote filesystem; force the flush. */
+	if (ret == 0 && wfhp != NULL) {
+		ret = __os_fsync(env, wfhp);
+		if (ret != 0)
+			__db_err(env, ret, DB_STR("0731", "Sync failed"));
+	}
+	if (wfhp != NULL &&
+	    (t_ret = __os_closehandle(env, wfhp)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+static void save_error(dbenv, prefix, errstr)
+	const DB_ENV *dbenv;
+	const char *prefix;
+	const char *errstr;
+{
+	COMPQUIET(prefix, NULL);
+	if (DB_GLOBAL(saved_errstr) != NULL)
+		__os_free(dbenv->env, DB_GLOBAL(saved_errstr));
+	(void)__os_strdup(dbenv->env, errstr, &DB_GLOBAL(saved_errstr));
+}
+
+/*
+ * backup_read_data_dir --
+ *	Read a directory looking for databases to copy.
+ */
+static int
+backup_read_data_dir(dbenv, ip, dir, backup_dir, flags)
+	DB_ENV *dbenv;
+	DB_THREAD_INFO *ip;
+	const char *dir, *backup_dir;
+	u_int32_t flags;
+{
+	DB_MSGBUF mb;
+	ENV *env;
+	FILE *savefile;
+	int fcnt, ret;
+	size_t cnt;
+	const char *bd;
+	char **names, buf[DB_MAXPATHLEN], bbuf[DB_MAXPATHLEN];
+	void (*savecall) (const DB_ENV *, const char *, const char *);
+
+	env = dbenv->env;
+	memset(bbuf, 0, sizeof(bbuf));
+
+	bd = backup_dir;
+	if (!LF_ISSET(DB_BACKUP_SINGLE_DIR) && dir != env->db_home) {
+		cnt = sizeof(bbuf);
+		/* Build a path name to the destination. */
+		if ((ret = __os_concat_path(bbuf, sizeof(bbuf),
+		    backup_dir, dir)) != 0 ||
+		    (((cnt = strlen(bbuf)) == sizeof(bbuf) ||
+		    (cnt == sizeof(bbuf) - 1 &&
+		    strchr(PATH_SEPARATOR, bbuf[cnt - 1]) == NULL)) &&
+		    LF_ISSET(DB_CREATE))) {
+			bbuf[sizeof(bbuf) - 1] = '\0';
+			__db_errx(env, DB_STR_A("0720",
+			    "%s: path too long", "%s"), bbuf);
+			return (1);
+		}
+
+		/* Create the path. */
+		if (LF_ISSET(DB_CREATE)) {
+			if (strchr(PATH_SEPARATOR, bbuf[cnt - 1]) == NULL)
+				bbuf[cnt] = PATH_SEPARATOR[0];
+
+			if ((ret = __db_mkpath(env, bbuf)) != 0) {
+				__db_err(env,  ret, DB_STR_A("0721",
+				    "%s: cannot create", "%s"), bbuf);
+				return (ret);
+			}
+			/* step on the trailing '/' */
+			bbuf[cnt] = '\0';
+		}
+		bd = bbuf;
+
+	}
+	if (!__os_abspath(dir) && dir != env->db_home) {
+		/* Build a path name to the source. */
+		if ((ret = __os_concat_path(buf,
+		    sizeof(buf), env->db_home, dir)) != 0) {
+			buf[sizeof(buf) - 1] = '\0';
+			__db_errx(env, DB_STR_A("0722",
+			    "%s: path too long", "%s"), buf);
+			return (EINVAL);
+		}
+		dir = buf;
+	}
+	/* Get a list of file names. */
+	if ((ret = __os_dirlist(env, dir, 0, &names, &fcnt)) != 0) {
+		__db_err(env, ret, DB_STR_A("0723", "%s: directory read",
+		    "%s"), dir);
+		return (ret);
+	}
+	for (cnt = (size_t)fcnt; cnt-- > 0;) {
+		/*
+		 * Skip files in DB's name space, except replication dbs.
+		 */
+		if (IS_LOG_FILE(names[cnt]))
+			continue;
+		if (IS_DB_FILE(names[cnt]) && !IS_REP_FILE(names[cnt])
+#ifdef HAVE_PARTITION
+		    && !IS_PARTITION_DB_FILE(names[cnt])
+#endif
+		)
+			continue;
+
+		/*
+		 * Skip DB_CONFIG.
+		 */
+		if (LF_ISSET(DB_BACKUP_SINGLE_DIR) &&
+		     !strncmp(names[cnt], "DB_CONFIG", sizeof("DB_CONFIG")))
+			continue;
+
+		/*
+		 * Copy the database.
+		 */
+
+		DB_MSGBUF_INIT(&mb);
+		if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP))
+			__db_msgadd(env, &mb, DB_STR_A("0724",
+			    "copying database %s%c%s to %s%c%s",
+			    "%s%c%s %s%c%s"),
+			    dir, PATH_SEPARATOR[0], names[cnt],
+			    bd, PATH_SEPARATOR[0], names[cnt]);
+
+		/*
+		 * Suppress errors on non-db files.
+		 */
+		savecall = dbenv->db_errcall;
+		dbenv->db_errcall = save_error;
+		savefile = dbenv->db_errfile;
+		dbenv->db_errfile = NULL;
+
+		ret = __db_dbbackup(dbenv, ip, names[cnt], bd, flags);
+
+		dbenv->db_errcall = savecall;
+		dbenv->db_errfile = savefile;
+
+		/* The file might not be a database. */
+		if (ret == ENOENT || ret == EINVAL) {
+			if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP)) {
+				__db_msgadd(env, &mb, " -- Not a database");
+				DB_MSGBUF_FLUSH(env, &mb);
+			}
+			if (LF_ISSET(DB_BACKUP_FILES))
+				ret = backup_data_copy(
+				    dbenv, names[cnt], dir, bd, 0);
+			else
+				ret = 0;
+		} else if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP))
+			DB_MSGBUF_FLUSH(env, &mb);
+
+		if (ret != 0) {
+			if (DB_GLOBAL(saved_errstr) != NULL) {
+				__db_errx(env, "%s", DB_GLOBAL(saved_errstr));
+				__os_free(env, DB_GLOBAL(saved_errstr));
+				DB_GLOBAL(saved_errstr) = NULL;
+			}
+			break;
+		}
+	}
+
+	__os_dirfree(env, names, fcnt);
+
+	return (ret);
+}
+
+/*
+ * backup_read_log_dir --
+ *	Read a directory looking for log files to copy.
+ */
+static int
+backup_read_log_dir(dbenv, backup_dir, copy_minp, flags)
+	DB_ENV *dbenv;
+	const char *backup_dir;
+	int *copy_minp;
+	u_int32_t flags;
+{
+	ENV *env;
+	u_int32_t aflag;
+	size_t cnt;
+	int ret, update, v;
+	const char *backupd;
+	char **begin, **names, *logd;
+	char from[DB_MAXPATHLEN], to[DB_MAXPATHLEN];
+
+	env = dbenv->env;
+	ret = 0;
+	begin = NULL;
+	memset(to, 0, sizeof(to));
+
+	/*
+	 * Figure out where the log files are and create the log
+	 * destination directory if necessary.
+	 */
+	backupd = backup_dir;
+	if ((logd = dbenv->db_log_dir) == NULL)
+		logd = env->db_home;
+	else {
+		if (!LF_ISSET(DB_BACKUP_SINGLE_DIR)) {
+			cnt = sizeof(to);
+			if ((ret = __os_concat_path(to,
+			    sizeof(to), backup_dir, logd)) != 0 ||
+			    (((cnt = strlen(to)) == sizeof(to) ||
+			    (cnt == sizeof(to) - 1 &&
+			    strchr(PATH_SEPARATOR, to[cnt - 1]) == NULL)) &&
+			    LF_ISSET(DB_CREATE))) {
+				to[sizeof(to) - 1] = '\0';
+				__db_errx(env, DB_STR_A("0733",
+				    "%s: path too long", "%s"), to);
+				goto err;
+			}
+			if (LF_ISSET(DB_CREATE)) {
+				if (strchr(PATH_SEPARATOR, to[cnt - 1]) == NULL)
+					to[cnt] = PATH_SEPARATOR[0];
+
+				if ((ret = __db_mkpath(env, to)) != 0) {
+					__db_err(env, ret, DB_STR_A("0734",
+					    "%s: cannot create", "%s"), to);
+					goto err;
+				}
+				to[cnt] = '\0';
+			}
+			if ((ret = __os_strdup(env, to, (void*) &backupd)) != 0)
+				goto err;
+		}
+		if (!__os_abspath(logd)) {
+			if ((ret = __os_concat_path(from,
+			    sizeof(from), env->db_home, logd)) != 0) {
+				from[sizeof(from) - 1] = '\0';
+				__db_errx(env, DB_STR_A("0732",
+				    "%s: path too long", "%s"), from);
+				goto err;
+			}
+			if ((ret = __os_strdup(env, from, &logd)) != 0)
+				goto err;
+		}
+	}
+
+	update = LF_ISSET(DB_BACKUP_UPDATE);
+again:	aflag = DB_ARCH_LOG;
+
+	/*
+	 * If this is an update and we are deleting files, first process
+	 * those files that can be removed, then repeat with the rest.
+	 */
+	if (update)
+		aflag = 0;
+
+	/* Flush the log to get latest info. */
+	if ((ret = __log_flush(env, NULL)) != 0) {
+		__db_err(env, ret, DB_STR("0735", "Can't flush log"));
+		goto err;
+	}
+
+	/* Get a list of file names to be copied. */
+	if ((ret = __log_archive(env, &names, aflag)) != 0) {
+		__db_err(env, ret, DB_STR("0736", "Can't get log file names"));
+		goto err;
+	}
+	if (names == NULL)
+		goto done;
+	begin = names;
+	for (; *names != NULL; names++) {
+		/* Track the lowest-numbered log file copied. */
+		v = atoi(*names + sizeof(LFPREFIX) - 1);
+		if (*copy_minp == 0 || *copy_minp > v)
+			*copy_minp = v;
+
+		if ((ret = __os_concat_path(from,
+		    sizeof(from), env->db_home, *names)) != 0) {
+			from[sizeof(from) - 1] = '\0';
+			__db_errx(env, DB_STR_A("0737",
+			    "%s: path too long", "%s"), from);
+			goto err;
+		}
+
+		/*
+		 * If we're going to remove the file, attempt to rename it
+		 * instead of copying and then removing.  The likely failure
+		 * is EXDEV (source and destination are on different volumes).
+		 * Fall back to a copy, regardless of the error.  We don't
+		 * worry about partial contents, the copy truncates the file
+		 * on open.
+		 */
+		if (update) {
+			if ((ret = __os_concat_path(to,
+			    sizeof(to), backupd, *names)) != 0) {
+				to[sizeof(to) - 1] = '\0';
+				__db_errx(env, DB_STR_A("0738",
+				    "%s: path too long", "%s"), to);
+				goto err;
+			}
+			if (__os_rename(env, from, to, 1) == 0) {
+				if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP))
+					__db_msg(env, DB_STR_A("0739",
+					    "moving %s to %s",
+					    "%s %s"), from, to);
+				continue;
+			}
+		}
+
+		/* Copy the file. */
+		if (backup_data_copy(dbenv, *names, logd, backupd, 1) != 0) {
+			ret = 1;
+			goto err;
+		}
+
+		if (update) {
+			if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP))
+				__db_msg(env, DB_STR_A("0740",
+				    "removing %s", "%s"), from);
+			if ((ret = __os_unlink(env, from, 0)) != 0) {
+				__db_err(env, ret, DB_STR_A("0741",
+				    "unlink of %s failed", "%s"), from);
+				goto err;
+			}
+		}
+
+	}
+
+	__os_ufree(env, begin);
+	begin = NULL;
+done:	if (update) {
+		update = 0;
+		goto again;
+	}
+
+	if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP) && *copy_minp != 0)
+		__db_msg(env, DB_STR_A("0742",
+		    "lowest numbered log file copied: %d", "%d"),
+		    *copy_minp);
+err:	if (logd != dbenv->db_log_dir && logd != env->db_home)
+		__os_free(env, logd);
+	if (backupd != NULL && backupd != backup_dir)
+		__os_free(env, (void *)backupd);
+	if (begin != NULL)
+		__os_free(env, begin);
+
+	return (ret);
+}
+
+/*
+ * __db_backup --
+ *	Backup databases in the enviornment.
+ *
+ * PUBLIC: int __db_backup __P((DB_ENV *, const char *, u_int32_t));
+ */
+int
+__db_backup(dbenv, target, flags)
+	DB_ENV *dbenv;
+	const char *target;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int copy_min, remove_max, ret;
+	char **dir;
+
+	env = dbenv->env;
+	remove_max = copy_min = 0;
+
+#undef	OKFLAGS
+#define	OKFLAGS								\
+	(DB_CREATE | DB_EXCL | DB_BACKUP_FILES | DB_BACKUP_SINGLE_DIR |	\
+	DB_BACKUP_UPDATE | DB_BACKUP_NO_LOGS | DB_BACKUP_CLEAN)
+
+	if ((ret = __db_fchk(env, "DB_ENV->backup", flags, OKFLAGS)) != 0)
+		return (ret);
+
+	if (target == NULL) {
+		__db_errx(env,
+		    DB_STR("0716", "Target directory may not be null."));
+		return (EINVAL);
+	}
+
+	/*
+	 * If the target directory for the backup does not exist, create it
+	 * with mode read-write-execute for the owner.  Ignore errors here,
+	 * it's simpler and more portable to just always try the create.  If
+	 * there's a problem, we'll fail with reasonable errors later.
+	 */
+	if (LF_ISSET(DB_CREATE))
+		(void)__os_mkdir(NULL, target, DB_MODE_700);
+
+	if (LF_ISSET(DB_BACKUP_CLEAN)) {
+		if (!LF_ISSET(DB_BACKUP_SINGLE_DIR) &&
+		    dbenv->db_log_dir != NULL &&
+		    (ret = backup_dir_clean(dbenv, target,
+		    dbenv->db_log_dir, &remove_max, flags)) != 0)
+			return (ret);
+		if ((ret = backup_dir_clean(dbenv,
+		    target, NULL, &remove_max, flags)) != 0)
+			return (ret);
+
+	}
+
+	ENV_ENTER(env, ip);
+
+	/*
+	 * If the UPDATE option was not specified, copy all database
+	 * files found in the database environment home directory and
+	 * data directories..
+	 */
+	if ((ret = __env_set_backup(env, 1)) != 0)
+		goto end;
+	F_SET(dbenv, DB_ENV_HOTBACKUP);
+	if (!LF_ISSET(DB_BACKUP_UPDATE)) {
+		if ((ret = backup_read_data_dir(dbenv,
+		    ip, env->db_home, target, flags)) != 0)
+			goto err;
+		for (dir = dbenv->db_data_dir;
+		    dir != NULL && *dir != NULL; ++dir) {
+			/*
+			 * Don't allow absolute path names taken from the
+			 * enviroment  -- running recovery with them would
+			 * corrupt the source files.
+			 */
+			if (!LF_ISSET(DB_BACKUP_SINGLE_DIR)
+			   && __os_abspath(*dir)) {
+				__db_errx(env, DB_STR_A("0725",
+"data directory '%s' is absolute path, not permitted unless backup is to a single directory",
+				    "%s"), *dir);
+				ret = EINVAL;
+				goto err;
+			}
+			if ((ret = backup_read_data_dir(
+			    dbenv, ip, *dir, target, flags)) != 0)
+				goto err;
+		}
+	}
+
+	/*
+	 * Copy all log files found in the log directory.
+	 * The log directory defaults to the home directory.
+	 */
+	if ((ret = backup_read_log_dir(dbenv, target, &copy_min, flags)) != 0)
+		goto err;
+	/*
+	 * If we're updating a snapshot, the lowest-numbered log file copied
+	 * into the backup directory should be less than, or equal to, the
+	 * highest-numbered log file removed from the backup directory during
+	 * cleanup.
+	 */
+	if (LF_ISSET(DB_BACKUP_UPDATE) && remove_max < copy_min &&
+	     !(remove_max == 0 && copy_min == 1)) {
+		__db_errx(env, DB_STR_A("0743",
+"the largest log file removed (%d) must be greater than or equal the smallest log file copied (%d)",
+		    "%d %d"), remove_max, copy_min);
+		ret = EINVAL;
+	}
+
+err:	F_CLR(dbenv, DB_ENV_HOTBACKUP);
+	(void)__env_set_backup(env, 0);
+end:	ENV_LEAVE(env, ip);
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_cam.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,3545 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2000, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+#include "dbinc/qam.h"
+#include "dbinc/txn.h"
+
+static int __db_s_count __P((DB *));
+static int __db_wrlock_err __P((ENV *));
+static int __dbc_del_foreign __P((DBC *));
+static int __dbc_del_oldskey __P((DB *, DBC *, DBT *, DBT *, DBT *));
+static int __dbc_del_secondary __P((DBC *));
+static int __dbc_pget_recno __P((DBC *, DBT *, DBT *, u_int32_t));
+static inline int __dbc_put_append __P((DBC *,
+		DBT *, DBT *, u_int32_t *, u_int32_t));
+static inline int __dbc_put_fixed_len __P((DBC *, DBT *, DBT *));
+static inline int __dbc_put_partial __P((DBC *,
+		DBT *, DBT *, DBT *, DBT *, u_int32_t *, u_int32_t));
+static int __dbc_put_primary __P((DBC *, DBT *, DBT *, u_int32_t));
+static inline int __dbc_put_resolve_key __P((DBC *,
+		DBT *, DBT *, u_int32_t *, u_int32_t));
+static inline int __dbc_put_secondaries __P((DBC *,
+		DBT *, DBT *, DBT *, int, DBT *, u_int32_t *));
+
+#define	CDB_LOCKING_INIT(env, dbc)					\
+	/*								\
+	 * If we are running CDB, this had better be either a write	\
+	 * cursor or an immediate writer.  If it's a regular writer,	\
+	 * that means we have an IWRITE lock and we need to upgrade	\
+	 * it to a write lock.						\
+	 */								\
+	if (CDB_LOCKING(env)) {						\
+		if (!F_ISSET(dbc, DBC_WRITECURSOR | DBC_WRITER))	\
+			return (__db_wrlock_err(env));			\
+									\
+		if (F_ISSET(dbc, DBC_WRITECURSOR) &&			\
+		    (ret = __lock_get(env,				\
+		    (dbc)->locker, DB_LOCK_UPGRADE, &(dbc)->lock_dbt,	\
+		    DB_LOCK_WRITE, &(dbc)->mylock)) != 0)		\
+			return (ret);					\
+	}
+#define	CDB_LOCKING_DONE(env, dbc)					\
+	/* Release the upgraded lock. */				\
+	if (F_ISSET(dbc, DBC_WRITECURSOR))				\
+		(void)__lock_downgrade(					\
+		    env, &(dbc)->mylock, DB_LOCK_IWRITE, 0);
+
+#define	SET_READ_LOCKING_FLAGS(dbc, var) do {				\
+	var = 0;							\
+	if (!F_ISSET(dbc, DBC_READ_COMMITTED | DBC_READ_UNCOMMITTED)) {	\
+		if (LF_ISSET(DB_READ_COMMITTED))			\
+			var = DBC_READ_COMMITTED | DBC_WAS_READ_COMMITTED; \
+		if (LF_ISSET(DB_READ_UNCOMMITTED))			\
+			var = DBC_READ_UNCOMMITTED;			\
+	}								\
+	LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED);		\
+} while (0)
+
+/*
+ * __dbc_close --
+ *	DBC->close.
+ *
+ * PUBLIC: int __dbc_close __P((DBC *));
+ */
+int
+__dbc_close(dbc)
+	DBC *dbc;
+{
+	DB *dbp;
+	DBC *opd;
+	DBC_INTERNAL *cp;
+	DB_TXN *txn;
+	ENV *env;
+	int ret, t_ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	cp = dbc->internal;
+	opd = cp->opd;
+	ret = 0;
+
+	/*
+	 * Remove the cursor(s) from the active queue.  We may be closing two
+	 * cursors at once here, a top-level one and a lower-level, off-page
+	 * duplicate one.  The access-method specific cursor close routine must
+	 * close both of them in a single call.
+	 *
+	 * !!!
+	 * Cursors must be removed from the active queue before calling the
+	 * access specific cursor close routine, btree depends on having that
+	 * order of operations.
+	 */
+	MUTEX_LOCK(env, dbp->mutex);
+
+	if (opd != NULL) {
+		DB_ASSERT(env, F_ISSET(opd, DBC_ACTIVE));
+		F_CLR(opd, DBC_ACTIVE);
+		TAILQ_REMOVE(&dbp->active_queue, opd, links);
+	}
+	DB_ASSERT(env, F_ISSET(dbc, DBC_ACTIVE));
+	F_CLR(dbc, DBC_ACTIVE);
+	TAILQ_REMOVE(&dbp->active_queue, dbc, links);
+
+	MUTEX_UNLOCK(env, dbp->mutex);
+
+	/* Call the access specific cursor close routine. */
+	if ((t_ret =
+	    dbc->am_close(dbc, PGNO_INVALID, NULL)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * Release the lock after calling the access method specific close
+	 * routine, a Btree cursor may have had pending deletes.
+	 *
+	 * Also, be sure not to free anything if mylock.off is INVALID;  in
+	 * some cases, such as idup'ed read cursors and secondary update
+	 * cursors, a cursor in a CDB environment may not have a lock at all.
+	 */
+	if (LOCK_ISSET(dbc->mylock)) {
+		if ((t_ret = __LPUT(dbc, dbc->mylock)) != 0 && ret == 0)
+			ret = t_ret;
+
+		/* For safety's sake, since this is going on the free queue. */
+		memset(&dbc->mylock, 0, sizeof(dbc->mylock));
+		if (opd != NULL)
+			memset(&opd->mylock, 0, sizeof(opd->mylock));
+	}
+
+	/*
+	 * Remove this cursor's locker ID from its family.
+	 */
+	if (F_ISSET(dbc, DBC_OWN_LID) && F_ISSET(dbc, DBC_FAMILY)) {
+		if ((t_ret = __lock_familyremove(env->lk_handle,
+		    dbc->lref)) != 0 && ret == 0)
+			ret = t_ret;
+		F_CLR(dbc, DBC_FAMILY);
+	}
+
+	if ((txn = dbc->txn) != NULL)
+		txn->cursors--;
+
+	/* Move the cursor(s) to the free queue. */
+	MUTEX_LOCK(env, dbp->mutex);
+	if (opd != NULL) {
+		if (txn != NULL)
+			txn->cursors--;
+		TAILQ_INSERT_TAIL(&dbp->free_queue, opd, links);
+	}
+	TAILQ_INSERT_TAIL(&dbp->free_queue, dbc, links);
+	MUTEX_UNLOCK(env, dbp->mutex);
+
+	if (txn != NULL && F_ISSET(txn, TXN_PRIVATE) && txn->cursors == 0 &&
+	    (t_ret = __txn_commit(txn, 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __dbc_destroy --
+ *	Destroy the cursor, called after DBC->close.
+ *
+ * PUBLIC: int __dbc_destroy __P((DBC *));
+ */
+int
+__dbc_destroy(dbc)
+	DBC *dbc;
+{
+	DB *dbp;
+	ENV *env;
+	int ret, t_ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	/* Remove the cursor from the free queue. */
+	MUTEX_LOCK(env, dbp->mutex);
+	TAILQ_REMOVE(&dbp->free_queue, dbc, links);
+	MUTEX_UNLOCK(env, dbp->mutex);
+
+	/* Free up allocated memory. */
+	if (dbc->my_rskey.data != NULL)
+		__os_free(env, dbc->my_rskey.data);
+	if (dbc->my_rkey.data != NULL)
+		__os_free(env, dbc->my_rkey.data);
+	if (dbc->my_rdata.data != NULL)
+		__os_free(env, dbc->my_rdata.data);
+
+	/* Call the access specific cursor destroy routine. */
+	ret = dbc->am_destroy == NULL ? 0 : dbc->am_destroy(dbc);
+
+	/*
+	 * Release the lock id for this cursor.
+	 */
+	if (LOCKING_ON(env) &&
+	    F_ISSET(dbc, DBC_OWN_LID) &&
+	    (t_ret = __lock_id_free(env, dbc->lref)) != 0 && ret == 0)
+		ret = t_ret;
+
+	__os_free(env, dbc);
+
+	return (ret);
+}
+
+/*
+ * __dbc_cmp --
+ *	Compare the position of two cursors. Return whether two cursors are
+ *	pointing to the same key/data pair.
+ *
+ * result == 0  if both cursors refer to the same item.
+ * result == 1  otherwise
+ *
+ * PUBLIC: int __dbc_cmp __P((DBC *, DBC *, int *));
+ */
+int
+__dbc_cmp(dbc, other_dbc, result)
+	DBC *dbc, *other_dbc;
+	int *result;
+{
+	DBC *curr_dbc, *curr_odbc;
+	DBC_INTERNAL *dbc_int, *odbc_int;
+	ENV *env;
+	int ret;
+
+	env = dbc->env;
+	ret = 0;
+
+#ifdef HAVE_PARTITION
+	if (DB_IS_PARTITIONED(dbc->dbp)) {
+		dbc = ((PART_CURSOR *)dbc->internal)->sub_cursor;
+		other_dbc = ((PART_CURSOR *)other_dbc->internal)->sub_cursor;
+	}
+	/* Both cursors must still be valid. */
+	if (dbc == NULL || other_dbc == NULL) {
+		__db_errx(env, DB_STR("0692",
+"Both cursors must be initialized before calling DBC->cmp."));
+		return (EINVAL);
+	}
+
+	if (dbc->dbp != other_dbc->dbp) {
+		*result = 1;
+		return (0);
+	}
+#endif
+
+#ifdef HAVE_COMPRESSION
+	if (DB_IS_COMPRESSED(dbc->dbp))
+		return (__bamc_compress_cmp(dbc, other_dbc, result));
+#endif
+
+	curr_dbc = dbc;
+	curr_odbc = other_dbc;
+	dbc_int = dbc->internal;
+	odbc_int = other_dbc->internal;
+
+	/* Both cursors must be on valid positions. */
+	if (dbc_int->pgno == PGNO_INVALID || odbc_int->pgno == PGNO_INVALID) {
+		__db_errx(env, DB_STR("0693",
+"Both cursors must be initialized before calling DBC->cmp."));
+		return (EINVAL);
+	}
+
+	/*
+	 * Use a loop since cursors can be nested. Off page duplicate
+	 * sets can only be nested one level deep, so it is safe to use a
+	 * while (true) loop.
+	 */
+	while (1) {
+		if (dbc_int->pgno == odbc_int->pgno &&
+		    dbc_int->indx == odbc_int->indx) {
+			/*
+			 * If one cursor is sitting on an off page duplicate
+			 * set, the other will be pointing to the same set. Be
+			 * careful, and check  anyway.
+			 */
+			if (dbc_int->opd != NULL && odbc_int->opd != NULL) {
+				curr_dbc = dbc_int->opd;
+				curr_odbc = odbc_int->opd;
+				dbc_int = dbc_int->opd->internal;
+				odbc_int= odbc_int->opd->internal;
+				continue;
+			} else if (dbc_int->opd == NULL &&
+			    odbc_int->opd == NULL)
+				*result = 0;
+			else {
+				__db_errx(env, DB_STR("0694",
+	    "DBCursor->cmp mismatched off page duplicate cursor pointers."));
+				return (EINVAL);
+			}
+
+			switch (curr_dbc->dbtype) {
+			case DB_HASH:
+				/*
+				 * Make sure that on-page duplicate data
+				 * indexes match, and that the deleted
+				 * flags are consistent.
+				 */
+				ret = __hamc_cmp(curr_dbc, curr_odbc, result);
+				break;
+			case DB_BTREE:
+			case DB_RECNO:
+				/*
+				 * Check for consisted deleted flags on btree
+				 * specific cursors.
+				 */
+				ret = __bamc_cmp(curr_dbc, curr_odbc, result);
+				break;
+			default:
+				/* NO-OP break out. */
+				break;
+			}
+		} else
+			*result = 1;
+		return (ret);
+	}
+	/* NOTREACHED. */
+	return (ret);
+}
+
+/*
+ * __dbc_count --
+ *	Return a count of duplicate data items.
+ *
+ * PUBLIC: int __dbc_count __P((DBC *, db_recno_t *));
+ */
+int
+__dbc_count(dbc, recnop)
+	DBC *dbc;
+	db_recno_t *recnop;
+{
+	ENV *env;
+	int ret;
+
+	env = dbc->env;
+
+#ifdef HAVE_PARTITION
+	if (DB_IS_PARTITIONED(dbc->dbp))
+		dbc = ((PART_CURSOR *)dbc->internal)->sub_cursor;
+#endif
+	/*
+	 * Cursor Cleanup Note:
+	 * All of the cursors passed to the underlying access methods by this
+	 * routine are not duplicated and will not be cleaned up on return.
+	 * So, pages/locks that the cursor references must be resolved by the
+	 * underlying functions.
+	 */
+	switch (dbc->dbtype) {
+	case DB_HEAP:
+	case DB_QUEUE:
+	case DB_RECNO:
+		*recnop = 1;
+		break;
+	case DB_HASH:
+		if (dbc->internal->opd == NULL) {
+			if ((ret = __hamc_count(dbc, recnop)) != 0)
+				return (ret);
+			break;
+		}
+		/* FALLTHROUGH */
+	case DB_BTREE:
+#ifdef HAVE_COMPRESSION
+		if (DB_IS_COMPRESSED(dbc->dbp))
+			return (__bamc_compress_count(dbc, recnop));
+#endif
+		if ((ret = __bamc_count(dbc, recnop)) != 0)
+			return (ret);
+		break;
+	case DB_UNKNOWN:
+	default:
+		return (__db_unknown_type(env, "__dbc_count", dbc->dbtype));
+	}
+	return (0);
+}
+
+/*
+ * __dbc_del --
+ *	DBC->del.
+ *
+ * PUBLIC: int __dbc_del __P((DBC *, u_int32_t));
+ */
+int
+__dbc_del(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	DB *dbp;
+	ENV *env;
+	int ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	CDB_LOCKING_INIT(env, dbc);
+	F_CLR(dbc, DBC_ERROR);
+
+	/*
+	 * If we're a secondary index, and DB_UPDATE_SECONDARY isn't set
+	 * (which it only is if we're being called from a primary update),
+	 * then we need to call through to the primary and delete the item.
+	 *
+	 * Note that this will delete the current item;  we don't need to
+	 * delete it ourselves as well, so we can just goto done.
+	 */
+	if (flags != DB_UPDATE_SECONDARY && F_ISSET(dbp, DB_AM_SECONDARY)) {
+		ret = __dbc_del_secondary(dbc);
+		goto done;
+	}
+
+	/*
+	 * If we are a foreign db, go through and check any foreign key
+	 * constraints first, which will make rolling back changes on an abort
+	 * simpler.
+	 */
+	if (LIST_FIRST(&dbp->f_primaries) != NULL &&
+	    (ret = __dbc_del_foreign(dbc)) != 0)
+		goto done;
+
+	/*
+	 * If we are a primary and have secondary indices, go through
+	 * and delete any secondary keys that point at the current record.
+	 */
+	if (DB_IS_PRIMARY(dbp) &&
+	    (ret = __dbc_del_primary(dbc)) != 0)
+		goto done;
+
+#ifdef HAVE_COMPRESSION
+	if (DB_IS_COMPRESSED(dbp))
+		ret = __bamc_compress_del(dbc, flags);
+	else
+#endif
+		ret = __dbc_idel(dbc, flags);
+
+done:	CDB_LOCKING_DONE(env, dbc);
+
+	if (!DB_RETOK_DBCDEL(ret))
+		F_SET(dbc, DBC_ERROR);
+	return (ret);
+}
+
+/*
+ * __dbc_del --
+ *	Implemenation of DBC->del.
+ *
+ * PUBLIC: int __dbc_idel __P((DBC *, u_int32_t));
+ */
+int
+__dbc_idel(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DBC *opd;
+	int ret, t_ret;
+
+	COMPQUIET(flags, 0);
+
+	dbp = dbc->dbp;
+
+	/*
+	 * Cursor Cleanup Note:
+	 * All of the cursors passed to the underlying access methods by this
+	 * routine are not duplicated and will not be cleaned up on return.
+	 * So, pages/locks that the cursor references must be resolved by the
+	 * underlying functions.
+	 */
+
+	/*
+	 * Off-page duplicate trees are locked in the primary tree, that is,
+	 * we acquire a write lock in the primary tree and no locks in the
+	 * off-page dup tree.  If the del operation is done in an off-page
+	 * duplicate tree, call the primary cursor's upgrade routine first.
+	 */
+	opd = dbc->internal->opd;
+	if (opd == NULL)
+		ret = dbc->am_del(dbc, flags);
+	else if ((ret = dbc->am_writelock(dbc)) == 0)
+		ret = opd->am_del(opd, flags);
+
+	/*
+	 * If this was an update that is supporting dirty reads
+	 * then we may have just swapped our read for a write lock
+	 * which is held by the surviving cursor.  We need
+	 * to explicitly downgrade this lock.  The closed cursor
+	 * may only have had a read lock.
+	 */
+	if (ret == 0 && F_ISSET(dbp, DB_AM_READ_UNCOMMITTED) &&
+	    dbc->internal->lock_mode == DB_LOCK_WRITE) {
+		if ((ret = __TLPUT(dbc, dbc->internal->lock)) == 0)
+			dbc->internal->lock_mode = DB_LOCK_WWRITE;
+		if (dbc->internal->page != NULL && (t_ret =
+		    __memp_shared(dbp->mpf, dbc->internal->page)) != 0 &&
+		    ret == 0)
+			ret = t_ret;
+	}
+
+	return (ret);
+}
+
+#ifdef HAVE_COMPRESSION
+/*
+ * __dbc_bulk_del --
+ *	Bulk del for a cursor.
+ *
+ *	Only implemented for compressed BTrees. In this file in order to
+ *	use the CDB_LOCKING_* macros.
+ *
+ * PUBLIC: #ifdef HAVE_COMPRESSION
+ * PUBLIC: int __dbc_bulk_del __P((DBC *, DBT *, u_int32_t));
+ * PUBLIC: #endif
+ */
+int
+__dbc_bulk_del(dbc, key, flags)
+	DBC *dbc;
+	DBT *key;
+	u_int32_t flags;
+{
+	ENV *env;
+	int ret;
+
+	env = dbc->env;
+
+	DB_ASSERT(env, DB_IS_COMPRESSED(dbc->dbp));
+
+	CDB_LOCKING_INIT(env, dbc);
+	F_CLR(dbc, DBC_ERROR);
+
+	ret = __bamc_compress_bulk_del(dbc, key, flags);
+
+	CDB_LOCKING_DONE(env, dbc);
+
+	return (ret);
+}
+#endif
+
+/*
+ * __dbc_dup --
+ *	Duplicate a cursor
+ *
+ * PUBLIC: int __dbc_dup __P((DBC *, DBC **, u_int32_t));
+ */
+int
+__dbc_dup(dbc_orig, dbcp, flags)
+	DBC *dbc_orig;
+	DBC **dbcp;
+	u_int32_t flags;
+{
+	DBC *dbc_n, *dbc_nopd;
+	int ret;
+
+	dbc_n = dbc_nopd = NULL;
+
+	/* Allocate a new cursor and initialize it. */
+	if ((ret = __dbc_idup(dbc_orig, &dbc_n, flags)) != 0)
+		goto err;
+	*dbcp = dbc_n;
+
+	/*
+	 * If the cursor references an off-page duplicate tree, allocate a
+	 * new cursor for that tree and initialize it.
+	 */
+	if (dbc_orig->internal->opd != NULL) {
+		if ((ret =
+		   __dbc_idup(dbc_orig->internal->opd, &dbc_nopd, flags)) != 0)
+			goto err;
+		dbc_n->internal->opd = dbc_nopd;
+		dbc_nopd->internal->pdbc = dbc_n;
+	}
+	return (0);
+
+err:	if (dbc_n != NULL)
+		(void)__dbc_close(dbc_n);
+	if (dbc_nopd != NULL)
+		(void)__dbc_close(dbc_nopd);
+
+	return (ret);
+}
+
+/*
+ * __dbc_idup --
+ *	Internal version of __dbc_dup.
+ *
+ * PUBLIC: int __dbc_idup __P((DBC *, DBC **, u_int32_t));
+ */
+int
+__dbc_idup(dbc_orig, dbcp, flags)
+	DBC *dbc_orig, **dbcp;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DBC *dbc_n;
+	DBC_INTERNAL *int_n, *int_orig;
+	ENV *env;
+	int ret;
+
+	dbp = dbc_orig->dbp;
+	dbc_n = *dbcp;
+	env = dbp->env;
+
+	if ((ret = __db_cursor_int(dbp, dbc_orig->thread_info,
+	    dbc_orig->txn, dbc_orig->dbtype, dbc_orig->internal->root,
+	    F_ISSET(dbc_orig, DBC_OPD) | DBC_DUPLICATE,
+	    dbc_orig->locker, &dbc_n)) != 0)
+		return (ret);
+
+	/* Position the cursor if requested, acquiring the necessary locks. */
+	if (LF_ISSET(DB_POSITION)) {
+		int_n = dbc_n->internal;
+		int_orig = dbc_orig->internal;
+
+		dbc_n->flags |= dbc_orig->flags & ~DBC_OWN_LID;
+
+		int_n->indx = int_orig->indx;
+		int_n->pgno = int_orig->pgno;
+		int_n->root = int_orig->root;
+		int_n->lock_mode = int_orig->lock_mode;
+
+		int_n->stream_start_pgno = int_orig->stream_start_pgno;
+		int_n->stream_off = int_orig->stream_off;
+		int_n->stream_curr_pgno = int_orig->stream_curr_pgno;
+
+		switch (dbc_orig->dbtype) {
+		case DB_QUEUE:
+			if ((ret = __qamc_dup(dbc_orig, dbc_n)) != 0)
+				goto err;
+			break;
+		case DB_BTREE:
+		case DB_RECNO:
+			if ((ret = __bamc_dup(dbc_orig, dbc_n, flags)) != 0)
+				goto err;
+			break;
+		case DB_HASH:
+			if ((ret = __hamc_dup(dbc_orig, dbc_n)) != 0)
+				goto err;
+			break;
+		case DB_HEAP:
+			if ((ret = __heapc_dup(dbc_orig, dbc_n)) != 0)
+				goto err;
+			break;
+		case DB_UNKNOWN:
+		default:
+			ret = __db_unknown_type(env,
+			    "__dbc_idup", dbc_orig->dbtype);
+			goto err;
+		}
+	} else if (F_ISSET(dbc_orig, DBC_BULK)) {
+		/*
+		 * For bulk cursors, remember what page were on, even if we
+		 * don't know that the next operation will be nearby.
+		 */
+		dbc_n->internal->pgno = dbc_orig->internal->pgno;
+	}
+
+	/* Copy the locking flags to the new cursor. */
+	F_SET(dbc_n, F_ISSET(dbc_orig, DBC_BULK |
+	    DBC_READ_COMMITTED | DBC_READ_UNCOMMITTED | DBC_WRITECURSOR));
+
+	/*
+	 * If we're in CDB and this isn't an offpage dup cursor, then
+	 * we need to get a lock for the duplicated cursor.
+	 */
+	if (CDB_LOCKING(env) && !F_ISSET(dbc_n, DBC_OPD) &&
+	    (ret = __lock_get(env, dbc_n->locker, 0,
+	    &dbc_n->lock_dbt, F_ISSET(dbc_orig, DBC_WRITECURSOR) ?
+	    DB_LOCK_IWRITE : DB_LOCK_READ, &dbc_n->mylock)) != 0)
+		goto err;
+
+	dbc_n->priority = dbc_orig->priority;
+	dbc_n->internal->pdbc = dbc_orig->internal->pdbc;
+	*dbcp = dbc_n;
+	return (0);
+
+err:	(void)__dbc_close(dbc_n);
+	return (ret);
+}
+
+/*
+ * __dbc_newopd --
+ *	Create a new off-page duplicate cursor.
+ *
+ * PUBLIC: int __dbc_newopd __P((DBC *, db_pgno_t, DBC *, DBC **));
+ */
+int
+__dbc_newopd(dbc_parent, root, oldopd, dbcp)
+	DBC *dbc_parent;
+	db_pgno_t root;
+	DBC *oldopd;
+	DBC **dbcp;
+{
+	DB *dbp;
+	DBC *opd;
+	DBTYPE dbtype;
+	int ret;
+
+	dbp = dbc_parent->dbp;
+	dbtype = (dbp->dup_compare == NULL) ? DB_RECNO : DB_BTREE;
+
+	/*
+	 * On failure, we want to default to returning the old off-page dup
+	 * cursor, if any;  our caller can't be left with a dangling pointer
+	 * to a freed cursor.  On error the only allowable behavior is to
+	 * close the cursor (and the old OPD cursor it in turn points to), so
+	 * this should be safe.
+	 */
+	*dbcp = oldopd;
+
+	if ((ret = __db_cursor_int(dbp, dbc_parent->thread_info,
+	    dbc_parent->txn,
+	    dbtype, root, DBC_OPD, dbc_parent->locker, &opd)) != 0)
+		return (ret);
+
+	opd->priority = dbc_parent->priority;
+	opd->internal->pdbc = dbc_parent;
+	*dbcp = opd;
+
+	/*
+	 * Check to see if we already have an off-page dup cursor that we've
+	 * passed in.  If we do, close it.  It'd be nice to use it again
+	 * if it's a cursor belonging to the right tree, but if we're doing
+	 * a cursor-relative operation this might not be safe, so for now
+	 * we'll take the easy way out and always close and reopen.
+	 *
+	 * Note that under no circumstances do we want to close the old
+	 * cursor without returning a valid new one;  we don't want to
+	 * leave the main cursor in our caller with a non-NULL pointer
+	 * to a freed off-page dup cursor.
+	 */
+	if (oldopd != NULL && (ret = __dbc_close(oldopd)) != 0)
+		return (ret);
+
+	return (0);
+}
+
+/*
+ * __dbc_get --
+ *	Get using a cursor.
+ *
+ * PUBLIC: int __dbc_get __P((DBC *, DBT *, DBT *, u_int32_t));
+ */
+int
+__dbc_get(dbc, key, data, flags)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	F_CLR(dbc, DBC_ERROR);
+#ifdef HAVE_PARTITION
+	if (F_ISSET(dbc, DBC_PARTITIONED))
+		return (__partc_get(dbc, key, data, flags));
+#endif
+
+#ifdef HAVE_COMPRESSION
+	if (DB_IS_COMPRESSED(dbc->dbp))
+		return (__bamc_compress_get(dbc, key, data, flags));
+#endif
+
+	return (__dbc_iget(dbc, key, data, flags));
+}
+
+/*
+ * __dbc_iget --
+ *	Implementation of get using a cursor.
+ *
+ * PUBLIC: int __dbc_iget __P((DBC *, DBT *, DBT *, u_int32_t));
+ */
+int
+__dbc_iget(dbc, key, data, flags)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DBC *ddbc, *dbc_n, *opd;
+	DBC_INTERNAL *cp, *cp_n;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	db_pgno_t pgno;
+	db_indx_t indx_off;
+	u_int32_t multi, orig_ulen, tmp_flags, tmp_read_locking, tmp_rmw;
+	u_int8_t type;
+	int key_small, ret, t_ret;
+
+	COMPQUIET(orig_ulen, 0);
+
+	key_small = 0;
+
+	/*
+	 * Cursor Cleanup Note:
+	 * All of the cursors passed to the underlying access methods by this
+	 * routine are duplicated cursors.  On return, any referenced pages
+	 * will be discarded, and, if the cursor is not intended to be used
+	 * again, the close function will be called.  So, pages/locks that
+	 * the cursor references do not need to be resolved by the underlying
+	 * functions.
+	 */
+	dbp = dbc->dbp;
+	env = dbp->env;
+	mpf = dbp->mpf;
+	dbc_n = NULL;
+	opd = NULL;
+
+	PERFMON6(env, db, get, dbp->fname, dbp->dname,
+	    dbc->txn == NULL ? 0 : dbc->txn->txnid, key, data, flags);
+
+	/* Clear OR'd in additional bits so we can check for flag equality. */
+	tmp_rmw = LF_ISSET(DB_RMW);
+	LF_CLR(DB_RMW);
+
+	SET_READ_LOCKING_FLAGS(dbc, tmp_read_locking);
+
+	multi = LF_ISSET(DB_MULTIPLE|DB_MULTIPLE_KEY);
+	LF_CLR(DB_MULTIPLE|DB_MULTIPLE_KEY);
+
+	/*
+	 * Return a cursor's record number.  It has nothing to do with the
+	 * cursor get code except that it was put into the interface.
+	 */
+	if (flags == DB_GET_RECNO) {
+		if (tmp_rmw)
+			F_SET(dbc, DBC_RMW);
+		F_SET(dbc, tmp_read_locking);
+		ret = __bamc_rget(dbc, data);
+		if (tmp_rmw)
+			F_CLR(dbc, DBC_RMW);
+		/* Clear the temp flags, but leave WAS_READ_COMMITTED. */
+		F_CLR(dbc, tmp_read_locking & ~DBC_WAS_READ_COMMITTED);
+		return (ret);
+	}
+
+	if (flags == DB_CONSUME || flags == DB_CONSUME_WAIT)
+		CDB_LOCKING_INIT(env, dbc);
+
+	/* Don't return the key or data if it was passed to us. */
+	if (!DB_RETURNS_A_KEY(dbp, flags))
+		F_SET(key, DB_DBT_ISSET);
+	if (flags == DB_GET_BOTH &&
+	    (dbp->dup_compare == NULL || dbp->dup_compare == __bam_defcmp))
+		F_SET(data, DB_DBT_ISSET);
+
+	/*
+	 * If we have an off-page duplicates cursor, and the operation applies
+	 * to it, perform the operation.  Duplicate the cursor and call the
+	 * underlying function.
+	 *
+	 * Off-page duplicate trees are locked in the primary tree, that is,
+	 * we acquire a write lock in the primary tree and no locks in the
+	 * off-page dup tree.  If the DB_RMW flag was specified and the get
+	 * operation is done in an off-page duplicate tree, call the primary
+	 * cursor's upgrade routine first.
+	 */
+	cp = dbc->internal;
+	if (cp->opd != NULL &&
+	    (flags == DB_CURRENT || flags == DB_GET_BOTHC ||
+	    flags == DB_NEXT || flags == DB_NEXT_DUP ||
+	    flags == DB_PREV || flags == DB_PREV_DUP)) {
+		if (tmp_rmw && (ret = dbc->am_writelock(dbc)) != 0)
+			goto err;
+		if (F_ISSET(dbc, DBC_TRANSIENT))
+			opd = cp->opd;
+		else if ((ret = __dbc_idup(cp->opd, &opd, DB_POSITION)) != 0)
+			goto err;
+
+		if ((ret = opd->am_get(opd, key, data, flags, NULL)) == 0)
+			goto done;
+		/*
+		 * Another cursor may have deleted all of the off-page
+		 * duplicates, so for operations that are moving a cursor, we
+		 * need to skip the empty tree and retry on the parent cursor.
+		 */
+		if (ret == DB_NOTFOUND &&
+		    (flags == DB_PREV || flags == DB_NEXT)) {
+			ret = __dbc_close(opd);
+			opd = NULL;
+			if (F_ISSET(dbc, DBC_TRANSIENT))
+				cp->opd = NULL;
+		}
+		if (ret != 0)
+			goto err;
+	} else if (cp->opd != NULL && F_ISSET(dbc, DBC_TRANSIENT)) {
+		if ((ret = __dbc_close(cp->opd)) != 0)
+			goto err;
+		cp->opd = NULL;
+	}
+
+	/*
+	 * Perform an operation on the main cursor.  Duplicate the cursor,
+	 * upgrade the lock as required, and call the underlying function.
+	 */
+	switch (flags) {
+	case DB_CURRENT:
+	case DB_GET_BOTHC:
+	case DB_NEXT:
+	case DB_NEXT_DUP:
+	case DB_NEXT_NODUP:
+	case DB_PREV:
+	case DB_PREV_DUP:
+	case DB_PREV_NODUP:
+		tmp_flags = DB_POSITION;
+		break;
+	default:
+		tmp_flags = 0;
+		break;
+	}
+
+	/*
+	 * If this cursor is going to be closed immediately, we don't
+	 * need to take precautions to clean it up on error.
+	 */
+	if (F_ISSET(dbc, DBC_TRANSIENT | DBC_PARTITIONED))
+		dbc_n = dbc;
+	else {
+		ret = __dbc_idup(dbc, &dbc_n, tmp_flags);
+
+		if (ret != 0)
+			goto err;
+		COPY_RET_MEM(dbc, dbc_n);
+	}
+
+	if (tmp_rmw)
+		F_SET(dbc_n, DBC_RMW);
+	F_SET(dbc_n, tmp_read_locking);
+
+	switch (multi) {
+	case DB_MULTIPLE:
+		F_SET(dbc_n, DBC_MULTIPLE);
+		break;
+	case DB_MULTIPLE_KEY:
+		F_SET(dbc_n, DBC_MULTIPLE_KEY);
+		break;
+	case DB_MULTIPLE | DB_MULTIPLE_KEY:
+		F_SET(dbc_n, DBC_MULTIPLE|DBC_MULTIPLE_KEY);
+		break;
+	case 0:
+	default:
+		break;
+	}
+
+retry:	pgno = PGNO_INVALID;
+	ret = dbc_n->am_get(dbc_n, key, data, flags, &pgno);
+	if (tmp_rmw)
+		F_CLR(dbc_n, DBC_RMW);
+	/*
+	 * Clear the temporary locking flags in the new cursor.  The user's
+	 * (old) cursor needs to have the WAS_READ_COMMITTED flag because this
+	 * is used on the next call on that cursor.
+	 */
+	F_CLR(dbc_n, tmp_read_locking);
+	F_SET(dbc, tmp_read_locking & DBC_WAS_READ_COMMITTED);
+	F_CLR(dbc_n, DBC_MULTIPLE|DBC_MULTIPLE_KEY);
+	if (ret != 0)
+		goto err;
+
+	cp_n = dbc_n->internal;
+
+	/*
+	 * We may be referencing a new off-page duplicates tree.  Acquire
+	 * a new cursor and call the underlying function.
+	 */
+	if (pgno != PGNO_INVALID) {
+		if ((ret = __dbc_newopd(dbc,
+		    pgno, cp_n->opd, &cp_n->opd)) != 0)
+			goto err;
+
+		switch (flags) {
+		case DB_FIRST:
+		case DB_NEXT:
+		case DB_NEXT_NODUP:
+		case DB_SET:
+		case DB_SET_RECNO:
+		case DB_SET_RANGE:
+			tmp_flags = DB_FIRST;
+			break;
+		case DB_LAST:
+		case DB_PREV:
+		case DB_PREV_NODUP:
+			tmp_flags = DB_LAST;
+			break;
+		case DB_GET_BOTH:
+		case DB_GET_BOTHC:
+		case DB_GET_BOTH_RANGE:
+			tmp_flags = flags;
+			break;
+		default:
+			ret = __db_unknown_flag(env, "__dbc_get", flags);
+			goto err;
+		}
+		ret = cp_n->opd->am_get(cp_n->opd, key, data, tmp_flags, NULL);
+		/*
+		 * Another cursor may have deleted all of the off-page
+		 * duplicates, so for operations that are moving a cursor, we
+		 * need to skip the empty tree and retry on the parent cursor.
+		 */
+		if (ret == DB_NOTFOUND) {
+			PERFMON5(env, race, dbc_get,
+			    dbp->fname, dbp->dname, ret, tmp_flags, key);
+
+			switch (flags) {
+			case DB_FIRST:
+			case DB_NEXT:
+			case DB_NEXT_NODUP:
+				flags = DB_NEXT;
+				break;
+			case DB_LAST:
+			case DB_PREV:
+			case DB_PREV_NODUP:
+				flags = DB_PREV;
+				break;
+			default:
+				goto err;
+			}
+
+			ret = __dbc_close(cp_n->opd);
+			cp_n->opd = NULL;
+			if (ret == 0)
+				goto retry;
+		}
+		if (ret != 0)
+			goto err;
+	}
+
+done:	/*
+	 * Return a key/data item.  The only exception is that we don't return
+	 * a key if the user already gave us one, that is, if the DB_SET flag
+	 * was set.  The DB_SET flag is necessary.  In a Btree, the user's key
+	 * doesn't have to be the same as the key stored the tree, depending on
+	 * the magic performed by the comparison function.  As we may not have
+	 * done any key-oriented operation here, the page reference may not be
+	 * valid.  Fill it in as necessary.  We don't have to worry about any
+	 * locks, the cursor must already be holding appropriate locks.
+	 *
+	 * XXX
+	 * If not a Btree and DB_SET_RANGE is set, we shouldn't return a key
+	 * either, should we?
+	 */
+	cp_n = dbc_n == NULL ? dbc->internal : dbc_n->internal;
+	if (!F_ISSET(key, DB_DBT_ISSET)) {
+		if (cp_n->page == NULL && (ret = __memp_fget(mpf, &cp_n->pgno,
+		    dbc->thread_info, dbc->txn, 0, &cp_n->page)) != 0)
+			goto err;
+
+		if ((ret = __db_ret(dbc, cp_n->page, cp_n->indx, key,
+		    &dbc->rkey->data, &dbc->rkey->ulen)) != 0) {
+			/*
+			 * If the key DBT is too small, we still want to return
+			 * the size of the data.  Otherwise applications are
+			 * forced to check each one with a separate call.  We
+			 * don't want to copy the data, so we set the ulen to
+			 * zero before calling __db_ret.
+			 */
+			if (ret == DB_BUFFER_SMALL &&
+			    F_ISSET(data, DB_DBT_USERMEM)) {
+				key_small = 1;
+				orig_ulen = data->ulen;
+				data->ulen = 0;
+			} else
+				goto err;
+		}
+	}
+	if (multi != 0 && dbc->am_bulk != NULL) {
+		/*
+		 * Even if fetching from the OPD cursor we need a duplicate
+		 * primary cursor if we are going after multiple keys.
+		 */
+		if (dbc_n == NULL) {
+			/*
+			 * Non-"_KEY" DB_MULTIPLE doesn't move the main cursor,
+			 * so it's safe to just use dbc, unless the cursor
+			 * has an open off-page duplicate cursor whose state
+			 * might need to be preserved.
+			 */
+			if ((!(multi & DB_MULTIPLE_KEY) &&
+			    dbc->internal->opd == NULL) ||
+			    F_ISSET(dbc, DBC_TRANSIENT | DBC_PARTITIONED))
+				dbc_n = dbc;
+			else {
+				if ((ret = __dbc_idup(dbc,
+				    &dbc_n, DB_POSITION)) != 0)
+					goto err;
+				if ((ret = dbc_n->am_get(dbc_n,
+				    key, data, DB_CURRENT, &pgno)) != 0)
+					goto err;
+			}
+			cp_n = dbc_n->internal;
+		}
+
+		/*
+		 * If opd is set then we dupped the opd that we came in with.
+		 * When we return we may have a new opd if we went to another
+		 * key.
+		 */
+		if (opd != NULL) {
+			DB_ASSERT(env, cp_n->opd == NULL);
+			cp_n->opd = opd;
+			opd = NULL;
+		}
+
+		/*
+		 * Bulk get doesn't use __db_retcopy, so data.size won't
+		 * get set up unless there is an error.  Assume success
+		 * here.  This is the only call to am_bulk, and it avoids
+		 * setting it exactly the same everywhere.  If we have an
+		 * DB_BUFFER_SMALL error, it'll get overwritten with the
+		 * needed value.
+		 */
+		data->size = data->ulen;
+		ret = dbc_n->am_bulk(dbc_n, data, flags | multi);
+	} else if (!F_ISSET(data, DB_DBT_ISSET)) {
+		ddbc = opd != NULL ? opd :
+		    cp_n->opd != NULL ? cp_n->opd : dbc_n;
+		cp = ddbc->internal;
+		if (cp->page == NULL &&
+		    (ret = __memp_fget(mpf, &cp->pgno,
+			 dbc->thread_info, ddbc->txn, 0, &cp->page)) != 0)
+			goto err;
+
+		type = TYPE(cp->page);
+		indx_off = ((type == P_LBTREE ||
+		    type == P_HASH || type == P_HASH_UNSORTED) ? O_INDX : 0);
+		ret = __db_ret(ddbc, cp->page, cp->indx + indx_off,
+		    data, &dbc->rdata->data, &dbc->rdata->ulen);
+	}
+
+err:	/* Don't pass DB_DBT_ISSET back to application level, error or no. */
+	F_CLR(key, DB_DBT_ISSET);
+	F_CLR(data, DB_DBT_ISSET);
+
+	/* Cleanup and cursor resolution. */
+	if (opd != NULL) {
+		/*
+		 * To support dirty reads we must reget the write lock
+		 * if we have just stepped off a deleted record.
+		 * Since the OPD cursor does not know anything
+		 * about the referencing page or cursor we need
+		 * to peek at the OPD cursor and get the lock here.
+		 */
+		if (F_ISSET(dbp, DB_AM_READ_UNCOMMITTED) &&
+		     F_ISSET((BTREE_CURSOR *)
+		     dbc->internal->opd->internal, C_DELETED))
+			if ((t_ret =
+			    dbc->am_writelock(dbc)) != 0 && ret == 0)
+				ret = t_ret;
+		if ((t_ret = __dbc_cleanup(
+		    dbc->internal->opd, opd, ret)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+
+	if (key_small) {
+		data->ulen = orig_ulen;
+		if (ret == 0)
+			ret = DB_BUFFER_SMALL;
+	}
+
+	if ((t_ret = __dbc_cleanup(dbc, dbc_n, ret)) != 0 &&
+	    (ret == 0 || ret == DB_BUFFER_SMALL))
+		ret = t_ret;
+
+	if (flags == DB_CONSUME || flags == DB_CONSUME_WAIT)
+		CDB_LOCKING_DONE(env, dbc);
+	return (ret);
+}
+
+/* Internal flags shared by the dbc_put functions. */
+#define	DBC_PUT_RMW		0x001
+#define	DBC_PUT_NODEL		0x002
+#define	DBC_PUT_HAVEREC		0x004
+
+/*
+ * __dbc_put_resolve_key --
+ *	Get the current key and data so that we can correctly update the
+ *	secondary and foreign databases.
+ */
+static inline int
+__dbc_put_resolve_key(dbc, oldkey, olddata, put_statep, flags)
+	DBC *dbc;
+	DBT *oldkey, *olddata;
+	u_int32_t flags, *put_statep;
+{
+	DB *dbp;
+	ENV *env;
+	int ret, rmw;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	rmw = FLD_ISSET(*put_statep, DBC_PUT_RMW) ? DB_RMW : 0;
+
+	DB_ASSERT(env, flags == DB_CURRENT);
+	COMPQUIET(flags, 0);
+
+	/*
+	 * This is safe to do on the cursor we already have;
+	 * error or no, it won't move.
+	 *
+	 * We use DB_RMW for all of these gets because we'll be
+	 * writing soon enough in the "normal" put code.  In
+	 * transactional databases we'll hold those write locks
+	 * even if we close the cursor we're reading with.
+	 *
+	 * The DB_KEYEMPTY return needs special handling -- if the
+	 * cursor is on a deleted key, we return DB_NOTFOUND.
+	 */
+	memset(oldkey, 0, sizeof(DBT));
+	if ((ret = __dbc_get(dbc, oldkey, olddata, rmw | DB_CURRENT)) != 0)
+		return (ret == DB_KEYEMPTY ? DB_NOTFOUND : ret);
+
+	/* Record that we've looked for the old record. */
+	FLD_SET(*put_statep, DBC_PUT_HAVEREC);
+	return (0);
+}
+
+/*
+ * __dbc_put_append --
+ *	Handle an append to a primary.
+ */
+static inline int
+__dbc_put_append(dbc, key, data, put_statep, flags)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags, *put_statep;
+{
+	DB *dbp;
+	ENV *env;
+	DBC *dbc_n;
+	DBT tdata;
+	int ret, t_ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	ret = 0;
+	dbc_n = NULL;
+
+	DB_ASSERT(env, flags == DB_APPEND);
+	COMPQUIET(flags, 0);
+
+	/*
+	 * With DB_APPEND, we need to do the insert to populate the key value.
+	 * So we swap the 'normal' order of updating secondary / verifying
+	 * foreign databases and inserting.
+	 *
+	 * If there is an append callback, the value stored in data->data may
+	 * be replaced and then freed.  To avoid passing a freed pointer back
+	 * to the user, just operate on a copy of the data DBT.
+	 */
+	tdata = *data;
+
+	/*
+	 * If this cursor is going to be closed immediately, we don't
+	 * need to take precautions to clean it up on error.
+	 */
+	if (F_ISSET(dbc, DBC_TRANSIENT))
+		dbc_n = dbc;
+	else if ((ret = __dbc_idup(dbc, &dbc_n, 0)) != 0)
+		goto err;
+
+	/*
+	 * Append isn't a normal put operation;  call the appropriate access
+	 * method's append function.
+	 */
+	switch (dbp->type) {
+	case DB_HEAP:
+		if ((ret = __heap_append(dbc_n, key, &tdata)) != 0)
+			goto err;
+		break;
+	case DB_QUEUE:
+		if ((ret = __qam_append(dbc_n, key, &tdata)) != 0)
+			goto err;
+		break;
+	case DB_RECNO:
+		if ((ret = __ram_append(dbc_n, key, &tdata)) != 0)
+			goto err;
+		break;
+	default:
+		/* The interface should prevent this. */
+		DB_ASSERT(env,
+		    dbp->type == DB_QUEUE || dbp->type == DB_RECNO);
+
+		ret = __db_ferr(env, "DBC->put", 0);
+		goto err;
+	}
+
+	/*
+	 * The append callback, if one exists, may have allocated a new
+	 * tdata.data buffer.  If so, free it.
+	 */
+	FREE_IF_NEEDED(env, &tdata);
+
+	/*
+	 * The key value may have been generated by the above operation, but
+	 * not set in the data buffer. Make sure it is there so that secondary
+	 * updates can complete.
+	 */
+	__dbt_userfree(env, key, NULL, NULL);
+	if ((ret = __dbt_usercopy(env, key)) != 0)
+		goto err;
+
+	/* An append cannot be replacing an existing item. */
+	FLD_SET(*put_statep, DBC_PUT_NODEL);
+
+err:	if (dbc_n != NULL &&
+	    (t_ret = __dbc_cleanup(dbc, dbc_n, ret)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+/*
+ * __dbc_put_partial --
+ *	Ensure that the data item we are using is complete and correct.
+ *      Otherwise we could break the secondary constraints.
+ */
+static inline int
+__dbc_put_partial(dbc, pkey, data, orig_data, out_data, put_statep, flags)
+	DBC *dbc;
+	DBT *pkey, *data, *orig_data, *out_data;
+	u_int32_t *put_statep, flags;
+{
+	DB *dbp;
+	DBC *pdbc;
+	ENV *env;
+	int ret, rmw, t_ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	ret = t_ret = 0;
+	rmw = FLD_ISSET(*put_statep, DBC_PUT_RMW) ? DB_RMW : 0;
+
+	if (!FLD_ISSET(*put_statep, DBC_PUT_HAVEREC) &&
+	    !FLD_ISSET(*put_statep, DBC_PUT_NODEL)) {
+		/*
+		 * We're going to have to search the tree for the
+		 * specified key.  Dup a cursor (so we have the same
+		 * locking info) and do a c_get.
+		 */
+		if ((ret = __dbc_idup(dbc, &pdbc, 0)) != 0)
+			return (ret);
+
+		/*
+		 * When doing a put with DB_CURRENT, partial data items have
+		 * already been resolved.
+		 */
+		DB_ASSERT(env, flags != DB_CURRENT);
+
+		F_SET(pkey, DB_DBT_ISSET);
+		ret = __dbc_get(pdbc, pkey, orig_data, rmw | DB_SET);
+		if (ret == DB_KEYEMPTY || ret == DB_NOTFOUND) {
+			FLD_SET(*put_statep, DBC_PUT_NODEL);
+			ret = 0;
+		}
+		if ((t_ret = __dbc_close(pdbc)) != 0)
+			ret = t_ret;
+		if (ret != 0)
+			return (ret);
+
+		FLD_SET(*put_statep, DBC_PUT_HAVEREC);
+	}
+
+	COMPQUIET(flags, 0);
+
+	/*
+	 * Now build the new datum from orig_data and the partial data
+	 * we were given.  It's okay to do this if no record was
+	 * returned above: a partial put on an empty record is allowed,
+	 * if a little strange.  The data is zero-padded.
+	 */
+	return (__db_buildpartial(dbp, orig_data, data, out_data));
+}
+
+/*
+ * __dbc_put_fixed_len --
+ *      Handle padding for fixed-length records.
+ */
+static inline int
+__dbc_put_fixed_len(dbc, data, out_data)
+	DBC *dbc;
+	DBT *data, *out_data;
+{
+	DB *dbp;
+	ENV *env;
+	int re_pad, ret;
+	u_int32_t re_len, size;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	ret = 0;
+
+	/*
+	 * Handle fixed-length records.  If the primary database has
+	 * fixed-length records, we need to pad out the datum before
+	 * we pass it into the callback function;  we always index the
+	 * "real" record.
+	 */
+	if (dbp->type == DB_QUEUE) {
+		re_len = ((QUEUE *)dbp->q_internal)->re_len;
+		re_pad = ((QUEUE *)dbp->q_internal)->re_pad;
+	} else {
+		re_len = ((BTREE *)dbp->bt_internal)->re_len;
+		re_pad = ((BTREE *)dbp->bt_internal)->re_pad;
+	}
+
+	size = data->size;
+	if (size > re_len) {
+		ret = __db_rec_toobig(env, size, re_len);
+		return (ret);
+	} else if (size < re_len) {
+		/*
+		 * If we're not doing a partial put, copy data->data into
+		 * out_data->data, then pad out out_data->data. This overrides
+		 * the assignment made above, which is used in the more common
+		 * case when padding is not needed.
+		 *
+		 * If we're doing a partial put, the data we want are already
+		 * in out_data.data; we just need to pad.
+		 */
+		if (F_ISSET(data, DB_DBT_PARTIAL)) {
+		       if ((ret = __os_realloc(
+			    env, re_len, &out_data->data)) != 0)
+				return (ret);
+		       /*
+			* In the partial case, we have built the item into
+			* out_data already using __db_buildpartial. Just need
+			* to pad from the end of out_data, not from data->size.
+			*/
+		       size = out_data->size;
+		} else {
+			if ((ret = __os_malloc(
+			    env, re_len, &out_data->data)) != 0)
+				return (ret);
+			memcpy(out_data->data, data->data, size);
+		}
+		memset((u_int8_t *)out_data->data + size, re_pad,
+		    re_len - size);
+		out_data->size = re_len;
+	}
+
+	return (ret);
+}
+
+/*
+ * __dbc_put_secondaries --
+ *	Insert the secondary keys, and validate the foreign key constraints.
+ */
+static inline int
+__dbc_put_secondaries(dbc,
+    pkey, data, orig_data, s_count, s_keys_buf, put_statep)
+	DBC *dbc;
+	DBT *pkey, *data, *orig_data, *s_keys_buf;
+	int s_count;
+	u_int32_t *put_statep;
+{
+	DB *dbp, *sdbp;
+	DBC *fdbc, *sdbc;
+	DBT fdata, oldpkey, *skeyp, temppkey, tempskey, *tskeyp;
+	ENV *env;
+	int cmp, ret, rmw, t_ret;
+	u_int32_t nskey;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	fdbc = sdbc = NULL;
+	sdbp = NULL;
+	t_ret = 0;
+	rmw = FLD_ISSET(*put_statep, DBC_PUT_RMW) ? DB_RMW : 0;
+
+	/*
+	 * Loop through the secondaries.  (Step 3.)
+	 *
+	 * Note that __db_s_first and __db_s_next will take care of
+	 * thread-locking and refcounting issues.
+	 */
+	for (ret = __db_s_first(dbp, &sdbp), skeyp = s_keys_buf;
+	    sdbp != NULL && ret == 0;
+	    ret = __db_s_next(&sdbp, dbc->txn), ++skeyp) {
+		DB_ASSERT(env, skeyp - s_keys_buf < s_count);
+		/*
+		 * Don't process this secondary if the key is immutable and we
+		 * know that the old record exists.  This optimization can't be
+		 * used if we have not checked for the old record yet.
+		 */
+		if (FLD_ISSET(*put_statep, DBC_PUT_HAVEREC) &&
+		    !FLD_ISSET(*put_statep, DBC_PUT_NODEL) &&
+		    FLD_ISSET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY))
+			continue;
+
+		/*
+		 * Call the callback for this secondary, to get the
+		 * appropriate secondary key.
+		 */
+		if ((ret = sdbp->s_callback(sdbp,
+		    pkey, data, skeyp)) != 0) {
+			/* Not indexing is equivalent to an empty key set. */
+			if (ret == DB_DONOTINDEX) {
+				F_SET(skeyp, DB_DBT_MULTIPLE);
+				skeyp->size = 0;
+				ret = 0;
+			} else
+				goto err;
+		}
+
+		if (sdbp->s_foreign != NULL &&
+		    (ret = __db_cursor_int(sdbp->s_foreign,
+		    dbc->thread_info, dbc->txn, sdbp->s_foreign->type,
+		    PGNO_INVALID, 0, dbc->locker, &fdbc)) != 0)
+			goto err;
+
+		/*
+		 * Mark the secondary key DBT(s) as set -- that is, the
+		 * callback returned at least one secondary key.
+		 *
+		 * Also, if this secondary index is associated with a foreign
+		 * database, check that the foreign db contains the key(s) to
+		 * maintain referential integrity.  Set flags in fdata to avoid
+		 * mem copying, we just need to know existence.  We need to do
+		 * this check before setting DB_DBT_ISSET, otherwise __dbc_get
+		 * will overwrite the flag values.
+		 */
+		if (F_ISSET(skeyp, DB_DBT_MULTIPLE)) {
+#ifdef DIAGNOSTIC
+			__db_check_skeyset(sdbp, skeyp);
+#endif
+			for (tskeyp = (DBT *)skeyp->data, nskey = skeyp->size;
+			     nskey > 0; nskey--, tskeyp++) {
+				if (fdbc != NULL) {
+					memset(&fdata, 0, sizeof(DBT));
+					F_SET(&fdata,
+					    DB_DBT_PARTIAL | DB_DBT_USERMEM);
+					if ((ret = __dbc_get(
+					    fdbc, tskeyp, &fdata,
+					    DB_SET | rmw)) == DB_NOTFOUND ||
+					    ret == DB_KEYEMPTY) {
+						ret = DB_FOREIGN_CONFLICT;
+						break;
+					}
+				}
+				F_SET(tskeyp, DB_DBT_ISSET);
+			}
+			tskeyp = (DBT *)skeyp->data;
+			nskey = skeyp->size;
+		} else {
+			if (fdbc != NULL) {
+				memset(&fdata, 0, sizeof(DBT));
+				F_SET(&fdata, DB_DBT_PARTIAL | DB_DBT_USERMEM);
+				if ((ret = __dbc_get(fdbc, skeyp, &fdata,
+				    DB_SET | rmw)) == DB_NOTFOUND ||
+				    ret == DB_KEYEMPTY)
+					ret = DB_FOREIGN_CONFLICT;
+			}
+			F_SET(skeyp, DB_DBT_ISSET);
+			tskeyp = skeyp;
+			nskey = 1;
+		}
+		if (fdbc != NULL && (t_ret = __dbc_close(fdbc)) != 0 &&
+		    ret == 0)
+			ret = t_ret;
+		fdbc = NULL;
+		if (ret != 0)
+			goto err;
+
+		/*
+		 * If we have the old record, we can generate and remove any
+		 * old secondary key(s) now.  We can also skip the secondary
+		 * put if there is no change.
+		 */
+		if (FLD_ISSET(*put_statep, DBC_PUT_HAVEREC)) {
+			if ((ret = __dbc_del_oldskey(sdbp, dbc,
+			    skeyp, pkey, orig_data)) == DB_KEYEXIST)
+				continue;
+			else if (ret != 0)
+				goto err;
+		}
+		if (nskey == 0)
+			continue;
+
+		/*
+		 * Open a cursor in this secondary.
+		 *
+		 * Use the same locker ID as our primary cursor, so that
+		 * we're guaranteed that the locks don't conflict (e.g. in CDB
+		 * or if we're subdatabases that share and want to lock a
+		 * metadata page).
+		 */
+		if ((ret = __db_cursor_int(sdbp, dbc->thread_info, dbc->txn,
+		    sdbp->type, PGNO_INVALID, 0, dbc->locker, &sdbc)) != 0)
+			goto err;
+
+		/*
+		 * If we're in CDB, updates will fail since the new cursor
+		 * isn't a writer.  However, we hold the WRITE lock in the
+		 * primary and will for as long as our new cursor lasts,
+		 * and the primary and secondary share a lock file ID,
+		 * so it's safe to consider this a WRITER.  The close
+		 * routine won't try to put anything because we don't
+		 * really have a lock.
+		 */
+		if (CDB_LOCKING(env)) {
+			DB_ASSERT(env, sdbc->mylock.off == LOCK_INVALID);
+			F_SET(sdbc, DBC_WRITER);
+		}
+
+		/*
+		 * Swap the primary key to the byte order of this secondary, if
+		 * necessary.  By doing this now, we can compare directly
+		 * against the data already in the secondary without having to
+		 * swap it after reading.
+		 */
+		SWAP_IF_NEEDED(sdbp, pkey);
+
+		for (; nskey > 0 && ret == 0; nskey--, tskeyp++) {
+			/* Skip this key if it is already in the database. */
+			if (!F_ISSET(tskeyp, DB_DBT_ISSET))
+				continue;
+
+			/*
+			 * There are three cases here--
+			 * 1) The secondary supports sorted duplicates.
+			 *	If we attempt to put a secondary/primary pair
+			 *	that already exists, that's a duplicate
+			 *	duplicate, and c_put will return DB_KEYEXIST
+			 *	(see __db_duperr).  This will leave us with
+			 *	exactly one copy of the secondary/primary pair,
+			 *	and this is just right--we'll avoid deleting it
+			 *	later, as the old and new secondaries will
+			 *	match (since the old secondary is the dup dup
+			 *	that's already there).
+			 * 2) The secondary supports duplicates, but they're not
+			 *	sorted.  We need to avoid putting a duplicate
+			 *	duplicate, because the matching old and new
+			 *	secondaries will prevent us from deleting
+			 *	anything and we'll wind up with two secondary
+			 *	records that point to the same primary key.  Do
+			 *	a c_get(DB_GET_BOTH);  only do the put if the
+			 *	secondary doesn't exist.
+			 * 3) The secondary doesn't support duplicates at all.
+			 *	In this case, secondary keys must be unique;
+			 *	if another primary key already exists for this
+			 *	secondary key, we have to either overwrite it
+			 *	or not put this one, and in either case we've
+			 *	corrupted the secondary index.  Do a
+			 *	c_get(DB_SET).  If the secondary/primary pair
+			 *	already exists, do nothing;  if the secondary
+			 *	exists with a different primary, return an
+			 *	error;  and if the secondary does not exist,
+			 *	put it.
+			 */
+			if (!F_ISSET(sdbp, DB_AM_DUP)) {
+				/* Case 3. */
+				memset(&oldpkey, 0, sizeof(DBT));
+				F_SET(&oldpkey, DB_DBT_MALLOC);
+				ret = __dbc_get(sdbc,
+				    tskeyp, &oldpkey, rmw | DB_SET);
+				if (ret == 0) {
+					cmp = __bam_defcmp(sdbp,
+					    &oldpkey, pkey);
+					__os_ufree(env, oldpkey.data);
+					/*
+					 * If the secondary key is unchanged,
+					 * skip the put and go on to the next
+					 * one.
+					 */
+					if (cmp == 0)
+						continue;
+
+					__db_errx(env, DB_STR("0695",
+			    "Put results in a non-unique secondary key in an "
+			    "index not configured to support duplicates"));
+					ret = EINVAL;
+				}
+				if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY)
+					break;
+			} else if (!F_ISSET(sdbp, DB_AM_DUPSORT)) {
+				/* Case 2. */
+				DB_INIT_DBT(tempskey,
+				    tskeyp->data, tskeyp->size);
+				DB_INIT_DBT(temppkey,
+				    pkey->data, pkey->size);
+				ret = __dbc_get(sdbc, &tempskey, &temppkey,
+				    rmw | DB_GET_BOTH);
+				if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY)
+					break;
+			}
+
+			ret = __dbc_put(sdbc, tskeyp, pkey,
+			    DB_UPDATE_SECONDARY);
+
+			/*
+			 * We don't know yet whether this was a put-overwrite
+			 * that in fact changed nothing.  If it was, we may get
+			 * DB_KEYEXIST.  This is not an error.
+			 */
+			if (ret == DB_KEYEXIST)
+				ret = 0;
+		}
+
+		/* Make sure the primary key is back in native byte-order. */
+		SWAP_IF_NEEDED(sdbp, pkey);
+
+		if ((t_ret = __dbc_close(sdbc)) != 0 && ret == 0)
+			ret = t_ret;
+
+		if (ret != 0)
+			goto err;
+
+		/*
+		 * Mark that we have a key for this secondary so we can check
+		 * it later before deleting the old one.  We can't set it
+		 * earlier or it would be cleared in the calls above.
+		 */
+		F_SET(skeyp, DB_DBT_ISSET);
+	}
+err:	if (sdbp != NULL &&
+	    (t_ret = __db_s_done(sdbp, dbc->txn)) != 0 && ret == 0)
+		ret = t_ret;
+	COMPQUIET(s_count, 0);
+	return (ret);
+}
+
+static int
+__dbc_put_primary(dbc, key, data, flags)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DB *dbp, *sdbp;
+	DBC *dbc_n, *pdbc;
+	DBT oldkey, olddata, newdata;
+	DBT *all_skeys, *skeyp, *tskeyp;
+	ENV *env;
+	int ret, t_ret, s_count;
+	u_int32_t nskey, put_state, rmw;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	t_ret = 0;
+	put_state = 0;
+	sdbp = NULL;
+	pdbc = dbc_n = NULL;
+	all_skeys = NULL;
+	memset(&newdata, 0, sizeof(DBT));
+	memset(&olddata, 0, sizeof(DBT));
+
+	/*
+	 * We do multiple cursor operations in some cases and subsequently
+	 * access the data DBT information.  Set DB_DBT_MALLOC so we don't risk
+	 * modification of the data between our uses of it.
+	 */
+	F_SET(&olddata, DB_DBT_MALLOC);
+
+	/*
+	 * We have at least one secondary which we may need to update.
+	 *
+	 * There is a rather vile locking issue here.  Secondary gets
+	 * will always involve acquiring a read lock in the secondary,
+	 * then acquiring a read lock in the primary.  Ideally, we
+	 * would likewise perform puts by updating all the secondaries
+	 * first, then doing the actual put in the primary, to avoid
+	 * deadlock (since having multiple threads doing secondary
+	 * gets and puts simultaneously is probably a common case).
+	 *
+	 * However, if this put is a put-overwrite--and we have no way to
+	 * tell in advance whether it will be--we may need to delete
+	 * an outdated secondary key.  In order to find that old
+	 * secondary key, we need to get the record we're overwriting,
+	 * before we overwrite it.
+	 *
+	 * (XXX: It would be nice to avoid this extra get, and have the
+	 * underlying put routines somehow pass us the old record
+	 * since they need to traverse the tree anyway.  I'm saving
+	 * this optimization for later, as it's a lot of work, and it
+	 * would be hard to fit into this locking paradigm anyway.)
+	 *
+	 * The simple thing to do would be to go get the old record before
+	 * we do anything else.  Unfortunately, though, doing so would
+	 * violate our "secondary, then primary" lock acquisition
+	 * ordering--even in the common case where no old primary record
+	 * exists, we'll still acquire and keep a lock on the page where
+	 * we're about to do the primary insert.
+	 *
+	 * To get around this, we do the following gyrations, which
+	 * hopefully solve this problem in the common case:
+	 *
+	 * 1) If this is a c_put(DB_CURRENT), go ahead and get the
+	 *    old record.  We already hold the lock on this page in
+	 *    the primary, so no harm done, and we'll need the primary
+	 *    key (which we weren't passed in this case) to do any
+	 *    secondary puts anyway.
+	 *    If this is a put(DB_APPEND), then we need to insert the item,
+	 *    so that we can know the key value. So go ahead and insert. In
+	 *    the case of a put(DB_APPEND) without secondaries it is
+	 *    implemented in the __db_put method as an optimization.
+	 *
+	 * 2) If we're doing a partial put, we need to perform the
+	 *    get on the primary key right away, since we don't have
+	 *    the whole datum that the secondary key is based on.
+	 *    We may also need to pad out the record if the primary
+	 *    has a fixed record length.
+	 *
+	 * 3) Loop through the secondary indices, putting into each a
+	 *    new secondary key that corresponds to the new record.
+	 *
+	 * 4) If we haven't done so in (1) or (2), get the old primary
+	 *    key/data pair.  If one does not exist--the common case--we're
+	 *    done with secondary indices, and can go straight on to the
+	 *    primary put.
+	 *
+	 * 5) If we do have an old primary key/data pair, however, we need
+	 *    to loop through all the secondaries a second time and delete
+	 *    the old secondary in each.
+	 */
+	s_count = __db_s_count(dbp);
+	if ((ret = __os_calloc(env,
+	    (u_int)s_count, sizeof(DBT), &all_skeys)) != 0)
+		goto err;
+
+	/*
+	 * Primary indices can't have duplicates, so only DB_APPEND,
+	 * DB_CURRENT, DB_KEYFIRST, and DB_KEYLAST make any sense.  Other flags
+	 * should have been caught by the checking routine, but
+	 * add a sprinkling of paranoia.
+	 */
+	DB_ASSERT(env, flags == DB_APPEND || flags == DB_CURRENT ||
+	      flags == DB_KEYFIRST || flags == DB_KEYLAST ||
+	      flags == DB_NOOVERWRITE || flags == DB_OVERWRITE_DUP);
+
+	/*
+	 * We'll want to use DB_RMW in a few places, but it's only legal
+	 * when locking is on.
+	 */
+	rmw = STD_LOCKING(dbc) ? DB_RMW : 0;
+	if (rmw)
+		FLD_SET(put_state, DBC_PUT_RMW);
+
+	/* Resolve the primary key if required (Step 1). */
+	if (flags == DB_CURRENT) {
+		if ((ret = __dbc_put_resolve_key(dbc,
+		    &oldkey, &olddata, &put_state, flags)) != 0)
+			goto err;
+		key = &oldkey;
+	} else if (flags == DB_APPEND) {
+		if ((ret = __dbc_put_append(dbc,
+		    key, data, &put_state, flags)) != 0)
+			goto err;
+	}
+
+	/*
+	 * PUT_NOOVERWRITE with secondaries is a troublesome case. We need
+	 * to check that the insert will work prior to making any changes
+	 * to secondaries. Try to work within the locking constraints outlined
+	 * above.
+	 *
+	 * This is DB->put (DB_NOOVERWRITE). DBC->put(DB_NODUPDATA) is not
+	 * relevant since it is only valid on DBs that support duplicates,
+	 * which primaries with secondaries can't have.
+	 */
+	if (flags == DB_NOOVERWRITE) {
+		/* Don't bother retrieving the data. */
+		F_SET(key, DB_DBT_ISSET);
+		olddata.dlen = 0;
+		olddata.flags = DB_DBT_PARTIAL | DB_DBT_USERMEM;
+		ret = __dbc_get(dbc, key, &olddata, DB_SET);
+		if (ret == 0) {
+			ret = DB_KEYEXIST;
+			goto done;
+		} else if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY)
+			goto err;
+	}
+
+	/*
+	 * Check for partial puts using DB_DBT_PARTIAL (Step 2).
+	 */
+	if (F_ISSET(data, DB_DBT_PARTIAL)) {
+		if ((ret = __dbc_put_partial(dbc,
+		    key, data, &olddata, &newdata, &put_state, flags)) != 0)
+			goto err;
+	} else {
+		newdata = *data;
+	}
+
+	/*
+	 * Check for partial puts, with fixed length record databases (Step 2).
+	 */
+	if ((dbp->type == DB_RECNO && F_ISSET(dbp, DB_AM_FIXEDLEN)) ||
+	    (dbp->type == DB_QUEUE)) {
+		if ((ret = __dbc_put_fixed_len(dbc, data, &newdata)) != 0)
+			goto err;
+	}
+
+	/* Validate any foreign databases, and update secondaries. (Step 3). */
+	if ((ret = __dbc_put_secondaries(dbc, key, &newdata,
+	    &olddata, s_count, all_skeys, &put_state))
+	    != 0)
+		goto err;
+	/*
+	 * If we've already got the old primary key/data pair, the secondary
+	 * updates are already done.
+	 */
+	if (FLD_ISSET(put_state, DBC_PUT_HAVEREC))
+		goto done;
+
+	/*
+	 * If still necessary, go get the old primary key/data.  (Step 4.)
+	 *
+	 * See the comments in step 2.  This is real familiar.
+	 */
+	if ((ret = __dbc_idup(dbc, &pdbc, 0)) != 0)
+		goto err;
+	DB_ASSERT(env, flags != DB_CURRENT);
+	F_SET(key, DB_DBT_ISSET);
+	ret = __dbc_get(pdbc, key, &olddata, rmw | DB_SET);
+	if (ret == DB_KEYEMPTY || ret == DB_NOTFOUND) {
+		FLD_SET(put_state, DBC_PUT_NODEL);
+		ret = 0;
+	}
+	if ((t_ret = __dbc_close(pdbc)) != 0 && ret == 0)
+		ret = t_ret;
+	if (ret != 0)
+		goto err;
+
+	/*
+	 * Check whether we do in fact have an old record we may need to
+	 * delete.  (Step 5).
+	 */
+	if (FLD_ISSET(put_state, DBC_PUT_NODEL))
+		goto done;
+
+	for (ret = __db_s_first(dbp, &sdbp), skeyp = all_skeys;
+	    sdbp != NULL && ret == 0;
+	    ret = __db_s_next(&sdbp, dbc->txn), skeyp++) {
+		DB_ASSERT(env, skeyp - all_skeys < s_count);
+		/*
+		 * Don't process this secondary if the key is immutable.  We
+		 * know that the old record exists, so this optimization can
+		 * always be used.
+		 */
+		if (FLD_ISSET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY))
+			continue;
+
+		if ((ret = __dbc_del_oldskey(sdbp, dbc,
+		    skeyp, key, &olddata)) != 0 && ret != DB_KEYEXIST)
+			goto err;
+	}
+	if (ret != 0)
+		goto err;
+
+done:
+err:
+	if ((t_ret = __dbc_cleanup(dbc, dbc_n, ret)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* If newdata or olddata were used, free their buffers. */
+	if (newdata.data != NULL && newdata.data != data->data)
+		__os_free(env, newdata.data);
+	if (olddata.data != NULL)
+		__os_ufree(env, olddata.data);
+
+	CDB_LOCKING_DONE(env, dbc);
+
+	if (sdbp != NULL &&
+	    (t_ret = __db_s_done(sdbp, dbc->txn)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (all_skeys != NULL) {
+		for (skeyp = all_skeys; skeyp - all_skeys < s_count; skeyp++) {
+			if (F_ISSET(skeyp, DB_DBT_MULTIPLE)) {
+				for (nskey = skeyp->size,
+				    tskeyp = (DBT *)skeyp->data;
+				    nskey > 0;
+				    nskey--, tskeyp++)
+					FREE_IF_NEEDED(env, tskeyp);
+			}
+			FREE_IF_NEEDED(env, skeyp);
+		}
+		__os_free(env, all_skeys);
+	}
+	return (ret);
+}
+
+/*
+ * __dbc_put --
+ *	Put using a cursor.
+ *
+ * PUBLIC: int __dbc_put __P((DBC *, DBT *, DBT *, u_int32_t));
+ */
+int
+__dbc_put(dbc, key, data, flags)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DB *dbp;
+	int ret;
+
+	dbp = dbc->dbp;
+	ret = 0;
+	F_CLR(dbc, DBC_ERROR);
+
+	/*
+	 * Putting to secondary indices is forbidden;  when we need to
+	 * internally update one, we're called with a private flag,
+	 * DB_UPDATE_SECONDARY, which does the right thing but won't return an
+	 * error during flag checking.
+	 *
+	 * As a convenience, many places that want the default DB_KEYLAST
+	 * behavior call DBC->put with flags == 0.  Protect lower-level code
+	 * here by translating that.
+	 *
+	 * Lastly, the DB_OVERWRITE_DUP flag is equivalent to DB_KEYLAST unless
+	 * there are sorted duplicates.  Limit the number of places that need
+	 * to test for it explicitly.
+	 */
+	if (flags == DB_UPDATE_SECONDARY || flags == 0 ||
+	    (flags == DB_OVERWRITE_DUP && !F_ISSET(dbp, DB_AM_DUPSORT)))
+		flags = DB_KEYLAST;
+
+	CDB_LOCKING_INIT(dbc->env, dbc);
+
+	PERFMON6(env, db, put, dbp->fname, dbp->dname,
+	    dbc->txn == NULL ? 0 : dbc->txn->txnid, key, data, flags);
+	/*
+	 * Check to see if we are a primary and have secondary indices.
+	 * If we are not, we save ourselves a good bit of trouble and
+	 * just skip to the "normal" put.
+	 */
+	if (DB_IS_PRIMARY(dbp) &&
+	    ((ret = __dbc_put_primary(dbc, key, data, flags)) != 0))
+		return (ret);
+
+	/*
+	 * If this is an append operation, the insert was done prior to the
+	 * secondary updates, so we are finished.
+	 */
+	if (flags == DB_APPEND)
+		return (ret);
+
+#ifdef HAVE_COMPRESSION
+	if (DB_IS_COMPRESSED(dbp))
+		return (__bamc_compress_put(dbc, key, data, flags));
+#endif
+
+	return (__dbc_iput(dbc, key, data, flags));
+}
+
+/*
+ * __dbc_iput --
+ *	Implementation of put using a cursor.
+ *
+ * PUBLIC: int __dbc_iput __P((DBC *, DBT *, DBT *, u_int32_t));
+ */
+int
+__dbc_iput(dbc, key, data, flags)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DBC *dbc_n, *oldopd, *opd;
+	db_pgno_t pgno;
+	int ret, t_ret;
+	u_int32_t tmp_flags;
+
+	/*
+	 * Cursor Cleanup Note:
+	 * All of the cursors passed to the underlying access methods by this
+	 * routine are duplicated cursors.  On return, any referenced pages
+	 * will be discarded, and, if the cursor is not intended to be used
+	 * again, the close function will be called.  So, pages/locks that
+	 * the cursor references do not need to be resolved by the underlying
+	 * functions.
+	 */
+	dbc_n = NULL;
+	ret = t_ret = 0;
+
+	/*
+	 * If we have an off-page duplicates cursor, and the operation applies
+	 * to it, perform the operation.  Duplicate the cursor and call the
+	 * underlying function.
+	 *
+	 * Off-page duplicate trees are locked in the primary tree, that is,
+	 * we acquire a write lock in the primary tree and no locks in the
+	 * off-page dup tree.  If the put operation is done in an off-page
+	 * duplicate tree, call the primary cursor's upgrade routine first.
+	 */
+	if (dbc->internal->opd != NULL &&
+	    (flags == DB_AFTER || flags == DB_BEFORE || flags == DB_CURRENT)) {
+		/*
+		 * A special case for hash off-page duplicates.  Hash doesn't
+		 * support (and is documented not to support) put operations
+		 * relative to a cursor which references an already deleted
+		 * item.  For consistency, apply the same criteria to off-page
+		 * duplicates as well.
+		 */
+		if (dbc->dbtype == DB_HASH && F_ISSET(
+		    ((BTREE_CURSOR *)(dbc->internal->opd->internal)),
+		    C_DELETED)) {
+			ret = DB_NOTFOUND;
+			goto err;
+		}
+
+		if ((ret = dbc->am_writelock(dbc)) != 0 ||
+		    (ret = __dbc_dup(dbc, &dbc_n, DB_POSITION)) != 0)
+			goto err;
+		opd = dbc_n->internal->opd;
+		if ((ret = opd->am_put(
+		    opd, key, data, flags, NULL)) != 0)
+			goto err;
+		goto done;
+	}
+
+	/*
+	 * Perform an operation on the main cursor.  Duplicate the cursor,
+	 * and call the underlying function.
+	 */
+	if (flags == DB_AFTER || flags == DB_BEFORE || flags == DB_CURRENT)
+		tmp_flags = DB_POSITION;
+	else
+		tmp_flags = 0;
+
+	/*
+	 * If this cursor is going to be closed immediately, we don't
+	 * need to take precautions to clean it up on error.
+	 */
+	if (F_ISSET(dbc, DBC_TRANSIENT | DBC_PARTITIONED))
+		dbc_n = dbc;
+	else if ((ret = __dbc_idup(dbc, &dbc_n, tmp_flags)) != 0)
+		goto err;
+
+	pgno = PGNO_INVALID;
+	if ((ret = dbc_n->am_put(dbc_n, key, data, flags, &pgno)) != 0)
+		goto err;
+
+	/*
+	 * We may be referencing a new off-page duplicates tree.  Acquire
+	 * a new cursor and call the underlying function.
+	 */
+	if (pgno != PGNO_INVALID) {
+		oldopd = dbc_n->internal->opd;
+		if ((ret = __dbc_newopd(dbc, pgno, oldopd, &opd)) != 0) {
+			dbc_n->internal->opd = opd;
+			goto err;
+		}
+
+		dbc_n->internal->opd = opd;
+		opd->internal->pdbc = dbc_n;
+
+		if (flags == DB_NOOVERWRITE)
+			flags = DB_KEYLAST;
+		if ((ret = opd->am_put(
+		    opd, key, data, flags, NULL)) != 0)
+			goto err;
+	}
+
+done:
+err:	/* Cleanup and cursor resolution. */
+	if (dbc_n != NULL && !DB_RETOK_DBCPUT(ret))
+		F_SET(dbc_n, DBC_ERROR);
+	if ((t_ret = __dbc_cleanup(dbc, dbc_n, ret)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+/*
+ * __dbc_del_oldskey --
+ *	Delete an old secondary key, if necessary.
+ *	Returns DB_KEYEXIST if the new and old keys match..
+ */
+static int
+__dbc_del_oldskey(sdbp, dbc, skey, pkey, olddata)
+	DB *sdbp;
+	DBC *dbc;
+	DBT *skey, *pkey, *olddata;
+{
+	DB *dbp;
+	DBC *sdbc;
+	DBT *toldskeyp, *tskeyp;
+	DBT oldskey, temppkey, tempskey;
+	ENV *env;
+	int ret, t_ret;
+	u_int32_t i, noldskey, nsame, nskey, rmw;
+
+	sdbc = NULL;
+	dbp = sdbp->s_primary;
+	env = dbp->env;
+	nsame = 0;
+	rmw = STD_LOCKING(dbc) ? DB_RMW : 0;
+
+	/*
+	 * Get the old secondary key.
+	 */
+	memset(&oldskey, 0, sizeof(DBT));
+	if ((ret = sdbp->s_callback(sdbp, pkey, olddata, &oldskey)) != 0) {
+		if (ret == DB_DONOTINDEX ||
+		    (F_ISSET(&oldskey, DB_DBT_MULTIPLE) && oldskey.size == 0))
+			/* There's no old key to delete. */
+			ret = 0;
+		return (ret);
+	}
+
+	if (F_ISSET(&oldskey, DB_DBT_MULTIPLE)) {
+#ifdef DIAGNOSTIC
+		__db_check_skeyset(sdbp, &oldskey);
+#endif
+		toldskeyp = (DBT *)oldskey.data;
+		noldskey = oldskey.size;
+	} else {
+		toldskeyp = &oldskey;
+		noldskey = 1;
+	}
+
+	if (F_ISSET(skey, DB_DBT_MULTIPLE)) {
+		nskey = skey->size;
+		skey = (DBT *)skey->data;
+	} else
+		nskey = F_ISSET(skey, DB_DBT_ISSET) ? 1 : 0;
+
+	for (; noldskey > 0 && ret == 0; noldskey--, toldskeyp++) {
+		/*
+		 * Check whether this old secondary key is also a new key
+		 * before we delete it.  Note that bt_compare is (and must be)
+		 * set no matter what access method we're in.
+		 */
+		for (i = 0, tskeyp = skey; i < nskey; i++, tskeyp++)
+			if (((BTREE *)sdbp->bt_internal)->bt_compare(sdbp,
+			    toldskeyp, tskeyp) == 0) {
+				nsame++;
+				F_CLR(tskeyp, DB_DBT_ISSET);
+				break;
+			}
+
+		if (i < nskey) {
+			FREE_IF_NEEDED(env, toldskeyp);
+			continue;
+		}
+
+		if (sdbc == NULL) {
+			if ((ret = __db_cursor_int(sdbp,
+			    dbc->thread_info, dbc->txn, sdbp->type,
+			    PGNO_INVALID, 0, dbc->locker, &sdbc)) != 0)
+				goto err;
+			if (CDB_LOCKING(env)) {
+				DB_ASSERT(env,
+				    sdbc->mylock.off == LOCK_INVALID);
+				F_SET(sdbc, DBC_WRITER);
+			}
+		}
+
+		/*
+		 * Don't let c_get(DB_GET_BOTH) stomp on our data.  Use
+		 * temporary DBTs instead.
+		 */
+		SWAP_IF_NEEDED(sdbp, pkey);
+		DB_INIT_DBT(temppkey, pkey->data, pkey->size);
+		DB_INIT_DBT(tempskey, toldskeyp->data, toldskeyp->size);
+		if ((ret = __dbc_get(sdbc,
+		    &tempskey, &temppkey, rmw | DB_GET_BOTH)) == 0)
+			ret = __dbc_del(sdbc, DB_UPDATE_SECONDARY);
+		else if (ret == DB_NOTFOUND)
+			ret = __db_secondary_corrupt(dbp);
+		SWAP_IF_NEEDED(sdbp, pkey);
+		FREE_IF_NEEDED(env, toldskeyp);
+	}
+
+err:	for (; noldskey > 0; noldskey--, toldskeyp++)
+		FREE_IF_NEEDED(env, toldskeyp);
+	FREE_IF_NEEDED(env, &oldskey);
+	if (sdbc != NULL && (t_ret = __dbc_close(sdbc)) != 0 && ret == 0)
+		ret = t_ret;
+	if (ret == 0 && nsame == nskey)
+		return (DB_KEYEXIST);
+	return (ret);
+}
+
+/*
+ * __db_duperr()
+ *	Error message: we don't currently support sorted duplicate duplicates.
+ * PUBLIC: int __db_duperr __P((DB *, u_int32_t));
+ */
+int
+__db_duperr(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	/*
+	 * If we run into this error while updating a secondary index,
+	 * don't yell--there's no clean way to pass DB_NODUPDATA in along
+	 * with DB_UPDATE_SECONDARY, but we may run into this problem
+	 * in a normal, non-error course of events.
+	 *
+	 * !!!
+	 * If and when we ever permit duplicate duplicates in sorted-dup
+	 * databases, we need to either change the secondary index code
+	 * to check for dup dups, or we need to maintain the implicit
+	 * "DB_NODUPDATA" behavior for databases with DB_AM_SECONDARY set.
+	 */
+	if (flags != DB_NODUPDATA && !F_ISSET(dbp, DB_AM_SECONDARY))
+		__db_errx(dbp->env, DB_STR("0696",
+		    "Duplicate data items are not supported with sorted data"));
+	return (DB_KEYEXIST);
+}
+
+/*
+ * __dbc_cleanup --
+ *	Clean up duplicate cursors.
+ *
+ * PUBLIC: int __dbc_cleanup __P((DBC *, DBC *, int));
+ */
+int
+__dbc_cleanup(dbc, dbc_n, failed)
+	DBC *dbc, *dbc_n;
+	int failed;
+{
+	DB *dbp;
+	DBC *opd;
+	DBC_INTERNAL *internal;
+	DB_MPOOLFILE *mpf;
+	int ret, t_ret;
+
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_OFF(dbc->thread_info);
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	internal = dbc->internal;
+	ret = 0;
+
+	/* Discard any pages we're holding. */
+	if (internal->page != NULL) {
+		if ((t_ret = __memp_fput(mpf, dbc->thread_info,
+		     internal->page, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+		internal->page = NULL;
+	}
+	opd = internal->opd;
+	if (opd != NULL && opd->internal->page != NULL) {
+		if ((t_ret = __memp_fput(mpf, dbc->thread_info,
+		    opd->internal->page, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+		opd->internal->page = NULL;
+	}
+
+	/*
+	 * If dbc_n is NULL, there's no internal cursor swapping to be done
+	 * and no dbc_n to close--we probably did the entire operation on an
+	 * offpage duplicate cursor.  Just return.
+	 *
+	 * If dbc and dbc_n are the same, we're either inside a DB->{put/get}
+	 * operation, and as an optimization we performed the operation on
+	 * the main cursor rather than on a duplicated one, or we're in a
+	 * bulk get that can't have moved the cursor (DB_MULTIPLE with the
+	 * initial c_get operation on an off-page dup cursor).  Just
+	 * return--either we know we didn't move the cursor, or we're going
+	 * to close it before we return to application code, so we're sure
+	 * not to visibly violate the "cursor stays put on error" rule.
+	 */
+	if (dbc_n == NULL || dbc == dbc_n)
+		goto done;
+
+	if (dbc_n->internal->page != NULL) {
+		if ((t_ret = __memp_fput(mpf, dbc->thread_info,
+		    dbc_n->internal->page, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+		dbc_n->internal->page = NULL;
+	}
+	opd = dbc_n->internal->opd;
+	if (opd != NULL && opd->internal->page != NULL) {
+		if ((t_ret = __memp_fput(mpf, dbc->thread_info,
+		     opd->internal->page, dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+		opd->internal->page = NULL;
+	}
+
+	/*
+	 * If we didn't fail before entering this routine or just now when
+	 * freeing pages, swap the interesting contents of the old and new
+	 * cursors.
+	 */
+	if (!failed && ret == 0) {
+		if (opd != NULL)
+			opd->internal->pdbc = dbc;
+		if (internal->opd != NULL)
+			internal->opd->internal->pdbc = dbc_n;
+		dbc->internal = dbc_n->internal;
+		dbc_n->internal = internal;
+	}
+
+	/*
+	 * Close the cursor we don't care about anymore.  The close can fail,
+	 * but we only expect DB_LOCK_DEADLOCK failures.  This violates our
+	 * "the cursor is unchanged on error" semantics, but since all you can
+	 * do with a DB_LOCK_DEADLOCK failure is close the cursor, I believe
+	 * that's OK.
+	 *
+	 * XXX
+	 * There's no way to recover from failure to close the old cursor.
+	 * All we can do is move to the new position and return an error.
+	 *
+	 * XXX
+	 * We might want to consider adding a flag to the cursor, so that any
+	 * subsequent operations other than close just return an error?
+	 */
+	if ((t_ret = __dbc_close(dbc_n)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * If this was an update that is supporting dirty reads
+	 * then we may have just swapped our read for a write lock
+	 * which is held by the surviving cursor.  We need
+	 * to explicitly downgrade this lock.  The closed cursor
+	 * may only have had a read lock.
+	 */
+	if (ret == 0 && failed == 0 && F_ISSET(dbp, DB_AM_READ_UNCOMMITTED) &&
+	    dbc->internal->lock_mode == DB_LOCK_WRITE &&
+	    (ret = __TLPUT(dbc, dbc->internal->lock)) == 0)
+		dbc->internal->lock_mode = DB_LOCK_WWRITE;
+
+done:
+	if (F_ISSET(dbc, DBC_OPD))
+		LOCK_CHECK_ON(dbc->thread_info);
+
+	return (ret);
+}
+
+/*
+ * __dbc_secondary_get_pp --
+ *	This wrapper function for DBC->pget() is the DBC->get() function
+ *	for a secondary index cursor.
+ *
+ * PUBLIC: int __dbc_secondary_get_pp __P((DBC *, DBT *, DBT *, u_int32_t));
+ */
+int
+__dbc_secondary_get_pp(dbc, skey, data, flags)
+	DBC *dbc;
+	DBT *skey, *data;
+	u_int32_t flags;
+{
+	DB_ASSERT(dbc->env, F_ISSET(dbc->dbp, DB_AM_SECONDARY));
+	return (__dbc_pget_pp(dbc, skey, NULL, data, flags));
+}
+
+/*
+ * __dbc_pget --
+ *	Get a primary key/data pair through a secondary index.
+ *
+ * PUBLIC: int __dbc_pget __P((DBC *, DBT *, DBT *, DBT *, u_int32_t));
+ */
+int
+__dbc_pget(dbc, skey, pkey, data, flags)
+	DBC *dbc;
+	DBT *skey, *pkey, *data;
+	u_int32_t flags;
+{
+	DB *pdbp, *sdbp;
+	DBC *dbc_n, *pdbc;
+	DBT nullpkey, *save_data;
+	u_int32_t save_pkey_flags, tmp_flags, tmp_read_locking, tmp_rmw;
+	int pkeymalloc, ret, t_ret;
+
+	sdbp = dbc->dbp;
+	pdbp = sdbp->s_primary;
+	dbc_n = NULL;
+	save_data = NULL;
+	pkeymalloc = t_ret = 0;
+
+	/*
+	 * The challenging part of this function is getting the behavior
+	 * right for all the various permutations of DBT flags.  The
+	 * next several blocks handle the various cases we need to
+	 * deal with specially.
+	 */
+
+	/*
+	 * We may be called with a NULL pkey argument, if we've been
+	 * wrapped by a 2-DBT get call.  If so, we need to use our
+	 * own DBT.
+	 */
+	if (pkey == NULL) {
+		memset(&nullpkey, 0, sizeof(DBT));
+		pkey = &nullpkey;
+	}
+
+	/* Clear OR'd in additional bits so we can check for flag equality. */
+	tmp_rmw = LF_ISSET(DB_RMW);
+	LF_CLR(DB_RMW);
+
+	SET_READ_LOCKING_FLAGS(dbc, tmp_read_locking);
+	/*
+	 * DB_GET_RECNO is a special case, because we're interested not in
+	 * the primary key/data pair, but rather in the primary's record
+	 * number.
+	 */
+	if (flags == DB_GET_RECNO) {
+		if (tmp_rmw)
+			F_SET(dbc, DBC_RMW);
+		F_SET(dbc, tmp_read_locking);
+		ret = __dbc_pget_recno(dbc, pkey, data, flags);
+		if (tmp_rmw)
+			F_CLR(dbc, DBC_RMW);
+		/* Clear the temp flags, but leave WAS_READ_COMMITTED. */
+		F_CLR(dbc, tmp_read_locking & ~DBC_WAS_READ_COMMITTED);
+		return (ret);
+	}
+
+	/*
+	 * If the DBTs we've been passed don't have any of the
+	 * user-specified memory management flags set, we want to make sure
+	 * we return values using the DBTs dbc->rskey, dbc->rkey, and
+	 * dbc->rdata, respectively.
+	 *
+	 * There are two tricky aspects to this:  first, we need to pass
+	 * skey and pkey *in* to the initial c_get on the secondary key,
+	 * since either or both may be looked at by it (depending on the
+	 * get flag).  Second, we must not use a normal DB->get call
+	 * on the secondary, even though that's what we want to accomplish,
+	 * because the DB handle may be free-threaded.  Instead,
+	 * we open a cursor, then take steps to ensure that we actually use
+	 * the rkey/rdata from the *secondary* cursor.
+	 *
+	 * We accomplish all this by passing in the DBTs we started out
+	 * with to the c_get, but swapping the contents of rskey and rkey,
+	 * respectively, into rkey and rdata;  __db_ret will treat them like
+	 * the normal key/data pair in a c_get call, and will realloc them as
+	 * need be (this is "step 1").  Then, for "step 2", we swap back
+	 * rskey/rkey/rdata to normal, and do a get on the primary with the
+	 * secondary dbc appointed as the owner of the returned-data memory.
+	 *
+	 * Note that in step 2, we copy the flags field in case we need to
+	 * pass down a DB_DBT_PARTIAL or other flag that is compatible with
+	 * letting DB do the memory management.
+	 */
+
+	/*
+	 * It is correct, though slightly sick, to attempt a partial get of a
+	 * primary key.  However, if we do so here, we'll never find the
+	 * primary record;  clear the DB_DBT_PARTIAL field of pkey just for the
+	 * duration of the next call.
+	 */
+	save_pkey_flags = pkey->flags;
+	F_CLR(pkey, DB_DBT_PARTIAL);
+
+	/*
+	 * Now we can go ahead with the meat of this call.  First, get the
+	 * primary key from the secondary index.  (What exactly we get depends
+	 * on the flags, but the underlying cursor get will take care of the
+	 * dirty work.)  Duplicate the cursor, in case the later get on the
+	 * primary fails.
+	 */
+	switch (flags) {
+	case DB_CURRENT:
+	case DB_GET_BOTHC:
+	case DB_NEXT:
+	case DB_NEXT_DUP:
+	case DB_NEXT_NODUP:
+	case DB_PREV:
+	case DB_PREV_DUP:
+	case DB_PREV_NODUP:
+		tmp_flags = DB_POSITION;
+		break;
+	default:
+		tmp_flags = 0;
+		break;
+	}
+
+	if (dbc->internal->opd != NULL ||
+	     F_ISSET(dbc, DBC_PARTITIONED | DBC_TRANSIENT)) {
+		dbc_n = dbc;
+		save_data = dbc_n->rdata;
+	} else {
+		if ((ret = __dbc_dup(dbc, &dbc_n, tmp_flags)) != 0)
+			return (ret);
+		F_SET(dbc_n, DBC_TRANSIENT);
+	}
+	dbc_n->rdata = dbc->rkey;
+	dbc_n->rkey = dbc->rskey;
+
+	if (tmp_rmw)
+		F_SET(dbc_n, DBC_RMW);
+	F_SET(dbc_n, tmp_read_locking);
+
+	/*
+	 * If we've been handed a primary key, it will be in native byte order,
+	 * so we need to swap it before reading from the secondary.
+	 */
+	if (flags == DB_GET_BOTH || flags == DB_GET_BOTHC ||
+	    flags == DB_GET_BOTH_RANGE)
+		SWAP_IF_NEEDED(sdbp, pkey);
+
+retry:	/* Step 1. */
+	ret = __dbc_get(dbc_n, skey, pkey, flags);
+	/* Restore pkey's flags in case we stomped the PARTIAL flag. */
+	pkey->flags = save_pkey_flags;
+
+	/*
+	 * We need to swap the primary key to native byte order if we read it
+	 * successfully, or if we swapped it on entry above.  We can't return
+	 * with the application's data modified.
+	 */
+	if (ret == 0 || flags == DB_GET_BOTH || flags == DB_GET_BOTHC ||
+	    flags == DB_GET_BOTH_RANGE)
+		SWAP_IF_NEEDED(sdbp, pkey);
+
+	if (ret != 0)
+		goto err;
+
+	/*
+	 * Now we're ready for "step 2".  If either or both of pkey and data do
+	 * not have memory management flags set--that is, if DB is managing
+	 * their memory--we need to swap around the rkey/rdata structures so
+	 * that we don't wind up trying to use memory managed by the primary
+	 * database cursor, which we'll close before we return.
+	 *
+	 * !!!
+	 * If you're carefully following the bouncing ball, you'll note that in
+	 * the DB-managed case, the buffer hanging off of pkey is the same as
+	 * dbc->rkey->data.  This is just fine;  we may well realloc and stomp
+	 * on it when we return, if we're doing a DB_GET_BOTH and need to
+	 * return a different partial or key (depending on the comparison
+	 * function), but this is safe.
+	 *
+	 * !!!
+	 * We need to use __db_cursor_int here rather than simply calling
+	 * pdbp->cursor, because otherwise, if we're in CDB, we'll allocate a
+	 * new locker ID and leave ourselves open to deadlocks.  (Even though
+	 * we're only acquiring read locks, we'll still block if there are any
+	 * waiters.)
+	 */
+	if ((ret = __db_cursor_int(pdbp, dbc->thread_info,
+	    dbc->txn, pdbp->type, PGNO_INVALID, 0, dbc->locker, &pdbc)) != 0)
+		goto err;
+
+	F_SET(pdbc, tmp_read_locking |
+	     F_ISSET(dbc, DBC_READ_UNCOMMITTED | DBC_READ_COMMITTED | DBC_RMW));
+
+	/*
+	 * We're about to use pkey a second time.  If DB_DBT_MALLOC is set on
+	 * it, we'll leak the memory we allocated the first time.  Thus, set
+	 * DB_DBT_REALLOC instead so that we reuse that memory instead of
+	 * leaking it.
+	 *
+	 * Alternatively, if the application is handling copying for pkey, we
+	 * need to take a copy now.  The copy will be freed on exit from
+	 * __dbc_pget_pp (and we must be coming through there if DB_DBT_USERCOPY
+	 * is set).  In the case of DB_GET_BOTH_RANGE, the pkey supplied by
+	 * the application has already been copied in but the value may have
+	 * changed in the search.  In that case, free the original copy and get
+	 * a new one.
+	 *
+	 * !!!
+	 * This assumes that the user must always specify a compatible realloc
+	 * function if a malloc function is specified.  I think this is a
+	 * reasonable requirement.
+	 */
+	if (F_ISSET(pkey, DB_DBT_MALLOC)) {
+		F_CLR(pkey, DB_DBT_MALLOC);
+		F_SET(pkey, DB_DBT_REALLOC);
+		pkeymalloc = 1;
+	} else if (F_ISSET(pkey, DB_DBT_USERCOPY)) {
+		if (flags == DB_GET_BOTH_RANGE)
+			__dbt_userfree(sdbp->env, NULL, pkey, NULL);
+		if ((ret = __dbt_usercopy(sdbp->env, pkey)) != 0)
+			goto err;
+	}
+
+	/*
+	 * Do the actual get.  Set DBC_TRANSIENT since we don't care about
+	 * preserving the position on error, and it's faster.  SET_RET_MEM so
+	 * that the secondary DBC owns any returned-data memory.
+	 */
+	F_SET(pdbc, DBC_TRANSIENT);
+	SET_RET_MEM(pdbc, dbc);
+	ret = __dbc_get(pdbc, pkey, data, DB_SET);
+	DB_ASSERT(pdbp->env, ret != DB_PAGE_NOTFOUND);
+
+	/*
+	 * If the item wasn't found in the primary, this is a bug; our
+	 * secondary has somehow gotten corrupted, and contains elements that
+	 * don't correspond to anything in the primary.  Complain.
+	 */
+
+	/* Now close the primary cursor. */
+	if ((t_ret = __dbc_close(pdbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	else if (ret == DB_NOTFOUND) {
+		if (!F_ISSET(dbc, DBC_READ_UNCOMMITTED))
+			ret = __db_secondary_corrupt(pdbp);
+		else switch (flags) {
+		case DB_GET_BOTHC:
+		case DB_NEXT:
+		case DB_NEXT_DUP:
+		case DB_NEXT_NODUP:
+		case DB_PREV:
+		case DB_PREV_DUP:
+		case DB_PREV_NODUP:
+			PERFMON5(pdbp->env, race, dbc_get,
+			    sdbp->fname, sdbp->dname, ret, flags, pkey);
+			goto retry;
+		default:
+			break;
+		}
+	}
+
+err:	/* Cleanup and cursor resolution. */
+	if (dbc_n == dbc) {
+		dbc_n->rkey = dbc_n->rdata;
+		dbc_n->rdata = save_data;
+	}
+	if ((t_ret = __dbc_cleanup(dbc, dbc_n, ret)) != 0 && ret == 0)
+		ret = t_ret;
+	if (pkeymalloc) {
+		/*
+		 * If pkey had a MALLOC flag, we need to restore it; otherwise,
+		 * if the user frees the buffer but reuses the DBT without
+		 * NULL'ing its data field or changing the flags, we may drop
+		 * core.
+		 */
+		F_CLR(pkey, DB_DBT_REALLOC);
+		F_SET(pkey, DB_DBT_MALLOC);
+	}
+
+	return (ret);
+}
+
+/*
+ * __dbc_pget_recno --
+ *	Perform a DB_GET_RECNO c_pget on a secondary index.  Returns
+ * the secondary's record number in the pkey field and the primary's
+ * in the data field.
+ */
+static int
+__dbc_pget_recno(sdbc, pkey, data, flags)
+	DBC *sdbc;
+	DBT *pkey, *data;
+	u_int32_t flags;
+{
+	DB *pdbp, *sdbp;
+	DBC *pdbc;
+	DBT discardme, primary_key;
+	ENV *env;
+	db_recno_t oob;
+	u_int32_t rmw;
+	int ret, t_ret;
+
+	sdbp = sdbc->dbp;
+	pdbp = sdbp->s_primary;
+	env = sdbp->env;
+	pdbc = NULL;
+	ret = t_ret = 0;
+
+	rmw = LF_ISSET(DB_RMW);
+
+	memset(&discardme, 0, sizeof(DBT));
+	F_SET(&discardme, DB_DBT_USERMEM | DB_DBT_PARTIAL);
+
+	oob = RECNO_OOB;
+
+	/*
+	 * If the primary is an rbtree, we want its record number, whether
+	 * or not the secondary is one too.  Fetch the recno into "data".
+	 *
+	 * If it's not an rbtree, return RECNO_OOB in "data".
+	 */
+	if (F_ISSET(pdbp, DB_AM_RECNUM)) {
+		/*
+		 * Get the primary key, so we can find the record number
+		 * in the primary. (We're uninterested in the secondary key.)
+		 */
+		memset(&primary_key, 0, sizeof(DBT));
+		F_SET(&primary_key, DB_DBT_MALLOC);
+		if ((ret = __dbc_get(sdbc,
+		    &discardme, &primary_key, rmw | DB_CURRENT)) != 0)
+			return (ret);
+
+		/*
+		 * Open a cursor on the primary, set it to the right record,
+		 * and fetch its recno into "data".
+		 *
+		 * (See __dbc_pget for comments on the use of __db_cursor_int.)
+		 *
+		 * SET_RET_MEM so that the secondary DBC owns any returned-data
+		 * memory.
+		 */
+		if ((ret = __db_cursor_int(pdbp, sdbc->thread_info, sdbc->txn,
+		    pdbp->type, PGNO_INVALID, 0, sdbc->locker, &pdbc)) != 0)
+			goto perr;
+		SET_RET_MEM(pdbc, sdbc);
+		if ((ret = __dbc_get(pdbc,
+		    &primary_key, &discardme, rmw | DB_SET)) != 0)
+			goto perr;
+
+		ret = __dbc_get(pdbc, &discardme, data, rmw | DB_GET_RECNO);
+
+perr:		__os_ufree(env, primary_key.data);
+		if (pdbc != NULL &&
+		    (t_ret = __dbc_close(pdbc)) != 0 && ret == 0)
+			ret = t_ret;
+		if (ret != 0)
+			return (ret);
+	} else if ((ret = __db_retcopy(env, data, &oob,
+		    sizeof(oob), &sdbc->rkey->data, &sdbc->rkey->ulen)) != 0)
+			return (ret);
+
+	/*
+	 * If the secondary is an rbtree, we want its record number, whether
+	 * or not the primary is one too.  Fetch the recno into "pkey".
+	 *
+	 * If it's not an rbtree, return RECNO_OOB in "pkey".
+	 */
+	if (F_ISSET(sdbp, DB_AM_RECNUM))
+		return (__dbc_get(sdbc, &discardme, pkey, flags));
+	else
+		return (__db_retcopy(env, pkey, &oob,
+		    sizeof(oob), &sdbc->rdata->data, &sdbc->rdata->ulen));
+}
+
+/*
+ * __db_wrlock_err -- do not have a write lock.
+ */
+static int
+__db_wrlock_err(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("0697", "Write attempted on read-only cursor"));
+	return (EPERM);
+}
+
+/*
+ * __dbc_del_secondary --
+ *	Perform a delete operation on a secondary index:  call through
+ *	to the primary and delete the primary record that this record
+ *	points to.
+ *
+ *	Note that deleting the primary record will call c_del on all
+ *	the secondaries, including this one;  thus, it is not necessary
+ *	to execute both this function and an actual delete.
+ */
+static int
+__dbc_del_secondary(dbc)
+	DBC *dbc;
+{
+	DB *pdbp;
+	DBC *pdbc;
+	DBT skey, pkey;
+	ENV *env;
+	int ret, t_ret;
+	u_int32_t rmw;
+
+	pdbp = dbc->dbp->s_primary;
+	env = pdbp->env;
+	rmw = STD_LOCKING(dbc) ? DB_RMW : 0;
+
+	/*
+	 * Get the current item that we're pointing at.
+	 * We don't actually care about the secondary key, just
+	 * the primary.
+	 */
+	memset(&skey, 0, sizeof(DBT));
+	memset(&pkey, 0, sizeof(DBT));
+	F_SET(&skey, DB_DBT_PARTIAL | DB_DBT_USERMEM);
+	if ((ret = __dbc_get(dbc, &skey, &pkey, DB_CURRENT)) != 0)
+		return (ret);
+
+	SWAP_IF_NEEDED(dbc->dbp, &pkey);
+	DEBUG_LWRITE(dbc, dbc->txn, "del_secondary", &skey, &pkey, 0);
+
+	/*
+	 * Create a cursor on the primary with our locker ID,
+	 * so that when it calls back, we don't conflict.
+	 *
+	 * We create a cursor explicitly because there's no
+	 * way to specify the same locker ID if we're using
+	 * locking but not transactions if we use the DB->del
+	 * interface.  This shouldn't be any less efficient
+	 * anyway.
+	 */
+	if ((ret = __db_cursor_int(pdbp, dbc->thread_info, dbc->txn,
+	    pdbp->type, PGNO_INVALID, 0, dbc->locker, &pdbc)) != 0)
+		return (ret);
+
+	/*
+	 * See comment in __dbc_put--if we're in CDB,
+	 * we already hold the locks we need, and we need to flag
+	 * the cursor as a WRITER so we don't run into errors
+	 * when we try to delete.
+	 */
+	if (CDB_LOCKING(env)) {
+		DB_ASSERT(env, pdbc->mylock.off == LOCK_INVALID);
+		F_SET(pdbc, DBC_WRITER);
+	}
+
+	/*
+	 * Set the new cursor to the correct primary key.  Then
+	 * delete it.  We don't really care about the datum;
+	 * just reuse our skey DBT.
+	 *
+	 * If the primary get returns DB_NOTFOUND, something is amiss--
+	 * every record in the secondary should correspond to some record
+	 * in the primary.
+	 */
+	if ((ret = __dbc_get(pdbc, &pkey, &skey, DB_SET | rmw)) == 0)
+		ret = __dbc_del(pdbc, 0);
+	else if (ret == DB_NOTFOUND)
+		ret = __db_secondary_corrupt(pdbp);
+
+	if ((t_ret = __dbc_close(pdbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __dbc_del_primary --
+ *	Perform a delete operation on a primary index.  Loop through
+ *	all the secondary indices which correspond to this primary
+ *	database, and delete any secondary keys that point at the current
+ *	record.
+ *
+ * PUBLIC: int __dbc_del_primary __P((DBC *));
+ */
+int
+__dbc_del_primary(dbc)
+	DBC *dbc;
+{
+	DB *dbp, *sdbp;
+	DBC *sdbc;
+	DBT *tskeyp;
+	DBT data, pkey, skey, temppkey, tempskey;
+	ENV *env;
+	u_int32_t nskey, rmw;
+	int ret, t_ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	sdbp = NULL;
+	rmw = STD_LOCKING(dbc) ? DB_RMW : 0;
+
+	/*
+	 * If we're called at all, we have at least one secondary.
+	 * (Unfortunately, we can't assert this without grabbing the mutex.)
+	 * Get the current record so that we can construct appropriate
+	 * secondary keys as needed.
+	 */
+	memset(&pkey, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+	if ((ret = __dbc_get(dbc, &pkey, &data, DB_CURRENT)) != 0)
+		return (ret);
+
+	memset(&skey, 0, sizeof(DBT));
+	for (ret = __db_s_first(dbp, &sdbp);
+	    sdbp != NULL && ret == 0;
+	    ret = __db_s_next(&sdbp, dbc->txn)) {
+		/*
+		 * Get the secondary key for this secondary and the current
+		 * item.
+		 */
+		if ((ret = sdbp->s_callback(sdbp, &pkey, &data, &skey)) != 0) {
+			/* Not indexing is equivalent to an empty key set. */
+			if (ret == DB_DONOTINDEX) {
+				F_SET(&skey, DB_DBT_MULTIPLE);
+				skey.size = 0;
+			} else /* We had a substantive error.  Bail. */
+				goto err;
+		}
+
+#ifdef DIAGNOSTIC
+		if (F_ISSET(&skey, DB_DBT_MULTIPLE))
+			__db_check_skeyset(sdbp, &skey);
+#endif
+
+		if (F_ISSET(&skey, DB_DBT_MULTIPLE)) {
+			tskeyp = (DBT *)skey.data;
+			nskey = skey.size;
+			if (nskey == 0)
+				continue;
+		} else {
+			tskeyp = &skey;
+			nskey = 1;
+		}
+
+		/* Open a secondary cursor. */
+		if ((ret = __db_cursor_int(sdbp,
+		    dbc->thread_info, dbc->txn, sdbp->type,
+		    PGNO_INVALID, 0, dbc->locker, &sdbc)) != 0)
+			goto err;
+		/* See comment above and in __dbc_put. */
+		if (CDB_LOCKING(env)) {
+			DB_ASSERT(env, sdbc->mylock.off == LOCK_INVALID);
+			F_SET(sdbc, DBC_WRITER);
+		}
+
+		for (; nskey > 0; nskey--, tskeyp++) {
+			/*
+			 * Set the secondary cursor to the appropriate item.
+			 * Delete it.
+			 *
+			 * We want to use DB_RMW if locking is on; it's only
+			 * legal then, though.
+			 *
+			 * !!!
+			 * Don't stomp on any callback-allocated buffer in skey
+			 * when we do a c_get(DB_GET_BOTH); use a temp DBT
+			 * instead.  Similarly, don't allow pkey to be
+			 * invalidated when the cursor is closed.
+			 */
+			DB_INIT_DBT(tempskey, tskeyp->data, tskeyp->size);
+			SWAP_IF_NEEDED(sdbp, &pkey);
+			DB_INIT_DBT(temppkey, pkey.data, pkey.size);
+			if ((ret = __dbc_get(sdbc, &tempskey, &temppkey,
+			    DB_GET_BOTH | rmw)) == 0)
+				ret = __dbc_del(sdbc, DB_UPDATE_SECONDARY);
+			else if (ret == DB_NOTFOUND)
+				ret = __db_secondary_corrupt(dbp);
+			SWAP_IF_NEEDED(sdbp, &pkey);
+			FREE_IF_NEEDED(env, tskeyp);
+		}
+
+		if ((t_ret = __dbc_close(sdbc)) != 0 && ret == 0)
+			ret = t_ret;
+		if (ret != 0)
+			goto err;
+
+		/*
+		 * In the common case where there is a single secondary key, we
+		 * will have freed any application-allocated data in skey
+		 * already.  In the multiple key case, we need to free it here.
+		 * It is safe to do this twice as the macro resets the data
+		 * field.
+		 */
+		FREE_IF_NEEDED(env, &skey);
+	}
+
+err:	if (sdbp != NULL &&
+	    (t_ret = __db_s_done(sdbp, dbc->txn)) != 0 && ret == 0)
+		ret = t_ret;
+	FREE_IF_NEEDED(env, &skey);
+	return (ret);
+}
+
+/*
+ * __dbc_del_foreign --
+ *	Apply the foreign database constraints for a particular foreign
+ *	database when an item is being deleted (dbc points at item being deleted
+ *	in the foreign database.)
+ *
+ *      Delete happens in dbp, check for occurrences of key in pdpb.
+ *      Terminology:
+ *        Foreign db = Where delete occurs (dbp).
+ *        Secondary db = Where references to dbp occur (sdbp, a secondary)
+ *        Primary db = sdbp's primary database, references to dbp are secondary
+ *                      keys here
+ *        Foreign Key = Key being deleted in dbp (fkey)
+ *        Primary Key = Key of the corresponding entry in sdbp's primary (pkey).
+ */
+static int
+__dbc_del_foreign(dbc)
+	DBC *dbc;
+{
+	DB_FOREIGN_INFO *f_info;
+	DB *dbp, *pdbp, *sdbp;
+	DBC *pdbc, *sdbc;
+	DBT data, fkey, pkey;
+	ENV *env;
+	u_int32_t flags, rmw;
+	int changed, ret, t_ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	memset(&fkey, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+	if ((ret = __dbc_get(dbc, &fkey, &data, DB_CURRENT)) != 0)
+		return (ret);
+
+	LIST_FOREACH(f_info, &(dbp->f_primaries), f_links) {
+		sdbp = f_info->dbp;
+		pdbp = sdbp->s_primary;
+		flags = f_info->flags;
+
+		rmw = (STD_LOCKING(dbc) &&
+		    !LF_ISSET(DB_FOREIGN_ABORT)) ? DB_RMW : 0;
+
+		/*
+		 * Handle CDB locking.  Some of this is copied from
+		 * __dbc_del_primary, but a bit more acrobatics are required.
+		 * If we're not going to abort, then we need to get a write
+		 * cursor.  If CDB_ALLDB is set, then only one write cursor is
+		 * allowed and we hold it, so we fudge things and promote the
+		 * cursor on the other DBs manually, it won't cause a problem.
+		 * If CDB_ALLDB is not set, then we go through the usual route
+		 * to make sure we block as necessary.  If there are any open
+		 * read cursors on sdbp, the delete or put call later will
+		 * block.
+		 *
+		 * If NULLIFY is set, we'll need a cursor on the primary to
+		 * update it with the nullified data.  Because primary and
+		 * secondary dbs share a lock file ID in CDB, we open a cursor
+		 * on the secondary and then get another writable cursor on the
+		 * primary via __db_cursor_int to avoid deadlocking.
+		 */
+		sdbc = pdbc = NULL;
+		if (!LF_ISSET(DB_FOREIGN_ABORT) && CDB_LOCKING(env) &&
+		    !F_ISSET(env->dbenv, DB_ENV_CDB_ALLDB)) {
+			ret = __db_cursor(sdbp,
+			    dbc->thread_info, dbc->txn, &sdbc, DB_WRITECURSOR);
+			if (LF_ISSET(DB_FOREIGN_NULLIFY) && ret == 0) {
+				ret = __db_cursor_int(pdbp,
+				    dbc->thread_info, dbc->txn, pdbp->type,
+				    PGNO_INVALID, 0, dbc->locker, &pdbc);
+				F_SET(pdbc, DBC_WRITER);
+			}
+		} else {
+			ret = __db_cursor_int(sdbp, dbc->thread_info, dbc->txn,
+			    sdbp->type, PGNO_INVALID, 0, dbc->locker, &sdbc);
+			if (LF_ISSET(DB_FOREIGN_NULLIFY) && ret == 0)
+				ret = __db_cursor_int(pdbp, dbc->thread_info,
+				    dbc->txn, pdbp->type, PGNO_INVALID, 0,
+				    dbc->locker, &pdbc);
+			}
+		if (ret != 0) {
+			if (sdbc != NULL)
+				(void)__dbc_close(sdbc);
+			return (ret);
+		}
+		if (CDB_LOCKING(env) && F_ISSET(env->dbenv, DB_ENV_CDB_ALLDB)) {
+			DB_ASSERT(env, sdbc->mylock.off == LOCK_INVALID);
+			F_SET(sdbc, DBC_WRITER);
+			if (LF_ISSET(DB_FOREIGN_NULLIFY) && pdbc != NULL) {
+				DB_ASSERT(env,
+				    pdbc->mylock.off == LOCK_INVALID);
+				F_SET(pdbc, DBC_WRITER);
+			}
+		}
+
+		/*
+		 * There are three actions possible when a foreign database has
+		 * items corresponding to a deleted item:
+		 * DB_FOREIGN_ABORT - The delete operation should be aborted.
+		 * DB_FOREIGN_CASCADE - All corresponding foreign items should
+		 *    be deleted.
+		 * DB_FOREIGN_NULLIFY - A callback needs to be made, allowing
+		 *    the application to modify the data DBT from the
+		 *    associated database.  If the callback makes a
+		 *    modification, the updated item needs to replace the
+		 *    original item in the foreign db
+		 */
+		memset(&pkey, 0, sizeof(DBT));
+		memset(&data, 0, sizeof(DBT));
+		ret = __dbc_pget(sdbc, &fkey, &pkey, &data, DB_SET|rmw);
+
+		if (ret == DB_NOTFOUND) {
+			/* No entry means no constraint */
+			ret = __dbc_close(sdbc);
+			if (LF_ISSET(DB_FOREIGN_NULLIFY) &&
+			    (t_ret = __dbc_close(pdbc)) != 0)
+				ret = t_ret;
+			if (ret != 0)
+				return (ret);
+			continue;
+		} else if (ret != 0) {
+			/* Just return the error code from the pget */
+			(void)__dbc_close(sdbc);
+			if (LF_ISSET(DB_FOREIGN_NULLIFY))
+				(void)__dbc_close(pdbc);
+			return (ret);
+		} else if (LF_ISSET(DB_FOREIGN_ABORT)) {
+			/* If the record exists and ABORT is set, we're done */
+			if ((ret = __dbc_close(sdbc)) != 0)
+				return (ret);
+			return (DB_FOREIGN_CONFLICT);
+		}
+
+		/*
+		 * There were matching items in the primary DB, and the action
+		 * is either DB_FOREIGN_CASCADE or DB_FOREIGN_NULLIFY.
+		 */
+		while (ret == 0) {
+			if (LF_ISSET(DB_FOREIGN_CASCADE)) {
+				/*
+				 * Don't use the DB_UPDATE_SECONDARY flag,
+				 * since we want the delete to cascade into the
+				 * secondary's primary.
+				 */
+				if ((ret = __dbc_del(sdbc, 0)) != 0) {
+					__db_err(env, ret, DB_STR("0698",
+	    "Attempt to execute cascading delete in a foreign index failed"));
+					break;
+				}
+			} else if (LF_ISSET(DB_FOREIGN_NULLIFY)) {
+				changed = 0;
+				if ((ret = f_info->callback(sdbp,
+				    &pkey, &data, &fkey, &changed)) != 0) {
+					__db_err(env, ret, DB_STR("0699",
+				    "Foreign database application callback"));
+					break;
+				}
+
+				/*
+				 * If the user callback modified the DBT and
+				 * a put on the primary failed.
+				 */
+				if (changed && (ret = __dbc_put(pdbc,
+				    &pkey, &data, DB_KEYFIRST)) != 0) {
+					__db_err(env, ret, DB_STR("0700",
+"Attempt to overwrite item in foreign database with nullified value failed"));
+					break;
+				}
+			}
+			/* retrieve the next matching item from the prim. db */
+			memset(&pkey, 0, sizeof(DBT));
+			memset(&data, 0, sizeof(DBT));
+			ret = __dbc_pget(sdbc,
+			    &fkey, &pkey, &data, DB_NEXT_DUP|rmw);
+		}
+
+		if (ret == DB_NOTFOUND)
+			ret = 0;
+		if ((t_ret = __dbc_close(sdbc)) != 0 && ret == 0)
+			ret = t_ret;
+		if (LF_ISSET(DB_FOREIGN_NULLIFY) &&
+		    (t_ret = __dbc_close(pdbc)) != 0 && ret == 0)
+			ret = t_ret;
+		if (ret != 0)
+			return (ret);
+	}
+
+	return (ret);
+}
+
+/*
+ * __db_s_first --
+ *	Get the first secondary, if any are present, from the primary.
+ *
+ * PUBLIC: int __db_s_first __P((DB *, DB **));
+ */
+int
+__db_s_first(pdbp, sdbpp)
+	DB *pdbp, **sdbpp;
+{
+	DB *sdbp;
+
+	MUTEX_LOCK(pdbp->env, pdbp->mutex);
+	sdbp = LIST_FIRST(&pdbp->s_secondaries);
+
+	/* See __db_s_next. */
+	if (sdbp != NULL)
+		sdbp->s_refcnt++;
+	MUTEX_UNLOCK(pdbp->env, pdbp->mutex);
+
+	*sdbpp = sdbp;
+
+	return (0);
+}
+
+/*
+ * __db_s_next --
+ *	Get the next secondary in the list.
+ *
+ * PUBLIC: int __db_s_next __P((DB **, DB_TXN *));
+ */
+int
+__db_s_next(sdbpp, txn)
+	DB **sdbpp;
+	DB_TXN *txn;
+{
+	DB *sdbp, *pdbp, *closeme;
+	ENV *env;
+	int ret;
+
+	/*
+	 * Secondary indices are kept in a linked list, s_secondaries,
+	 * off each primary DB handle.  If a primary is free-threaded,
+	 * this list may only be traversed or modified while the primary's
+	 * thread mutex is held.
+	 *
+	 * The tricky part is that we don't want to hold the thread mutex
+	 * across the full set of secondary puts necessary for each primary
+	 * put, or we'll wind up essentially single-threading all the puts
+	 * to the handle;  the secondary puts will each take about as
+	 * long as the primary does, and may require I/O.  So we instead
+	 * hold the thread mutex only long enough to follow one link to the
+	 * next secondary, and then we release it before performing the
+	 * actual secondary put.
+	 *
+	 * The only danger here is that we might legitimately close a
+	 * secondary index in one thread while another thread is performing
+	 * a put and trying to update that same secondary index.  To
+	 * prevent this from happening, we refcount the secondary handles.
+	 * If close is called on a secondary index handle while we're putting
+	 * to it, it won't really be closed--the refcount will simply drop,
+	 * and we'll be responsible for closing it here.
+	 */
+	sdbp = *sdbpp;
+	pdbp = sdbp->s_primary;
+	env = pdbp->env;
+	closeme = NULL;
+
+	MUTEX_LOCK(env, pdbp->mutex);
+	DB_ASSERT(env, sdbp->s_refcnt != 0);
+	if (--sdbp->s_refcnt == 0) {
+		LIST_REMOVE(sdbp, s_links);
+		closeme = sdbp;
+	}
+	sdbp = LIST_NEXT(sdbp, s_links);
+	if (sdbp != NULL)
+		sdbp->s_refcnt++;
+	MUTEX_UNLOCK(env, pdbp->mutex);
+
+	*sdbpp = sdbp;
+
+	/*
+	 * closeme->close() is a wrapper;  call __db_close explicitly.
+	 */
+	if (closeme == NULL)
+		ret = 0;
+	else
+		ret = __db_close(closeme, txn, 0);
+
+	return (ret);
+}
+
+/*
+ * __db_s_done --
+ *	Properly decrement the refcount on a secondary database handle we're
+ *	using, without calling __db_s_next.
+ *
+ * PUBLIC: int __db_s_done __P((DB *, DB_TXN *));
+ */
+int
+__db_s_done(sdbp, txn)
+	DB *sdbp;
+	DB_TXN *txn;
+{
+	DB *pdbp;
+	ENV *env;
+	int doclose, ret;
+
+	pdbp = sdbp->s_primary;
+	env = pdbp->env;
+	doclose = 0;
+
+	MUTEX_LOCK(env, pdbp->mutex);
+	DB_ASSERT(env, sdbp->s_refcnt != 0);
+	if (--sdbp->s_refcnt == 0) {
+		LIST_REMOVE(sdbp, s_links);
+		doclose = 1;
+	}
+	MUTEX_UNLOCK(env, pdbp->mutex);
+
+	if (doclose == 0)
+		ret = 0;
+	else
+		ret = __db_close(sdbp, txn, 0);
+	return (ret);
+}
+
+/*
+ * __db_s_count --
+ *	Count the number of secondaries associated with a given primary.
+ */
+static int
+__db_s_count(pdbp)
+	DB *pdbp;
+{
+	DB *sdbp;
+	ENV *env;
+	int count;
+
+	env = pdbp->env;
+	count = 0;
+
+	MUTEX_LOCK(env, pdbp->mutex);
+	for (sdbp = LIST_FIRST(&pdbp->s_secondaries);
+	    sdbp != NULL;
+	    sdbp = LIST_NEXT(sdbp, s_links))
+		++count;
+	MUTEX_UNLOCK(env, pdbp->mutex);
+
+	return (count);
+}
+
+/*
+ * __db_buildpartial --
+ *	Build the record that will result after a partial put is applied to
+ *	an existing record.
+ *
+ *	This should probably be merged with __bam_build, but that requires
+ *	a little trickery if we plan to keep the overflow-record optimization
+ *	in that function.
+ *
+ * PUBLIC: int __db_buildpartial __P((DB *, DBT *, DBT *, DBT *));
+ */
+int
+__db_buildpartial(dbp, oldrec, partial, newrec)
+	DB *dbp;
+	DBT *oldrec, *partial, *newrec;
+{
+	ENV *env;
+	u_int32_t len, nbytes;
+	u_int8_t *buf;
+	int ret;
+
+	env = dbp->env;
+
+	DB_ASSERT(env, F_ISSET(partial, DB_DBT_PARTIAL));
+
+	memset(newrec, 0, sizeof(DBT));
+
+	nbytes = __db_partsize(oldrec->size, partial);
+	newrec->size = nbytes;
+
+	if ((ret = __os_malloc(env, nbytes, &buf)) != 0)
+		return (ret);
+	newrec->data = buf;
+
+	/* Nul or pad out the buffer, for any part that isn't specified. */
+	memset(buf,
+	    F_ISSET(dbp, DB_AM_FIXEDLEN) ? ((BTREE *)dbp->bt_internal)->re_pad :
+	    0, nbytes);
+
+	/* Copy in any leading data from the original record. */
+	memcpy(buf, oldrec->data,
+	    partial->doff > oldrec->size ? oldrec->size : partial->doff);
+
+	/* Copy the data from partial. */
+	memcpy(buf + partial->doff, partial->data, partial->size);
+
+	/* Copy any trailing data from the original record. */
+	len = partial->doff + partial->dlen;
+	if (oldrec->size > len)
+		memcpy(buf + partial->doff + partial->size,
+		    (u_int8_t *)oldrec->data + len, oldrec->size - len);
+
+	return (0);
+}
+
+/*
+ * __db_partsize --
+ *	Given the number of bytes in an existing record and a DBT that
+ *	is about to be partial-put, calculate the size of the record
+ *	after the put.
+ *
+ *	This code is called from __bam_partsize.
+ *
+ * PUBLIC: u_int32_t __db_partsize __P((u_int32_t, DBT *));
+ */
+u_int32_t
+__db_partsize(nbytes, data)
+	u_int32_t nbytes;
+	DBT *data;
+{
+
+	/*
+	 * There are really two cases here:
+	 *
+	 * Case 1: We are replacing some bytes that do not exist (i.e., they
+	 * are past the end of the record).  In this case the number of bytes
+	 * we are replacing is irrelevant and all we care about is how many
+	 * bytes we are going to add from offset.  So, the new record length
+	 * is going to be the size of the new bytes (size) plus wherever those
+	 * new bytes begin (doff).
+	 *
+	 * Case 2: All the bytes we are replacing exist.  Therefore, the new
+	 * size is the oldsize (nbytes) minus the bytes we are replacing (dlen)
+	 * plus the bytes we are adding (size).
+	 */
+	if (nbytes < data->doff + data->dlen)		/* Case 1 */
+		return (data->doff + data->size);
+
+	return (nbytes + data->size - data->dlen);	/* Case 2 */
+}
+
+/*
+ * __db_secondary_corrupt --
+ *	Report primary/secondary inconsistencies.
+ *
+ * PUBLIC: int __db_secondary_corrupt __P((DB *));
+ */
+int
+__db_secondary_corrupt(dbp)
+	DB *dbp;
+{
+	__db_err(dbp->env, DB_SECONDARY_BAD, "%s%s%s",
+	    dbp->fname == NULL ? "unnamed" : dbp->fname,
+	    dbp->dname == NULL ? "" : "/",
+	    dbp->dname == NULL ? "" : dbp->dname);
+	return (DB_SECONDARY_BAD);
+}
+
+#ifdef DIAGNOSTIC
+/*
+ * __db_check_skeyset --
+ *	Diagnostic check that the application's callback returns a set of
+ *	secondary keys without repeats.
+ *
+ * PUBLIC: #ifdef DIAGNOSTIC
+ * PUBLIC: void __db_check_skeyset __P((DB *, DBT *));
+ * PUBLIC: #endif
+ */
+void
+__db_check_skeyset(sdbp, skeyp)
+	DB *sdbp;
+	DBT *skeyp;
+{
+	DBT *first_key, *last_key, *key1, *key2;
+	ENV *env;
+
+	env = sdbp->env;
+
+	first_key = (DBT *)skeyp->data;
+	last_key = first_key + skeyp->size;
+	for (key1 = first_key; key1 < last_key; key1++)
+		for (key2 = key1 + 1; key2 < last_key; key2++)
+			DB_ASSERT(env,
+			    ((BTREE *)sdbp->bt_internal)->bt_compare(sdbp,
+			    key1, key2) != 0);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_conv.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,944 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/crypto.h"
+#include "dbinc/hmac.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_swap.h"
+#include "dbinc/btree.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/qam.h"
+
+/*
+ * __db_pgin --
+ *	Primary page-swap routine.
+ *
+ * PUBLIC: int __db_pgin __P((DB_ENV *, db_pgno_t, void *, DBT *));
+ */
+int
+__db_pgin(dbenv, pg, pp, cookie)
+	DB_ENV *dbenv;
+	db_pgno_t pg;
+	void *pp;
+	DBT *cookie;
+{
+	DB dummydb, *dbp;
+	DB_CIPHER *db_cipher;
+	DB_LSN not_used;
+	DB_PGINFO *pginfo;
+	ENV *env;
+	PAGE *pagep;
+	size_t sum_len;
+	int is_hmac, ret;
+	u_int8_t *chksum;
+
+	pginfo = (DB_PGINFO *)cookie->data;
+	env = dbenv->env;
+	pagep = (PAGE *)pp;
+
+	ret = is_hmac = 0;
+	chksum = NULL;
+	memset(&dummydb, 0, sizeof(DB));
+	dbp = &dummydb;
+	dbp->dbenv = dbenv;
+	dbp->env = env;
+	dbp->flags = pginfo->flags;
+	dbp->pgsize = pginfo->db_pagesize;
+	db_cipher = env->crypto_handle;
+	switch (pagep->type) {
+	case P_HASHMETA:
+	case P_HEAPMETA:
+	case P_BTREEMETA:
+	case P_QAMMETA:
+		/*
+		 * If checksumming is set on the meta-page, we must set
+		 * it in the dbp.
+		 */
+		if (FLD_ISSET(((DBMETA *)pp)->metaflags, DBMETA_CHKSUM))
+			F_SET(dbp, DB_AM_CHKSUM);
+		else
+			F_CLR(dbp, DB_AM_CHKSUM);
+		if (((DBMETA *)pp)->encrypt_alg != 0 ||
+		    F_ISSET(dbp, DB_AM_ENCRYPT))
+			is_hmac = 1;
+		/*
+		 * !!!
+		 * For all meta pages it is required that the chksum
+		 * be at the same location.  Use BTMETA to get to it
+		 * for any meta type.
+		 */
+		chksum = ((BTMETA *)pp)->chksum;
+		sum_len = DBMETASIZE;
+		break;
+	case P_INVALID:
+		/*
+		 * We assume that we've read a file hole if we have
+		 * a zero LSN, zero page number and P_INVALID.  Otherwise
+		 * we have an invalid page that might contain real data.
+		 */
+		if (IS_ZERO_LSN(LSN(pagep)) && pagep->pgno == PGNO_INVALID) {
+			sum_len = 0;
+			break;
+		}
+		/* FALLTHROUGH */
+	default:
+		chksum = P_CHKSUM(dbp, pagep);
+		sum_len = pginfo->db_pagesize;
+		/*
+		 * If we are reading in a non-meta page, then if we have
+		 * a db_cipher then we are using hmac.
+		 */
+		is_hmac = CRYPTO_ON(env) ? 1 : 0;
+		break;
+	}
+
+	/*
+	 * We expect a checksum error if there was a configuration problem.
+	 * If there is no configuration problem and we don't get a match,
+	 * it's fatal: panic the system.
+	 */
+	if (F_ISSET(dbp, DB_AM_CHKSUM) && sum_len != 0) {
+		if (F_ISSET(dbp, DB_AM_SWAP) && is_hmac == 0)
+			P_32_SWAP(chksum);
+		switch (ret = __db_check_chksum(
+		    env, NULL, db_cipher, chksum, pp, sum_len, is_hmac)) {
+		case 0:
+			break;
+		case -1:
+			if (DBENV_LOGGING(env))
+				(void)__db_cksum_log(
+				    env, NULL, &not_used, DB_FLUSH);
+			__db_errx(env, DB_STR_A("0684",
+	    "checksum error: page %lu: catastrophic recovery required",
+			    "%lu"), (u_long)pg);
+			return (__env_panic(env, DB_RUNRECOVERY));
+		default:
+			return (ret);
+		}
+	}
+	if ((ret = __db_decrypt_pg(env, dbp, pagep)) != 0)
+		return (ret);
+	switch (pagep->type) {
+	case P_INVALID:
+		if (pginfo->type == DB_QUEUE)
+			return (__qam_pgin_out(env, pg, pp, cookie));
+		else if (pginfo->type == DB_HEAP)
+			return (__heap_pgin(dbp, pg, pp, cookie));
+		/*
+		 * This page is either newly allocated from the end of the
+		 * file, or from the free list, or it is an as-yet unwritten
+		 * hash bucket page. In this last case it needs to be
+		 * initialized, but never byte-swapped. Otherwise the header
+		 * may need swapping. It will not be a metadata page, so the
+		 * byte swapping code of __ham_pgin is adequate.  If hash
+		 * is not configured fall back to btree swapping.
+		 */
+#ifdef HAVE_HASH
+		return (__ham_pgin(dbp, pg, pp, cookie));
+#else
+		return (__bam_pgin(dbp, pg, pp, cookie));
+#endif
+		/* NOTREACHED. */
+		break;
+	case P_HASH_UNSORTED:
+	case P_HASH:
+	case P_HASHMETA:
+		return (__ham_pgin(dbp, pg, pp, cookie));
+	case P_HEAP:
+	case P_HEAPMETA:
+	case P_IHEAP:
+		return (__heap_pgin(dbp, pg, pp, cookie));
+	case P_BTREEMETA:
+	case P_IBTREE:
+	case P_IRECNO:
+	case P_LBTREE:
+	case P_LDUP:
+	case P_LRECNO:
+	case P_OVERFLOW:
+		return (__bam_pgin(dbp, pg, pp, cookie));
+	case P_QAMMETA:
+	case P_QAMDATA:
+		return (__qam_pgin_out(env, pg, pp, cookie));
+	default:
+		break;
+	}
+	return (__db_pgfmt(env, pg));
+}
+
+/*
+ * __db_pgout --
+ *	Primary page-swap routine.
+ *
+ * PUBLIC: int __db_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *));
+ */
+int
+__db_pgout(dbenv, pg, pp, cookie)
+	DB_ENV *dbenv;
+	db_pgno_t pg;
+	void *pp;
+	DBT *cookie;
+{
+	DB dummydb, *dbp;
+	DB_PGINFO *pginfo;
+	ENV *env;
+	PAGE *pagep;
+	int ret;
+
+	pginfo = (DB_PGINFO *)cookie->data;
+	env = dbenv->env;
+	pagep = (PAGE *)pp;
+
+	memset(&dummydb, 0, sizeof(DB));
+	dbp = &dummydb;
+	dbp->dbenv = dbenv;
+	dbp->env = env;
+	dbp->flags = pginfo->flags;
+	dbp->pgsize = pginfo->db_pagesize;
+	ret = 0;
+	switch (pagep->type) {
+	case P_INVALID:
+		switch (pginfo->type) {
+		case DB_QUEUE:
+			ret = __qam_pgin_out(env, pg, pp, cookie);
+			break;
+#ifdef HAVE_HASH
+		case DB_HASH:
+			ret = __ham_pgout(dbp, pg, pp, cookie);
+			break;
+#endif
+#ifdef HAVE_HEAP
+		case DB_HEAP:
+			ret = __heap_pgout(dbp, pg, pp, cookie);
+			break;
+#endif
+		case DB_BTREE:
+		case DB_RECNO:
+			ret = __bam_pgout(dbp, pg, pp, cookie);
+			break;
+		default:
+			return (__db_pgfmt(env, pg));
+		}
+		break;
+	case P_HASH:
+	case P_HASH_UNSORTED:
+		/*
+		 * Support pgout of unsorted hash pages - since online
+		 * replication upgrade can cause pages of this type to be
+		 * written out.
+		 *
+		 * FALLTHROUGH
+		 */
+	case P_HASHMETA:
+		ret = __ham_pgout(dbp, pg, pp, cookie);
+		break;
+	case P_HEAP:
+	case P_HEAPMETA:
+	case P_IHEAP:
+		ret = __heap_pgout(dbp, pg, pp, cookie);
+		break;
+	case P_BTREEMETA:
+	case P_IBTREE:
+	case P_IRECNO:
+	case P_LBTREE:
+	case P_LDUP:
+	case P_LRECNO:
+	case P_OVERFLOW:
+		ret = __bam_pgout(dbp, pg, pp, cookie);
+		break;
+	case P_QAMMETA:
+	case P_QAMDATA:
+		ret = __qam_pgin_out(env, pg, pp, cookie);
+		break;
+	default:
+		return (__db_pgfmt(env, pg));
+	}
+	if (ret)
+		return (ret);
+
+	return (__db_encrypt_and_checksum_pg(env, dbp, pagep));
+}
+
+/*
+ * __db_decrypt_pg --
+ *      Utility function to decrypt a db page.
+ *
+ * PUBLIC: int __db_decrypt_pg __P((ENV *, DB *, PAGE *));
+ */
+int
+__db_decrypt_pg (env, dbp, pagep)
+	ENV *env;
+	DB *dbp;
+	PAGE *pagep;
+{
+	DB_CIPHER *db_cipher;
+	size_t pg_len, pg_off;
+	u_int8_t *iv;
+	int ret;
+
+	db_cipher = env->crypto_handle;
+	ret = 0;
+	iv = NULL;
+	if (F_ISSET(dbp, DB_AM_ENCRYPT)) {
+		DB_ASSERT(env, db_cipher != NULL);
+		DB_ASSERT(env, F_ISSET(dbp, DB_AM_CHKSUM));
+
+		pg_off = P_OVERHEAD(dbp);
+		DB_ASSERT(env, db_cipher->adj_size(pg_off) == 0);
+
+		switch (pagep->type) {
+		case P_HASHMETA:
+		case P_HEAPMETA:
+		case P_BTREEMETA:
+		case P_QAMMETA:
+			/*
+			 * !!!
+			 * For all meta pages it is required that the iv
+			 * be at the same location.  Use BTMETA to get to it
+			 * for any meta type.
+			 */
+			iv = ((BTMETA *)pagep)->iv;
+			pg_len = DBMETASIZE;
+			break;
+		case P_INVALID:
+			if (IS_ZERO_LSN(LSN(pagep)) &&
+			    pagep->pgno == PGNO_INVALID) {
+				pg_len = 0;
+				break;
+			}
+			/* FALLTHROUGH */
+		default:
+			iv = P_IV(dbp, pagep);
+			pg_len = dbp->pgsize;
+			break;
+		}
+		if (pg_len != 0)
+			ret = db_cipher->decrypt(env, db_cipher->data,
+			    iv, ((u_int8_t *)pagep) + pg_off,
+			    pg_len - pg_off);
+	}
+	return (ret);
+}
+
+/*
+ * __db_encrypt_and_checksum_pg --
+ *	Utility function to encrypt and checksum a db page.
+ *
+ * PUBLIC: int __db_encrypt_and_checksum_pg
+ * PUBLIC:     __P((ENV *, DB *, PAGE *));
+ */
+int
+__db_encrypt_and_checksum_pg (env, dbp, pagep)
+	ENV *env;
+	DB *dbp;
+	PAGE *pagep;
+{
+	DB_CIPHER *db_cipher;
+	int ret;
+	size_t pg_off, pg_len, sum_len;
+	u_int8_t *chksum, *iv, *key;
+
+	chksum = iv = key = NULL;
+	db_cipher = env->crypto_handle;
+
+	if (F_ISSET(dbp, DB_AM_ENCRYPT)) {
+		DB_ASSERT(env, db_cipher != NULL);
+		DB_ASSERT(env, F_ISSET(dbp, DB_AM_CHKSUM));
+
+		pg_off = P_OVERHEAD(dbp);
+		DB_ASSERT(env, db_cipher->adj_size(pg_off) == 0);
+
+		key = db_cipher->mac_key;
+
+		switch (pagep->type) {
+		case P_HASHMETA:
+		case P_HEAPMETA:
+		case P_BTREEMETA:
+		case P_QAMMETA:
+			/*
+			 * !!!
+			 * For all meta pages it is required that the iv
+			 * be at the same location.  Use BTMETA to get to it
+			 * for any meta type.
+			 */
+			iv = ((BTMETA *)pagep)->iv;
+			pg_len = DBMETASIZE;
+			break;
+		default:
+			iv = P_IV(dbp, pagep);
+			pg_len = dbp->pgsize;
+			break;
+		}
+		if ((ret = db_cipher->encrypt(env, db_cipher->data,
+		    iv, ((u_int8_t *)pagep) + pg_off, pg_len - pg_off)) != 0)
+			return (ret);
+	}
+	if (F_ISSET(dbp, DB_AM_CHKSUM)) {
+		switch (pagep->type) {
+		case P_HASHMETA:
+		case P_HEAPMETA:
+		case P_BTREEMETA:
+		case P_QAMMETA:
+			/*
+			 * !!!
+			 * For all meta pages it is required that the chksum
+			 * be at the same location.  Use BTMETA to get to it
+			 * for any meta type.
+			 */
+			chksum = ((BTMETA *)pagep)->chksum;
+			sum_len = DBMETASIZE;
+			break;
+		default:
+			chksum = P_CHKSUM(dbp, pagep);
+			sum_len = dbp->pgsize;
+			break;
+		}
+		__db_chksum(NULL, (u_int8_t *)pagep, sum_len, key, chksum);
+		if (F_ISSET(dbp, DB_AM_SWAP) && !F_ISSET(dbp, DB_AM_ENCRYPT))
+			 P_32_SWAP(chksum);
+	}
+	return (0);
+}
+
+/*
+ * __db_metaswap --
+ *	Byteswap the common part of the meta-data page.
+ *
+ * PUBLIC: void __db_metaswap __P((PAGE *));
+ */
+void
+__db_metaswap(pg)
+	PAGE *pg;
+{
+	u_int8_t *p;
+
+	p = (u_int8_t *)pg;
+
+	/* Swap the meta-data information. */
+	SWAP32(p);	/* lsn.file */
+	SWAP32(p);	/* lsn.offset */
+	SWAP32(p);	/* pgno */
+	SWAP32(p);	/* magic */
+	SWAP32(p);	/* version */
+	SWAP32(p);	/* pagesize */
+	p += 4;		/* unused, page type, unused, unused */
+	SWAP32(p);	/* free */
+	SWAP32(p);	/* alloc_lsn part 1 */
+	SWAP32(p);	/* alloc_lsn part 2 */
+	SWAP32(p);	/* cached key count */
+	SWAP32(p);	/* cached record count */
+	SWAP32(p);	/* flags */
+}
+
+/*
+ * __db_byteswap --
+ *	Byteswap an ordinary database page.
+ *
+ * PUBLIC: int __db_byteswap
+ * PUBLIC:         __P((DB *, db_pgno_t, PAGE *, size_t, int));
+ */
+int
+__db_byteswap(dbp, pg, h, pagesize, pgin)
+	DB *dbp;
+	db_pgno_t pg;
+	PAGE *h;
+	size_t pagesize;
+	int pgin;
+{
+	ENV *env;
+	BINTERNAL *bi;
+	BKEYDATA *bk;
+	BOVERFLOW *bo;
+	HEAPHDR *hh;
+	HEAPSPLITHDR *hsh;
+	RINTERNAL *ri;
+	db_indx_t i, *inp, len, tmp;
+	u_int8_t *end, *p, *pgend;
+
+	if (pagesize == 0)
+		return (0);
+
+	if (pgin) {
+		M_32_SWAP(h->lsn.file);
+		M_32_SWAP(h->lsn.offset);
+		M_32_SWAP(h->pgno);
+		M_32_SWAP(h->prev_pgno);
+		M_32_SWAP(h->next_pgno);
+		M_16_SWAP(h->entries);
+		M_16_SWAP(h->hf_offset);
+	}
+
+	if (dbp == NULL)
+		return (0);
+	env = dbp->env;
+
+	pgend = (u_int8_t *)h + pagesize;
+
+	inp = P_INP(dbp, h);
+	if ((u_int8_t *)inp >= pgend)
+		goto out;
+
+	switch (TYPE(h)) {
+	case P_HASH_UNSORTED:
+	case P_HASH:
+		for (i = 0; i < NUM_ENT(h); i++) {
+			if (pgin)
+				M_16_SWAP(inp[i]);
+
+			if (P_ENTRY(dbp, h, i) >= pgend)
+				continue;
+
+			switch (HPAGE_TYPE(dbp, h, i)) {
+			case H_KEYDATA:
+				break;
+			case H_DUPLICATE:
+				len = LEN_HKEYDATA(dbp, h, pagesize, i);
+				p = HKEYDATA_DATA(P_ENTRY(dbp, h, i));
+				for (end = p + len; p < end;) {
+					if (pgin) {
+						P_16_SWAP(p);
+						memcpy(&tmp,
+						    p, sizeof(db_indx_t));
+						p += sizeof(db_indx_t);
+					} else {
+						memcpy(&tmp,
+						    p, sizeof(db_indx_t));
+						SWAP16(p);
+					}
+					p += tmp;
+					SWAP16(p);
+				}
+				break;
+			case H_OFFDUP:
+				p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
+				SWAP32(p);			/* pgno */
+				break;
+			case H_OFFPAGE:
+				p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
+				SWAP32(p);			/* pgno */
+				SWAP32(p);			/* tlen */
+				break;
+			default:
+				return (__db_pgfmt(env, pg));
+			}
+
+		}
+
+		/*
+		 * The offsets in the inp array are used to determine
+		 * the size of entries on a page; therefore they
+		 * cannot be converted until we've done all the
+		 * entries.
+		 */
+		if (!pgin)
+			for (i = 0; i < NUM_ENT(h); i++)
+				M_16_SWAP(inp[i]);
+		break;
+	case P_LBTREE:
+	case P_LDUP:
+	case P_LRECNO:
+		for (i = 0; i < NUM_ENT(h); i++) {
+			if (pgin)
+				M_16_SWAP(inp[i]);
+
+			/*
+			 * In the case of on-page duplicates, key information
+			 * should only be swapped once.
+			 */
+			if (h->type == P_LBTREE && i > 1) {
+				if (pgin) {
+					if (inp[i] == inp[i - 2])
+						continue;
+				} else {
+					M_16_SWAP(inp[i]);
+					if (inp[i] == inp[i - 2])
+						continue;
+					M_16_SWAP(inp[i]);
+				}
+			}
+
+			bk = GET_BKEYDATA(dbp, h, i);
+			if ((u_int8_t *)bk >= pgend)
+				continue;
+			switch (B_TYPE(bk->type)) {
+			case B_KEYDATA:
+				M_16_SWAP(bk->len);
+				break;
+			case B_DUPLICATE:
+			case B_OVERFLOW:
+				bo = (BOVERFLOW *)bk;
+				M_32_SWAP(bo->pgno);
+				M_32_SWAP(bo->tlen);
+				break;
+			default:
+				return (__db_pgfmt(env, pg));
+			}
+
+			if (!pgin)
+				M_16_SWAP(inp[i]);
+		}
+		break;
+	case P_IBTREE:
+		for (i = 0; i < NUM_ENT(h); i++) {
+			if (pgin)
+				M_16_SWAP(inp[i]);
+
+			bi = GET_BINTERNAL(dbp, h, i);
+			if ((u_int8_t *)bi >= pgend)
+				continue;
+
+			M_16_SWAP(bi->len);
+			M_32_SWAP(bi->pgno);
+			M_32_SWAP(bi->nrecs);
+
+			switch (B_TYPE(bi->type)) {
+			case B_KEYDATA:
+				break;
+			case B_DUPLICATE:
+			case B_OVERFLOW:
+				bo = (BOVERFLOW *)bi->data;
+				M_32_SWAP(bo->pgno);
+				M_32_SWAP(bo->tlen);
+				break;
+			default:
+				return (__db_pgfmt(env, pg));
+			}
+
+			if (!pgin)
+				M_16_SWAP(inp[i]);
+		}
+		break;
+	case P_IRECNO:
+		for (i = 0; i < NUM_ENT(h); i++) {
+			if (pgin)
+				M_16_SWAP(inp[i]);
+
+			ri = GET_RINTERNAL(dbp, h, i);
+			if ((u_int8_t *)ri >= pgend)
+				continue;
+
+			M_32_SWAP(ri->pgno);
+			M_32_SWAP(ri->nrecs);
+
+			if (!pgin)
+				M_16_SWAP(inp[i]);
+		}
+		break;
+	case P_HEAP:
+		for (i = 0; i < HEAP_HIGHINDX(h); i++) {
+			if (pgin)
+				M_16_SWAP(inp[i]);
+
+			hh = (HEAPHDR *)P_ENTRY(dbp, h, i);
+			if ((u_int8_t *)hh >= pgend)
+				continue;
+			M_16_SWAP(hh->size);
+			if (F_ISSET(hh, HEAP_RECSPLIT)) {
+				hsh = (HEAPSPLITHDR *)hh;
+				M_32_SWAP(hsh->tsize);
+				M_32_SWAP(hsh->nextpg);
+				M_16_SWAP(hsh->nextindx);
+			}
+
+			if (!pgin)
+				M_16_SWAP(inp[i]);
+		}
+		break;
+	case P_IHEAP:
+	case P_INVALID:
+	case P_OVERFLOW:
+	case P_QAMDATA:
+		/* Nothing to do. */
+		break;
+	default:
+		return (__db_pgfmt(env, pg));
+	}
+
+out:	if (!pgin) {
+		/* Swap the header information. */
+		M_32_SWAP(h->lsn.file);
+		M_32_SWAP(h->lsn.offset);
+		M_32_SWAP(h->pgno);
+		M_32_SWAP(h->prev_pgno);
+		M_32_SWAP(h->next_pgno);
+		M_16_SWAP(h->entries);
+		M_16_SWAP(h->hf_offset);
+	}
+	return (0);
+}
+
+/*
+ * __db_pageswap --
+ *	Byteswap any database page.  Normally, the page to be swapped will be
+ *	referenced by the "pp" argument and the pdata argument will be NULL.
+ *	This function is also called by automatically generated log functions,
+ *	where the page may be split into separate header and data parts.  In
+ *	that case, pdata is not NULL we reconsitute
+ *
+ * PUBLIC: int __db_pageswap
+ * PUBLIC:         __P((ENV *, DB *, void *, size_t, DBT *, int));
+ */
+int
+__db_pageswap(env, dbp, pp, len, pdata, pgin)
+	ENV *env;
+	DB *dbp;
+	void *pp;
+	size_t len;
+	DBT *pdata;
+	int pgin;
+{
+	db_pgno_t pg;
+	size_t pgsize;
+	void *pgcopy;
+	int ret;
+	u_int16_t hoffset;
+
+	switch (TYPE(pp)) {
+	case P_BTREEMETA:
+		return (__bam_mswap(env, pp));
+
+	case P_HASHMETA:
+		return (__ham_mswap(env, pp));
+
+	case P_QAMMETA:
+		return (__qam_mswap(env, pp));
+
+	case P_INVALID:
+	case P_OVERFLOW:
+	case P_QAMDATA:
+		/*
+		 * We may have been passed an invalid page, or a queue data
+		 * page, or an overflow page where fields like hoffset have a
+		 * special meaning.  In that case, no swapping of the page data
+		 * is required, just the fields in the page header.
+		 */
+		pdata = NULL;
+		break;
+
+	default:
+		break;
+	}
+
+	if (pgin) {
+		P_32_COPYSWAP(&PGNO(pp), &pg);
+		P_16_COPYSWAP(&HOFFSET(pp), &hoffset);
+	} else {
+		pg = PGNO(pp);
+		hoffset = HOFFSET(pp);
+	}
+
+	if (pdata == NULL)
+		ret = __db_byteswap(dbp, pg, (PAGE *)pp, len, pgin);
+	else {
+		pgsize = hoffset + pdata->size;
+		if ((ret = __os_malloc(env, pgsize, &pgcopy)) != 0)
+			return (ret);
+		memset(pgcopy, 0, pgsize);
+		memcpy(pgcopy, pp, len);
+		memcpy((u_int8_t *)pgcopy + hoffset, pdata->data, pdata->size);
+
+		ret = __db_byteswap(dbp, pg, (PAGE *)pgcopy, pgsize, pgin);
+		memcpy(pp, pgcopy, len);
+
+		/*
+		 * If we are swapping data to be written to the log, we can't
+		 * overwrite the buffer that was passed in: it may be a pointer
+		 * into a page in cache.  We set DB_DBT_APPMALLOC here so that
+		 * the calling code can free the memory we allocate here.
+		 */
+		if (!pgin) {
+			if ((ret =
+			    __os_malloc(env, pdata->size, &pdata->data)) != 0) {
+				__os_free(env, pgcopy);
+				return (ret);
+			}
+			F_SET(pdata, DB_DBT_APPMALLOC);
+		}
+		memcpy(pdata->data, (u_int8_t *)pgcopy + hoffset, pdata->size);
+		__os_free(env, pgcopy);
+	}
+
+	return (ret);
+}
+
+/*
+ * __db_recordswap --
+ *	Byteswap any database record.
+ *
+ * PUBLIC: void __db_recordswap __P((u_int32_t,
+ * PUBLIC:     u_int32_t, void *, void *, u_int32_t));
+ */
+void
+__db_recordswap(op, size, hdr, data, pgin)
+	u_int32_t op;
+	u_int32_t size;
+	void *hdr, *data;
+	u_int32_t pgin;
+{
+	BKEYDATA *bk;
+	BOVERFLOW *bo;
+	BINTERNAL *bi;
+	HEAPHDR *hh;
+	HEAPSPLITHDR *hsh;
+	RINTERNAL *ri;
+	db_indx_t tmp;
+	u_int8_t *p, *end;
+
+	if (size == 0)
+		return;
+	switch (OP_PAGE_GET(op)) {
+	case P_LDUP:
+	case P_LBTREE:
+	case P_LRECNO:
+		bk = (BKEYDATA *)hdr;
+		switch (B_TYPE(bk->type)) {
+		case B_KEYDATA:
+			M_16_SWAP(bk->len);
+			break;
+		case B_DUPLICATE:
+		case B_OVERFLOW:
+			bo = (BOVERFLOW *)hdr;
+			M_32_SWAP(bo->pgno);
+			M_32_SWAP(bo->tlen);
+			break;
+		default:
+			DB_ASSERT(NULL, bk->type != bk->type);
+		}
+		break;
+	case P_IBTREE:
+		bi = (BINTERNAL *)hdr;
+		M_16_SWAP(bi->len);
+		M_32_SWAP(bi->pgno);
+		M_32_SWAP(bi->nrecs);
+		if (B_TYPE(bi->type) == B_OVERFLOW) {
+			if (data == NULL) {
+				DB_ASSERT(NULL,
+				    size == BINTERNAL_SIZE(BOVERFLOW_SIZE));
+				bo = (BOVERFLOW *)bi->data;
+			} else
+				bo = (BOVERFLOW *)data;
+			M_32_SWAP(bo->pgno);
+		}
+		break;
+	case P_IRECNO:
+		ri = (RINTERNAL *)hdr;
+		M_32_SWAP(ri->pgno);
+		M_32_SWAP(ri->nrecs);
+		break;
+	case P_OVERFLOW:
+		break;
+	case P_HASH:
+	case P_HASH_UNSORTED:
+		switch (OP_MODE_GET(op)) {
+		/* KEYDATA and DUPLICATE records do not include the header. */
+		case H_KEYDATA:
+			break;
+		case H_DUPLICATE:
+			p = (u_int8_t *)hdr;
+			for (end = p + size; p < end;) {
+				if (pgin) {
+					P_16_SWAP(p);
+					memcpy(&tmp,
+					    p, sizeof(db_indx_t));
+					p += sizeof(db_indx_t);
+				} else {
+					memcpy(&tmp,
+					    p, sizeof(db_indx_t));
+					SWAP16(p);
+				}
+				p += tmp;
+				SWAP16(p);
+			}
+			break;
+		/* These two record types include the full header. */
+		case H_OFFDUP:
+			p = (u_int8_t *)hdr;
+			p += SSZ(HOFFPAGE, pgno);
+			SWAP32(p);			/* pgno */
+			break;
+		case H_OFFPAGE:
+			p = (u_int8_t *)hdr;
+			p += SSZ(HOFFPAGE, pgno);
+			SWAP32(p);			/* pgno */
+			SWAP32(p);			/* tlen */
+			break;
+		default:
+			DB_ASSERT(NULL, op != op);
+		}
+		break;
+	case P_HEAP:
+		hh = (HEAPHDR *)hdr;
+		M_16_SWAP(hh->size);
+		if (F_ISSET(hh, HEAP_RECSPLIT)) {
+			hsh = (HEAPSPLITHDR *)hdr;
+			M_32_SWAP(hsh->tsize);
+			M_32_SWAP(hsh->nextpg);
+			M_16_SWAP(hsh->nextindx);
+		}
+		break;
+	default:
+		DB_ASSERT(NULL, op != op);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_copy.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,53 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2011, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+
+/*
+ * db_copy --
+ *	Copy a database file coordinated with mpool.
+ * This is for backward compatibility to the quick fix in 5.2.
+ *
+ * EXTERN: int db_copy __P((DB_ENV *,
+ * EXTERN:     const char *, const char *, const char *));
+ */
+int
+db_copy(dbenv, dbfile, target, passwd)
+	DB_ENV *dbenv;
+	const char *dbfile;
+	const char *target;
+	const char *passwd;
+{
+	COMPQUIET(passwd, NULL);
+	return (__db_dbbackup_pp(dbenv, dbfile, target, 0));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_dup.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,236 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/mp.h"
+#include "dbinc/log.h"
+#include "dbinc/db_am.h"
+#include "dbinc/txn.h"
+
+/*
+ * __db_ditem_nolog --
+ *	Remove an item from a page without affecting its recoverability.
+ *
+ * PUBLIC:  int __db_ditem_nolog __P((DBC *, PAGE *, u_int32_t, u_int32_t));
+ */
+int
+__db_ditem_nolog(dbc, pagep, indx, nbytes)
+	DBC *dbc;
+	PAGE *pagep;
+	u_int32_t indx, nbytes;
+{
+	DB *dbp;
+	db_indx_t cnt, *inp, offset;
+	u_int8_t *from;
+
+	dbp = dbc->dbp;
+	DB_ASSERT(dbp->env, IS_DIRTY(pagep));
+	DB_ASSERT(dbp->env, indx < NUM_ENT(pagep));
+
+	/*
+	 * If there's only a single item on the page, we don't have to
+	 * work hard.
+	 */
+	if (NUM_ENT(pagep) == 1) {
+		NUM_ENT(pagep) = 0;
+		HOFFSET(pagep) = dbp->pgsize;
+		return (0);
+	}
+
+	inp = P_INP(dbp, pagep);
+	/*
+	 * Pack the remaining key/data items at the end of the page.  Use
+	 * memmove(3), the regions may overlap.
+	 */
+	from = (u_int8_t *)pagep + HOFFSET(pagep);
+	DB_ASSERT(dbp->env, inp[indx] >= HOFFSET(pagep));
+	memmove(from + nbytes, from, inp[indx] - HOFFSET(pagep));
+	HOFFSET(pagep) += nbytes;
+
+	/* Adjust the indices' offsets. */
+	offset = inp[indx];
+	for (cnt = 0; cnt < NUM_ENT(pagep); ++cnt)
+		if (inp[cnt] < offset)
+			inp[cnt] += nbytes;
+
+	/* Shift the indices down. */
+	--NUM_ENT(pagep);
+	if (indx != NUM_ENT(pagep))
+		memmove(&inp[indx], &inp[indx + 1],
+		    sizeof(db_indx_t) * (NUM_ENT(pagep) - indx));
+
+	return (0);
+}
+
+/*
+ * __db_ditem --
+ *	Remove an item from a page, logging it if enabled.
+ *
+ * PUBLIC:  int __db_ditem __P((DBC *, PAGE *, u_int32_t, u_int32_t));
+ */
+int
+__db_ditem(dbc, pagep, indx, nbytes)
+	DBC *dbc;
+	PAGE *pagep;
+	u_int32_t indx, nbytes;
+{
+	DB *dbp;
+	DBT ldbt;
+	int ret;
+
+	dbp = dbc->dbp;
+
+	if (DBC_LOGGING(dbc)) {
+		ldbt.data = P_ENTRY(dbp, pagep, indx);
+		ldbt.size = nbytes;
+		if ((ret = __db_addrem_log(dbp, dbc->txn, &LSN(pagep), 0,
+		    OP_SET(DB_REM_DUP, pagep), PGNO(pagep),
+		    (u_int32_t)indx, nbytes, &ldbt, NULL, &LSN(pagep))) != 0)
+			return (ret);
+	} else
+		LSN_NOT_LOGGED(LSN(pagep));
+
+	return (__db_ditem_nolog(dbc, pagep, indx, nbytes));
+}
+
+/*
+ * __db_pitem_nolog --
+ *	Put an item on a page without logging.
+ *
+ * PUBLIC: int __db_pitem_nolog
+ * PUBLIC:     __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *));
+ */
+int
+__db_pitem_nolog(dbc, pagep, indx, nbytes, hdr, data)
+	DBC *dbc;
+	PAGE *pagep;
+	u_int32_t indx;
+	u_int32_t nbytes;
+	DBT *hdr, *data;
+{
+	BKEYDATA bk;
+	DB *dbp;
+	DBT thdr;
+	db_indx_t *inp;
+	u_int8_t *p;
+
+	dbp = dbc->dbp;
+
+	DB_ASSERT(dbp->env, IS_DIRTY(pagep));
+
+	if (nbytes > P_FREESPACE(dbp, pagep)) {
+		DB_ASSERT(dbp->env, nbytes <= P_FREESPACE(dbp, pagep));
+		return (EINVAL);
+	}
+
+	if (hdr == NULL) {
+		B_TSET(bk.type, B_KEYDATA);
+		bk.len = data == NULL ? 0 : data->size;
+
+		thdr.data = &bk;
+		thdr.size = SSZA(BKEYDATA, data);
+		hdr = &thdr;
+	}
+	inp = P_INP(dbp, pagep);
+
+	/* Adjust the index table, then put the item on the page. */
+	if (indx != NUM_ENT(pagep))
+		memmove(&inp[indx + 1], &inp[indx],
+		    sizeof(db_indx_t) * (NUM_ENT(pagep) - indx));
+	HOFFSET(pagep) -= nbytes;
+	inp[indx] = HOFFSET(pagep);
+	++NUM_ENT(pagep);
+
+	p = P_ENTRY(dbp, pagep, indx);
+	memcpy(p, hdr->data, hdr->size);
+	if (data != NULL)
+		memcpy(p + hdr->size, data->data, data->size);
+
+	return (0);
+}
+
+/*
+ * __db_pitem --
+ *	Put an item on a page.
+ *
+ * PUBLIC: int __db_pitem
+ * PUBLIC:     __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *));
+ */
+int
+__db_pitem(dbc, pagep, indx, nbytes, hdr, data)
+	DBC *dbc;
+	PAGE *pagep;
+	u_int32_t indx;
+	u_int32_t nbytes;
+	DBT *hdr, *data;
+{
+	DB *dbp;
+	MPOOLFILE *mpf;
+	int ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf->mfp;
+	/*
+	 * Put a single item onto a page.  The logic figuring out where to
+	 * insert and whether it fits is handled in the caller.  All we do
+	 * here is manage the page shuffling.  We cheat a little bit in that
+	 * we don't want to copy the dbt on a normal put twice.  If hdr is
+	 * NULL, we create a BKEYDATA structure on the page, otherwise, just
+	 * copy the caller's information onto the page.
+	 *
+	 * This routine is also used to put entries onto the page where the
+	 * entry is pre-built, e.g., during recovery.  In this case, the hdr
+	 * will point to the entry, and the data argument will be NULL.
+	 *
+	 * If transactional bulk loading is enabled in this
+	 * transaction, and the page is above the file's extension
+	 * watermark, skip logging, but do not invoke LSN_NOT_LOGGED.
+	 *
+	 * !!!
+	 * There's a tremendous potential for off-by-one errors here, since
+	 * the passed in header sizes must be adjusted for the structure's
+	 * placeholder for the trailing variable-length data field.
+	 */
+	if (DBC_LOGGING(dbc)) {
+		if (__txn_pg_above_fe_watermark(dbc->txn, mpf, PGNO(pagep))) {
+			mpf->fe_nlws++; /* Note that logging was skipped. */
+		} else if ((ret = __db_addrem_log(dbp, dbc->txn, &LSN(pagep),
+		    0, OP_SET(DB_ADD_DUP, pagep), PGNO(pagep),
+		    (u_int32_t)indx, nbytes, hdr, data, &LSN(pagep)))) {
+			return (ret);
+		}
+	} else
+		LSN_NOT_LOGGED(LSN(pagep));
+
+	return (__db_pitem_nolog(dbc, pagep, indx, nbytes, hdr, data));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_iface.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,2717 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/hash.h"
+#ifndef HAVE_QUEUE
+#include "dbinc/qam.h"			/* For __db_no_queue_am(). */
+#endif
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+#include "dbinc/txn.h"
+
+static int __db_associate_arg __P((DB *, DB *,
+    int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t));
+static int __dbc_del_arg __P((DBC *, u_int32_t));
+static int __dbc_pget_arg __P((DBC *, DBT *, u_int32_t));
+static int __dbc_put_arg __P((DBC *, DBT *, DBT *, u_int32_t));
+static int __db_curinval __P((const ENV *));
+static int __db_cursor_arg __P((DB *, u_int32_t));
+static int __db_del_arg __P((DB *, DBT *, u_int32_t));
+static int __db_get_arg __P((const DB *, DBT *, DBT *, u_int32_t));
+static int __db_open_arg __P((DB *,
+    DB_TXN *, const char *, const char *, DBTYPE, u_int32_t));
+static int __db_pget_arg __P((DB *, DBT *, u_int32_t));
+static int __db_put_arg __P((DB *, DBT *, DBT *, u_int32_t));
+static int __dbt_ferr __P((const DB *, const char *, const DBT *, int));
+
+/*
+ * These functions implement the Berkeley DB API.  They are organized in a
+ * layered fashion.  The interface functions (XXX_pp) perform all generic
+ * error checks (for example, PANIC'd region, replication state change
+ * in progress, inconsistent transaction usage), call function-specific
+ * check routines (_arg) to check for proper flag usage, etc., do pre-amble
+ * processing (incrementing handle counts, handling local transactions),
+ * call the function and then do post-amble processing (local transactions,
+ * decrement handle counts).
+ *
+ * The basic structure is:
+ *	Check for simple/generic errors (PANIC'd region)
+ *	Check if replication is changing state (increment handle count).
+ *	Call function-specific argument checking routine
+ *	Create internal transaction if necessary
+ *	Call underlying worker function
+ *	Commit/abort internal transaction if necessary
+ *	Decrement handle count
+ */
+
+/*
+ * __db_associate_pp --
+ *	DB->associate pre/post processing.
+ *
+ * PUBLIC: int __db_associate_pp __P((DB *, DB_TXN *, DB *,
+ * PUBLIC:     int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t));
+ */
+int
+__db_associate_pp(dbp, txn, sdbp, callback, flags)
+	DB *dbp, *sdbp;
+	DB_TXN *txn;
+	int (*callback) __P((DB *, const DBT *, const DBT *, DBT *));
+	u_int32_t flags;
+{
+	DBC *sdbc;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret, txn_local;
+
+	env = dbp->env;
+	txn_local = 0;
+
+	STRIP_AUTO_COMMIT(flags);
+
+	ENV_ENTER(env, ip);
+	XA_CHECK_TXN(ip, txn);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check &&
+	    (ret = __db_rep_enter(dbp, 1, 0, IS_REAL_TXN(txn))) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	/*
+	 * Secondary cursors may have the primary's lock file ID, so we need
+	 * to make sure that no older cursors are lying around when we make
+	 * the transition.
+	 */
+	if (TAILQ_FIRST(&sdbp->active_queue) != NULL ||
+	    TAILQ_FIRST(&sdbp->join_queue) != NULL) {
+		__db_errx(env, DB_STR("0572",
+    "Databases may not become secondary indices while cursors are open"));
+		ret = EINVAL;
+		goto err;
+	}
+
+	if ((ret = __db_associate_arg(dbp, sdbp, callback, flags)) != 0)
+		goto err;
+
+	/*
+	 * Create a local transaction as necessary, check for consistent
+	 * transaction usage, and, if we have no transaction but do have
+	 * locking on, acquire a locker id for the handle lock acquisition.
+	 */
+	if (IS_DB_AUTO_COMMIT(dbp, txn)) {
+		if ((ret = __txn_begin(env, ip, NULL, &txn, 0)) != 0)
+			goto err;
+		txn_local = 1;
+	}
+
+	/* Check for consistent transaction usage. */
+	if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0)
+		goto err;
+
+	while ((sdbc = TAILQ_FIRST(&sdbp->free_queue)) != NULL)
+		if ((ret = __dbc_destroy(sdbc)) != 0)
+			goto err;
+
+	ret = __db_associate(dbp, ip, txn, sdbp, callback, flags);
+
+err:	if (txn_local &&
+	    (t_ret = __db_txn_auto_resolve(env, txn, 0, ret)) && ret == 0)
+		ret = t_ret;
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_associate_arg --
+ *	Check DB->associate arguments.
+ */
+static int
+__db_associate_arg(dbp, sdbp, callback, flags)
+	DB *dbp, *sdbp;
+	int (*callback) __P((DB *, const DBT *, const DBT *, DBT *));
+	u_int32_t flags;
+{
+	ENV *env;
+	int ret;
+
+	env = dbp->env;
+
+	if (sdbp->type == DB_HEAP) {
+		__db_errx(env,
+		    "Heap databases may not be used as secondary databases");
+		return (EINVAL);
+	}
+
+	if (F_ISSET(sdbp, DB_AM_SECONDARY)) {
+		__db_errx(env, DB_STR("0573",
+		    "Secondary index handles may not be re-associated"));
+		return (EINVAL);
+	}
+	if (F_ISSET(dbp, DB_AM_SECONDARY)) {
+		__db_errx(env, DB_STR("0574",
+		    "Secondary indices may not be used as primary databases"));
+		return (EINVAL);
+	}
+	if (F_ISSET(dbp, DB_AM_DUP)) {
+		__db_errx(env, DB_STR("0575",
+		    "Primary databases may not be configured with duplicates"));
+		return (EINVAL);
+	}
+	if (F_ISSET(dbp, DB_AM_RENUMBER)) {
+		__db_errx(env, DB_STR("0576",
+    "Renumbering recno databases may not be used as primary databases"));
+		return (EINVAL);
+	}
+
+	/*
+	 * It's OK for the primary and secondary to not share an environment IFF
+	 * the environments are local to the DB handle.  (Specifically, cursor
+	 * adjustment will work correctly in this case.)  The environment being
+	 * local implies the environment is not configured for either locking or
+	 * transactions, as neither of those could work correctly.
+	 */
+	if (dbp->env != sdbp->env &&
+	    (!F_ISSET(dbp->env, ENV_DBLOCAL) ||
+	     !F_ISSET(sdbp->env, ENV_DBLOCAL))) {
+		__db_errx(env, DB_STR("0577",
+    "The primary and secondary must be opened in the same environment"));
+		return (EINVAL);
+	}
+	if ((DB_IS_THREADED(dbp) && !DB_IS_THREADED(sdbp)) ||
+	    (!DB_IS_THREADED(dbp) && DB_IS_THREADED(sdbp))) {
+		__db_errx(env, DB_STR("0578",
+    "The DB_THREAD setting must be the same for primary and secondary"));
+		return (EINVAL);
+	}
+	if (callback == NULL &&
+	    (!F_ISSET(dbp, DB_AM_RDONLY) || !F_ISSET(sdbp, DB_AM_RDONLY))) {
+		__db_errx(env, DB_STR("0579",
+"Callback function may be NULL only when database handles are read-only"));
+		return (EINVAL);
+	}
+
+	if ((ret = __db_fchk(env, "DB->associate", flags, DB_CREATE |
+	    DB_IMMUTABLE_KEY)) != 0)
+		return (ret);
+
+	return (0);
+}
+
+/*
+ * __db_close_pp --
+ *	DB->close pre/post processing.
+ *
+ * PUBLIC: int __db_close_pp __P((DB *, u_int32_t));
+ */
+int
+__db_close_pp(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret;
+
+	env = dbp->env;
+	ret = 0;
+
+	/*
+	 * Close a DB handle -- as a handle destructor, we can't fail.
+	 *
+	 * !!!
+	 * The actual argument checking is simple, do it inline, outside of
+	 * the replication block.
+	 */
+	if (flags != 0 && flags != DB_NOSYNC)
+		ret = __db_ferr(env, "DB->close", 0);
+
+	ENV_ENTER(env, ip);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check && (t_ret = __db_rep_enter(dbp, 0, 0, 0)) != 0) {
+		handle_check = 0;
+		if (ret == 0)
+			ret = t_ret;
+	}
+
+	if ((t_ret = __db_close(dbp, NULL, flags)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_cursor_pp --
+ *	DB->cursor pre/post processing.
+ *
+ * PUBLIC: int __db_cursor_pp __P((DB *, DB_TXN *, DBC **, u_int32_t));
+ */
+int
+__db_cursor_pp(dbp, txn, dbcp, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	DBC **dbcp;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	REGENV *renv;
+	int rep_blocked, ret;
+
+	env = dbp->env;
+
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->cursor");
+
+	ENV_ENTER(env, ip);
+	XA_CHECK_TXN(ip, txn);
+
+	/* Check for replication block. */
+	rep_blocked = 0;
+	if (IS_ENV_REPLICATED(env)) {
+		if (!IS_REAL_TXN(txn)) {
+			if ((ret = __op_rep_enter(env, 0, 1)) != 0)
+				goto err;
+			rep_blocked = 1;
+		}
+		renv = env->reginfo->primary;
+		if (dbp->timestamp != renv->rep_timestamp) {
+			__db_errx(env, DB_STR("0580",
+		    "replication recovery unrolled committed transactions;"
+		    "open DB and DBcursor handles must be closed"));
+			ret = DB_REP_HANDLE_DEAD;
+			goto err;
+		}
+	}
+	if ((ret = __db_cursor_arg(dbp, flags)) != 0)
+		goto err;
+
+	/*
+	 * Check for consistent transaction usage.  For now, assume this
+	 * cursor might be used for read operations only (in which case
+	 * it may not require a txn).  We'll check more stringently in
+	 * c_del and c_put.  (Note this means the read-op txn tests have
+	 * to be a subset of the write-op ones.)
+	 */
+	if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 1)) != 0)
+		goto err;
+
+	ret = __db_cursor(dbp, ip, txn, dbcp, flags);
+
+	/*
+	 * Register externally created cursors into the valid transaction.
+	 * If a family transaction was passed in, the transaction handle in
+	 * the cursor may not match.
+	 */
+	txn = (*dbcp)->txn;
+	if (txn != NULL && ret == 0)
+		TAILQ_INSERT_HEAD(&(txn->my_cursors), *dbcp, txn_cursors);
+
+err:	/* Release replication block on error. */
+	if (ret != 0 && rep_blocked)
+		(void)__op_rep_exit(env);
+
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_cursor --
+ *	DB->cursor.
+ *
+ * PUBLIC: int __db_cursor __P((DB *,
+ * PUBLIC:      DB_THREAD_INFO *, DB_TXN *, DBC **, u_int32_t));
+ */
+int
+__db_cursor(dbp, ip, txn, dbcp, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DBC **dbcp;
+	u_int32_t flags;
+{
+	DBC *dbc;
+	ENV *env;
+	db_lockmode_t mode;
+	int ret;
+
+	env = dbp->env;
+
+	if (MULTIVERSION(dbp) && txn == NULL && (LF_ISSET(DB_TXN_SNAPSHOT) ||
+	    F_ISSET(env->dbenv, DB_ENV_TXN_SNAPSHOT))) {
+		if ((ret =
+		    __txn_begin(env, ip, NULL, &txn, DB_TXN_SNAPSHOT)) != 0)
+			return (ret);
+		F_SET(txn, TXN_PRIVATE);
+	}
+
+	PERFMON5(env, db, cursor, dbp->fname,
+	    dbp->dname, txn == NULL ? 0 : txn->txnid, flags, &dbp->fileid[0]);
+
+	if ((ret = __db_cursor_int(dbp, ip, txn, dbp->type, PGNO_INVALID,
+	    LF_ISSET(DB_CURSOR_BULK | DB_CURSOR_TRANSIENT | DB_RECOVER),
+	    NULL, &dbc)) != 0)
+		return (ret);
+
+	/*
+	 * If this is CDB, do all the locking in the interface, which is
+	 * right here.
+	 */
+	if (CDB_LOCKING(env)) {
+		mode = (LF_ISSET(DB_WRITELOCK)) ? DB_LOCK_WRITE :
+		    ((LF_ISSET(DB_WRITECURSOR) || txn != NULL) ?
+		    DB_LOCK_IWRITE : DB_LOCK_READ);
+		if ((ret = __lock_get(env, dbc->locker, 0,
+		    &dbc->lock_dbt, mode, &dbc->mylock)) != 0)
+			goto err;
+		if (LF_ISSET(DB_WRITECURSOR))
+			F_SET(dbc, DBC_WRITECURSOR);
+		if (LF_ISSET(DB_WRITELOCK))
+			F_SET(dbc, DBC_WRITER);
+	}
+
+	if (LF_ISSET(DB_READ_UNCOMMITTED) ||
+	    (txn != NULL && F_ISSET(txn, TXN_READ_UNCOMMITTED)))
+		F_SET(dbc, DBC_READ_UNCOMMITTED);
+
+	if (LF_ISSET(DB_READ_COMMITTED) ||
+	    (txn != NULL && F_ISSET(txn, TXN_READ_COMMITTED)))
+		F_SET(dbc, DBC_READ_COMMITTED);
+
+	*dbcp = dbc;
+	return (0);
+
+err:	(void)__dbc_close(dbc);
+	return (ret);
+}
+
+/*
+ * __db_cursor_arg --
+ *	Check DB->cursor arguments.
+ */
+static int
+__db_cursor_arg(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	ENV *env;
+
+	env = dbp->env;
+
+	/*
+	 * DB_READ_COMMITTED and DB_READ_UNCOMMITTED require locking.
+	 */
+	if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED)) {
+		if (!LOCKING_ON(env))
+			return (__db_fnl(env, "DB->cursor"));
+	}
+
+	LF_CLR(DB_CURSOR_BULK |
+	    DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_TXN_SNAPSHOT);
+
+	/* Check for invalid function flags. */
+	if (LF_ISSET(DB_WRITECURSOR)) {
+		if (DB_IS_READONLY(dbp))
+			return (__db_rdonly(env, "DB->cursor"));
+		if (!CDB_LOCKING(env))
+			return (__db_ferr(env, "DB->cursor", 0));
+		LF_CLR(DB_WRITECURSOR);
+	} else if (LF_ISSET(DB_WRITELOCK)) {
+		if (DB_IS_READONLY(dbp))
+			return (__db_rdonly(env, "DB->cursor"));
+		LF_CLR(DB_WRITELOCK);
+	}
+
+	if (flags != 0)
+		return (__db_ferr(env, "DB->cursor", 0));
+
+	return (0);
+}
+
+/*
+ * __db_del_pp --
+ *	DB->del pre/post processing.
+ *
+ * PUBLIC: int __db_del_pp __P((DB *, DB_TXN *, DBT *, u_int32_t));
+ */
+int
+__db_del_pp(dbp, txn, key, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	DBT *key;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret, txn_local;
+
+	env = dbp->env;
+	txn_local = 0;
+
+	STRIP_AUTO_COMMIT(flags);
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->del");
+
+#ifdef CONFIG_TEST
+	if (IS_REP_MASTER(env))
+		DB_TEST_WAIT(env, env->test_check);
+#endif
+	ENV_ENTER(env, ip);
+	XA_CHECK_TXN(ip, txn);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check &&
+	     (ret = __db_rep_enter(dbp, 1, 0, IS_REAL_TXN(txn))) != 0) {
+			handle_check = 0;
+			goto err;
+	}
+
+	if ((ret = __db_del_arg(dbp, key, flags)) != 0)
+		goto err;
+
+	/* Create local transaction as necessary. */
+	if (IS_DB_AUTO_COMMIT(dbp, txn)) {
+		if ((ret = __txn_begin(env, ip, NULL, &txn, 0)) != 0)
+			goto err;
+		txn_local = 1;
+	}
+
+	/* Check for consistent transaction usage. */
+	if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0)
+		goto err;
+
+	ret = __db_del(dbp, ip, txn, key, flags);
+
+err:	if (txn_local &&
+	    (t_ret = __db_txn_auto_resolve(env, txn, 0, ret)) && ret == 0)
+		ret = t_ret;
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+	ENV_LEAVE(env, ip);
+	__dbt_userfree(env, key, NULL, NULL);
+	return (ret);
+}
+
+/*
+ * __db_del_arg --
+ *	Check DB->delete arguments.
+ */
+static int
+__db_del_arg(dbp, key, flags)
+	DB *dbp;
+	DBT *key;
+	u_int32_t flags;
+{
+	ENV *env;
+	int ret;
+
+	env = dbp->env;
+
+	/* Check for changes to a read-only tree. */
+	if (DB_IS_READONLY(dbp))
+		return (__db_rdonly(env, "DB->del"));
+
+	/* Check for invalid function flags. */
+	switch (flags) {
+	case DB_CONSUME:
+		if (dbp->type != DB_QUEUE)
+			return (__db_ferr(env, "DB->del", 0));
+		goto copy;
+	case DB_MULTIPLE:
+	case DB_MULTIPLE_KEY:
+		if (!F_ISSET(key, DB_DBT_BULK)) {
+			__db_errx(env, DB_STR("0581",
+	    "DB->del with DB_MULTIPLE(_KEY) requires multiple key records"));
+			return (EINVAL);
+		}
+		/* FALL THROUGH */
+	case 0:
+copy:		if ((ret = __dbt_usercopy(env, key)) != 0)
+			return (ret);
+		break;
+	default:
+		return (__db_ferr(env, "DB->del", 0));
+	}
+
+	return (0);
+}
+
+/*
+ * __db_exists --
+ *	DB->exists implementation.
+ *
+ * PUBLIC: int __db_exists __P((DB *, DB_TXN *, DBT *, u_int32_t));
+ */
+int
+__db_exists(dbp, txn, key, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	DBT *key;
+	u_int32_t flags;
+{
+	DBT data;
+	int ret;
+
+	/*
+	 * Most flag checking is done in the DB->get call, we only check for
+	 * specific incompatibilities here.  This saves making __get_arg
+	 * aware of the exist method's API constraints.
+	 */
+	STRIP_AUTO_COMMIT(flags);
+
+	if ((ret = __db_fchk(dbp->env, "DB->exists", flags,
+	    DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW)) != 0)
+		return (ret);
+
+	/*
+	 * Configure a data DBT that returns no bytes so there's no copy
+	 * of the data.
+	 */
+	memset(&data, 0, sizeof(data));
+	data.dlen = 0;
+	data.flags = DB_DBT_PARTIAL | DB_DBT_USERMEM;
+
+	return (dbp->get(dbp, txn, key, &data, flags));
+}
+
+/*
+ * db_fd_pp --
+ *	DB->fd pre/post processing.
+ *
+ * PUBLIC: int __db_fd_pp __P((DB *, int *));
+ */
+int
+__db_fd_pp(dbp, fdp)
+	DB *dbp;
+	int *fdp;
+{
+	DB_FH *fhp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret;
+
+	env = dbp->env;
+
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->fd");
+
+	ENV_ENTER(env, ip);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0)
+		goto err;
+
+	/*
+	 * !!!
+	 * There's no argument checking to be done.
+	 *
+	 * !!!
+	 * The actual method call is simple, do it inline.
+	 *
+	 * XXX
+	 * Truly spectacular layering violation.
+	 */
+	if ((ret = __mp_xxx_fh(dbp->mpf, &fhp)) == 0) {
+		if (fhp == NULL) {
+			*fdp = -1;
+			__db_errx(env, DB_STR("0582",
+			    "Database does not have a valid file handle"));
+			ret = ENOENT;
+		} else
+			*fdp = fhp->fd;
+	}
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+err:	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_get_pp --
+ *	DB->get pre/post processing.
+ *
+ * PUBLIC: int __db_get_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
+ */
+int
+__db_get_pp(dbp, txn, key, data, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	u_int32_t mode;
+	int handle_check, ignore_lease, ret, t_ret, txn_local;
+
+	env = dbp->env;
+	mode = 0;
+	txn_local = 0;
+
+	STRIP_AUTO_COMMIT(flags);
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get");
+
+	ignore_lease = LF_ISSET(DB_IGNORE_LEASE) ? 1 : 0;
+	LF_CLR(DB_IGNORE_LEASE);
+
+	if ((ret = __db_get_arg(dbp, key, data, flags)) != 0) {
+		__dbt_userfree(env, key, NULL, data);
+		return (ret);
+	}
+
+	ENV_ENTER(env, ip);
+	XA_CHECK_TXN(ip, txn);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check &&
+	     (ret = __db_rep_enter(dbp, 1, 0, IS_REAL_TXN(txn))) != 0) {
+			handle_check = 0;
+			goto err;
+	}
+
+	if (LF_ISSET(DB_READ_UNCOMMITTED))
+		mode = DB_READ_UNCOMMITTED;
+	else if ((flags & DB_OPFLAGS_MASK) == DB_CONSUME ||
+	    (flags & DB_OPFLAGS_MASK) == DB_CONSUME_WAIT) {
+		mode = DB_WRITELOCK;
+		if (IS_DB_AUTO_COMMIT(dbp, txn)) {
+			if ((ret = __txn_begin(env, ip, NULL, &txn, 0)) != 0)
+				goto err;
+			txn_local = 1;
+		}
+	}
+
+	/* Check for consistent transaction usage. */
+	if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID,
+	    mode == DB_WRITELOCK || LF_ISSET(DB_RMW) ? 0 : 1)) != 0)
+		goto err;
+
+	ret = __db_get(dbp, ip, txn, key, data, flags);
+	/*
+	 * Check for master leases.
+	 */
+	if (ret == 0 &&
+	    IS_REP_MASTER(env) && IS_USING_LEASES(env) && !ignore_lease)
+		ret = __rep_lease_check(env, 1);
+
+err:	if (txn_local &&
+	    (t_ret = __db_txn_auto_resolve(env, txn, 0, ret)) && ret == 0)
+		ret = t_ret;
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	__dbt_userfree(env, key, NULL, data);
+	return (ret);
+}
+
+/*
+ * __db_get --
+ *	DB->get.
+ *
+ * PUBLIC: int __db_get __P((DB *,
+ * PUBLIC:     DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, u_int32_t));
+ */
+int
+__db_get(dbp, ip, txn, key, data, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DBC *dbc;
+	u_int32_t mode;
+	int ret, t_ret;
+
+	/*
+	 * The DB_CURSOR_TRANSIENT flag indicates that we're just doing a single
+	 * operation with this cursor, and that in case of error we don't need
+	 * to restore it to its old position.  Thus, we can perform the get
+	 * without duplicating the cursor, saving some cycles in this common
+	 * case.
+	 */
+	mode = DB_CURSOR_TRANSIENT;
+	if (LF_ISSET(DB_READ_UNCOMMITTED)) {
+		mode |= DB_READ_UNCOMMITTED;
+		LF_CLR(DB_READ_UNCOMMITTED);
+	} else if (LF_ISSET(DB_READ_COMMITTED)) {
+		mode |= DB_READ_COMMITTED;
+		LF_CLR(DB_READ_COMMITTED);
+	} else if ((flags & DB_OPFLAGS_MASK) == DB_CONSUME ||
+	    (flags & DB_OPFLAGS_MASK) == DB_CONSUME_WAIT)
+		mode |= DB_WRITELOCK;
+
+	if ((ret = __db_cursor(dbp, ip, txn, &dbc, mode)) != 0)
+		return (ret);
+
+	DEBUG_LREAD(dbc, txn, "DB->get", key, NULL, flags);
+
+	/*
+	 * The semantics of bulk gets are different for DB->get vs DBC->get.
+	 * Mark the cursor so the low-level bulk get routines know which
+	 * behavior we want.
+	 */
+	F_SET(dbc, DBC_FROM_DB_GET);
+
+	/*
+	 * SET_RET_MEM indicates that if key and/or data have no DBT
+	 * flags set and DB manages the returned-data memory, that memory
+	 * will belong to this handle, not to the underlying cursor.
+	 */
+	SET_RET_MEM(dbc, dbp);
+
+	if (LF_ISSET(~(DB_RMW | DB_MULTIPLE)) == 0)
+		LF_SET(DB_SET);
+
+#ifdef HAVE_PARTITION
+	if (F_ISSET(dbc, DBC_PARTITIONED))
+		ret = __partc_get(dbc, key, data, flags);
+	else
+#endif
+		ret = __dbc_get(dbc, key, data, flags);
+
+	if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __db_get_arg --
+ *	DB->get argument checking, used by both DB->get and DB->pget.
+ */
+static int
+__db_get_arg(dbp, key, data, flags)
+	const DB *dbp;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	ENV *env;
+	int dirty, multi, ret;
+
+	env = dbp->env;
+
+	/*
+	 * Check for read-modify-write validity.  DB_RMW doesn't make sense
+	 * with CDB cursors since if you're going to write the cursor, you
+	 * had to create it with DB_WRITECURSOR.  Regardless, we check for
+	 * LOCKING_ON and not STD_LOCKING, as we don't want to disallow it.
+	 * If this changes, confirm that DB does not itself set the DB_RMW
+	 * flag in a path where CDB may have been configured.
+	 */
+	dirty = 0;
+	if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW)) {
+		if (!LOCKING_ON(env))
+			return (__db_fnl(env, "DB->get"));
+		if ((ret = __db_fcchk(env, "DB->get",
+		    flags, DB_READ_UNCOMMITTED, DB_READ_COMMITTED)) != 0)
+			return (ret);
+		if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED))
+			dirty = 1;
+		LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW);
+	}
+
+	multi = 0;
+	if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {
+		if (LF_ISSET(DB_MULTIPLE_KEY))
+			goto multi_err;
+		multi = LF_ISSET(DB_MULTIPLE) ? 1 : 0;
+		LF_CLR(DB_MULTIPLE);
+	}
+
+	/* Check for invalid function flags. */
+	switch (flags) {
+	case DB_GET_BOTH:
+		if ((ret = __dbt_usercopy(env, data)) != 0)
+			return (ret);
+		/* FALLTHROUGH */
+	case 0:
+		if ((ret = __dbt_usercopy(env, key)) != 0) {
+			__dbt_userfree(env, key, NULL, data);
+			return (ret);
+		}
+		break;
+	case DB_SET_RECNO:
+		if (!F_ISSET(dbp, DB_AM_RECNUM))
+			goto err;
+		if ((ret = __dbt_usercopy(env, key)) != 0)
+			return (ret);
+		break;
+	case DB_CONSUME:
+	case DB_CONSUME_WAIT:
+		if (DB_IS_READONLY(dbp))
+			return (__db_rdonly(env,
+			    "DB->get CONSUME/CONSUME_WAIT"));
+		if (dirty) {
+			__db_errx(env, DB_STR_A("0583",
+		    "%s is not supported with DB_CONSUME or DB_CONSUME_WAIT",
+			    "%s"), LF_ISSET(DB_READ_UNCOMMITTED) ?
+			     "DB_READ_UNCOMMITTED" : "DB_READ_COMMITTED");
+			return (EINVAL);
+		}
+		if (multi)
+multi_err:		return (__db_ferr(env, "DB->get", 1));
+		if (dbp->type == DB_QUEUE)
+			break;
+		/* FALLTHROUGH */
+	default:
+err:		return (__db_ferr(env, "DB->get", 0));
+	}
+
+	/*
+	 * Check for invalid key/data flags.
+	 */
+	if ((ret =
+	    __dbt_ferr(dbp, "key", key, DB_RETURNS_A_KEY(dbp, flags))) != 0)
+		return (ret);
+
+	if (F_ISSET(data, DB_DBT_READONLY)) {
+		__db_errx(env, DB_STR("0584",
+		    "DB_DBT_READONLY should not be set on data DBT."));
+			return (EINVAL);
+	}
+	if ((ret = __dbt_ferr(dbp, "data", data, 1)) != 0)
+		return (ret);
+
+	if (multi) {
+		if (!F_ISSET(data, DB_DBT_USERMEM)) {
+			__db_errx(env, DB_STR("0585",
+			    "DB_MULTIPLE requires DB_DBT_USERMEM be set"));
+			return (EINVAL);
+		}
+		if (F_ISSET(key, DB_DBT_PARTIAL) ||
+		    F_ISSET(data, DB_DBT_PARTIAL)) {
+			__db_errx(env, DB_STR("0586",
+			    "DB_MULTIPLE does not support DB_DBT_PARTIAL"));
+			return (EINVAL);
+		}
+		if (data->ulen < 1024 ||
+		    data->ulen < dbp->pgsize || data->ulen % 1024 != 0) {
+			__db_errx(env, DB_STR("0587",
+			    "DB_MULTIPLE buffers must be aligned, "
+			    "at least page size and multiples of 1KB"));
+			return (EINVAL);
+		}
+	}
+
+	/* Check invalid partial key. */
+	if (F_ISSET(key, DB_DBT_PARTIAL) && !(LF_ISSET(DB_CONSUME) &&
+	    LF_ISSET(DB_CONSUME_WAIT) && LF_ISSET(DB_SET_RECNO))) {
+		__db_errx(env, DB_STR("0708",
+		    "Invalid positioning flag combined with DB_DBT_PARTIAL"));
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+/*
+ * __db_key_range_pp --
+ *	DB->key_range pre/post processing.
+ *
+ * PUBLIC: int __db_key_range_pp
+ * PUBLIC:     __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t));
+ */
+int
+__db_key_range_pp(dbp, txn, key, kr, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	DBT *key;
+	DB_KEY_RANGE *kr;
+	u_int32_t flags;
+{
+	DBC *dbc;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret;
+
+	env = dbp->env;
+
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->key_range");
+
+	/*
+	 * !!!
+	 * The actual argument checking is simple, do it inline, outside of
+	 * the replication block.
+	 */
+	if (flags != 0)
+		return (__db_ferr(env, "DB->key_range", 0));
+
+	ENV_ENTER(env, ip);
+	XA_CHECK_TXN(ip, txn);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check &&
+	     (ret = __db_rep_enter(dbp, 1, 0, IS_REAL_TXN(txn))) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	/* Check for consistent transaction usage. */
+	if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 1)) != 0)
+		goto err;
+
+	/*
+	 * !!!
+	 * The actual method call is simple, do it inline.
+	 */
+	switch (dbp->type) {
+	case DB_BTREE:
+		if ((ret = __dbt_usercopy(env, key)) != 0)
+			goto err;
+
+		/* Acquire a cursor. */
+		if ((ret = __db_cursor(dbp, ip, txn, &dbc, 0)) != 0) {
+			__dbt_userfree(env, key, NULL, NULL);
+			break;
+		}
+
+		DEBUG_LWRITE(dbc, NULL, "bam_key_range", NULL, NULL, 0);
+#ifdef HAVE_PARTITION
+		if (DB_IS_PARTITIONED(dbp))
+			ret = __part_key_range(dbc, key, kr, flags);
+		else
+#endif
+			ret = __bam_key_range(dbc, key, kr, flags);
+
+		if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+			ret = t_ret;
+		__dbt_userfree(env, key, NULL, NULL);
+		break;
+	case DB_HASH:
+	case DB_QUEUE:
+	case DB_RECNO:
+		ret = __dbh_am_chk(dbp, DB_OK_BTREE);
+		break;
+	case DB_UNKNOWN:
+	default:
+		ret = __db_unknown_type(env, "DB->key_range", dbp->type);
+		break;
+	}
+
+err:	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_open_pp --
+ *	DB->open pre/post processing.
+ *
+ * PUBLIC: int __db_open_pp __P((DB *, DB_TXN *,
+ * PUBLIC:     const char *, const char *, DBTYPE, u_int32_t, int));
+ */
+int
+__db_open_pp(dbp, txn, fname, dname, type, flags, mode)
+	DB *dbp;
+	DB_TXN *txn;
+	const char *fname, *dname;
+	DBTYPE type;
+	u_int32_t flags;
+	int mode;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, nosync, remove_me, ret, t_ret, txn_local;
+
+	env = dbp->env;
+	nosync = 1;
+	handle_check = remove_me = txn_local = 0;
+
+	ENV_ENTER(env, ip);
+
+	/*
+	 * Save the flags.  We do this here because we don't pass all of the
+	 * flags down into the actual DB->open method call, we strip
+	 * DB_AUTO_COMMIT at this layer.
+	 */
+	dbp->open_flags = flags;
+
+	/* Save the current DB handle flags for refresh. */
+	dbp->orig_flags = dbp->flags;
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check &&
+	    (ret = __db_rep_enter(dbp, 1, 0, IS_REAL_TXN(txn))) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	/*
+	 * A replication client can't create a database, but it's convenient to
+	 * allow a repmgr application to specify DB_CREATE anyway.  Thus for
+	 * such an application the meaning of DB_CREATE becomes "create it if
+	 * I'm a master, and otherwise ignore the flag".  A repmgr application
+	 * running as master can't be sure that it won't spontaneously become a
+	 * client, so there's a race condition.
+	 */
+	if (IS_REP_CLIENT(env) && !F_ISSET(dbp, DB_AM_NOT_DURABLE))
+		LF_CLR(DB_CREATE);
+
+	/*
+	 * Create local transaction as necessary, check for consistent
+	 * transaction usage.
+	 */
+	if (IS_ENV_AUTO_COMMIT(env, txn, flags)) {
+		if ((ret = __db_txn_auto_init(env, ip, &txn)) != 0)
+			goto err;
+		txn_local = 1;
+	} else if (txn != NULL && !TXN_ON(env) &&
+	    (!CDB_LOCKING(env) || !F_ISSET(txn, TXN_FAMILY))) {
+		ret = __db_not_txn_env(env);
+		goto err;
+	}
+	LF_CLR(DB_AUTO_COMMIT);
+
+	/*
+	 * We check arguments after possibly creating a local transaction,
+	 * which is unusual -- the reason is some flags are illegal if any
+	 * kind of transaction is in effect.
+	 */
+	if ((ret = __db_open_arg(dbp, txn, fname, dname, type, flags)) == 0)
+		if ((ret = __db_open(dbp, ip, txn, fname, dname, type,
+		    flags, mode, PGNO_BASE_MD)) != 0)
+			goto txnerr;
+
+	/*
+	 * You can open the database that describes the subdatabases in the
+	 * rest of the file read-only.  The content of each key's data is
+	 * unspecified and applications should never be adding new records
+	 * or updating existing records.  However, during recovery, we need
+	 * to open these databases R/W so we can redo/undo changes in them.
+	 * Likewise, we need to open master databases read/write during
+	 * rename and remove so we can be sure they're fully sync'ed, so
+	 * we provide an override flag for the purpose.
+	 */
+	if (dname == NULL && !IS_RECOVERING(env) && !LF_ISSET(DB_RDONLY) &&
+	    !LF_ISSET(DB_RDWRMASTER) && F_ISSET(dbp, DB_AM_SUBDB)) {
+		__db_errx(env, DB_STR("0590",
+    "files containing multiple databases may only be opened read-only"));
+		ret = EINVAL;
+		goto txnerr;
+	}
+
+	/*
+	 * Success: file creations have to be synchronous, otherwise we don't
+	 * care.
+	 */
+	if (F_ISSET(dbp, DB_AM_CREATED | DB_AM_CREATED_MSTR))
+		nosync = 0;
+
+	/* Success: don't discard the file on close. */
+	F_CLR(dbp, DB_AM_DISCARD | DB_AM_CREATED | DB_AM_CREATED_MSTR);
+
+	/*
+	 * If not transactional, remove the databases/subdatabases if it is
+	 * persistent.  If we're transactional, the child transaction abort
+	 * cleans up.
+	 */
+txnerr:	if (ret != 0 && !IS_REAL_TXN(txn)) {
+		remove_me = (F_ISSET(dbp, DB_AM_CREATED) &&
+			(fname != NULL || dname != NULL)) ? 1 : 0;
+		if (F_ISSET(dbp, DB_AM_CREATED_MSTR) ||
+		    (dname == NULL && remove_me))
+			/* Remove file. */
+			(void)__db_remove_int(dbp,
+			    ip, txn, fname, NULL, DB_FORCE);
+		else if (remove_me)
+			/* Remove subdatabase. */
+			(void)__db_remove_int(dbp,
+			    ip, txn, fname, dname, DB_FORCE);
+	}
+
+	if (txn_local && (t_ret =
+	     __db_txn_auto_resolve(env, txn, nosync, ret)) && ret == 0)
+		ret = t_ret;
+
+err:	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_open_arg --
+ *	Check DB->open arguments.
+ */
+static int
+__db_open_arg(dbp, txn, fname, dname, type, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	const char *fname, *dname;
+	DBTYPE type;
+	u_int32_t flags;
+{
+	ENV *env;
+	u_int32_t ok_flags;
+	int ret;
+
+	env = dbp->env;
+
+	/* Validate arguments. */
+#undef	OKFLAGS
+#define	OKFLAGS								\
+	(DB_AUTO_COMMIT | DB_CREATE | DB_EXCL | DB_FCNTL_LOCKING |	\
+	DB_MULTIVERSION | DB_NOMMAP | DB_NO_AUTO_COMMIT | DB_RDONLY |	\
+	DB_RDWRMASTER | DB_READ_UNCOMMITTED | DB_THREAD | DB_TRUNCATE)
+	if ((ret = __db_fchk(env, "DB->open", flags, OKFLAGS)) != 0)
+		return (ret);
+	if (LF_ISSET(DB_EXCL) && !LF_ISSET(DB_CREATE))
+		return (__db_ferr(env, "DB->open", 1));
+	if (LF_ISSET(DB_RDONLY) && LF_ISSET(DB_CREATE))
+		return (__db_ferr(env, "DB->open", 1));
+
+#ifdef	HAVE_VXWORKS
+	if (LF_ISSET(DB_TRUNCATE)) {
+		__db_errx(env, DB_STR("0591",
+		    "DB_TRUNCATE not supported on VxWorks"));
+		return (DB_OPNOTSUP);
+	}
+#endif
+	switch (type) {
+	case DB_UNKNOWN:
+		if (LF_ISSET(DB_CREATE|DB_TRUNCATE)) {
+			__db_errx(env, DB_STR("0592",
+	    "DB_UNKNOWN type specified with DB_CREATE or DB_TRUNCATE"));
+			return (EINVAL);
+		}
+		ok_flags = 0;
+		break;
+	case DB_BTREE:
+		ok_flags = DB_OK_BTREE;
+		break;
+	case DB_HASH:
+#ifndef HAVE_HASH
+		return (__db_no_hash_am(env));
+#endif
+		ok_flags = DB_OK_HASH;
+		break;
+	case DB_HEAP:
+		ok_flags = DB_OK_HEAP;
+		break;
+	case DB_QUEUE:
+#ifndef HAVE_QUEUE
+		return (__db_no_queue_am(env));
+#endif
+		ok_flags = DB_OK_QUEUE;
+		break;
+	case DB_RECNO:
+		ok_flags = DB_OK_RECNO;
+		break;
+	default:
+		__db_errx(env, DB_STR_A("0593",
+		    "unknown type: %lu", "%lu"), (u_long)type);
+		return (EINVAL);
+	}
+	if (ok_flags)
+		DB_ILLEGAL_METHOD(dbp, ok_flags);
+
+	/* The environment may have been created, but never opened. */
+	if (!F_ISSET(env, ENV_DBLOCAL | ENV_OPEN_CALLED)) {
+		__db_errx(env, DB_STR("0594",
+		    "database environment not yet opened"));
+		return (EINVAL);
+	}
+
+	/*
+	 * Historically, you could pass in an environment that didn't have a
+	 * mpool, and DB would create a private one behind the scenes.  This
+	 * no longer works.
+	 */
+	if (!F_ISSET(env, ENV_DBLOCAL) && !MPOOL_ON(env)) {
+		__db_errx(env, DB_STR("0595",
+		    "environment did not include a memory pool"));
+		return (EINVAL);
+	}
+
+	/*
+	 * You can't specify threads during DB->open if subsystems in the
+	 * environment weren't configured with them.
+	 */
+	if (LF_ISSET(DB_THREAD) && !F_ISSET(env, ENV_DBLOCAL | ENV_THREAD)) {
+		__db_errx(env, DB_STR("0596",
+		    "environment not created using DB_THREAD"));
+		return (EINVAL);
+	}
+
+	/* Exclusive database handles cannot be threaded.*/
+	if (LF_ISSET(DB_THREAD) && F2_ISSET(dbp, DB2_AM_EXCL)) {
+		__db_errx(env, DB_STR("0744",
+		    "Exclusive database handles cannot be threaded."));
+		return (EINVAL);
+	}
+
+	/* Exclusive database handles require transactional environments. */
+	if (F2_ISSET(dbp, DB2_AM_EXCL) && !TXN_ON(env)) {
+		__db_errx(env, DB_STR("0745",
+	"Exclusive database handles require transactional environments."));
+		return (EINVAL);
+	}
+
+	/* Replication clients cannot open exclusive database handles. */
+	if (F2_ISSET(dbp, DB2_AM_EXCL) && IS_REP_CLIENT(env)) {
+		__db_errx(env, DB_STR("0746",
+"Exclusive database handles cannot be opened on replication clients."));
+		return (EINVAL);
+	}
+
+	/* DB_MULTIVERSION requires a database configured for transactions. */
+	if (LF_ISSET(DB_MULTIVERSION) && !IS_REAL_TXN(txn)) {
+		__db_errx(env, DB_STR("0597",
+		    "DB_MULTIVERSION illegal without a transaction specified"));
+		return (EINVAL);
+	}
+
+	if (LF_ISSET(DB_MULTIVERSION) && type == DB_QUEUE) {
+		__db_errx(env, DB_STR("0598",
+		    "DB_MULTIVERSION illegal with queue databases"));
+		return (EINVAL);
+	}
+
+	/* DB_TRUNCATE is neither transaction recoverable nor lockable. */
+	if (LF_ISSET(DB_TRUNCATE) && (LOCKING_ON(env) || txn != NULL)) {
+		__db_errx(env, DB_STR_A("0599",
+		    "DB_TRUNCATE illegal with %s specified", "%s"),
+		    LOCKING_ON(env) ? "locking" : "transactions");
+		return (EINVAL);
+	}
+
+	/* Subdatabase checks. */
+	if (dname != NULL) {
+		/* QAM can only be done on in-memory subdatabases. */
+		if (type == DB_QUEUE && fname != NULL) {
+			__db_errx(env, DB_STR("0600",
+			    "Queue databases must be one-per-file"));
+			return (EINVAL);
+		}
+
+		/*
+		 * Named in-memory databases can't support certain flags,
+		 * so check here.
+		 */
+		if (fname == NULL)
+			F_CLR(dbp, DB_AM_CHKSUM | DB_AM_ENCRYPT);
+	}
+
+	return (0);
+}
+
+/*
+ * __db_pget_pp --
+ *	DB->pget pre/post processing.
+ *
+ * PUBLIC: int __db_pget_pp
+ * PUBLIC:     __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t));
+ */
+int
+__db_pget_pp(dbp, txn, skey, pkey, data, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	DBT *skey, *pkey, *data;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ignore_lease, ret, t_ret;
+
+	env = dbp->env;
+
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->pget");
+
+	ignore_lease = LF_ISSET(DB_IGNORE_LEASE) ? 1 : 0;
+	LF_CLR(DB_IGNORE_LEASE);
+
+	if ((ret = __db_pget_arg(dbp, pkey, flags)) != 0 ||
+	    (ret = __db_get_arg(dbp, skey, data, flags)) != 0) {
+		__dbt_userfree(env, skey, pkey, data);
+		return (ret);
+	}
+
+	ENV_ENTER(env, ip);
+	XA_CHECK_TXN(ip, txn);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check &&
+	    (ret = __db_rep_enter(dbp, 1, 0, IS_REAL_TXN(txn))) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	ret = __db_pget(dbp, ip, txn, skey, pkey, data, flags);
+	/*
+	 * Check for master leases.
+	 */
+	if (ret == 0 &&
+	    IS_REP_MASTER(env) && IS_USING_LEASES(env) && !ignore_lease)
+		ret = __rep_lease_check(env, 1);
+
+err:	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	__dbt_userfree(env, skey, pkey, data);
+	return (ret);
+}
+
+/*
+ * __db_pget --
+ *	DB->pget.
+ *
+ * PUBLIC: int __db_pget __P((DB *,
+ * PUBLIC:     DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t));
+ */
+int
+__db_pget(dbp, ip, txn, skey, pkey, data, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DBT *skey, *pkey, *data;
+	u_int32_t flags;
+{
+	DBC *dbc;
+	u_int32_t mode;
+	int ret, t_ret;
+
+	mode = DB_CURSOR_TRANSIENT;
+	if (LF_ISSET(DB_READ_UNCOMMITTED)) {
+		mode |= DB_READ_UNCOMMITTED;
+		LF_CLR(DB_READ_UNCOMMITTED);
+	} else if (LF_ISSET(DB_READ_COMMITTED)) {
+		mode |= DB_READ_COMMITTED;
+		LF_CLR(DB_READ_COMMITTED);
+	}
+
+	if ((ret = __db_cursor(dbp, ip, txn, &dbc, mode)) != 0)
+		return (ret);
+
+	SET_RET_MEM(dbc, dbp);
+
+	DEBUG_LREAD(dbc, txn, "__db_pget", skey, NULL, flags);
+
+	/*
+	 * !!!
+	 * The actual method call is simple, do it inline.
+	 *
+	 * The underlying cursor pget will fill in a default DBT for null
+	 * pkeys, and use the cursor's returned-key memory internally to
+	 * store any intermediate primary keys.  However, we've just set
+	 * the returned-key memory to the DB handle's key memory, which
+	 * is unsafe to use if the DB handle is threaded.  If the pkey
+	 * argument is NULL, use the DBC-owned returned-key memory
+	 * instead;  it'll go away when we close the cursor before we
+	 * return, but in this case that's just fine, as we're not
+	 * returning the primary key.
+	 */
+	if (pkey == NULL)
+		dbc->rkey = &dbc->my_rkey;
+
+	/*
+	 * The cursor is just a perfectly ordinary secondary database cursor.
+	 * Call its c_pget() method to do the dirty work.
+	 */
+	if (flags == 0 || flags == DB_RMW)
+		flags |= DB_SET;
+
+	ret = __dbc_pget(dbc, skey, pkey, data, flags);
+
+	if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __db_pget_arg --
+ *	Check DB->pget arguments.
+ */
+static int
+__db_pget_arg(dbp, pkey, flags)
+	DB *dbp;
+	DBT *pkey;
+	u_int32_t flags;
+{
+	ENV *env;
+	int ret;
+
+	env = dbp->env;
+
+	if (!F_ISSET(dbp, DB_AM_SECONDARY)) {
+		__db_errx(env, DB_STR("0601",
+		    "DB->pget may only be used on secondary indices"));
+		return (EINVAL);
+	}
+
+	if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {
+		__db_errx(env,DB_STR("0602",
+"DB_MULTIPLE and DB_MULTIPLE_KEY may not be used on secondary indices"));
+		return (EINVAL);
+	}
+
+	/* DB_CONSUME makes no sense on a secondary index. */
+	LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW);
+	switch (flags) {
+	case DB_CONSUME:
+	case DB_CONSUME_WAIT:
+		return (__db_ferr(env, "DB->pget", 0));
+	default:
+		/* __db_get_arg will catch the rest. */
+		break;
+	}
+
+	/*
+	 * We allow the pkey field to be NULL, so that we can make the
+	 * two-DBT get calls into wrappers for the three-DBT ones.
+	 */
+	if (pkey != NULL &&
+	    (ret = __dbt_ferr(dbp, "primary key", pkey, 1)) != 0)
+		return (ret);
+
+	/* Check invalid partial pkey. */
+	if (pkey != NULL && F_ISSET(pkey, DB_DBT_PARTIAL)) {
+		__db_errx(env, DB_STR("0709",
+		    "The primary key returned by pget can't be partial"));
+		return (EINVAL);
+	}
+
+	if (flags == DB_GET_BOTH) {
+		/* The pkey field can't be NULL if we're doing a DB_GET_BOTH. */
+		if (pkey == NULL) {
+			__db_errx(env, DB_STR("0603",
+		    "DB_GET_BOTH on a secondary index requires a primary key"));
+			return (EINVAL);
+		}
+		if ((ret = __dbt_usercopy(env, pkey)) != 0)
+			return (ret);
+	}
+
+	return (0);
+}
+
+/*
+ * __db_put_pp --
+ *	DB->put pre/post processing.
+ *
+ * PUBLIC: int __db_put_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
+ */
+int
+__db_put_pp(dbp, txn, key, data, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, txn_local, t_ret;
+
+	env = dbp->env;
+	txn_local = 0;
+
+	STRIP_AUTO_COMMIT(flags);
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->put");
+
+	if ((ret = __db_put_arg(dbp, key, data, flags)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+	XA_CHECK_TXN(ip, txn);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check &&
+	    (ret = __db_rep_enter(dbp, 1, 0, IS_REAL_TXN(txn))) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	/* Create local transaction as necessary. */
+	if (IS_DB_AUTO_COMMIT(dbp, txn)) {
+		if ((ret = __txn_begin(env, ip, NULL, &txn, 0)) != 0)
+			goto err;
+		txn_local = 1;
+	}
+
+	/* Check for consistent transaction usage. */
+	if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0)
+		goto err;
+
+	ret = __db_put(dbp, ip, txn, key, data, flags);
+
+err:	if (txn_local &&
+	    (t_ret = __db_txn_auto_resolve(env, txn, 0, ret)) && ret == 0)
+		ret = t_ret;
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	__dbt_userfree(env, key, NULL, data);
+	return (ret);
+}
+
+/*
+ * __db_put_arg --
+ *	Check DB->put arguments.
+ */
+static int
+__db_put_arg(dbp, key, data, flags)
+	DB *dbp;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	ENV *env;
+	int ret, returnkey;
+
+	env = dbp->env;
+	returnkey = 0;
+
+	/* Check for changes to a read-only tree. */
+	if (DB_IS_READONLY(dbp))
+		return (__db_rdonly(env, "DB->put"));
+
+	/* Check for puts on a secondary. */
+	if (F_ISSET(dbp, DB_AM_SECONDARY)) {
+		__db_errx(env, DB_STR("0604",
+		    "DB->put forbidden on secondary indices"));
+		return (EINVAL);
+	}
+
+	if (LF_ISSET(DB_MULTIPLE_KEY | DB_MULTIPLE)) {
+		if (LF_ISSET(DB_MULTIPLE) && LF_ISSET(DB_MULTIPLE_KEY))
+			goto err;
+
+		switch (LF_ISSET(DB_OPFLAGS_MASK)) {
+		case 0:
+		case DB_OVERWRITE_DUP:
+			break;
+		default:
+			__db_errx(env, DB_STR("0605",
+"DB->put: DB_MULTIPLE(_KEY) can only be combined with DB_OVERWRITE_DUP"));
+			return (EINVAL);
+		}
+
+		if (!F_ISSET(key, DB_DBT_BULK)) {
+			__db_errx(env, DB_STR("0606",
+	    "DB->put with DB_MULTIPLE(_KEY) requires a bulk key buffer"));
+			return (EINVAL);
+		}
+	}
+	if (LF_ISSET(DB_MULTIPLE)) {
+		if (!F_ISSET(data, DB_DBT_BULK)) {
+			__db_errx(env, DB_STR("0607",
+		    "DB->put with DB_MULTIPLE requires a bulk data buffer"));
+			return (EINVAL);
+		}
+	}
+
+	/* Check for invalid function flags. */
+	switch (LF_ISSET(DB_OPFLAGS_MASK)) {
+	case 0:
+	case DB_NOOVERWRITE:
+	case DB_OVERWRITE_DUP:
+		break;
+	case DB_APPEND:
+		if (dbp->type != DB_RECNO &&
+		    dbp->type != DB_QUEUE && dbp->type != DB_HEAP)
+			goto err;
+		returnkey = 1;
+		break;
+	case DB_NODUPDATA:
+		if (F_ISSET(dbp, DB_AM_DUPSORT))
+			break;
+		/* FALLTHROUGH */
+	default:
+err:		return (__db_ferr(env, "DB->put", 0));
+	}
+
+	/*
+	 * Check for invalid key/data flags.  The key may reasonably be NULL
+	 * if DB_APPEND is set and the application doesn't care about the
+	 * returned key.
+	 */
+	if (((returnkey && key != NULL) || !returnkey) &&
+	    (ret = __dbt_ferr(dbp, "key", key, returnkey)) != 0)
+		return (ret);
+	if (!LF_ISSET(DB_MULTIPLE_KEY) &&
+	    (ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
+		return (ret);
+
+	/*
+	 * The key parameter should not be NULL or have the "partial" flag set
+	 * in a put call unless the user doesn't care about a key value we'd
+	 * return.  The user tells us they don't care about the returned key by
+	 * setting the key parameter to NULL or configuring the key DBT to not
+	 * return any information.  (Returned keys from a put are always record
+	 * numbers, and returning part of a record number  doesn't make sense:
+	 * only accept a partial return if the length returned is 0.)
+	 */
+	if ((returnkey &&
+	    key != NULL && F_ISSET(key, DB_DBT_PARTIAL) && key->dlen != 0) ||
+	    (!returnkey && F_ISSET(key, DB_DBT_PARTIAL)))
+		return (__db_ferr(env, "key DBT", 0));
+
+	/* Check for partial puts in the presence of duplicates. */
+	if (data != NULL && F_ISSET(data, DB_DBT_PARTIAL) &&
+	    (F_ISSET(dbp, DB_AM_DUP) || F_ISSET(key, DB_DBT_DUPOK))) {
+		__db_errx(env, DB_STR("0608",
+"a partial put in the presence of duplicates requires a cursor operation"));
+		return (EINVAL);
+	}
+
+	if ((flags != DB_APPEND && (ret = __dbt_usercopy(env, key)) != 0) ||
+	    (!LF_ISSET(DB_MULTIPLE_KEY) &&
+	    (ret = __dbt_usercopy(env, data)) != 0))
+		return (ret);
+
+	return (0);
+}
+
+/*
+ * __db_sync_pp --
+ *	DB->sync pre/post processing.
+ *
+ * PUBLIC: int __db_sync_pp __P((DB *, u_int32_t));
+ */
+int
+__db_sync_pp(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret;
+
+	env = dbp->env;
+
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->sync");
+
+	/*
+	 * !!!
+	 * The actual argument checking is simple, do it inline, outside of
+	 * the replication block.
+	 */
+	if (flags != 0)
+		return (__db_ferr(env, "DB->sync", 0));
+
+	ENV_ENTER(env, ip);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	ret = __db_sync(dbp);
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+err:	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __dbc_close_pp --
+ *	DBC->close pre/post processing.
+ *
+ * PUBLIC: int __dbc_close_pp __P((DBC *));
+ */
+int
+__dbc_close_pp(dbc)
+	DBC *dbc;
+{
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	DB_TXN *txn;
+	int handle_check, ret, t_ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	txn = dbc->txn;
+
+	/*
+	 * If the cursor is already closed we have a serious problem, and we
+	 * assume that the cursor isn't on the active queue.  Don't do any of
+	 * the remaining cursor close processing.
+	 */
+	if (!F_ISSET(dbc, DBC_ACTIVE)) {
+		__db_errx(env, DB_STR("0616",
+		    "Closing already-closed cursor"));
+		return (EINVAL);
+	}
+
+	ENV_ENTER(env, ip);
+
+	/* Check for replication block. */
+	handle_check = !IS_REAL_TXN(dbc->txn) && IS_ENV_REPLICATED(env);
+
+	/* Unregister the cursor from its transaction, regardless of ret. */
+	if (txn != NULL) {
+		TAILQ_REMOVE(&(txn->my_cursors), dbc, txn_cursors);
+		dbc->txn_cursors.tqe_next = NULL;
+		dbc->txn_cursors.tqe_prev = NULL;
+	} else {
+		DB_ASSERT(env, dbc->txn_cursors.tqe_next == NULL &&
+		    dbc->txn_cursors.tqe_prev == NULL);
+	}
+
+	ret = __dbc_close(dbc);
+
+	/* Release replication block. */
+	if (handle_check &&
+	    (t_ret = __op_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __dbc_cmp_pp --
+ *	DBC->cmp pre/post processing.
+ *
+ * PUBLIC: int __dbc_cmp_pp __P((DBC *, DBC *, int*, u_int32_t));
+ */
+int
+__dbc_cmp_pp(dbc, other_cursor, result, flags)
+	DBC *dbc, *other_cursor;
+	int *result;
+	u_int32_t flags;
+{
+	DB *dbp, *odbp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	dbp = dbc->dbp;
+	odbp = other_cursor->dbp;
+	env = dbp->env;
+
+	if (flags != 0)
+		return (__db_ferr(env, "DBcursor->cmp", 0));
+
+	if (other_cursor == NULL) {
+		__db_errx(env, DB_STR("0617",
+		    "DBcursor->cmp dbc pointer must not be null"));
+		return (EINVAL);
+	}
+
+	if (dbp != odbp) {
+		__db_errx(env, DB_STR("0618",
+"DBcursor->cmp both cursors must refer to the same database."));
+		return (EINVAL);
+	}
+
+	ENV_ENTER(env, ip);
+	ret = __dbc_cmp(dbc, other_cursor, result);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __dbc_count_pp --
+ *	DBC->count pre/post processing.
+ *
+ * PUBLIC: int __dbc_count_pp __P((DBC *, db_recno_t *, u_int32_t));
+ */
+int
+__dbc_count_pp(dbc, recnop, flags)
+	DBC *dbc;
+	db_recno_t *recnop;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	/*
+	 * !!!
+	 * The actual argument checking is simple, do it inline, outside of
+	 * the replication block.
+	 *
+	 * The cursor must be initialized, return EINVAL for an invalid cursor.
+	 */
+	if (flags != 0)
+		return (__db_ferr(env, "DBcursor->count", 0));
+
+	if (!IS_INITIALIZED(dbc))
+		return (__db_curinval(env));
+
+	ENV_ENTER(env, ip);
+	ret = __dbc_count(dbc, recnop);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __dbc_del_pp --
+ *	DBC->del pre/post processing.
+ *
+ * PUBLIC: int __dbc_del_pp __P((DBC *, u_int32_t));
+ */
+int
+__dbc_del_pp(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	if ((ret = __dbc_del_arg(dbc, flags)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+
+	/* Check for consistent transaction usage. */
+	if ((ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0)
+		goto err;
+
+	DEBUG_LWRITE(dbc, dbc->txn, "DBcursor->del", NULL, NULL, flags);
+	ret = __dbc_del(dbc, flags);
+
+err:	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __dbc_del_arg --
+ *	Check DBC->del arguments.
+ */
+static int
+__dbc_del_arg(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	DB *dbp;
+	ENV *env;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	/* Check for changes to a read-only tree. */
+	if (DB_IS_READONLY(dbp))
+		return (__db_rdonly(env, "DBcursor->del"));
+
+	/* Check for invalid function flags. */
+	switch (flags) {
+	case 0:
+		break;
+	case DB_CONSUME:
+		if (dbp->type != DB_QUEUE)
+			return (__db_ferr(env, "DBC->del", 0));
+		break;
+	case DB_UPDATE_SECONDARY:
+		DB_ASSERT(env, F_ISSET(dbp, DB_AM_SECONDARY));
+		break;
+	default:
+		return (__db_ferr(env, "DBcursor->del", 0));
+	}
+
+	/*
+	 * The cursor must be initialized, return EINVAL for an invalid cursor,
+	 * otherwise 0.
+	 */
+	if (!IS_INITIALIZED(dbc))
+		return (__db_curinval(env));
+
+	return (0);
+}
+
+/*
+ * __dbc_dup_pp --
+ *	DBC->dup pre/post processing.
+ *
+ * PUBLIC: int __dbc_dup_pp __P((DBC *, DBC **, u_int32_t));
+ */
+int
+__dbc_dup_pp(dbc, dbcp, flags)
+	DBC *dbc, **dbcp;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int rep_blocked, ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	/*
+	 * !!!
+	 * The actual argument checking is simple, do it inline, outside of
+	 * the replication block.
+	 */
+	if (flags != 0 && flags != DB_POSITION)
+		return (__db_ferr(env, "DBcursor->dup", 0));
+
+	ENV_ENTER(env, ip);
+	rep_blocked = 0;
+	if (dbc->txn == NULL && IS_ENV_REPLICATED(env)) {
+		if ((ret = __op_rep_enter(env, 1, 1)) != 0)
+			goto err;
+		rep_blocked = 1;
+	}
+	ret = __dbc_dup(dbc, dbcp, flags);
+
+	/* Register externally created cursors into the valid transaction. */
+	DB_ASSERT(env, (*dbcp)->txn == dbc->txn);
+	if ((*dbcp)->txn != NULL && ret == 0)
+		TAILQ_INSERT_HEAD(&((*dbcp)->txn->my_cursors), *dbcp,
+		    txn_cursors);
+err:
+	if (ret != 0 && rep_blocked)
+		(void)__op_rep_exit(env);
+
+	ENV_LEAVE(env, ip);
+
+	return (ret);
+}
+
+/*
+ * __dbc_get_pp --
+ *	DBC->get pre/post processing.
+ *
+ * PUBLIC: int __dbc_get_pp __P((DBC *, DBT *, DBT *, u_int32_t));
+ */
+int
+__dbc_get_pp(dbc, key, data, flags)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ignore_lease, ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	ignore_lease = LF_ISSET(DB_IGNORE_LEASE) ? 1 : 0;
+	LF_CLR(DB_IGNORE_LEASE);
+	if ((ret = __dbc_get_arg(dbc, key, data, flags)) != 0) {
+		__dbt_userfree(env, key, NULL, data);
+		return (ret);
+	}
+
+	ENV_ENTER(env, ip);
+
+	DEBUG_LREAD(dbc, dbc->txn, "DBcursor->get",
+	    flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags);
+	ret = __dbc_get(dbc, key, data, flags);
+
+	/*
+	 * Check for master leases.
+	 */
+	if (ret == 0 &&
+	    IS_REP_MASTER(env) && IS_USING_LEASES(env) && !ignore_lease)
+		ret = __rep_lease_check(env, 1);
+
+	ENV_LEAVE(env, ip);
+	__dbt_userfree(env, key, NULL, data);
+	return (ret);
+}
+
+/*
+ * __dbc_get_arg --
+ *	Common DBC->get argument checking, used by both DBC->get and DBC->pget.
+ * PUBLIC: int __dbc_get_arg __P((DBC *, DBT *, DBT *, u_int32_t));
+ */
+int
+__dbc_get_arg(dbc, key, data, flags)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DB *dbp;
+	ENV *env;
+	int dirty, multi, ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	/*
+	 * Typically in checking routines that modify the flags, we have
+	 * to save them and restore them, because the checking routine
+	 * calls the work routine.  However, this is a pure-checking
+	 * routine which returns to a function that calls the work routine,
+	 * so it's OK that we do not save and restore the flags, even though
+	 * we modify them.
+	 *
+	 * Check for read-modify-write validity.  DB_RMW doesn't make sense
+	 * with CDB cursors since if you're going to write the cursor, you
+	 * had to create it with DB_WRITECURSOR.  Regardless, we check for
+	 * LOCKING_ON and not STD_LOCKING, as we don't want to disallow it.
+	 * If this changes, confirm that DB does not itself set the DB_RMW
+	 * flag in a path where CDB may have been configured.
+	 */
+	dirty = 0;
+	if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW)) {
+		if (!LOCKING_ON(env))
+			return (__db_fnl(env, "DBcursor->get"));
+		if (LF_ISSET(DB_READ_UNCOMMITTED))
+			dirty = 1;
+		LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW);
+	}
+
+	multi = 0;
+	if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {
+		multi = 1;
+		if (LF_ISSET(DB_MULTIPLE) && LF_ISSET(DB_MULTIPLE_KEY))
+			goto multi_err;
+		LF_CLR(DB_MULTIPLE | DB_MULTIPLE_KEY);
+	}
+
+	/* Check for invalid function flags. */
+	switch (flags) {
+	case DB_CONSUME:
+	case DB_CONSUME_WAIT:
+		if (dirty) {
+			__db_errx(env, DB_STR("0619",
+"DB_READ_UNCOMMITTED is not supported with DB_CONSUME or DB_CONSUME_WAIT"));
+			return (EINVAL);
+		}
+		if (dbp->type != DB_QUEUE)
+			goto err;
+		break;
+	case DB_CURRENT:
+	case DB_FIRST:
+	case DB_NEXT:
+	case DB_NEXT_DUP:
+	case DB_NEXT_NODUP:
+		break;
+	case DB_LAST:
+	case DB_PREV:
+	case DB_PREV_DUP:
+	case DB_PREV_NODUP:
+		if (multi)
+multi_err:		return (__db_ferr(env, "DBcursor->get", 1));
+		break;
+	case DB_GET_BOTHC:
+		if (dbp->type == DB_QUEUE)
+			goto err;
+		/* FALLTHROUGH */
+	case DB_GET_BOTH:
+	case DB_GET_BOTH_RANGE:
+		if ((ret = __dbt_usercopy(env, data)) != 0)
+			goto err;
+		/* FALLTHROUGH */
+	case DB_SET:
+	case DB_SET_RANGE:
+		if ((ret = __dbt_usercopy(env, key)) != 0)
+			goto err;
+		break;
+	case DB_GET_RECNO:
+		/*
+		 * The one situation in which this might be legal with a
+		 * non-RECNUM dbp is if dbp is a secondary and its primary is
+		 * DB_AM_RECNUM.
+		 */
+		if (!F_ISSET(dbp, DB_AM_RECNUM) &&
+		    (!F_ISSET(dbp, DB_AM_SECONDARY) ||
+		    !F_ISSET(dbp->s_primary, DB_AM_RECNUM)))
+			goto err;
+		break;
+	case DB_SET_RECNO:
+		if (!F_ISSET(dbp, DB_AM_RECNUM))
+			goto err;
+		if ((ret = __dbt_usercopy(env, key)) != 0)
+			goto err;
+		break;
+	default:
+err:		__dbt_userfree(env, key, NULL, data);
+		return (__db_ferr(env, "DBcursor->get", 0));
+	}
+
+	/* Check for invalid key/data flags. */
+	if ((ret = __dbt_ferr(dbp, "key", key, 0)) != 0)
+		return (ret);
+	if (F_ISSET(data, DB_DBT_READONLY)) {
+		__db_errx(env, DB_STR("0620",
+		    "DB_DBT_READONLY should not be set on data DBT."));
+			return (EINVAL);
+	}
+	if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
+		return (ret);
+
+	if (multi) {
+		if (!F_ISSET(data, DB_DBT_USERMEM)) {
+			__db_errx(env, DB_STR("0621",
+	    "DB_MULTIPLE/DB_MULTIPLE_KEY require DB_DBT_USERMEM be set"));
+			return (EINVAL);
+		}
+		if (F_ISSET(key, DB_DBT_PARTIAL) ||
+		    F_ISSET(data, DB_DBT_PARTIAL)) {
+			__db_errx(env, DB_STR("0622",
+	    "DB_MULTIPLE/DB_MULTIPLE_KEY do not support DB_DBT_PARTIAL"));
+			return (EINVAL);
+		}
+		if (data->ulen < 1024 ||
+		    data->ulen < dbp->pgsize || data->ulen % 1024 != 0) {
+			__db_errx(env, DB_STR("0623",
+			    "DB_MULTIPLE/DB_MULTIPLE_KEY buffers must be "
+		    "aligned, at least page size and multiples of 1KB"));
+			return (EINVAL);
+		}
+	}
+
+	/* Check compatible flags for partial key. */
+	if (F_ISSET(key, DB_DBT_PARTIAL) && (flags == DB_GET_BOTH ||
+	    flags == DB_GET_BOTH_RANGE || flags == DB_SET)) {
+		__db_errx(env, DB_STR("0710",
+		    "Invalid positioning flag combined with DB_DBT_PARTIAL"));
+		return (EINVAL);
+	}
+
+	/*
+	 * The cursor must be initialized for DB_CURRENT, DB_GET_RECNO,
+	 * DB_PREV_DUP and DB_NEXT_DUP.  Return EINVAL for an invalid
+	 * cursor, otherwise 0.
+	 */
+	if (!IS_INITIALIZED(dbc) && (flags == DB_CURRENT ||
+	    flags == DB_GET_RECNO ||
+	    flags == DB_NEXT_DUP || flags == DB_PREV_DUP))
+		return (__db_curinval(env));
+
+	/* Check for consistent transaction usage. */
+	if (LF_ISSET(DB_RMW) &&
+	    (ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0)
+		return (ret);
+
+	return (0);
+}
+
+/*
+ * __db_secondary_close_pp --
+ *	DB->close for secondaries
+ *
+ * PUBLIC: int __db_secondary_close_pp __P((DB *, u_int32_t));
+ */
+int
+__db_secondary_close_pp(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret;
+
+	env = dbp->env;
+	ret = 0;
+
+	/*
+	 * As a DB handle destructor, we can't fail.
+	 *
+	 * !!!
+	 * The actual argument checking is simple, do it inline, outside of
+	 * the replication block.
+	 */
+	if (flags != 0 && flags != DB_NOSYNC)
+		ret = __db_ferr(env, "DB->close", 0);
+
+	ENV_ENTER(env, ip);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check && (t_ret = __db_rep_enter(dbp, 0, 0, 0)) != 0) {
+		handle_check = 0;
+		if (ret == 0)
+			ret = t_ret;
+	}
+
+	if ((t_ret = __db_secondary_close(dbp, flags)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __dbc_pget_pp --
+ *	DBC->pget pre/post processing.
+ *
+ * PUBLIC: int __dbc_pget_pp __P((DBC *, DBT *, DBT *, DBT *, u_int32_t));
+ */
+int
+__dbc_pget_pp(dbc, skey, pkey, data, flags)
+	DBC *dbc;
+	DBT *skey, *pkey, *data;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ignore_lease, ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	ignore_lease = LF_ISSET(DB_IGNORE_LEASE) ? 1 : 0;
+	LF_CLR(DB_IGNORE_LEASE);
+	if ((ret = __dbc_pget_arg(dbc, pkey, flags)) != 0 ||
+	    (ret = __dbc_get_arg(dbc, skey, data, flags)) != 0) {
+		__dbt_userfree(env, skey, pkey, data);
+		return (ret);
+	}
+
+	ENV_ENTER(env, ip);
+	DEBUG_LREAD(dbc, dbc->txn, "DBcursor->pget",
+	    flags == DB_SET ||
+	    flags == DB_SET_RANGE ? skey : NULL, NULL, flags);
+	ret = __dbc_pget(dbc, skey, pkey, data, flags);
+	/*
+	 * Check for master leases.
+	 */
+	if (ret == 0 &&
+	    IS_REP_MASTER(env) && IS_USING_LEASES(env) && !ignore_lease)
+		ret = __rep_lease_check(env, 1);
+
+	ENV_LEAVE(env, ip);
+
+	__dbt_userfree(env, skey, pkey, data);
+	return (ret);
+}
+
+/*
+ * __dbc_pget_arg --
+ *	Check DBC->pget arguments.
+ */
+static int
+__dbc_pget_arg(dbc, pkey, flags)
+	DBC *dbc;
+	DBT *pkey;
+	u_int32_t flags;
+{
+	DB *dbp;
+	ENV *env;
+	int ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	if (!F_ISSET(dbp, DB_AM_SECONDARY)) {
+		__db_errx(env, DB_STR("0624",
+		    "DBcursor->pget may only be used on secondary indices"));
+		return (EINVAL);
+	}
+
+	if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) {
+		__db_errx(env, DB_STR("0625",
+    "DB_MULTIPLE and DB_MULTIPLE_KEY may not be used on secondary indices"));
+		return (EINVAL);
+	}
+
+	switch (LF_ISSET(DB_OPFLAGS_MASK)) {
+	case DB_CONSUME:
+	case DB_CONSUME_WAIT:
+		/* These flags make no sense on a secondary index. */
+		return (__db_ferr(env, "DBcursor->pget", 0));
+	case DB_GET_BOTH:
+	case DB_GET_BOTH_RANGE:
+		/* BOTH is "get both the primary and the secondary". */
+		if (pkey == NULL) {
+			__db_errx(env, DB_STR_A("0626",
+			    "%s requires both a secondary and a primary key",
+			    "%s"), LF_ISSET(DB_GET_BOTH) ?
+			    "DB_GET_BOTH" : "DB_GET_BOTH_RANGE");
+			return (EINVAL);
+		}
+		if ((ret = __dbt_usercopy(env, pkey)) != 0)
+			return (ret);
+		break;
+	default:
+		/* __dbc_get_arg will catch the rest. */
+		break;
+	}
+
+	/*
+	 * We allow the pkey field to be NULL, so that we can make the
+	 * two-DBT get calls into wrappers for the three-DBT ones.
+	 */
+	if (pkey != NULL &&
+	    (ret = __dbt_ferr(dbp, "primary key", pkey, 0)) != 0)
+		return (ret);
+
+	/* Check invalid partial pkey. */
+	if (pkey != NULL && F_ISSET(pkey, DB_DBT_PARTIAL)) {
+		__db_errx(env, DB_STR("0711",
+		    "The primary key returned by pget can't be partial."));
+		return (EINVAL);
+	}
+
+	/* But the pkey field can't be NULL if we're doing a DB_GET_BOTH. */
+	if (pkey == NULL && (flags & DB_OPFLAGS_MASK) == DB_GET_BOTH) {
+		__db_errx(env, DB_STR("0627",
+		    "DB_GET_BOTH on a secondary index requires a primary key"));
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+/*
+ * __dbc_put_pp --
+ *	DBC->put pre/post processing.
+ *
+ * PUBLIC: int __dbc_put_pp __P((DBC *, DBT *, DBT *, u_int32_t));
+ */
+int
+__dbc_put_pp(dbc, key, data, flags)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+
+	if ((ret = __dbc_put_arg(dbc, key, data, flags)) != 0) {
+		__dbt_userfree(env, key, NULL, data);
+		return (ret);
+	}
+
+	ENV_ENTER(env, ip);
+
+	/* Check for consistent transaction usage. */
+	if ((ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0)
+		goto err;
+
+	DEBUG_LWRITE(dbc, dbc->txn, "DBcursor->put",
+	    flags == DB_KEYFIRST || flags == DB_KEYLAST ||
+	    flags == DB_NODUPDATA || flags == DB_UPDATE_SECONDARY ?
+	    key : NULL, data, flags);
+	ret = __dbc_put(dbc, key, data, flags);
+
+err:	ENV_LEAVE(env, ip);
+	__dbt_userfree(env, key, NULL, data);
+	return (ret);
+}
+
+/*
+ * __dbc_put_arg --
+ *	Check DBC->put arguments.
+ */
+static int
+__dbc_put_arg(dbc, key, data, flags)
+	DBC *dbc;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	DB *dbp;
+	ENV *env;
+	int key_flags, ret;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	key_flags = 0;
+
+	/* Check for changes to a read-only tree. */
+	if (DB_IS_READONLY(dbp))
+		return (__db_rdonly(env, "DBcursor->put"));
+
+	/* Check for puts on a secondary. */
+	if (F_ISSET(dbp, DB_AM_SECONDARY)) {
+		if (flags == DB_UPDATE_SECONDARY)
+			flags = 0;
+		else {
+			__db_errx(env, DB_STR("0628",
+			    "DBcursor->put forbidden on secondary indices"));
+			return (EINVAL);
+		}
+	}
+
+	if ((ret = __dbt_usercopy(env, data)) != 0)
+		return (ret);
+
+	/* Check for invalid function flags. */
+	switch (flags) {
+	case DB_AFTER:
+	case DB_BEFORE:
+		switch (dbp->type) {
+		case DB_BTREE:
+		case DB_HASH:		/* Only with unsorted duplicates. */
+			if (!F_ISSET(dbp, DB_AM_DUP))
+				goto err;
+			if (dbp->dup_compare != NULL)
+				goto err;
+			break;
+		case DB_QUEUE:		/* Not permitted. */
+			goto err;
+		case DB_RECNO:		/* Only with mutable record numbers. */
+			if (!F_ISSET(dbp, DB_AM_RENUMBER))
+				goto err;
+			key_flags = key == NULL ? 0 : 1;
+			break;
+		case DB_UNKNOWN:
+		default:
+			goto err;
+		}
+		break;
+	case DB_CURRENT:
+		/*
+		 * If there is a comparison function, doing a DB_CURRENT
+		 * must not change the part of the data item that is used
+		 * for the comparison.
+		 */
+		break;
+	case DB_NODUPDATA:
+		if (!F_ISSET(dbp, DB_AM_DUPSORT))
+			goto err;
+		/* FALLTHROUGH */
+	case DB_KEYFIRST:
+	case DB_KEYLAST:
+	case DB_OVERWRITE_DUP:
+		key_flags = 1;
+		if ((ret = __dbt_usercopy(env, key)) != 0)
+			return (ret);
+		break;
+	default:
+err:		return (__db_ferr(env, "DBcursor->put", 0));
+	}
+
+	/*
+	 * Check for invalid key/data flags.  The key may reasonably be NULL
+	 * if DB_AFTER or DB_BEFORE is set and the application doesn't care
+	 * about the returned key, or if the DB_CURRENT flag is set.
+	 */
+	if (key_flags && (ret = __dbt_ferr(dbp, "key", key, 0)) != 0)
+		return (ret);
+	if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0)
+		return (ret);
+
+	/*
+	 * The key parameter should not be NULL or have the "partial" flag set
+	 * in a put call unless the user doesn't care about a key value we'd
+	 * return.  The user tells us they don't care about the returned key by
+	 * setting the key parameter to NULL or configuring the key DBT to not
+	 * return any information.  (Returned keys from a put are always record
+	 * numbers, and returning part of a record number  doesn't make sense:
+	 * only accept a partial return if the length returned is 0.)
+	 */
+	if (key_flags && F_ISSET(key, DB_DBT_PARTIAL) && key->dlen != 0)
+		return (__db_ferr(env, "key DBT", 0));
+
+	/*
+	 * The cursor must be initialized for anything other than DB_KEYFIRST,
+	 * DB_KEYLAST or zero: return EINVAL for an invalid cursor, otherwise 0.
+	 */
+	if (!IS_INITIALIZED(dbc) && flags != 0 && flags != DB_KEYFIRST &&
+	    flags != DB_KEYLAST && flags != DB_NODUPDATA &&
+	    flags != DB_OVERWRITE_DUP)
+		return (__db_curinval(env));
+
+	return (0);
+}
+
+/*
+ * __dbt_ferr --
+ *	Check a DBT for flag errors.
+ */
+static int
+__dbt_ferr(dbp, name, dbt, check_thread)
+	const DB *dbp;
+	const char *name;
+	const DBT *dbt;
+	int check_thread;
+{
+	ENV *env;
+	int ret;
+
+	env = dbp->env;
+
+	/*
+	 * Check for invalid DBT flags.  We allow any of the flags to be
+	 * specified to any DB or DBcursor call so that applications can
+	 * set DB_DBT_MALLOC when retrieving a data item from a secondary
+	 * database and then specify that same DBT as a key to a primary
+	 * database, without having to clear flags.
+	 */
+	if ((ret = __db_fchk(env, name, dbt->flags,
+	    DB_DBT_APPMALLOC | DB_DBT_BULK | DB_DBT_DUPOK |
+	    DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERCOPY |
+	    DB_DBT_USERMEM | DB_DBT_PARTIAL | DB_DBT_READONLY)) != 0)
+		return (ret);
+	switch (F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC |
+	    DB_DBT_USERCOPY | DB_DBT_USERMEM)) {
+	case 0:
+	case DB_DBT_MALLOC:
+	case DB_DBT_REALLOC:
+	case DB_DBT_USERCOPY:
+	case DB_DBT_USERMEM:
+		break;
+	default:
+		return (__db_ferr(env, name, 1));
+	}
+
+	if (F_ISSET(dbt, DB_DBT_BULK) && F_ISSET(dbt, DB_DBT_PARTIAL)) {
+		__db_errx(env, DB_STR_A("0629",
+		    "Bulk and partial operations cannot be combined on %s DBT",
+		    "%s"), name);
+		return (EINVAL);
+	}
+
+	if (check_thread && DB_IS_THREADED(dbp) &&
+	    !F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC |
+		DB_DBT_USERCOPY | DB_DBT_USERMEM | DB_DBT_READONLY)) {
+		__db_errx(env, DB_STR_A("0630",
+		    "DB_THREAD mandates memory allocation flag on %s DBT",
+		    "%s"), name);
+		return (EINVAL);
+	}
+	return (0);
+}
+
+/*
+ * __db_curinval
+ *	Report that a cursor is in an invalid state.
+ */
+static int
+__db_curinval(env)
+	const ENV *env;
+{
+	__db_errx(env, DB_STR("0631",
+	    "Cursor position must be set before performing this operation"));
+	return (EINVAL);
+}
+
+/*
+ * __db_txn_auto_init --
+ *	Handle DB_AUTO_COMMIT initialization.
+ *
+ * PUBLIC: int __db_txn_auto_init __P((ENV *, DB_THREAD_INFO *, DB_TXN **));
+ */
+int
+__db_txn_auto_init(env, ip, txnidp)
+	ENV *env;
+	DB_THREAD_INFO *ip;
+	DB_TXN **txnidp;
+{
+	/*
+	 * Method calls where applications explicitly specify DB_AUTO_COMMIT
+	 * require additional validation: the DB_AUTO_COMMIT flag cannot be
+	 * specified if a transaction cookie is also specified, nor can the
+	 * flag be specified in a non-transactional environment.
+	 */
+	if (*txnidp != NULL && !F_ISSET(*txnidp, TXN_FAMILY)) {
+		__db_errx(env, DB_STR("0632",
+    "DB_AUTO_COMMIT may not be specified along with a transaction handle"));
+		return (EINVAL);
+	}
+
+	if (!TXN_ON(env)) {
+		__db_errx(env, DB_STR("0633",
+    "DB_AUTO_COMMIT may not be specified in non-transactional environment"));
+		return (EINVAL);
+	}
+
+	/*
+	 * Our caller checked to see if replication is making a state change.
+	 * Don't call the user-level API (which would repeat that check).
+	 */
+	return (__txn_begin(env, ip, *txnidp, txnidp, 0));
+}
+
+/*
+ * __db_txn_auto_resolve --
+ *	Resolve local transactions.
+ *
+ * PUBLIC: int __db_txn_auto_resolve __P((ENV *, DB_TXN *, int, int));
+ */
+int
+__db_txn_auto_resolve(env, txn, nosync, ret)
+	ENV *env;
+	DB_TXN *txn;
+	int nosync, ret;
+{
+	int t_ret;
+
+	if (ret == 0)
+		return (__txn_commit(txn, nosync ? DB_TXN_NOSYNC : 0));
+
+	if ((t_ret = __txn_abort(txn)) != 0)
+		return (__env_panic(env, t_ret));
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_meta.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1126 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/lock.h"
+#include "dbinc/log.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+#include "dbinc/db_am.h"
+#include "dbinc/hash.h"
+
+static void __db_init_meta __P((DB *, void *, db_pgno_t, u_int32_t));
+#ifdef HAVE_FTRUNCATE
+static int  __db_pglistcmp __P((const void *, const void *));
+static int  __db_truncate_freelist __P((DBC *, DBMETA *,
+      PAGE *, db_pgno_t *, u_int32_t, u_int32_t));
+#endif
+
+/*
+ * __db_init_meta --
+ *	Helper function for __db_new that initializes the important fields in
+ * a meta-data page (used instead of P_INIT).  We need to make sure that we
+ * retain the page number and LSN of the existing page.
+ */
+static void
+__db_init_meta(dbp, p, pgno, pgtype)
+	DB *dbp;
+	void *p;
+	db_pgno_t pgno;
+	u_int32_t pgtype;
+{
+	DBMETA *meta;
+	DB_LSN save_lsn;
+
+	meta = (DBMETA *)p;
+	save_lsn = meta->lsn;
+	memset(meta, 0, sizeof(DBMETA));
+	meta->lsn = save_lsn;
+	meta->pagesize = dbp->pgsize;
+	if (F_ISSET(dbp, DB_AM_CHKSUM))
+		FLD_SET(meta->metaflags, DBMETA_CHKSUM);
+	meta->pgno = pgno;
+	meta->type = (u_int8_t)pgtype;
+}
+
+/*
+ * __db_new --
+ *	Get a new page, preferably from the freelist.
+ *
+ * PUBLIC: int __db_new __P((DBC *, u_int32_t, DB_LOCK *, PAGE **));
+ */
+int
+__db_new(dbc, type, lockp, pagepp)
+	DBC *dbc;
+	u_int32_t type;
+	DB_LOCK *lockp;
+	PAGE **pagepp;
+{
+	DB *dbp;
+	DBMETA *meta;
+	DB_LOCK metalock;
+	DB_LSN lsn;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h;
+	db_pgno_t last, *list, pgno, newnext;
+	int extend, hash, ret;
+
+	meta = NULL;
+	dbp = dbc->dbp;
+	env = dbp->env;
+	mpf = dbp->mpf;
+	h = NULL;
+	newnext = PGNO_INVALID;
+	if (lockp != NULL)
+		LOCK_INIT(*lockp);
+
+	hash = 0;
+	ret = 0;
+	LOCK_INIT(metalock);
+
+#ifdef HAVE_HASH
+	if (dbp->type == DB_HASH) {
+		if ((ret = __ham_return_meta(dbc, DB_MPOOL_DIRTY, &meta)) != 0)
+			goto err;
+		if (meta != NULL)
+			hash = 1;
+	}
+#endif
+	if (meta == NULL) {
+		pgno = PGNO_BASE_MD;
+		if ((ret = __db_lget(dbc,
+		    LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0)
+			goto err;
+		if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn,
+		    DB_MPOOL_DIRTY, &meta)) != 0)
+			goto err;
+	}
+
+	last = meta->last_pgno;
+	if (meta->free == PGNO_INVALID) {
+		if (FLD_ISSET(type, P_DONTEXTEND)) {
+			*pagepp = NULL;
+			goto err;
+		}
+		last = pgno = meta->last_pgno + 1;
+		ZERO_LSN(lsn);
+		extend = 1;
+	} else {
+		pgno = meta->free;
+		/*
+		 * Lock the new page.  Do this here because we must do it
+		 * before getting the page and the caller may need the lock
+		 * to keep readers from seeing the page before the transaction
+		 * commits.  We can do this because no one will hold a free
+		 * page locked.
+		 */
+		if (lockp != NULL && (ret =
+		     __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, lockp)) != 0)
+			goto err;
+		if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn,
+		    DB_MPOOL_DIRTY, &h)) != 0)
+			goto err;
+
+		/*
+		 * We want to take the first page off the free list and
+		 * then set meta->free to the that page's next_pgno, but
+		 * we need to log the change first.
+		 */
+		newnext = h->next_pgno;
+		lsn = h->lsn;
+		extend = 0;
+		DB_ASSERT(env, TYPE(h) == P_INVALID);
+
+		if (TYPE(h) != P_INVALID) {
+			__db_errx(env, DB_STR_A("0689",
+			    "%s page %lu is on free list with type %lu",
+			    "%s %lu %lu"), dbp->fname, (u_long)PGNO(h),
+			    (u_long)TYPE(h));
+			return (__env_panic(env, EINVAL));
+		}
+
+	}
+
+	FLD_CLR(type, P_DONTEXTEND);
+
+	/*
+	 * Log the allocation before fetching the new page.  If we
+	 * don't have room in the log then we don't want to tell
+	 * mpool to extend the file.
+	 */
+	if (DBC_LOGGING(dbc)) {
+		if ((ret = __db_pg_alloc_log(dbp, dbc->txn, &LSN(meta), 0,
+		    &LSN(meta), PGNO_BASE_MD, &lsn,
+		    pgno, (u_int32_t)type, newnext, meta->last_pgno)) != 0)
+			goto err;
+	} else
+		LSN_NOT_LOGGED(LSN(meta));
+
+	meta->free = newnext;
+
+	if (extend == 1) {
+		if (lockp != NULL && (ret =
+		     __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, lockp)) != 0)
+			goto err;
+		if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn,
+		    DB_MPOOL_NEW, &h)) != 0)
+			goto err;
+		DB_ASSERT(env, last == pgno);
+		meta->last_pgno = pgno;
+		ZERO_LSN(h->lsn);
+		h->pgno = pgno;
+
+		/*
+		 * If the file was extended for the first time in this
+		 * transaction, set the MPOOLFILE's file extension
+		 * watermark.
+		 */
+		__txn_add_fe_watermark(dbc->txn, dbp, h->pgno);
+
+	}
+	LSN(h) = LSN(meta);
+
+	if (hash == 0 && (ret = __memp_fput(mpf,
+	    dbc->thread_info, meta, dbc->priority)) != 0)
+		goto err;
+	meta = NULL;
+
+	switch (type) {
+		case P_BTREEMETA:
+		case P_HASHMETA:
+		case P_QAMMETA:
+			__db_init_meta(dbp, h, h->pgno, type);
+			break;
+		default:
+			P_INIT(h, dbp->pgsize,
+			    h->pgno, PGNO_INVALID, PGNO_INVALID, 0, type);
+			break;
+	}
+
+	/* Fix up the sorted free list if necessary. */
+#ifdef HAVE_FTRUNCATE
+	if (extend == 0) {
+		u_int32_t nelems = 0;
+
+		if ((ret = __memp_get_freelist(dbp->mpf, &nelems, &list)) != 0)
+			goto err;
+		if (nelems != 0) {
+			DB_ASSERT(env, h->pgno == list[0]);
+			memmove(list, &list[1], (nelems - 1) * sizeof(*list));
+			if ((ret = __memp_extend_freelist(
+			    dbp->mpf, nelems - 1, &list)) != 0)
+				goto err;
+		}
+	}
+#else
+	COMPQUIET(list, NULL);
+#endif
+
+	if ((ret = __TLPUT(dbc, metalock)) != 0)
+		return (ret);
+	*pagepp = h;
+	PERFMON6(env, alloc, new, dbp->fname, dbp->dname, pgno, type, h, 0);
+	return (0);
+
+err:	if (h != NULL)
+		(void)__memp_fput(mpf, dbc->thread_info, h, dbc->priority);
+	if (meta != NULL && hash == 0)
+		(void)__memp_fput(mpf, dbc->thread_info, meta, dbc->priority);
+	(void)__TLPUT(dbc, metalock);
+	if (lockp != NULL)
+		(void)__LPUT(dbc, *lockp);
+	/* Failure return - report 0 pgno, null page address. */
+	PERFMON6(env, alloc, new, dbp->fname, dbp->dname, 0, type, NULL, ret);
+	return (ret);
+}
+
+/*
+ * __db_free --
+ *	Add a page to the head of the freelist.
+ *
+ * PUBLIC: int __db_free __P((DBC *, PAGE *, u_int32_t));
+ */
+int
+__db_free(dbc, h, flags)
+	DBC *dbc;
+	PAGE *h;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DBMETA *meta;
+	DBT ddbt, ldbt;
+	DB_LOCK metalock;
+	DB_LSN *lsnp;
+	DB_MPOOLFILE *mpf;
+	PAGE *prev;
+	db_pgno_t last_pgno, next_pgno, pgno, prev_pgno;
+	u_int32_t lflag;
+	int hash, ret, t_ret;
+#ifdef HAVE_FTRUNCATE
+	db_pgno_t *list, *lp;
+	u_int32_t nelem, position, start;
+	int do_truncate;
+#endif
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	prev_pgno = PGNO_INVALID;
+	meta = NULL;
+	prev = NULL;
+	LOCK_INIT(metalock);
+#ifdef HAVE_FTRUNCATE
+	lp = NULL;
+	nelem = 0;
+	do_truncate = 0;
+#endif
+
+	/*
+	 * Retrieve the metadata page.  If we are not keeping a sorted
+	 * free list put the page at the head of the the free list.
+	 * If we are keeping a sorted free list, for truncation,
+	 * then figure out where this page belongs and either
+	 * link it in or truncate the file as much as possible.
+	 * If either the lock get or page get routines
+	 * fail, then we need to put the page with which we were called
+	 * back because our caller assumes we take care of it.
+	 */
+	hash = 0;
+
+	pgno = PGNO_BASE_MD;
+	if ((ret = __db_lget(dbc,
+	    LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0)
+		goto err;
+
+#ifdef HAVE_HASH
+	if (dbp->type == DB_HASH) {
+		if ((ret = __ham_return_meta(dbc,
+#ifdef HAVE_FTRUNCATE
+		    0,
+#else
+		    DB_MPOOL_DIRTY,
+#endif
+		&meta)) != 0)
+			goto err;
+		if (meta != NULL)
+			hash = 1;
+	}
+#endif
+	if (meta == NULL) {
+		/* If we support truncate, we might not dirty the meta page. */
+		if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn,
+#ifdef HAVE_FTRUNCATE
+		    0,
+#else
+		    DB_MPOOL_DIRTY,
+#endif
+		    &meta)) != 0)
+			goto err1;
+	}
+
+	last_pgno = meta->last_pgno;
+	next_pgno = meta->free;
+	/*
+	 * Assign lsnp here so it always initialized when
+	 * HAVE_FTRUNCATE is not defined.
+	 */
+	lsnp = &LSN(meta);
+
+	DB_ASSERT(dbp->env, h->pgno != next_pgno);
+
+#ifdef HAVE_FTRUNCATE
+	/*
+	 * If we are maintaining a sorted free list see if we either have a
+	 * new truncation point or the page goes somewhere in the middle of
+	 * the list.  If it goes in the middle of the list, we will drop the
+	 * meta page and get the previous page.
+	 */
+	COMPQUIET(position, 0);
+	if ((ret = __memp_get_freelist(mpf, &nelem, &list)) != 0)
+		goto err1;
+	if (list == NULL)
+		goto no_sort;
+
+	if (h->pgno != last_pgno) {
+		/*
+		 * Put the page number in the sorted list.  Find its
+		 * position and the previous page.  After logging we
+		 * will extend the list, make room and insert the page in
+		 * the list.
+		 */
+		position = 0;
+		if (nelem != 0) {
+			__db_freelist_pos(h->pgno, list, nelem, &position);
+
+			DB_ASSERT(dbp->env, h->pgno != list[position]);
+
+			/* Get the previous page if this is not the smallest. */
+			if (position != 0 || h->pgno > list[0])
+				prev_pgno = list[position];
+		}
+
+	} else if (nelem != 0) {
+		/* Find the truncation point. */
+		for (lp = &list[nelem - 1]; lp >= list; lp--)
+			if (--last_pgno != *lp)
+				break;
+		if (lp < list || last_pgno < h->pgno - 1)
+			do_truncate = 1;
+		last_pgno = meta->last_pgno;
+	}
+
+no_sort:
+	if (prev_pgno == PGNO_INVALID) {
+#ifdef HAVE_HASH
+		if (hash) {
+			if ((ret =
+			    __ham_return_meta(dbc, DB_MPOOL_DIRTY, &meta)) != 0)
+				goto err1;
+		} else
+#endif
+		if ((ret = __memp_dirty(mpf,
+		    &meta, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+			goto err1;
+		lsnp = &LSN(meta);
+	} else {
+		pgno = prev_pgno;
+		if ((ret = __memp_fget(mpf, &pgno,
+		    dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &prev)) != 0)
+			goto err1;
+		next_pgno = NEXT_PGNO(prev);
+		lsnp = &LSN(prev);
+	}
+#endif
+
+	/*
+	 * Log the change.
+	 *	We are either logging an update to the metapage or to the
+	 * previous page in the sorted list.
+	 */
+	if (DBC_LOGGING(dbc)) {
+		memset(&ldbt, 0, sizeof(ldbt));
+		ldbt.data = h;
+		ldbt.size = P_OVERHEAD(dbp);
+		/*
+		 * If we are removing pages from the file, we need to make
+		 * sure the logging happens before the truncation.  If we
+		 * are truncating multiple pages we don't need to flush the
+		 * log here as it will be flushed by __db_truncate_freelist.
+		 */
+		lflag = 0;
+
+#ifdef HAVE_FTRUNCATE
+		if (h->pgno == last_pgno && do_truncate == 0)
+			lflag = DB_FLUSH;
+#endif
+		switch (h->type) {
+		case P_HASH:
+		case P_IBTREE:
+		case P_IRECNO:
+		case P_LBTREE:
+		case P_LRECNO:
+		case P_LDUP:
+			if (h->entries > 0 && (h->pgno == last_pgno ||
+			    !LF_ISSET(DB_LOG_NO_DATA))) {
+				ldbt.size += h->entries * sizeof(db_indx_t);
+				ddbt.data = (u_int8_t *)h + HOFFSET(h);
+				ddbt.size = dbp->pgsize - HOFFSET(h);
+				if ((ret = __db_pg_freedata_log(dbp, dbc->txn,
+				     lsnp, lflag,
+				     h->pgno, lsnp, pgno,
+				     &ldbt, next_pgno, last_pgno, &ddbt)) != 0)
+					goto err1;
+				goto logged;
+			}
+			break;
+		case P_HASHMETA:
+			ldbt.size = sizeof(HMETA);
+			break;
+		case P_BTREEMETA:
+			ldbt.size = sizeof(BTMETA);
+			break;
+		case P_OVERFLOW:
+			ldbt.size += OV_LEN(h);
+			break;
+		default:
+			DB_ASSERT(dbp->env, h->type != P_QAMDATA);
+		}
+
+		if ((ret = __db_pg_free_log(dbp,
+		      dbc->txn, lsnp, lflag, h->pgno,
+		      lsnp, pgno, &ldbt, next_pgno, last_pgno)) != 0)
+			goto err1;
+	} else
+		LSN_NOT_LOGGED(*lsnp);
+
+logged:
+#ifdef HAVE_FTRUNCATE
+	if (do_truncate) {
+		start = (u_int32_t) (lp - list) + 1;
+		meta->last_pgno--;
+		ret = __db_truncate_freelist(
+		      dbc, meta, h, list, start, nelem);
+		h = NULL;
+	} else if (h->pgno == last_pgno) {
+		/*
+		 * We are going to throw this page away, but if we are
+		 * using MVCC then this version may stick around and we
+		 * might have to make a copy.
+		 */
+		if (atomic_read(&mpf->mfp->multiversion) &&
+		    (ret = __memp_dirty(mpf,
+		    &h, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+			goto err1;
+		LSN(h) = *lsnp;
+		P_INIT(h, dbp->pgsize,
+		    h->pgno, PGNO_INVALID, next_pgno, 0, P_INVALID);
+		if ((ret = __memp_fput(mpf,
+		    dbc->thread_info, h, DB_PRIORITY_VERY_LOW)) != 0)
+			goto err1;
+		h = NULL;
+		/* Give the page back to the OS. */
+		if ((ret = __memp_ftruncate(mpf, dbc->txn, dbc->thread_info,
+		    last_pgno, 0)) != 0)
+			goto err1;
+		DB_ASSERT(dbp->env, meta->pgno == PGNO_BASE_MD);
+		meta->last_pgno--;
+	} else {
+		if (list != NULL) {
+			/* Put the page number into the list. */
+			if ((ret =
+			    __memp_extend_freelist(mpf, nelem + 1, &list)) != 0)
+				goto err1;
+			if (prev_pgno != PGNO_INVALID)
+				lp = &list[position + 1];
+			else
+				lp = list;
+			if (nelem != 0 && position != nelem)
+				memmove(lp + 1, lp, (size_t)
+				    ((u_int8_t*)&list[nelem] - (u_int8_t*)lp));
+			*lp = h->pgno;
+		}
+#else
+	{
+#endif
+		/*
+		 * If we are not truncating the page then we
+		 * reinitialize it and put it at the head of
+		 * the free list.
+		 */
+		if ((ret = __memp_dirty(mpf,
+		    &h, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+			goto err1;
+		LSN(h) = *lsnp;
+		P_INIT(h, dbp->pgsize,
+		    h->pgno, PGNO_INVALID, next_pgno, 0, P_INVALID);
+#ifdef DIAGNOSTIC
+		memset((u_int8_t *) h + P_OVERHEAD(dbp),
+		    CLEAR_BYTE, dbp->pgsize - P_OVERHEAD(dbp));
+#endif
+		if (prev_pgno == PGNO_INVALID)
+			meta->free = h->pgno;
+		else
+			NEXT_PGNO(prev) = h->pgno;
+	}
+
+	/* Discard the metadata or previous page. */
+err1:	if (hash == 0 && meta != NULL && (t_ret = __memp_fput(mpf,
+	    dbc->thread_info, (PAGE *)meta, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0)
+		ret = t_ret;
+	if (prev != (PAGE*) meta && prev != NULL && (t_ret = __memp_fput(mpf,
+	    dbc->thread_info, prev, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Discard the caller's page reference. */
+err:	if (h != NULL && (t_ret = __memp_fput(mpf,
+	    dbc->thread_info, h, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+
+	PERFMON4(dbp->env, alloc, free, dbp->fname, dbp->dname, pgno, ret);
+	/*
+	 * XXX
+	 * We have to unlock the caller's page in the caller!
+	 */
+	return (ret);
+}
+
+#ifdef HAVE_FTRUNCATE
+/*
+ * __db_freelist_pos -- find the position of a page in the freelist.
+ *	The list is sorted, we do a binary search.
+ *
+ * PUBLIC: #ifdef HAVE_FTRUNCATE
+ * PUBLIC: void __db_freelist_pos __P((db_pgno_t,
+ * PUBLIC:       db_pgno_t *, u_int32_t, u_int32_t *));
+ * PUBLIC: #endif
+ */
+void
+__db_freelist_pos(pgno, list, nelem, posp)
+	db_pgno_t pgno;
+	db_pgno_t *list;
+	u_int32_t nelem;
+	u_int32_t *posp;
+{
+	u_int32_t base, indx, lim;
+
+	indx = 0;
+	for (base = 0, lim = nelem; lim != 0; lim >>= 1) {
+		indx = base + (lim >> 1);
+		if (pgno == list[indx]) {
+			*posp = indx;
+			return;
+		}
+		if (pgno > list[indx]) {
+			base = indx + 1;
+			--lim;
+		}
+	}
+	if (base != 0)
+		base--;
+	*posp = base;
+	return;
+}
+
+static int
+__db_pglistcmp(a, b)
+	const void *a, *b;
+{
+	db_pglist_t *ap, *bp;
+
+	ap = (db_pglist_t *)a;
+	bp = (db_pglist_t *)b;
+
+	return ((ap->pgno > bp->pgno) ? 1 : (ap->pgno < bp->pgno) ? -1: 0);
+}
+
+/*
+ * __db_freelist_sort -- sort a list of free pages.
+ * PUBLIC: void __db_freelist_sort __P((db_pglist_t *, u_int32_t));
+ */
+void
+__db_freelist_sort(list, nelems)
+	db_pglist_t *list;
+	u_int32_t nelems;
+{
+	qsort(list, (size_t)nelems, sizeof(db_pglist_t), __db_pglistcmp);
+}
+
+/*
+ * __db_pg_truncate -- find the truncation point in a sorted freelist.
+ *
+ * PUBLIC: #ifdef HAVE_FTRUNCATE
+ * PUBLIC: int __db_pg_truncate __P((DBC *, DB_TXN *,
+ * PUBLIC:    db_pglist_t *, DB_COMPACT *, u_int32_t *,
+ * PUBLIC:    db_pgno_t , db_pgno_t *, DB_LSN *, int));
+ * PUBLIC: #endif
+ */
+int
+__db_pg_truncate(dbc, txn,
+    list, c_data, nelemp, free_pgno, last_pgno, lsnp, in_recovery)
+	DBC *dbc;
+	DB_TXN *txn;
+	db_pglist_t *list;
+	DB_COMPACT *c_data;
+	u_int32_t *nelemp;
+	db_pgno_t free_pgno, *last_pgno;
+	DB_LSN *lsnp;
+	int in_recovery;
+{
+	DB *dbp;
+	DBT ddbt;
+	DB_LSN null_lsn;
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	db_pglist_t *lp, *slp;
+	db_pgno_t lpgno, pgno;
+	u_int32_t elems, log_size, tpoint;
+	int last, ret;
+
+	ret = 0;
+	h = NULL;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	elems = tpoint = *nelemp;
+
+	/*
+	 * Figure out what (if any) pages can be truncated immediately and
+	 * record the place from which we can truncate, so we can do the
+	 * memp_ftruncate below.  We also use this to avoid ever putting
+	 * these pages on the freelist, which we are about to relink.
+	 */
+	pgno = *last_pgno;
+	lp = &list[elems - 1];
+	last = 1;
+	while (tpoint != 0) {
+		if (lp->pgno != pgno)
+			break;
+		pgno--;
+		tpoint--;
+		lp--;
+	}
+
+	lp = list;
+	slp = &list[elems];
+	/*
+	 * Log the sorted list. We log the whole list so it can be rebuilt.
+	 * Don't overflow the log file.
+	 */
+again:	if (DBC_LOGGING(dbc)) {
+		last = 1;
+		lpgno = *last_pgno;
+		ddbt.size = elems * sizeof(*lp);
+		ddbt.data = lp;
+		log_size = ((LOG *)dbc->env->
+		    lg_handle->reginfo.primary)->log_size;
+		if (ddbt.size > log_size / 2) {
+			elems = (log_size / 2) / sizeof(*lp);
+			ddbt.size = elems * sizeof(*lp);
+			last = 0;
+			/*
+			 * If we stopped after the truncation point
+			 * then we need to truncate from here.
+			 */
+			if (lp + elems >= &list[tpoint])
+				lpgno = lp[elems - 1].pgno;
+		}
+		/*
+		 * If this is not the beginning of the list fetch the end
+		 * of the previous segment.  This page becomes the last_free
+		 * page and will link to this segment if it is not truncated.
+		 */
+		if (lp != list) {
+			if ((ret = __memp_fget(mpf, &lp[-1].pgno,
+			    dbc->thread_info, txn, 0, &h)) != 0)
+				goto err;
+		}
+
+		slp = &lp[elems];
+
+		ZERO_LSN(null_lsn);
+		if ((ret = __db_pg_trunc_log(dbp, dbc->txn,
+		     lsnp, last == 1 ? DB_FLUSH : 0, PGNO_BASE_MD,
+		     lsnp, h != NULL ? PGNO(h) : PGNO_INVALID,
+		     h != NULL ? &LSN(h) : &null_lsn,
+		     free_pgno, lpgno, &ddbt)) != 0)
+			goto err;
+		if (h != NULL) {
+			LSN(h) = *lsnp;
+			if ((ret = __memp_fput(mpf,
+			    dbc->thread_info, h, dbc->priority)) != 0)
+				goto err;
+		}
+		h = NULL;
+	} else if (!in_recovery)
+		LSN_NOT_LOGGED(*lsnp);
+
+	for (; lp < slp && lp < &list[tpoint]; lp++) {
+		if ((ret = __memp_fget(mpf, &lp->pgno, dbc->thread_info,
+		    txn, !in_recovery ? DB_MPOOL_DIRTY : 0, &h)) != 0) {
+			/* Page may have been truncated later. */
+			if (in_recovery && ret == DB_PAGE_NOTFOUND) {
+				ret = 0;
+				continue;
+			}
+			goto err;
+		}
+		if (in_recovery) {
+			if (LOG_COMPARE(&LSN(h), &lp->lsn) == 0) {
+				if ((ret = __memp_dirty(mpf, &h,
+				    dbc->thread_info,
+				    txn, dbp->priority, 0)) != 0) {
+					(void)__memp_fput(mpf,
+					    dbc->thread_info, h, dbp->priority);
+					goto err;
+				}
+			} else
+				goto skip;
+		}
+
+		if (lp == &list[tpoint - 1])
+			NEXT_PGNO(h) = PGNO_INVALID;
+		else
+			NEXT_PGNO(h) = lp[1].pgno;
+		DB_ASSERT(mpf->env, NEXT_PGNO(h) < *last_pgno);
+
+		LSN(h) = *lsnp;
+skip:		if ((ret = __memp_fput(mpf,
+		    dbc->thread_info, h, dbp->priority)) != 0)
+			goto err;
+		h = NULL;
+	}
+
+	/*
+	 * If we did not log everything try again.  We start from slp and
+	 * try to go to the end of the list.
+	 */
+	if (last == 0) {
+		elems = (u_int32_t)(&list[*nelemp] - slp);
+		lp = slp;
+		goto again;
+	}
+
+	/*
+	 * Truncate the file.  Its possible that the last page is the
+	 * only one that got truncated and that's done in the caller.
+	 */
+	if (pgno != *last_pgno) {
+		if (tpoint != *nelemp &&
+		    (ret = __memp_ftruncate(mpf, dbc->txn, dbc->thread_info,
+		    pgno + 1, in_recovery ? MP_TRUNC_RECOVER : 0)) != 0)
+			goto err;
+		if (c_data)
+			c_data->compact_pages_truncated += *last_pgno - pgno;
+		*last_pgno = pgno;
+	}
+	*nelemp = tpoint;
+
+	if (0) {
+err:		if (h != NULL)
+			(void)__memp_fput(mpf,
+			    dbc->thread_info, h, dbc->priority);
+	}
+	return (ret);
+}
+
+/*
+ * __db_free_truncate --
+ *	  Build a sorted free list and truncate free pages at the end
+ *	  of the file.
+ *
+ * PUBLIC: #ifdef HAVE_FTRUNCATE
+ * PUBLIC: int __db_free_truncate __P((DB *, DB_THREAD_INFO *, DB_TXN *,
+ * PUBLIC:    u_int32_t, DB_COMPACT *, db_pglist_t **, u_int32_t *,
+ * PUBLIC:    db_pgno_t *));
+ * PUBLIC: #endif
+ */
+int
+__db_free_truncate(dbp, ip, txn, flags, c_data, listp, nelemp, last_pgnop)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	u_int32_t flags;
+	DB_COMPACT *c_data;
+	db_pglist_t **listp;
+	u_int32_t *nelemp;
+	db_pgno_t *last_pgnop;
+{
+	DBC *dbc;
+	DBMETA *meta;
+	DB_LOCK metalock;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h;
+	db_pglist_t *list, *lp;
+	db_pgno_t pgno;
+	u_int32_t nelems;
+	int ret, t_ret;
+	size_t size;
+
+	COMPQUIET(flags, 0);
+	list = NULL;
+	meta = NULL;
+	env = dbp->env;
+	mpf = dbp->mpf;
+	h = NULL;
+	nelems = 0;
+	if (listp != NULL) {
+		*listp = NULL;
+		DB_ASSERT(env, nelemp != NULL);
+		*nelemp = 0;
+	}
+
+	if ((ret = __db_cursor(dbp, ip, txn, &dbc, DB_WRITELOCK)) != 0)
+		return (ret);
+
+	pgno = PGNO_BASE_MD;
+	if ((ret = __db_lget(dbc,
+	    LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0)
+		goto err;
+	if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn, 0,
+	    &meta)) != 0)
+		goto err;
+
+	if (last_pgnop != NULL)
+		*last_pgnop = meta->last_pgno;
+	if ((pgno = meta->free) == PGNO_INVALID)
+		goto done;
+
+	size = 128;
+	if ((ret = __os_malloc(env, size * sizeof(*list), &list)) != 0)
+		goto err;
+	lp = list;
+
+	do {
+		if (lp == &list[size]) {
+			size *= 2;
+			if ((ret = __os_realloc(env,
+			    size * sizeof(*list), &list)) != 0)
+				goto err;
+			lp = &list[size / 2];
+		}
+		if ((ret = __memp_fget(mpf, &pgno,
+		     dbc->thread_info, dbc->txn, 0, &h)) != 0)
+			goto err;
+
+		lp->pgno = pgno;
+		lp->next_pgno = NEXT_PGNO(h);
+		lp->lsn = LSN(h);
+		pgno = NEXT_PGNO(h);
+		if ((ret = __memp_fput(mpf,
+		    dbc->thread_info, h, dbc->priority)) != 0)
+			goto err;
+		lp++;
+	} while (pgno != PGNO_INVALID);
+	nelems = (u_int32_t)(lp - list);
+
+	if ((ret = __memp_dirty(mpf,
+	    &meta, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+		goto err;
+
+	/* Sort the list */
+	__db_freelist_sort(list, nelems);
+
+	if ((ret = __db_pg_truncate(dbc, txn, list, c_data,
+	    &nelems, meta->free, &meta->last_pgno, &LSN(meta), 0)) != 0)
+		goto err;
+
+	if (nelems == 0)
+		meta->free = PGNO_INVALID;
+	else
+		meta->free = list[0].pgno;
+
+done:	if (last_pgnop != NULL)
+		*last_pgnop = meta->last_pgno;
+
+	/*
+	 * The truncate point is the number of pages in the free
+	 * list back from the last page.  The number of pages
+	 * in the free list are the number that we can swap in.
+	 * Adjust it down slightly so if we find higher numbered
+	 * pages early and then free other pages later we can
+	 * truncate them.
+	 */
+	if (c_data) {
+		c_data->compact_truncate = (u_int32_t)meta->last_pgno - nelems;
+		if (c_data->compact_truncate > nelems >> 2)
+			c_data->compact_truncate -= nelems >> 2;
+	}
+
+	if (nelems != 0 && listp != NULL) {
+		*listp = list;
+		*nelemp = nelems;
+		list = NULL;
+	}
+
+err:	if (list != NULL)
+		__os_free(env, list);
+	if (meta != NULL && (t_ret = __memp_fput(mpf,
+	     dbc->thread_info, (PAGE *)meta, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+static int
+__db_truncate_freelist(dbc, meta, h, list, start, nelem)
+	DBC *dbc;
+	DBMETA *meta;
+	PAGE *h;
+	db_pgno_t *list;
+	u_int32_t start, nelem;
+{
+	DB *dbp;
+	DBT ddbt;
+	DB_LSN null_lsn;
+	DB_MPOOLFILE *mpf;
+	PAGE *last_free, *pg;
+	db_pgno_t *lp, free_pgno, lpgno;
+	db_pglist_t *plist, *pp, *spp;
+	u_int32_t elem, log_size;
+	int last, ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	plist = NULL;
+	last_free = NULL;
+	pg = NULL;
+
+	if (start != 0 &&
+	    (ret = __memp_fget(mpf, &list[start - 1],
+	    dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &last_free)) != 0)
+		goto err;
+
+	if (DBC_LOGGING(dbc)) {
+		if ((ret = __os_malloc(dbp->env,
+		     (nelem - start) * sizeof(*pp), &plist)) != 0)
+			goto err;
+
+		pp = plist;
+		for (lp = &list[start]; lp < &list[nelem]; lp++) {
+			pp->pgno = *lp;
+			if ((ret = __memp_fget(mpf, lp,
+			     dbc->thread_info, dbc->txn, 0, &pg)) != 0)
+				goto err;
+			pp->lsn = LSN(pg);
+			pp->next_pgno = NEXT_PGNO(pg);
+			if ((ret = __memp_fput(mpf,
+			    dbc->thread_info, pg, DB_PRIORITY_VERY_LOW)) != 0)
+				goto err;
+			pg = NULL;
+			pp++;
+		}
+		ZERO_LSN(null_lsn);
+		pp = plist;
+		elem = nelem - start;
+		log_size = ((LOG *)dbc->env->
+		    lg_handle->reginfo.primary)->log_size;
+again:		ddbt.data = spp = pp;
+		free_pgno = pp->pgno;
+		lpgno = meta->last_pgno;
+		ddbt.size = elem * sizeof(*pp);
+		if (ddbt.size > log_size / 2) {
+			elem = (log_size / 2) / (u_int32_t)sizeof(*pp);
+			ddbt.size = elem * sizeof(*pp);
+			pp += elem;
+			elem = (nelem - start) - (u_int32_t)(pp - plist);
+			lpgno = pp[-1].pgno;
+			last = 0;
+		} else
+			last = 1;
+		/*
+		 * Get the page which will link to this section if we abort.
+		 * If this is the first segment then its last_free.
+		 */
+		if (spp == plist)
+			pg = last_free;
+		else if ((ret = __memp_fget(mpf, &spp[-1].pgno,
+		     dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &pg)) != 0)
+			goto err;
+
+		if ((ret = __db_pg_trunc_log(dbp, dbc->txn,
+		     &LSN(meta), last == 1 ? DB_FLUSH : 0,
+		     PGNO(meta), &LSN(meta),
+		     pg != NULL ? PGNO(pg) : PGNO_INVALID,
+		     pg != NULL ? &LSN(pg) : &null_lsn,
+		     free_pgno, lpgno, &ddbt)) != 0)
+			goto err;
+		if (pg != NULL) {
+			LSN(pg) = LSN(meta);
+			if (pg != last_free && (ret = __memp_fput(mpf,
+			    dbc->thread_info, pg, DB_PRIORITY_VERY_LOW)) != 0)
+				goto err;
+			pg = NULL;
+		}
+		if (last == 0)
+			goto again;
+	} else
+		LSN_NOT_LOGGED(LSN(meta));
+
+	if ((ret = __memp_fput(mpf,
+	    dbc->thread_info, h, DB_PRIORITY_VERY_LOW)) != 0)
+		goto err;
+	h = NULL;
+	if ((ret = __memp_ftruncate(mpf, dbc->txn, dbc->thread_info,
+	    list[start], 0)) != 0)
+		goto err;
+	meta->last_pgno = list[start] - 1;
+
+	if (start == 0)
+		meta->free = PGNO_INVALID;
+	else {
+		NEXT_PGNO(last_free) = PGNO_INVALID;
+		if ((ret = __memp_fput(mpf,
+		    dbc->thread_info, last_free, dbc->priority)) != 0)
+			goto err;
+		last_free = NULL;
+	}
+
+	/* Shrink the number of elements in the list. */
+	ret = __memp_extend_freelist(mpf, start, &list);
+
+err:	if (plist != NULL)
+		__os_free(dbp->env, plist);
+
+	/* We need to put the page on error. */
+	if (h != NULL)
+		(void)__memp_fput(mpf, dbc->thread_info, h, dbc->priority);
+	if (pg != NULL && pg != last_free)
+		(void)__memp_fput(mpf, dbc->thread_info, pg, dbc->priority);
+	if (last_free != NULL)
+		(void)__memp_fput(mpf,
+		    dbc->thread_info, last_free, dbc->priority);
+
+	return (ret);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_method.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1272 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/crypto.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/qam.h"
+#include "dbinc/txn.h"
+
+static int  __db_get_byteswapped __P((DB *, int *));
+static int  __db_get_dbname __P((DB *, const char **, const char **));
+static DB_ENV *__db_get_env __P((DB *));
+static void __db_get_msgcall
+	      __P((DB *, void (**)(const DB_ENV *, const char *)));
+static DB_MPOOLFILE *__db_get_mpf __P((DB *));
+static int  __db_get_multiple __P((DB *));
+static int  __db_get_transactional __P((DB *));
+static int  __db_get_type __P((DB *, DBTYPE *dbtype));
+static int  __db_init __P((DB *, u_int32_t));
+static int  __db_get_alloc __P((DB *, void *(**)(size_t),
+		void *(**)(void *, size_t), void (**)(void *)));
+static int  __db_set_alloc __P((DB *, void *(*)(size_t),
+		void *(*)(void *, size_t), void (*)(void *)));
+static int  __db_get_append_recno __P((DB *,
+		int (**)(DB *, DBT *, db_recno_t)));
+static int  __db_set_append_recno __P((DB *, int (*)(DB *, DBT *, db_recno_t)));
+static int  __db_get_cachesize __P((DB *, u_int32_t *, u_int32_t *, int *));
+static int  __db_set_cachesize __P((DB *, u_int32_t, u_int32_t, int));
+static int  __db_get_create_dir __P((DB *, const char **));
+static int  __db_set_create_dir __P((DB *, const char *));
+static int  __db_get_dup_compare
+		__P((DB *, int (**)(DB *, const DBT *, const DBT *)));
+static int  __db_set_dup_compare
+		__P((DB *, int (*)(DB *, const DBT *, const DBT *)));
+static int  __db_set_encrypt __P((DB *, const char *, u_int32_t));
+static int  __db_get_feedback __P((DB *, void (**)(DB *, int, int)));
+static int  __db_set_feedback __P((DB *, void (*)(DB *, int, int)));
+static void __db_map_flags __P((DB *, u_int32_t *, u_int32_t *));
+static int  __db_get_pagesize __P((DB *, u_int32_t *));
+static int  __db_set_paniccall __P((DB *, void (*)(DB_ENV *, int)));
+static int  __db_set_priority __P((DB *, DB_CACHE_PRIORITY));
+static int  __db_get_priority __P((DB *, DB_CACHE_PRIORITY *));
+static void __db_get_errcall __P((DB *,
+	      void (**)(const DB_ENV *, const char *, const char *)));
+static void __db_set_errcall
+	      __P((DB *, void (*)(const DB_ENV *, const char *, const char *)));
+static void __db_get_errfile __P((DB *, FILE **));
+static void __db_set_errfile __P((DB *, FILE *));
+static void __db_get_errpfx __P((DB *, const char **));
+static void __db_set_errpfx __P((DB *, const char *));
+static void __db_set_msgcall
+	      __P((DB *, void (*)(const DB_ENV *, const char *)));
+static void __db_get_msgfile __P((DB *, FILE **));
+static void __db_set_msgfile __P((DB *, FILE *));
+static int  __db_get_assoc_flags __P((DB *, u_int32_t *));
+static void __dbh_err __P((DB *, int, const char *, ...));
+static void __dbh_errx __P((DB *, const char *, ...));
+
+/*
+ * db_create --
+ *	DB constructor.
+ *
+ * EXTERN: int db_create __P((DB **, DB_ENV *, u_int32_t));
+ */
+int
+db_create(dbpp, dbenv, flags)
+	DB **dbpp;
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	ip = NULL;
+	env = dbenv == NULL ? NULL : dbenv->env;
+
+	/* Check for invalid function flags. */
+	switch (flags) {
+	case 0:
+		break;
+	case DB_XA_CREATE:
+		if (dbenv != NULL) {
+			__db_errx(env, DB_STR("0504",
+	    "XA applications may not specify an environment to db_create"));
+			return (EINVAL);
+		}
+
+		/*
+		 * If it's an XA database, open it within the XA environment,
+		 * taken from the global list of environments.  (When the XA
+		 * transaction manager called our xa_start() routine the
+		 * "current" environment was moved to the start of the list.
+		 */
+		env = TAILQ_FIRST(&DB_GLOBAL(envq));
+		if (env == NULL) {
+			__db_errx(env, DB_STR("0505",
+			    "Cannot open XA database before XA is enabled"));
+			return (EINVAL);
+		}
+		break;
+	default:
+		return (__db_ferr(env, "db_create", 0));
+	}
+
+	if (env != NULL)
+		ENV_ENTER(env, ip);
+
+	/*
+	 * If we are opening an XA database, make sure we don't have a global XA
+	 * transaction running.
+	 */
+	if (LF_ISSET(DB_XA_CREATE)) {
+		XA_NO_TXN(ip, ret);
+		if (ret != 0)
+			goto err;
+	}
+
+	ret = __db_create_internal(dbpp, env, flags);
+err:	if (env != NULL)
+		ENV_LEAVE(env, ip);
+
+	return (ret);
+}
+
+/*
+ * __db_create_internal --
+ *	DB constructor internal routine.
+ *
+ * PUBLIC: int __db_create_internal  __P((DB **, ENV *, u_int32_t));
+ */
+int
+__db_create_internal(dbpp, env, flags)
+	DB **dbpp;
+	ENV *env;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DB_ENV *dbenv;
+	DB_REP *db_rep;
+	int ret;
+
+	*dbpp = NULL;
+
+	/* If we don't have an environment yet, allocate a local one. */
+	if (env == NULL) {
+		if ((ret = db_env_create(&dbenv, 0)) != 0)
+			return (ret);
+		env = dbenv->env;
+		F_SET(env, ENV_DBLOCAL);
+	} else
+		dbenv = env->dbenv;
+
+	/* Allocate and initialize the DB handle. */
+	if ((ret = __os_calloc(env, 1, sizeof(*dbp), &dbp)) != 0)
+		goto err;
+
+	dbp->dbenv = env->dbenv;
+	dbp->env = env;
+	if ((ret = __db_init(dbp, flags)) != 0)
+		goto err;
+
+	MUTEX_LOCK(env, env->mtx_dblist);
+	++env->db_ref;
+	MUTEX_UNLOCK(env, env->mtx_dblist);
+
+	/*
+	 * Set the replication timestamp; it's 0 if we're not in a replicated
+	 * environment.  Don't acquire a lock to read the value, even though
+	 * it's opaque: all we check later is value equality, nothing else.
+	 */
+	dbp->timestamp = REP_ON(env) ?
+	    ((REGENV *)env->reginfo->primary)->rep_timestamp : 0;
+	/*
+	 * Set the replication generation number for fid management; valid
+	 * replication generations start at 1.  Don't acquire a lock to
+	 * read the value.  All we check later is value equality.
+	 */
+	db_rep = env->rep_handle;
+	dbp->fid_gen = REP_ON(env) ? ((REP *)db_rep->region)->gen : 0;
+
+	/* Open a backing DB_MPOOLFILE handle in the memory pool. */
+	if ((ret = __memp_fcreate(env, &dbp->mpf)) != 0)
+		goto err;
+
+	dbp->type = DB_UNKNOWN;
+
+	*dbpp = dbp;
+	return (0);
+
+err:	if (dbp != NULL) {
+		if (dbp->mpf != NULL)
+			(void)__memp_fclose(dbp->mpf, 0);
+		__os_free(env, dbp);
+	}
+
+	if (dbp != NULL && F_ISSET(env, ENV_DBLOCAL))
+		(void)__env_close(dbp->dbenv, 0);
+
+	return (ret);
+}
+
+/*
+ * __db_init --
+ *	Initialize a DB structure.
+ */
+static int
+__db_init(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	int ret;
+
+	dbp->locker = NULL;
+	dbp->alt_close = NULL;
+	LOCK_INIT(dbp->handle_lock);
+
+	TAILQ_INIT(&dbp->free_queue);
+	TAILQ_INIT(&dbp->active_queue);
+	TAILQ_INIT(&dbp->join_queue);
+	LIST_INIT(&dbp->s_secondaries);
+
+	FLD_SET(dbp->am_ok,
+	    DB_OK_BTREE | DB_OK_HASH | DB_OK_HEAP | DB_OK_QUEUE | DB_OK_RECNO);
+
+	/* DB PUBLIC HANDLE LIST BEGIN */
+	dbp->associate = __db_associate_pp;
+	dbp->close = __db_close_pp;
+	dbp->cursor = __db_cursor_pp;
+	dbp->del = __db_del_pp;
+	dbp->dump = __db_dump_pp;
+	dbp->err = __dbh_err;
+	dbp->errx = __dbh_errx;
+	dbp->exists = __db_exists;
+	dbp->fd = __db_fd_pp;
+	dbp->get = __db_get_pp;
+	dbp->get_alloc = __db_get_alloc;
+	dbp->get_append_recno = __db_get_append_recno;
+	dbp->get_assoc_flags = __db_get_assoc_flags;
+	dbp->get_byteswapped = __db_get_byteswapped;
+	dbp->get_cachesize = __db_get_cachesize;
+	dbp->get_create_dir = __db_get_create_dir;
+	dbp->get_dbname = __db_get_dbname;
+	dbp->get_dup_compare = __db_get_dup_compare;
+	dbp->get_env = __db_get_env;
+	dbp->get_errcall = __db_get_errcall;
+	dbp->get_errfile = __db_get_errfile;
+	dbp->get_errpfx = __db_get_errpfx;
+	dbp->get_feedback = __db_get_feedback;
+	dbp->get_flags = __db_get_flags;
+	dbp->get_lorder = __db_get_lorder;
+	dbp->get_mpf = __db_get_mpf;
+	dbp->get_msgcall = __db_get_msgcall;
+	dbp->get_msgfile = __db_get_msgfile;
+	dbp->get_multiple = __db_get_multiple;
+	dbp->get_open_flags = __db_get_open_flags;
+	dbp->get_pagesize = __db_get_pagesize;
+	dbp->get_priority = __db_get_priority;
+	dbp->get_transactional = __db_get_transactional;
+	dbp->get_type = __db_get_type;
+	dbp->key_range = __db_key_range_pp;
+	dbp->open = __db_open_pp;
+	dbp->pget = __db_pget_pp;
+	dbp->put = __db_put_pp;
+	dbp->remove = __db_remove_pp;
+	dbp->rename = __db_rename_pp;
+	dbp->set_alloc = __db_set_alloc;
+	dbp->set_append_recno = __db_set_append_recno;
+	dbp->set_cachesize = __db_set_cachesize;
+	dbp->set_create_dir = __db_set_create_dir;
+	dbp->set_dup_compare = __db_set_dup_compare;
+	dbp->set_encrypt = __db_set_encrypt;
+	dbp->set_errcall = __db_set_errcall;
+	dbp->set_errfile = __db_set_errfile;
+	dbp->set_errpfx = __db_set_errpfx;
+	dbp->set_feedback = __db_set_feedback;
+	dbp->set_flags = __db_set_flags;
+	dbp->set_lorder = __db_set_lorder;
+	dbp->set_msgcall = __db_set_msgcall;
+	dbp->set_msgfile = __db_set_msgfile;
+	dbp->set_pagesize = __db_set_pagesize;
+	dbp->set_paniccall = __db_set_paniccall;
+	dbp->set_priority = __db_set_priority;
+	dbp->sort_multiple = __db_sort_multiple;
+	dbp->stat = __db_stat_pp;
+	dbp->stat_print = __db_stat_print_pp;
+	dbp->sync = __db_sync_pp;
+	dbp->truncate = __db_truncate_pp;
+	dbp->verify = __db_verify_pp;
+	/* DB PUBLIC HANDLE LIST END */
+
+					/* Access method specific. */
+	if ((ret = __bam_db_create(dbp)) != 0)
+		return (ret);
+	if ((ret = __ham_db_create(dbp)) != 0)
+		return (ret);
+	if ((ret = __heap_db_create(dbp)) != 0)
+		return (ret);
+	if ((ret = __qam_db_create(dbp)) != 0)
+		return (ret);
+
+	COMPQUIET(flags, 0);
+
+	return (0);
+}
+
+/*
+ * __dbh_am_chk --
+ *	Error if an unreasonable method is called.
+ *
+ * PUBLIC: int __dbh_am_chk __P((DB *, u_int32_t));
+ */
+int
+__dbh_am_chk(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	/*
+	 * We start out allowing any access methods to be called, and as the
+	 * application calls the methods the options become restricted.  The
+	 * idea is to quit as soon as an illegal method combination is called.
+	 */
+	if ((LF_ISSET(DB_OK_BTREE) && FLD_ISSET(dbp->am_ok, DB_OK_BTREE)) ||
+	    (LF_ISSET(DB_OK_HASH) && FLD_ISSET(dbp->am_ok, DB_OK_HASH)) ||
+	    (LF_ISSET(DB_OK_HEAP) && FLD_ISSET(dbp->am_ok, DB_OK_HEAP)) ||
+	    (LF_ISSET(DB_OK_QUEUE) && FLD_ISSET(dbp->am_ok, DB_OK_QUEUE)) ||
+	    (LF_ISSET(DB_OK_RECNO) && FLD_ISSET(dbp->am_ok, DB_OK_RECNO))) {
+		FLD_CLR(dbp->am_ok, ~flags);
+		return (0);
+	}
+
+	__db_errx(dbp->env, DB_STR("0506",
+"call implies an access method which is inconsistent with previous calls"));
+	return (EINVAL);
+}
+
+/*
+ * __dbh_err --
+ *	Db.err method.
+ */
+static void
+#ifdef STDC_HEADERS
+__dbh_err(DB *dbp, int error, const char *fmt, ...)
+#else
+__dbh_err(dbp, error, fmt, va_alist)
+	DB *dbp;
+	int error;
+	const char *fmt;
+	va_dcl
+#endif
+{
+	/* Message with error string, to stderr by default. */
+	DB_REAL_ERR(dbp->dbenv, error, DB_ERROR_SET, 1, fmt);
+}
+
+/*
+ * __dbh_errx --
+ *	Db.errx method.
+ */
+static void
+#ifdef STDC_HEADERS
+__dbh_errx(DB *dbp, const char *fmt, ...)
+#else
+__dbh_errx(dbp, fmt, va_alist)
+	DB *dbp;
+	const char *fmt;
+	va_dcl
+#endif
+{
+	/* Message without error string, to stderr by default. */
+	DB_REAL_ERR(dbp->dbenv, 0, DB_ERROR_NOT_SET, 1, fmt);
+}
+
+/*
+ * __db_get_byteswapped --
+ *	Return if database requires byte swapping.
+ */
+static int
+__db_get_byteswapped(dbp, isswapped)
+	DB *dbp;
+	int *isswapped;
+{
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_byteswapped");
+
+	*isswapped = F_ISSET(dbp, DB_AM_SWAP) ? 1 : 0;
+	return (0);
+}
+
+/*
+ * __db_get_dbname --
+ *	Get the name of the database as passed to DB->open.
+ */
+static int
+__db_get_dbname(dbp, fnamep, dnamep)
+	DB *dbp;
+	const char **fnamep, **dnamep;
+{
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_dbname");
+
+	if (fnamep != NULL)
+		*fnamep = dbp->fname;
+	if (dnamep != NULL)
+		*dnamep = dbp->dname;
+	return (0);
+}
+
+/*
+ * __db_get_env --
+ *	Get the DB_ENV handle that was passed to db_create.
+ */
+static DB_ENV *
+__db_get_env(dbp)
+	DB *dbp;
+{
+	return (dbp->dbenv);
+}
+
+/*
+ * __db_get_mpf --
+ *	Get the underlying DB_MPOOLFILE handle.
+ */
+static DB_MPOOLFILE *
+__db_get_mpf(dbp)
+	DB *dbp;
+{
+	return (dbp->mpf);
+}
+
+/*
+ * get_multiple --
+ *	Return whether this DB handle references a physical file with multiple
+ *	databases.
+ */
+static int
+__db_get_multiple(dbp)
+	DB *dbp;
+{
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_multiple");
+
+	/*
+	 * Only return TRUE if the handle is for the master database, not for
+	 * any subdatabase in the physical file.  If it's a Btree, with the
+	 * subdatabases flag set, and the meta-data page has the right value,
+	 * return TRUE.  (We don't need to check it's a Btree, I suppose, but
+	 * it doesn't hurt.)
+	 */
+	return (dbp->type == DB_BTREE &&
+	    F_ISSET(dbp, DB_AM_SUBDB) &&
+	    dbp->meta_pgno == PGNO_BASE_MD ? 1 : 0);
+}
+
+/*
+ * get_transactional --
+ *	Return whether this database was created in a transaction.
+ */
+static int
+__db_get_transactional(dbp)
+	DB *dbp;
+{
+	return (F_ISSET(dbp, DB_AM_TXN) ? 1 : 0);
+}
+
+/*
+ * __db_get_type --
+ *	Return type of underlying database.
+ */
+static int
+__db_get_type(dbp, dbtype)
+	DB *dbp;
+	DBTYPE *dbtype;
+{
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_type");
+
+	*dbtype = dbp->type;
+	return (0);
+}
+
+/*
+ * __db_get_append_recno --
+ *	Get record number append routine.
+ */
+static int
+__db_get_append_recno(dbp, funcp)
+	DB *dbp;
+	int (**funcp) __P((DB *, DBT *, db_recno_t));
+{
+	DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
+	if (funcp)
+		*funcp = dbp->db_append_recno;
+
+	return (0);
+}
+/*
+ * __db_set_append_recno --
+ *	Set record number append routine.
+ */
+static int
+__db_set_append_recno(dbp, func)
+	DB *dbp;
+	int (*func) __P((DB *, DBT *, db_recno_t));
+{
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_append_recno");
+	DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
+
+	dbp->db_append_recno = func;
+
+	return (0);
+}
+
+/*
+ * __db_get_cachesize --
+ *	Get underlying cache size.
+ */
+static int
+__db_get_cachesize(dbp, cache_gbytesp, cache_bytesp, ncachep)
+	DB *dbp;
+	u_int32_t *cache_gbytesp, *cache_bytesp;
+	int *ncachep;
+{
+	DB_ILLEGAL_IN_ENV(dbp, "DB->get_cachesize");
+
+	return (__memp_get_cachesize(dbp->dbenv,
+	    cache_gbytesp, cache_bytesp, ncachep));
+}
+
+/*
+ * __db_set_cachesize --
+ *	Set underlying cache size.
+ */
+static int
+__db_set_cachesize(dbp, cache_gbytes, cache_bytes, ncache)
+	DB *dbp;
+	u_int32_t cache_gbytes, cache_bytes;
+	int ncache;
+{
+	DB_ILLEGAL_IN_ENV(dbp, "DB->set_cachesize");
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_cachesize");
+
+	return (__memp_set_cachesize(
+	    dbp->dbenv, cache_gbytes, cache_bytes, ncache));
+}
+
+static int
+__db_set_create_dir(dbp, dir)
+	DB *dbp;
+	const char *dir;
+{
+	DB_ENV *dbenv;
+	int i;
+
+	dbenv = dbp->dbenv;
+
+	for (i = 0; i < dbenv->data_next; i++)
+		if (strcmp(dir, dbenv->db_data_dir[i]) == 0)
+			break;
+
+	if (i == dbenv->data_next) {
+		__db_errx(dbp->env, DB_STR_A("0507",
+		    "Directory %s not in environment list.", "%s"), dir);
+		return (EINVAL);
+	}
+
+	dbp->dirname = dbenv->db_data_dir[i];
+	return (0);
+}
+
+static int
+__db_get_create_dir(dbp, dirp)
+	DB *dbp;
+	const char **dirp;
+{
+	*dirp = dbp->dirname;
+	return (0);
+}
+
+/*
+ * __db_get_dup_compare --
+ *	Get duplicate comparison routine.
+ */
+static int
+__db_get_dup_compare(dbp, funcp)
+	DB *dbp;
+	int (**funcp) __P((DB *, const DBT *, const DBT *));
+{
+
+	DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH);
+
+	if (funcp != NULL) {
+#ifdef HAVE_COMPRESSION
+		if (DB_IS_COMPRESSED(dbp)) {
+			*funcp =
+			     ((BTREE *)dbp->bt_internal)->compress_dup_compare;
+		} else
+#endif
+			*funcp = dbp->dup_compare;
+	}
+
+	return (0);
+}
+
+/*
+ * __db_set_dup_compare --
+ *	Set duplicate comparison routine.
+ */
+static int
+__db_set_dup_compare(dbp, func)
+	DB *dbp;
+	int (*func) __P((DB *, const DBT *, const DBT *));
+{
+	int ret;
+
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_dup_compare");
+	DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH);
+
+	if ((ret = __db_set_flags(dbp, DB_DUPSORT)) != 0)
+		return (ret);
+
+#ifdef HAVE_COMPRESSION
+	if (DB_IS_COMPRESSED(dbp)) {
+		dbp->dup_compare = __bam_compress_dupcmp;
+		((BTREE *)dbp->bt_internal)->compress_dup_compare = func;
+	} else
+#endif
+		dbp->dup_compare = func;
+
+	return (0);
+}
+
+/*
+ * __db_set_encrypt --
+ *	Set database passwd.
+ */
+static int
+__db_set_encrypt(dbp, passwd, flags)
+	DB *dbp;
+	const char *passwd;
+	u_int32_t flags;
+{
+	DB_CIPHER *db_cipher;
+	int ret;
+
+	DB_ILLEGAL_IN_ENV(dbp, "DB->set_encrypt");
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_encrypt");
+
+	if ((ret = __env_set_encrypt(dbp->dbenv, passwd, flags)) != 0)
+		return (ret);
+
+	/*
+	 * In a real env, this gets initialized with the region.  In a local
+	 * env, we must do it here.
+	 */
+	db_cipher = dbp->env->crypto_handle;
+	if (!F_ISSET(db_cipher, CIPHER_ANY) &&
+	    (ret = db_cipher->init(dbp->env, db_cipher)) != 0)
+		return (ret);
+
+	return (__db_set_flags(dbp, DB_ENCRYPT));
+}
+
+static void
+__db_get_errcall(dbp, errcallp)
+	DB *dbp;
+	void (**errcallp) __P((const DB_ENV *, const char *, const char *));
+{
+	__env_get_errcall(dbp->dbenv, errcallp);
+}
+
+static void
+__db_set_errcall(dbp, errcall)
+	DB *dbp;
+	void (*errcall) __P((const DB_ENV *, const char *, const char *));
+{
+	__env_set_errcall(dbp->dbenv, errcall);
+}
+
+static void
+__db_get_errfile(dbp, errfilep)
+	DB *dbp;
+	FILE **errfilep;
+{
+	__env_get_errfile(dbp->dbenv, errfilep);
+}
+
+static void
+__db_set_errfile(dbp, errfile)
+	DB *dbp;
+	FILE *errfile;
+{
+	__env_set_errfile(dbp->dbenv, errfile);
+}
+
+static void
+__db_get_errpfx(dbp, errpfxp)
+	DB *dbp;
+	const char **errpfxp;
+{
+	__env_get_errpfx(dbp->dbenv, errpfxp);
+}
+
+static void
+__db_set_errpfx(dbp, errpfx)
+	DB *dbp;
+	const char *errpfx;
+{
+	__env_set_errpfx(dbp->dbenv, errpfx);
+}
+
+static int
+__db_get_feedback(dbp, feedbackp)
+	DB *dbp;
+	void (**feedbackp) __P((DB *, int, int));
+{
+	if (feedbackp != NULL)
+		*feedbackp = dbp->db_feedback;
+	return (0);
+}
+
+static int
+__db_set_feedback(dbp, feedback)
+	DB *dbp;
+	void (*feedback) __P((DB *, int, int));
+{
+	dbp->db_feedback = feedback;
+	return (0);
+}
+
+/*
+ * __db_map_flags --
+ *	Maps between public and internal flag values.
+ *      This function doesn't check for validity, so it can't fail.
+ */
+static void
+__db_map_flags(dbp, inflagsp, outflagsp)
+	DB *dbp;
+	u_int32_t *inflagsp, *outflagsp;
+{
+	COMPQUIET(dbp, NULL);
+
+	if (FLD_ISSET(*inflagsp, DB_CHKSUM)) {
+		FLD_SET(*outflagsp, DB_AM_CHKSUM);
+		FLD_CLR(*inflagsp, DB_CHKSUM);
+	}
+	if (FLD_ISSET(*inflagsp, DB_ENCRYPT)) {
+		FLD_SET(*outflagsp, DB_AM_ENCRYPT | DB_AM_CHKSUM);
+		FLD_CLR(*inflagsp, DB_ENCRYPT);
+	}
+	if (FLD_ISSET(*inflagsp, DB_TXN_NOT_DURABLE)) {
+		FLD_SET(*outflagsp, DB_AM_NOT_DURABLE);
+		FLD_CLR(*inflagsp, DB_TXN_NOT_DURABLE);
+	}
+}
+
+/*
+ * __db_get_assoc_flags --
+ */
+static int
+__db_get_assoc_flags(dbp, flagsp)
+	DB *dbp;
+	u_int32_t *flagsp;
+{
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_assoc_flags");
+
+	*flagsp = dbp->s_assoc_flags;
+	return (0);
+}
+
+/*
+ * __db_get_flags --
+ *	The DB->get_flags method.
+ *
+ * PUBLIC: int __db_get_flags __P((DB *, u_int32_t *));
+ */
+int
+__db_get_flags(dbp, flagsp)
+	DB *dbp;
+	u_int32_t *flagsp;
+{
+	static const u_int32_t db_flags[] = {
+		DB_CHKSUM,
+		DB_DUP,
+		DB_DUPSORT,
+		DB_ENCRYPT,
+#ifdef HAVE_QUEUE
+		DB_INORDER,
+#endif
+		DB_RECNUM,
+		DB_RENUMBER,
+		DB_REVSPLITOFF,
+		DB_SNAPSHOT,
+		DB_TXN_NOT_DURABLE,
+		0
+	};
+	u_int32_t f, flags, mapped_flag;
+	int i;
+
+	flags = 0;
+	for (i = 0; (f = db_flags[i]) != 0; i++) {
+		mapped_flag = 0;
+		__db_map_flags(dbp, &f, &mapped_flag);
+		__bam_map_flags(dbp, &f, &mapped_flag);
+		__ram_map_flags(dbp, &f, &mapped_flag);
+#ifdef HAVE_QUEUE
+		__qam_map_flags(dbp, &f, &mapped_flag);
+#endif
+		DB_ASSERT(dbp->env, f == 0);
+		if (F_ISSET(dbp, mapped_flag) == mapped_flag)
+			LF_SET(db_flags[i]);
+	}
+
+	*flagsp = flags;
+	return (0);
+}
+
+/*
+ * __db_set_flags --
+ *	DB->set_flags.
+ *
+ * PUBLIC: int  __db_set_flags __P((DB *, u_int32_t));
+ */
+int
+__db_set_flags(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	ENV *env;
+	int ret;
+
+	env = dbp->env;
+
+	if (LF_ISSET(DB_ENCRYPT) && !CRYPTO_ON(env)) {
+		__db_errx(env, DB_STR("0508",
+		    "Database environment not configured for encryption"));
+		return (EINVAL);
+	}
+	if (LF_ISSET(DB_TXN_NOT_DURABLE))
+		ENV_REQUIRES_CONFIG(env,
+		    env->tx_handle, "DB_NOT_DURABLE", DB_INIT_TXN);
+
+	__db_map_flags(dbp, &flags, &dbp->flags);
+
+	if ((ret = __bam_set_flags(dbp, &flags)) != 0)
+		return (ret);
+	if ((ret = __ram_set_flags(dbp, &flags)) != 0)
+		return (ret);
+#ifdef HAVE_QUEUE
+	if ((ret = __qam_set_flags(dbp, &flags)) != 0)
+		return (ret);
+#endif
+
+	return (flags == 0 ? 0 : __db_ferr(env, "DB->set_flags", 0));
+}
+
+/*
+ * __db_get_lorder --
+ *	Get whether lorder is swapped or not.
+ *
+ * PUBLIC: int  __db_get_lorder __P((DB *, int *));
+ */
+int
+__db_get_lorder(dbp, db_lorderp)
+	DB *dbp;
+	int *db_lorderp;
+{
+	int ret;
+
+	/* Flag if the specified byte order requires swapping. */
+	switch (ret = __db_byteorder(dbp->env, 1234)) {
+	case 0:
+		*db_lorderp = F_ISSET(dbp, DB_AM_SWAP) ? 4321 : 1234;
+		break;
+	case DB_SWAPBYTES:
+		*db_lorderp = F_ISSET(dbp, DB_AM_SWAP) ? 1234 : 4321;
+		break;
+	default:
+		return (ret);
+		/* NOTREACHED */
+	}
+
+	return (0);
+}
+
+/*
+ * __db_set_lorder --
+ *	Set whether lorder is swapped or not.
+ *
+ * PUBLIC: int  __db_set_lorder __P((DB *, int));
+ */
+int
+__db_set_lorder(dbp, db_lorder)
+	DB *dbp;
+	int db_lorder;
+{
+	int ret;
+
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_lorder");
+
+	/* Flag if the specified byte order requires swapping. */
+	switch (ret = __db_byteorder(dbp->env, db_lorder)) {
+	case 0:
+		F_CLR(dbp, DB_AM_SWAP);
+		break;
+	case DB_SWAPBYTES:
+		F_SET(dbp, DB_AM_SWAP);
+		break;
+	default:
+		return (ret);
+		/* NOTREACHED */
+	}
+	return (0);
+}
+
+static int
+__db_get_alloc(dbp, mal_funcp, real_funcp, free_funcp)
+	DB *dbp;
+	void *(**mal_funcp) __P((size_t));
+	void *(**real_funcp) __P((void *, size_t));
+	void (**free_funcp) __P((void *));
+{
+	DB_ILLEGAL_IN_ENV(dbp, "DB->get_alloc");
+
+	return (__env_get_alloc(dbp->dbenv, mal_funcp,
+	    real_funcp, free_funcp));
+}
+
+static int
+__db_set_alloc(dbp, mal_func, real_func, free_func)
+	DB *dbp;
+	void *(*mal_func) __P((size_t));
+	void *(*real_func) __P((void *, size_t));
+	void (*free_func) __P((void *));
+{
+	DB_ILLEGAL_IN_ENV(dbp, "DB->set_alloc");
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_alloc");
+
+	return (__env_set_alloc(dbp->dbenv, mal_func, real_func, free_func));
+}
+
+static void
+__db_get_msgcall(dbp, msgcallp)
+	DB *dbp;
+	void (**msgcallp) __P((const DB_ENV *, const char *));
+{
+	__env_get_msgcall(dbp->dbenv, msgcallp);
+}
+
+static void
+__db_set_msgcall(dbp, msgcall)
+	DB *dbp;
+	void (*msgcall) __P((const DB_ENV *, const char *));
+{
+	__env_set_msgcall(dbp->dbenv, msgcall);
+}
+
+static void
+__db_get_msgfile(dbp, msgfilep)
+	DB *dbp;
+	FILE **msgfilep;
+{
+	__env_get_msgfile(dbp->dbenv, msgfilep);
+}
+
+static void
+__db_set_msgfile(dbp, msgfile)
+	DB *dbp;
+	FILE *msgfile;
+{
+	__env_set_msgfile(dbp->dbenv, msgfile);
+}
+
+static int
+__db_get_pagesize(dbp, db_pagesizep)
+	DB *dbp;
+	u_int32_t *db_pagesizep;
+{
+	*db_pagesizep = dbp->pgsize;
+	return (0);
+}
+
+/*
+ * __db_set_pagesize --
+ *	DB->set_pagesize
+ *
+ * PUBLIC: int  __db_set_pagesize __P((DB *, u_int32_t));
+ */
+int
+__db_set_pagesize(dbp, db_pagesize)
+	DB *dbp;
+	u_int32_t db_pagesize;
+{
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_pagesize");
+
+	if (db_pagesize < DB_MIN_PGSIZE) {
+		__db_errx(dbp->env, DB_STR_A("0509",
+		    "page sizes may not be smaller than %lu", "%lu"),
+		    (u_long)DB_MIN_PGSIZE);
+		return (EINVAL);
+	}
+	if (db_pagesize > DB_MAX_PGSIZE) {
+		__db_errx(dbp->env, DB_STR_A("0510",
+		    "page sizes may not be larger than %lu", "%lu"),
+		    (u_long)DB_MAX_PGSIZE);
+		return (EINVAL);
+	}
+
+	/*
+	 * We don't want anything that's not a power-of-2, as we rely on that
+	 * for alignment of various types on the pages.
+	 */
+	if (!POWER_OF_TWO(db_pagesize)) {
+		__db_errx(dbp->env, DB_STR("0511",
+		    "page sizes must be a power-of-2"));
+		return (EINVAL);
+	}
+
+	/*
+	 * XXX
+	 * Should we be checking for a page size that's not a multiple of 512,
+	 * so that we never try and write less than a disk sector?
+	 */
+	dbp->pgsize = db_pagesize;
+
+	return (0);
+}
+
+static int
+__db_set_paniccall(dbp, paniccall)
+	DB *dbp;
+	void (*paniccall) __P((DB_ENV *, int));
+{
+	return (__env_set_paniccall(dbp->dbenv, paniccall));
+}
+
+static int
+__db_set_priority(dbp, priority)
+	DB *dbp;
+	DB_CACHE_PRIORITY priority;
+{
+	dbp->priority = priority;
+	return (0);
+}
+
+static int
+__db_get_priority(dbp, priority)
+	DB *dbp;
+	DB_CACHE_PRIORITY *priority;
+{
+	if (dbp->priority == DB_PRIORITY_UNCHANGED)
+		return (__memp_get_priority(dbp->mpf, priority));
+	else
+		*priority = dbp->priority;
+
+	return (0);
+}
+
+/*
+ * __db_relink --
+ *	Relink around a deleted page.
+ *
+ * PUBLIC: int __db_relink __P((DBC *, PAGE *, PAGE *, db_pgno_t));
+ *	Otherp can be either the previous or the next page to use if
+ * the caller already holds that page.
+ */
+int
+__db_relink(dbc, pagep, otherp, new_pgno)
+	DBC *dbc;
+	PAGE *pagep, *otherp;
+	db_pgno_t new_pgno;
+{
+	DB *dbp;
+	DB_LOCK npl, ppl;
+	DB_LSN *nlsnp, *plsnp, ret_lsn;
+	DB_MPOOLFILE *mpf;
+	PAGE *np, *pp;
+	int ret, t_ret;
+
+	dbp = dbc->dbp;
+	np = pp = NULL;
+	LOCK_INIT(npl);
+	LOCK_INIT(ppl);
+	nlsnp = plsnp = NULL;
+	mpf = dbp->mpf;
+	ret = 0;
+
+	/*
+	 * Retrieve the one/two pages.  The caller must have them locked
+	 * because the parent is latched. For a remove, we may need
+	 * two pages (the before and after).  For an add, we only need one
+	 * because, the split took care of the prev.
+	 */
+	if (pagep->next_pgno != PGNO_INVALID) {
+		if (((np = otherp) == NULL ||
+		    PGNO(otherp) != pagep->next_pgno) &&
+		    (ret = __memp_fget(mpf, &pagep->next_pgno,
+		    dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &np)) != 0) {
+			ret = __db_pgerr(dbp, pagep->next_pgno, ret);
+			goto err;
+		}
+		nlsnp = &np->lsn;
+	}
+	if (pagep->prev_pgno != PGNO_INVALID) {
+		if (((pp = otherp) == NULL ||
+		    PGNO(otherp) != pagep->prev_pgno) &&
+		    (ret = __memp_fget(mpf, &pagep->prev_pgno,
+		    dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &pp)) != 0) {
+			ret = __db_pgerr(dbp, pagep->prev_pgno, ret);
+			goto err;
+		}
+		plsnp = &pp->lsn;
+	}
+
+	/* Log the change. */
+	if (DBC_LOGGING(dbc)) {
+		if ((ret = __db_relink_log(dbp, dbc->txn, &ret_lsn, 0,
+		    pagep->pgno, new_pgno, pagep->prev_pgno, plsnp,
+		    pagep->next_pgno, nlsnp)) != 0)
+			goto err;
+	} else
+		LSN_NOT_LOGGED(ret_lsn);
+	if (np != NULL)
+		np->lsn = ret_lsn;
+	if (pp != NULL)
+		pp->lsn = ret_lsn;
+
+	/*
+	 * Modify and release the two pages.
+	 */
+	if (np != NULL) {
+		if (new_pgno == PGNO_INVALID)
+			np->prev_pgno = pagep->prev_pgno;
+		else
+			np->prev_pgno = new_pgno;
+		if (np != otherp)
+			ret = __memp_fput(mpf,
+			    dbc->thread_info, np, dbc->priority);
+		if ((t_ret = __TLPUT(dbc, npl)) != 0 && ret == 0)
+			ret = t_ret;
+		if (ret != 0)
+			goto err;
+	}
+
+	if (pp != NULL) {
+		if (new_pgno == PGNO_INVALID)
+			pp->next_pgno = pagep->next_pgno;
+		else
+			pp->next_pgno = new_pgno;
+		if (pp != otherp)
+			ret = __memp_fput(mpf,
+			    dbc->thread_info, pp, dbc->priority);
+		if ((t_ret = __TLPUT(dbc, ppl)) != 0 && ret == 0)
+			ret = t_ret;
+		if (ret != 0)
+			goto err;
+	}
+	return (0);
+
+err:	if (np != NULL && np != otherp)
+		(void)__memp_fput(mpf, dbc->thread_info, np, dbc->priority);
+	if (pp != NULL && pp != otherp)
+		(void)__memp_fput(mpf, dbc->thread_info, pp, dbc->priority);
+	return (ret);
+}
+
+#ifdef DIAGNOSTIC
+/*
+ * __db_haslock --
+ *	Determine if this locker holds a particular lock.
+ *	Returns 0 if lock is held, non-zero otherwise.
+ *
+ * PUBLIC: #ifdef DIAGNOSTIC
+ * PUBLIC: int __db_haslock __P((ENV *, DB_LOCKER *,
+ * PUBLIC:     DB_MPOOLFILE *, db_pgno_t, db_lockmode_t, u_int32_t));
+ * PUBLIC: #endif
+ */
+int
+__db_haslock(env, locker, dbmfp, pgno, mode, type)
+	ENV *env;
+	DB_LOCKER *locker;
+	DB_MPOOLFILE *dbmfp;
+	db_pgno_t pgno;
+	db_lockmode_t mode;
+	u_int32_t type;
+{
+	DBT lkdata;
+	DB_LOCK lock;
+	DB_LOCK_ILOCK ilock;
+
+	memset(&lkdata, 0, sizeof(lkdata));
+	lkdata.data = &ilock;
+	lkdata.size = sizeof(ilock);
+
+	memcpy(ilock.fileid, dbmfp->fileid, DB_FILE_ID_LEN);
+	ilock.pgno = pgno;
+	ilock.type = type;
+
+	return (__lock_get(env, locker, DB_LOCK_CHECK, &lkdata, mode, &lock));
+}
+
+/*
+ * __db_has_pagelock --
+ *	Determine if this locker holds a particular page lock.
+ *	Returns 0 if lock is held, non-zero otherwise.
+ *
+ * PUBLIC: #ifdef DIAGNOSTIC
+ * PUBLIC: int __db_has_pagelock __P((ENV *, DB_LOCKER *,
+ * PUBLIC:     DB_MPOOLFILE *, PAGE *, db_lockmode_t));
+ * PUBLIC: #endif
+ */
+int
+__db_has_pagelock(env, locker, dbmfp, pagep, mode)
+	ENV *env;
+	DB_LOCKER *locker;
+	DB_MPOOLFILE *dbmfp;
+	PAGE *pagep;
+	db_lockmode_t mode;
+{
+	int ret;
+
+	switch (pagep->type) {
+	case P_OVERFLOW:
+	case P_INVALID:
+	case P_QAMDATA:
+	case P_QAMMETA:
+	case P_IHEAP:
+		return (0);
+	case P_HASH:
+		if (PREV_PGNO(pagep) != PGNO_INVALID)
+			return (0);
+		break;
+	default:
+		break;
+	}
+	if ((ret = __db_haslock(env,
+	    locker, dbmfp, pagep->pgno, mode, DB_PAGE_LOCK)) != 0)
+		ret = __db_haslock(env,
+		    locker, dbmfp, PGNO_BASE_MD, mode, DB_DATABASE_LOCK);
+	return (ret);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_open.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,879 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_swap.h"
+#include "dbinc/btree.h"
+#include "dbinc/crypto.h"
+#include "dbinc/hmac.h"
+#include "dbinc/fop.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/qam.h"
+#include "dbinc/txn.h"
+
+static int __db_handle_lock __P((DB *));
+
+/*
+ * __db_open --
+ *	DB->open method.
+ *
+ * This routine gets called in three different ways:
+ *
+ * 1. It can be called to open a file/database.  In this case, subdb will
+ *    be NULL and meta_pgno will be PGNO_BASE_MD.
+ * 2. It can be called to open a subdatabase during normal operation.  In
+ *    this case, name and subname will both be non-NULL and meta_pgno will
+ *    be PGNO_BASE_MD (also PGNO_INVALID).
+ * 3. It can be called to open an in-memory database (name == NULL;
+ *    subname = name).
+ * 4. It can be called during recovery to open a file/database, in which case
+ *    name will be non-NULL, subname will be NULL, and meta-pgno will be
+ *    PGNO_BASE_MD.
+ * 5. It can be called during recovery to open a subdatabase, in which case
+ *    name will be non-NULL, subname may be NULL and meta-pgno will be
+ *    a valid pgno (i.e., not PGNO_BASE_MD).
+ * 6. It can be called during recovery to open an in-memory database.
+ *
+ * PUBLIC: int __db_open __P((DB *, DB_THREAD_INFO *, DB_TXN *,
+ * PUBLIC:     const char *, const char *, DBTYPE, u_int32_t, int, db_pgno_t));
+ */
+int
+__db_open(dbp, ip, txn, fname, dname, type, flags, mode, meta_pgno)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *fname, *dname;
+	DBTYPE type;
+	u_int32_t flags;
+	int mode;
+	db_pgno_t meta_pgno;
+{
+	DB *tdbp;
+	ENV *env;
+	int ret;
+	u_int32_t id;
+
+	env = dbp->env;
+	id = TXN_INVALID;
+
+	/*
+	 * We must flush any existing pages before truncating the file
+	 * since they could age out of mpool and overwrite new pages.
+	 */
+	if (LF_ISSET(DB_TRUNCATE)) {
+		if ((ret = __db_create_internal(&tdbp, dbp->env, 0)) != 0)
+			goto err;
+		ret = __db_open(tdbp, ip, txn, fname, dname, DB_UNKNOWN,
+		     DB_NOERROR | (flags &  ~(DB_TRUNCATE|DB_CREATE)),
+		     mode, meta_pgno);
+		if (ret == 0)
+			ret = __memp_ftruncate(tdbp->mpf, txn, ip, 0, 0);
+		(void)__db_close(tdbp, txn, DB_NOSYNC);
+		if (ret != 0 && ret != ENOENT && ret != EINVAL)
+			goto err;
+		ret = 0;
+	}
+
+	DB_TEST_RECOVERY(dbp, DB_TEST_PREOPEN, ret, fname);
+
+	/*
+	 * If the environment was configured with threads, the DB handle
+	 * must also be free-threaded, so we force the DB_THREAD flag on.
+	 * (See SR #2033 for why this is a requirement--recovery needs
+	 * to be able to grab a dbp using __db_fileid_to_dbp, and it has
+	 * no way of knowing which dbp goes with which thread, so whichever
+	 * one it finds has to be usable in any of them.)
+	 */
+	if (F_ISSET(env, ENV_THREAD))
+		LF_SET(DB_THREAD);
+
+	/* Convert any DB->open flags. */
+	if (LF_ISSET(DB_RDONLY))
+		F_SET(dbp, DB_AM_RDONLY);
+	if (LF_ISSET(DB_READ_UNCOMMITTED))
+		F_SET(dbp, DB_AM_READ_UNCOMMITTED);
+
+	if (IS_REAL_TXN(txn))
+		F_SET(dbp, DB_AM_TXN);
+
+	/* Fill in the type. */
+	dbp->type = type;
+
+	/* Save the file and database names. */
+	if ((fname != NULL &&
+	    (ret = __os_strdup(env, fname, &dbp->fname)) != 0))
+		goto err;
+	if ((dname != NULL &&
+	    (ret = __os_strdup(env, dname, &dbp->dname)) != 0))
+		goto err;
+
+	/*
+	 * If both fname and subname are NULL, it's always a create, so make
+	 * sure that we have both DB_CREATE and a type specified.  It would
+	 * be nice if this checking were done in __db_open where most of the
+	 * interface checking is done, but this interface (__db_dbopen) is
+	 * used by the recovery and limbo system, so we need to safeguard
+	 * this interface as well.
+	 */
+	if (fname == NULL) {
+		if (dbp->p_internal != NULL) {
+			__db_errx(env, DB_STR("0634",
+			    "Partitioned databases may not be in memory."));
+			return (ENOENT);
+		}
+		if (dname == NULL) {
+			if (!LF_ISSET(DB_CREATE)) {
+				__db_errx(env, DB_STR("0635",
+		    "DB_CREATE must be specified to create databases."));
+				return (ENOENT);
+			}
+
+			F_SET(dbp, DB_AM_INMEM);
+			F_SET(dbp, DB_AM_CREATED);
+
+			if (dbp->type == DB_UNKNOWN) {
+				__db_errx(env, DB_STR("0636",
+				    "DBTYPE of unknown without existing file"));
+				return (EINVAL);
+			}
+
+			if (dbp->pgsize == 0)
+				dbp->pgsize = DB_DEF_IOSIZE;
+
+			/*
+			 * If the file is a temporary file and we're
+			 * doing locking, then we have to create a
+			 * unique file ID.  We can't use our normal
+			 * dev/inode pair (or whatever this OS uses
+			 * in place of dev/inode pairs) because no
+			 * backing file will be created until the
+			 * mpool cache is filled forcing the buffers
+			 * to disk.  Grab a random locker ID to use
+			 * as a file ID.  The created ID must never
+			 * match a potential real file ID -- we know
+			 * it won't because real file IDs contain a
+			 * time stamp after the dev/inode pair, and
+			 * we're simply storing a 4-byte value.
+
+			 * !!!
+			 * Store the locker in the file id structure
+			 * -- we can get it from there as necessary,
+			 * and it saves having two copies.
+			*/
+			if (LOCKING_ON(env) && (ret = __lock_id(env,
+			    (u_int32_t *)dbp->fileid, NULL)) != 0)
+				return (ret);
+		} else
+			MAKE_INMEM(dbp);
+
+		/*
+		 * Normally we would do handle locking here, however, with
+		 * in-memory files, we cannot do any database manipulation
+		 * until the mpool is open, so it happens later.
+		 */
+	} else if (dname == NULL && meta_pgno == PGNO_BASE_MD) {
+		/* Open/create the underlying file.  Acquire locks. */
+		if ((ret = __fop_file_setup(dbp, ip,
+		    txn, fname, mode, flags, &id)) != 0)
+			return (ret);
+		/*
+		 * If we are creating the first sub-db then this is the
+		 * call to create the master db and we tried to open it
+		 * read-only.  The create will force it to be read/write
+		 * So clear the RDONLY flag if we just created it.
+		 */
+		if (!F_ISSET(dbp, DB_AM_RDONLY))
+			LF_CLR(DB_RDONLY);
+	} else {
+		if (dbp->p_internal != NULL) {
+			__db_errx(env, DB_STR("0637",
+    "Partitioned databases may not be included with multiple databases."));
+			return (ENOENT);
+		}
+		if ((ret = __fop_subdb_setup(dbp, ip,
+		    txn, fname, dname, mode, flags)) != 0)
+			return (ret);
+		meta_pgno = dbp->meta_pgno;
+	}
+
+	/* Set up the underlying environment. */
+	if ((ret = __env_setup(dbp, txn, fname, dname, id, flags)) != 0)
+		return (ret);
+
+	/* For in-memory databases, we now need to open/create the database. */
+	if (F_ISSET(dbp, DB_AM_INMEM)) {
+		if (dname == NULL)
+			ret = __db_new_file(dbp, ip, txn, NULL, NULL);
+		else {
+			id = TXN_INVALID;
+			ret = __fop_file_setup(dbp,
+			     ip, txn, dname, mode, flags, &id);
+		}
+		if (ret != 0)
+			goto err;
+	}
+
+	/*
+	 * Internal exclusive databases need to use the shared
+	 * memory pool to lock out existing database handles before
+	 * it gets its handle lock.  So getting the lock is delayed
+	 * until after the memory pool is allocated.
+	 */
+	if (F2_ISSET(dbp, DB2_AM_INTEXCL) &&
+	    (ret = __db_handle_lock(dbp)) != 0)
+			goto err;
+
+	switch (dbp->type) {
+		case DB_BTREE:
+			ret = __bam_open(dbp, ip, txn, fname, meta_pgno, flags);
+			break;
+		case DB_HASH:
+			ret = __ham_open(dbp, ip, txn, fname, meta_pgno, flags);
+			break;
+		case DB_HEAP:
+			ret = __heap_open(dbp,
+			    ip, txn, fname, meta_pgno, flags);
+			break;
+		case DB_RECNO:
+			ret = __ram_open(dbp, ip, txn, fname, meta_pgno, flags);
+			break;
+		case DB_QUEUE:
+			ret = __qam_open(
+			    dbp, ip, txn, fname, meta_pgno, mode, flags);
+			break;
+		case DB_UNKNOWN:
+			return (
+			    __db_unknown_type(env, "__db_dbopen", dbp->type));
+	}
+	if (ret != 0)
+		goto err;
+
+#ifdef HAVE_PARTITION
+	if (dbp->p_internal != NULL && (ret =
+	    __partition_open(dbp, ip, txn, fname, type, flags, mode, 1)) != 0)
+		goto err;
+#endif
+	DB_TEST_RECOVERY(dbp, DB_TEST_POSTOPEN, ret, fname);
+
+	/*
+	 * Temporary files don't need handle locks, so we only have to check
+	 * for a handle lock downgrade or lockevent in the case of named
+	 * files.
+	 */
+	if (!F_ISSET(dbp, DB_AM_RECOVER) && (fname != NULL || dname != NULL) &&
+	    LOCK_ISSET(dbp->handle_lock)) {
+		if (IS_REAL_TXN(txn))
+			ret = __txn_lockevent(env,
+			    txn, dbp, &dbp->handle_lock, dbp->locker);
+		else if (LOCKING_ON(env) && !F2_ISSET(dbp, DB2_AM_EXCL))
+			/*
+			 * Trade write handle lock for read handle lock,
+			 * unless this is an exclusive database handle.
+			 */
+			ret = __lock_downgrade(env,
+			    &dbp->handle_lock, DB_LOCK_READ, 0);
+	}
+DB_TEST_RECOVERY_LABEL
+err:
+	PERFMON4(env,
+	    db, open, (char *) fname, (char *) dname, flags, &dbp->fileid[0]);
+	return (ret);
+}
+
+/*
+ * __db_get_open_flags --
+ *	Accessor for flags passed into DB->open call
+ *
+ * PUBLIC: int __db_get_open_flags __P((DB *, u_int32_t *));
+ */
+int
+__db_get_open_flags(dbp, flagsp)
+	DB *dbp;
+	u_int32_t *flagsp;
+{
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_open_flags");
+
+	*flagsp = dbp->open_flags;
+	return (0);
+}
+
+/*
+ * __db_new_file --
+ *	Create a new database file.
+ *
+ * PUBLIC: int __db_new_file __P((DB *,
+ * PUBLIC:      DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *));
+ */
+int
+__db_new_file(dbp, ip, txn, fhp, name)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DB_FH *fhp;
+	const char *name;
+{
+	int ret;
+
+	/*
+	 * For in-memory database, it is created by mpool and doesn't
+	 * take any lock, so temporarily turn off the lock checking here.
+	 */
+	if (F_ISSET(dbp, DB_AM_INMEM))
+		LOCK_CHECK_OFF(ip);
+
+	switch (dbp->type) {
+	case DB_BTREE:
+	case DB_RECNO:
+		ret = __bam_new_file(dbp, ip, txn, fhp, name);
+		break;
+	case DB_HASH:
+		ret = __ham_new_file(dbp, ip, txn, fhp, name);
+		break;
+	case DB_HEAP:
+		ret = __heap_new_file(dbp, ip, txn, fhp, name);
+		break;
+	case DB_QUEUE:
+		ret = __qam_new_file(dbp, ip, txn, fhp, name);
+		break;
+	case DB_UNKNOWN:
+	default:
+		__db_errx(dbp->env, DB_STR_A("0638",
+		    "%s: Invalid type %d specified", "%s %d"),
+		    name, dbp->type);
+		ret = EINVAL;
+		break;
+	}
+
+	DB_TEST_RECOVERY(dbp, DB_TEST_POSTLOGMETA, ret, name);
+	/* Sync the file in preparation for moving it into place. */
+	if (ret == 0 && fhp != NULL)
+		ret = __os_fsync(dbp->env, fhp);
+
+	DB_TEST_RECOVERY(dbp, DB_TEST_POSTSYNC, ret, name);
+
+	if (F_ISSET(dbp, DB_AM_INMEM))
+		LOCK_CHECK_ON(ip);
+
+DB_TEST_RECOVERY_LABEL
+	return (ret);
+}
+
+/*
+ * __db_init_subdb --
+ *	Initialize the dbp for a subdb.
+ *
+ * PUBLIC: int __db_init_subdb __P((DB *,
+ * PUBLIC:       DB *, const char *, DB_THREAD_INFO *, DB_TXN *));
+ */
+int
+__db_init_subdb(mdbp, dbp, name, ip, txn)
+	DB *mdbp, *dbp;
+	const char *name;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+{
+	DBMETA *meta;
+	DB_MPOOLFILE *mpf;
+	int ret, t_ret;
+
+	ret = 0;
+	if (!F_ISSET(dbp, DB_AM_CREATED)) {
+		/* Subdb exists; read meta-data page and initialize. */
+		mpf = mdbp->mpf;
+		if  ((ret = __memp_fget(mpf, &dbp->meta_pgno,
+		    ip, txn, 0, &meta)) != 0)
+			goto err;
+		ret = __db_meta_setup(mdbp->env, dbp, name, meta, 0, 0);
+		if ((t_ret = __memp_fput(mpf,
+		    ip, meta, dbp->priority)) != 0 && ret == 0)
+			ret = t_ret;
+		/*
+		 * If __db_meta_setup found that the meta-page hadn't
+		 * been written out during recovery, we can just return.
+		 */
+		if (ret == ENOENT)
+			ret = 0;
+		goto err;
+	}
+
+	/* Handle the create case here. */
+	switch (dbp->type) {
+	case DB_BTREE:
+	case DB_RECNO:
+		ret = __bam_new_subdb(mdbp, dbp, ip, txn);
+		break;
+	case DB_HASH:
+		ret = __ham_new_subdb(mdbp, dbp, ip, txn);
+		break;
+	case DB_QUEUE:
+		ret = EINVAL;
+		break;
+	case DB_UNKNOWN:
+	default:
+		__db_errx(dbp->env, DB_STR_A("0639",
+		    "Invalid subdatabase type %d specified", "%d"),
+		    dbp->type);
+		return (EINVAL);
+	}
+
+err:	return (ret);
+}
+
+/*
+ * __db_chk_meta --
+ *	Take a buffer containing a meta-data page and check it for a valid LSN,
+ *	checksum (and verify the checksum if necessary) and possibly decrypt it.
+ *
+ *	Return 0 on success, >0 (errno).
+ *
+ * PUBLIC: int __db_chk_meta __P((ENV *, DB *, DBMETA *, u_int32_t));
+ */
+int
+__db_chk_meta(env, dbp, meta, flags)
+	ENV *env;
+	DB *dbp;
+	DBMETA *meta;
+	u_int32_t flags;
+{
+	DB_LSN swap_lsn;
+	int is_hmac, ret, swapped;
+	u_int32_t magic, orig_chk;
+	u_int8_t *chksum;
+
+	ret = 0;
+	swapped = 0;
+
+	if (FLD_ISSET(meta->metaflags, DBMETA_CHKSUM)) {
+		if (dbp != NULL)
+			F_SET(dbp, DB_AM_CHKSUM);
+
+		is_hmac = meta->encrypt_alg == 0 ? 0 : 1;
+		chksum = ((BTMETA *)meta)->chksum;
+
+		/*
+		 * If we need to swap, the checksum function overwrites the
+		 * original checksum with 0, so we need to save a copy of the
+		 * original for swapping later.
+		 */
+		orig_chk = *(u_int32_t *)chksum;
+
+		/*
+		 * We cannot add this to __db_metaswap because that gets done
+		 * later after we've verified the checksum or decrypted.
+		 */
+		if (LF_ISSET(DB_CHK_META)) {
+			swapped = 0;
+chk_retry:		if ((ret =
+			    __db_check_chksum(env, NULL, env->crypto_handle,
+			    chksum, meta, DBMETASIZE, is_hmac)) != 0) {
+				if (is_hmac || swapped)
+					return (DB_CHKSUM_FAIL);
+
+				M_32_SWAP(orig_chk);
+				swapped = 1;
+				*(u_int32_t *)chksum = orig_chk;
+				goto chk_retry;
+			}
+		}
+	} else if (dbp != NULL)
+		F_CLR(dbp, DB_AM_CHKSUM);
+
+#ifdef HAVE_CRYPTO
+	if (__crypto_decrypt_meta(env,
+	     dbp, (u_int8_t *)meta, LF_ISSET(DB_CHK_META)) != 0)
+	     	ret = DB_CHKSUM_FAIL;
+	else
+#endif
+
+	/* Now that we're decrypted, we can check LSN. */
+	if (LOGGING_ON(env) && !LF_ISSET(DB_CHK_NOLSN)) {
+		/*
+		 * This gets called both before and after swapping, so we
+		 * need to check ourselves.  If we already swapped it above,
+		 * we'll know that here.
+		 */
+
+		swap_lsn = meta->lsn;
+		magic = meta->magic;
+lsn_retry:
+		if (swapped) {
+			M_32_SWAP(swap_lsn.file);
+			M_32_SWAP(swap_lsn.offset);
+			M_32_SWAP(magic);
+		}
+		switch (magic) {
+		case DB_BTREEMAGIC:
+		case DB_HASHMAGIC:
+		case DB_HEAPMAGIC:
+		case DB_QAMMAGIC:
+		case DB_RENAMEMAGIC:
+			break;
+		default:
+			if (swapped)
+				return (EINVAL);
+			swapped = 1;
+			goto lsn_retry;
+		}
+		if (!IS_REP_CLIENT(env) &&
+		    !IS_NOT_LOGGED_LSN(swap_lsn) && !IS_ZERO_LSN(swap_lsn))
+			/* Need to do check. */
+			ret = __log_check_page_lsn(env, dbp, &swap_lsn);
+	}
+	return (ret);
+}
+
+/*
+ * __db_meta_setup --
+ *
+ * Take a buffer containing a meta-data page and figure out if it's
+ * valid, and if so, initialize the dbp from the meta-data page.
+ *
+ * PUBLIC: int __db_meta_setup __P((ENV *,
+ * PUBLIC:     DB *, const char *, DBMETA *, u_int32_t, u_int32_t));
+ */
+int
+__db_meta_setup(env, dbp, name, meta, oflags, flags)
+	ENV *env;
+	DB *dbp;
+	const char *name;
+	DBMETA *meta;
+	u_int32_t oflags;
+	u_int32_t flags;
+{
+	u_int32_t magic;
+	int ret;
+
+	ret = 0;
+
+	/*
+	 * Figure out what access method we're dealing with, and then
+	 * call access method specific code to check error conditions
+	 * based on conflicts between the found file and application
+	 * arguments.  A found file overrides some user information --
+	 * we don't consider it an error, for example, if the user set
+	 * an expected byte order and the found file doesn't match it.
+	 */
+	F_CLR(dbp, DB_AM_SWAP | DB_AM_IN_RENAME);
+	magic = meta->magic;
+
+swap_retry:
+	switch (magic) {
+	case DB_BTREEMAGIC:
+	case DB_HASHMAGIC:
+	case DB_HEAPMAGIC:
+	case DB_QAMMAGIC:
+	case DB_RENAMEMAGIC:
+		break;
+	case 0:
+		/*
+		 * The only time this should be 0 is if we're in the
+		 * midst of opening a subdb during recovery and that
+		 * subdatabase had its meta-data page allocated, but
+		 * not yet initialized.
+		 */
+		if (F_ISSET(dbp, DB_AM_SUBDB) && ((IS_RECOVERING(env) &&
+		    F_ISSET(env->lg_handle, DBLOG_FORCE_OPEN)) ||
+		    meta->pgno != PGNO_INVALID))
+			return (ENOENT);
+
+		goto bad_format;
+	default:
+		if (F_ISSET(dbp, DB_AM_SWAP))
+			goto bad_format;
+
+		M_32_SWAP(magic);
+		F_SET(dbp, DB_AM_SWAP);
+		goto swap_retry;
+	}
+
+	/*
+	 * We can only check the meta page if we are sure we have a meta page.
+	 * If it is random data, then this check can fail.  So only now can we
+	 * checksum and decrypt.  Don't distinguish between configuration and
+	 * checksum match errors here, because we haven't opened the database
+	 * and even a checksum error isn't a reason to panic the environment.
+	 * If DB_SKIP_CHK is set, it means the checksum was already checked
+	 * and the page was already decrypted.
+	 */
+	if (!LF_ISSET(DB_SKIP_CHK) && 
+	    (ret = __db_chk_meta(env, dbp, meta, flags)) != 0) {
+		if (ret == DB_CHKSUM_FAIL) 
+			__db_errx(env, DB_STR_A("0640",
+			    "%s: metadata page checksum error", "%s"), name);
+		goto bad_format;
+	}
+
+	switch (magic) {
+	case DB_BTREEMAGIC:
+		if (dbp->type != DB_UNKNOWN &&
+		    dbp->type != DB_RECNO && dbp->type != DB_BTREE)
+			goto bad_format;
+
+		flags = meta->flags;
+		if (F_ISSET(dbp, DB_AM_SWAP))
+			M_32_SWAP(flags);
+		if (LF_ISSET(BTM_RECNO))
+			dbp->type = DB_RECNO;
+		else
+			dbp->type = DB_BTREE;
+		if ((oflags & DB_TRUNCATE) == 0 && (ret =
+		    __bam_metachk(dbp, name, (BTMETA *)meta)) != 0)
+			return (ret);
+		break;
+	case DB_HASHMAGIC:
+		if (dbp->type != DB_UNKNOWN && dbp->type != DB_HASH)
+			goto bad_format;
+
+		dbp->type = DB_HASH;
+		if ((oflags & DB_TRUNCATE) == 0 && (ret =
+		    __ham_metachk(dbp, name, (HMETA *)meta)) != 0)
+			return (ret);
+		break;
+	case DB_HEAPMAGIC:
+		if (dbp->type != DB_UNKNOWN && dbp->type != DB_HEAP)
+			goto bad_format;
+
+		dbp->type = DB_HEAP;
+		if ((oflags & DB_TRUNCATE) == 0 && (ret =
+		    __heap_metachk(dbp, name, (HEAPMETA *)meta)) != 0)
+			return (ret);
+		break;
+	case DB_QAMMAGIC:
+		if (dbp->type != DB_UNKNOWN && dbp->type != DB_QUEUE)
+			goto bad_format;
+		dbp->type = DB_QUEUE;
+		if ((oflags & DB_TRUNCATE) == 0 && (ret =
+		    __qam_metachk(dbp, name, (QMETA *)meta)) != 0)
+			return (ret);
+		break;
+	case DB_RENAMEMAGIC:
+		F_SET(dbp, DB_AM_IN_RENAME);
+
+		/* Copy the file's ID. */
+		memcpy(dbp->fileid, ((DBMETA *)meta)->uid, DB_FILE_ID_LEN);
+
+		break;
+	default:
+		goto bad_format;
+	}
+
+	if (FLD_ISSET(meta->metaflags,
+	    DBMETA_PART_RANGE | DBMETA_PART_CALLBACK))
+		if ((ret =
+		    __partition_init(dbp, meta->metaflags)) != 0)
+			return (ret);
+	return (0);
+
+bad_format:
+	if (F_ISSET(dbp, DB_AM_RECOVER))
+		ret = ENOENT;
+	else
+		__db_errx(env, DB_STR_A("0641",
+		    "__db_meta_setup: %s: unexpected file type or format",
+		    "%s"), name);
+	return (ret == 0 ? EINVAL : ret);
+}
+
+/*
+ * __db_reopen --
+ *	Reopen a subdatabase if its meta/root pages move.
+ * PUBLIC: int __db_reopen __P((DBC *));
+ */
+int
+__db_reopen(arg_dbc)
+	DBC *arg_dbc;
+{
+	BTREE *bt;
+	DBC *dbc;
+	DB_TXN *txn;
+	HASH *ht;
+	DB *dbp, *mdbp;
+	DB_LOCK new_lock, old_lock;
+	PAGE *new_page, *old_page;
+	db_pgno_t newpgno, oldpgno;
+	int ret, t_ret;
+
+	dbc = arg_dbc;
+	dbp = dbc->dbp;
+	old_page = new_page = NULL;
+	mdbp = NULL;
+
+	COMPQUIET(bt, NULL);
+	COMPQUIET(ht, NULL);
+	COMPQUIET(txn, NULL);
+	LOCK_INIT(new_lock);
+	LOCK_INIT(old_lock);
+
+	/*
+	 * This must be done in the context of a transaction.  If the
+	 * requester does not have a transaction, create one.
+	 */
+
+	if (TXN_ON(dbp->env) && (txn = dbc->txn) == NULL) {
+		if ((ret = __txn_begin(dbp->env,
+		     dbc->thread_info, NULL, &txn, 0)) != 0)
+			return (ret);
+		if ((ret = __db_cursor(dbp,
+		     dbc->thread_info, txn, &dbc, 0)) != 0) {
+			(void)__txn_abort(txn);
+			return (ret);
+		}
+	}
+
+	/*
+	 * Lock and latch the old metadata page before re-opening the
+	 * database so that the information is stable.  Then lock
+	 * and latch the new page before getting the revision so that
+	 * it cannot change.
+	 */
+
+	if (dbp->type == DB_HASH) {
+		ht = (HASH*)dbp->h_internal;
+		oldpgno = ht->meta_pgno;
+	} else {
+		bt = (BTREE *)dbp->bt_internal;
+		oldpgno = bt->bt_root;
+	}
+	if (STD_LOCKING(dbc) && (ret = __db_lget(dbc,
+	    0, oldpgno, DB_LOCK_READ, 0, &old_lock)) != 0)
+		goto err;
+
+	if ((ret = __memp_fget(dbp->mpf, &oldpgno,
+	    dbc->thread_info, dbc->txn, 0, &old_page)) != 0 &&
+	    ret != DB_PAGE_NOTFOUND)
+		goto err;
+
+	/* If the page is free we must not hold its lock. */
+	if (ret == DB_PAGE_NOTFOUND || TYPE(old_page) == P_INVALID) {
+		if ((ret = __LPUT(dbc, old_lock)) != 0)
+			goto err;
+		/* Drop the latch too. */
+		if (old_page != NULL && (ret = __memp_fput(dbp->mpf,
+		    dbc->thread_info, old_page, dbc->priority)) != 0)
+			goto err;
+		old_page = NULL;
+	}
+
+	if ((ret = __db_master_open(dbp,
+	    dbc->thread_info, dbc->txn, dbp->fname, 0, 0, &mdbp)) != 0)
+		goto err;
+
+	if ((ret = __db_master_update(mdbp, dbp, dbc->thread_info,
+	    dbc->txn, dbp->dname, dbp->type, MU_OPEN, NULL, 0)) != 0)
+		goto err;
+
+	if (dbp->type == DB_HASH)
+		newpgno = ht->meta_pgno = dbp->meta_pgno;
+	else {
+		bt->bt_meta = dbp->meta_pgno;
+		if ((ret = __bam_read_root(dbp,
+		    dbc->thread_info, dbc->txn, bt->bt_meta, 0)) != 0)
+			goto err;
+		newpgno = bt->bt_root;
+	}
+
+	if (oldpgno == newpgno)
+		goto done;
+
+	if (STD_LOCKING(dbc) && (ret = __db_lget(dbc,
+	    0, newpgno, DB_LOCK_READ, 0, &new_lock)) != 0)
+		goto err;
+
+	if ((ret = __memp_fget(dbp->mpf, &newpgno,
+	    dbc->thread_info, dbc->txn, 0, &new_page)) != 0)
+		goto err;
+
+done:	if (dbp->type == DB_HASH)
+		ht->revision = dbp->mpf->mfp->revision;
+	else
+		bt->revision = dbp->mpf->mfp->revision;
+
+err:	if (old_page != NULL && (t_ret = __memp_fput(dbp->mpf,
+	    dbc->thread_info, old_page, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	if (new_page != NULL && (t_ret = __memp_fput(dbp->mpf,
+	    dbc->thread_info, new_page, dbc->priority)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (mdbp != NULL &&
+	    (t_ret = __db_close(mdbp, dbc->txn, DB_NOSYNC)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (dbc != arg_dbc) {
+		if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+			ret = t_ret;
+		if ((t_ret = __txn_commit(txn, 0)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+	return (ret);
+}
+
+static int
+__db_handle_lock(dbp)
+	DB *dbp;
+{
+	ENV *env;
+	int ret;
+	u_int32_t old_flags;
+
+	env = dbp->env;
+	ret = 0;
+	old_flags = dbp->flags;
+
+	/*
+	 * Internal exclusive database handles need to get and hold
+	 * their own handle locks so that the client cannot open any
+	 * external handles on that database.
+	 */
+	F_CLR(dbp, DB_AM_RECOVER);
+	F_SET(dbp, DB_AM_NOT_DURABLE);
+
+	/* Begin exclusive handle lockout. */
+	dbp->mpf->mfp->excl_lockout = 1;
+
+	if ((ret = __lock_id(env, NULL, &dbp->locker)) != 0)
+		goto err;
+	LOCK_INIT(dbp->handle_lock);
+	if ((ret = __fop_lock_handle(env, dbp, dbp->locker, DB_LOCK_WRITE,
+	    NULL, 0))!= 0)
+		goto err;
+
+err:	/* End exclusive handle lockout. */
+	dbp->mpf->mfp->excl_lockout = 0;
+	dbp->flags = old_flags;
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_overflow.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,727 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/mp.h"
+
+/*
+ * Big key/data code.
+ *
+ * Big key and data entries are stored on linked lists of pages.  The initial
+ * reference is a structure with the total length of the item and the page
+ * number where it begins.  Each entry in the linked list contains a pointer
+ * to the next page of data, and so on.
+ */
+
+/*
+ * __db_goff --
+ *	Get an offpage item.
+ *
+ * PUBLIC: int __db_goff __P((DBC *,
+ * PUBLIC:     DBT *, u_int32_t, db_pgno_t, void **, u_int32_t *));
+ */
+int
+__db_goff(dbc, dbt, tlen, pgno, bpp, bpsz)
+	DBC *dbc;
+	DBT *dbt;
+	u_int32_t tlen;
+	db_pgno_t pgno;
+	void **bpp;
+	u_int32_t *bpsz;
+{
+	DB *dbp;
+	DB_MPOOLFILE *mpf;
+	DB_TXN *txn;
+	DBC_INTERNAL *cp;
+	ENV *env;
+	PAGE *h;
+	DB_THREAD_INFO *ip;
+	db_indx_t bytes;
+	u_int32_t curoff, needed, start;
+	u_int8_t *p, *src;
+	int ret;
+
+	dbp = dbc->dbp;
+	cp = dbc->internal;
+	env = dbp->env;
+	ip = dbc->thread_info;
+	mpf = dbp->mpf;
+	txn = dbc->txn;
+
+	/*
+	 * Check if the buffer is big enough; if it is not and we are
+	 * allowed to malloc space, then we'll malloc it.  If we are
+	 * not (DB_DBT_USERMEM), then we'll set the dbt and return
+	 * appropriately.
+	 */
+	if (F_ISSET(dbt, DB_DBT_PARTIAL)) {
+		start = dbt->doff;
+		if (start > tlen)
+			needed = 0;
+		else if (dbt->dlen > tlen - start)
+			needed = tlen - start;
+		else
+			needed = dbt->dlen;
+	} else {
+		start = 0;
+		needed = tlen;
+	}
+
+	/*
+	 * If the caller has not requested any data, return success. This
+	 * "early-out" also avoids setting up the streaming optimization when
+	 * no page would be retrieved. If it were removed, the streaming code
+	 * should only initialize when needed is not 0.
+	 */
+	if (needed == 0) {
+		dbt->size = 0;
+		return (0);
+	}
+
+	if (F_ISSET(dbt, DB_DBT_USERCOPY))
+		goto skip_alloc;
+
+	/* Allocate any necessary memory. */
+	if (F_ISSET(dbt, DB_DBT_USERMEM)) {
+		if (needed > dbt->ulen) {
+			dbt->size = needed;
+			return (DB_BUFFER_SMALL);
+		}
+	} else if (F_ISSET(dbt, DB_DBT_MALLOC)) {
+		if ((ret = __os_umalloc(env, needed, &dbt->data)) != 0)
+			return (ret);
+	} else if (F_ISSET(dbt, DB_DBT_REALLOC)) {
+		if ((ret = __os_urealloc(env, needed, &dbt->data)) != 0)
+			return (ret);
+	} else if (bpsz != NULL && (*bpsz == 0 || *bpsz < needed)) {
+		if ((ret = __os_realloc(env, needed, bpp)) != 0)
+			return (ret);
+		*bpsz = needed;
+		dbt->data = *bpp;
+	} else if (bpp != NULL)
+		dbt->data = *bpp;
+	else {
+		DB_ASSERT(env,
+		    F_ISSET(dbt,
+		    DB_DBT_USERMEM | DB_DBT_MALLOC | DB_DBT_REALLOC) ||
+		    bpsz != NULL);
+		return (DB_BUFFER_SMALL);
+	}
+
+skip_alloc:
+	/* Set up a start page in the overflow chain if streaming. */
+	if (cp->stream_start_pgno != PGNO_INVALID &&
+	    pgno == cp->stream_start_pgno && start >= cp->stream_off &&
+	    start < cp->stream_off + P_MAXSPACE(dbp, dbp->pgsize)) {
+		pgno = cp->stream_curr_pgno;
+		curoff = cp->stream_off;
+	} else {
+		cp->stream_start_pgno = cp->stream_curr_pgno = pgno;
+		cp->stream_off = curoff = 0;
+	}
+
+	/*
+	 * Step through the linked list of pages, copying the data on each
+	 * one into the buffer.  Never copy more than the total data length.
+	 */
+	dbt->size = needed;
+	for (p = dbt->data; pgno != PGNO_INVALID && needed > 0;) {
+		if ((ret = __memp_fget(mpf,
+		    &pgno, ip, txn, 0, &h)) != 0)
+			return (ret);
+		DB_ASSERT(env, TYPE(h) == P_OVERFLOW);
+
+		/* Check if we need any bytes from this page. */
+		if (curoff + OV_LEN(h) >= start) {
+			bytes = OV_LEN(h);
+			src = (u_int8_t *)h + P_OVERHEAD(dbp);
+			if (start > curoff) {
+				src += start - curoff;
+				bytes -= start - curoff;
+			}
+			if (bytes > needed)
+				bytes = needed;
+			if (F_ISSET(dbt, DB_DBT_USERCOPY)) {
+				/*
+				 * The offset into the DBT is the total size
+				 * less the amount of data still needed.  Care
+				 * needs to be taken if doing a partial copy
+				 * beginning at an offset other than 0.
+				 */
+				if ((ret = env->dbt_usercopy(
+				    dbt, dbt->size - needed,
+				    src, bytes, DB_USERCOPY_SETDATA)) != 0) {
+					(void)__memp_fput(mpf,
+					    ip, h, dbp->priority);
+					return (ret);
+				}
+			} else
+				memcpy(p, src, bytes);
+			p += bytes;
+			needed -= bytes;
+		}
+		cp->stream_off = curoff;
+		curoff += OV_LEN(h);
+		cp->stream_curr_pgno = pgno;
+		pgno = h->next_pgno;
+		(void)__memp_fput(mpf, ip, h, dbp->priority);
+	}
+
+	return (0);
+}
+
+/*
+ * __db_poff --
+ *	Put an offpage item.
+ *
+ * PUBLIC: int __db_poff __P((DBC *, const DBT *, db_pgno_t *));
+ */
+int
+__db_poff(dbc, dbt, pgnop)
+	DBC *dbc;
+	const DBT *dbt;
+	db_pgno_t *pgnop;
+{
+	DB *dbp;
+	DBT tmp_dbt;
+	DB_LSN null_lsn;
+	DB_MPOOLFILE *mpf;
+	PAGE *pagep, *lastp;
+	db_indx_t pagespace;
+	db_pgno_t pgno;
+	u_int32_t space, sz, tlen;
+	u_int8_t *p;
+	int ret, t_ret;
+
+	/*
+	 * Allocate pages and copy the key/data item into them.  Calculate the
+	 * number of bytes we get for pages we fill completely with a single
+	 * item.
+	 */
+	dbp = dbc->dbp;
+	lastp = NULL;
+	mpf = dbp->mpf;
+	pagespace = P_MAXSPACE(dbp, dbp->pgsize);
+	p = dbt->data;
+	sz = dbt->size;
+
+	/*
+	 * Check whether we are streaming at the end of the overflow item.
+	 * If so, the last pgno and offset will be cached in the cursor.
+	 */
+	if (F_ISSET(dbt, DB_DBT_STREAMING)) {
+		tlen = dbt->size - dbt->dlen;
+		pgno = dbc->internal->stream_curr_pgno;
+		if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info,
+		    dbc->txn, DB_MPOOL_DIRTY, &lastp)) != 0)
+			return (ret);
+
+		/*
+		 * Calculate how much we can write on the last page of the
+		 * overflow item.
+		 */
+		DB_ASSERT(dbp->env,
+		    OV_LEN(lastp) == (tlen - dbc->internal->stream_off));
+		space = pagespace - OV_LEN(lastp);
+
+		/* Only copy as much data as we have. */
+		if (space > dbt->dlen)
+			space = dbt->dlen;
+
+		if (DBC_LOGGING(dbc)) {
+			tmp_dbt.data = dbt->data;
+			tmp_dbt.size = space;
+			ZERO_LSN(null_lsn);
+			if ((ret = __db_big_log(dbp, dbc->txn, &LSN(lastp), 0,
+			    OP_SET(DB_APPEND_BIG, lastp), pgno,
+			    PGNO_INVALID, PGNO_INVALID, &tmp_dbt,
+			    &LSN(lastp), &null_lsn, &null_lsn)) != 0)
+				goto err;
+		} else
+			LSN_NOT_LOGGED(LSN(lastp));
+
+		memcpy((u_int8_t *)lastp + P_OVERHEAD(dbp) + OV_LEN(lastp),
+		    dbt->data, space);
+		OV_LEN(lastp) += space;
+		sz -= space + dbt->doff;
+		p += space;
+		*pgnop = dbc->internal->stream_start_pgno;
+	}
+
+	ret = 0;
+	for (; sz > 0; p += pagespace, sz -= pagespace) {
+		/*
+		 * Reduce pagespace so we terminate the loop correctly and
+		 * don't copy too much data.
+		 */
+		if (sz < pagespace)
+			pagespace = sz;
+
+		/*
+		 * Allocate and initialize a new page and copy all or part of
+		 * the item onto the page.  If sz is less than pagespace, we
+		 * have a partial record.
+		 */
+		if ((ret = __db_new(dbc, P_OVERFLOW, NULL, &pagep)) != 0)
+			break;
+		if (DBC_LOGGING(dbc)) {
+			tmp_dbt.data = p;
+			tmp_dbt.size = pagespace;
+			ZERO_LSN(null_lsn);
+			if ((ret = __db_big_log(dbp, dbc->txn, &LSN(pagep), 0,
+			    OP_SET(DB_ADD_BIG, pagep),
+			    PGNO(pagep), lastp ? PGNO(lastp) : PGNO_INVALID,
+			    PGNO_INVALID, &tmp_dbt, &LSN(pagep),
+			    lastp == NULL ? &null_lsn : &LSN(lastp),
+			    &null_lsn)) != 0) {
+				(void)__memp_fput(mpf, dbc->thread_info,
+				    pagep, dbc->priority);
+				goto err;
+			}
+		} else
+			LSN_NOT_LOGGED(LSN(pagep));
+
+		/* Move LSN onto page. */
+		if (lastp != NULL)
+			LSN(lastp) = LSN(pagep);
+
+		OV_LEN(pagep) = pagespace;
+		OV_REF(pagep) = 1;
+		memcpy((u_int8_t *)pagep + P_OVERHEAD(dbp), p, pagespace);
+
+		/*
+		 * If this is the first entry, update the user's info and
+		 * initialize the cursor to allow for streaming of subsequent
+		 * updates.  Otherwise, update the entry on the last page
+		 * filled in and release that page.
+		 */
+		if (lastp == NULL) {
+			*pgnop = PGNO(pagep);
+			dbc->internal->stream_start_pgno =
+			    dbc->internal->stream_curr_pgno = *pgnop;
+			dbc->internal->stream_off = 0;
+		} else {
+			lastp->next_pgno = PGNO(pagep);
+			pagep->prev_pgno = PGNO(lastp);
+			if ((ret = __memp_fput(mpf,
+			    dbc->thread_info, lastp, dbc->priority)) != 0) {
+				lastp = NULL;
+				goto err;
+			}
+		}
+		lastp = pagep;
+	}
+err:	if (lastp != NULL) {
+		if (ret == 0) {
+			dbc->internal->stream_curr_pgno = PGNO(lastp);
+			dbc->internal->stream_off = dbt->size - OV_LEN(lastp);
+		}
+
+		if ((t_ret = __memp_fput(mpf, dbc->thread_info, lastp,
+		    dbc->priority)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+	return (ret);
+}
+
+/*
+ * __db_ovref --
+ *	Decrement the reference count on an overflow page.
+ *
+ * PUBLIC: int __db_ovref __P((DBC *, db_pgno_t));
+ */
+int
+__db_ovref(dbc, pgno)
+	DBC *dbc;
+	db_pgno_t pgno;
+{
+	DB *dbp;
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	int ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+
+	if ((ret = __memp_fget(mpf, &pgno,
+	     dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &h)) != 0)
+		return (ret);
+
+	if (DBC_LOGGING(dbc)) {
+		if ((ret = __db_ovref_log(dbp,
+		    dbc->txn, &LSN(h), 0, h->pgno, -1, &LSN(h))) != 0) {
+			(void)__memp_fput(mpf,
+			     dbc->thread_info, h, dbc->priority);
+			return (ret);
+		}
+	} else
+		LSN_NOT_LOGGED(LSN(h));
+
+	/*
+	 * In BDB releases before 4.5, the overflow reference counts were
+	 * incremented when an overflow item was split onto an internal
+	 * page.  There was a lock race in that code, and rather than fix
+	 * the race, we changed BDB to copy overflow items when splitting
+	 * them onto internal pages.  The code to decrement reference
+	 * counts remains so databases already in the field continue to
+	 * work.
+	 */
+	--OV_REF(h);
+
+	return (__memp_fput(mpf, dbc->thread_info, h, dbc->priority));
+}
+
+/*
+ * __db_doff --
+ *	Delete an offpage chain of overflow pages.
+ *
+ * PUBLIC: int __db_doff __P((DBC *, db_pgno_t));
+ */
+int
+__db_doff(dbc, pgno)
+	DBC *dbc;
+	db_pgno_t pgno;
+{
+	DB *dbp;
+	DBT tmp_dbt;
+	DB_LSN null_lsn;
+	DB_MPOOLFILE *mpf;
+	PAGE *pagep;
+	int ret;
+
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+
+	do {
+		if ((ret = __memp_fget(mpf, &pgno,
+		     dbc->thread_info, dbc->txn, 0, &pagep)) != 0)
+			return (ret);
+
+		DB_ASSERT(dbp->env, TYPE(pagep) == P_OVERFLOW);
+		/*
+		 * If it's referenced by more than one key/data item,
+		 * decrement the reference count and return.
+		 */
+		if (OV_REF(pagep) > 1) {
+			(void)__memp_fput(mpf,
+			    dbc->thread_info, pagep, dbc->priority);
+			return (__db_ovref(dbc, pgno));
+		}
+
+		if ((ret = __memp_dirty(mpf, &pagep,
+		    dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) {
+			if (pagep != NULL)
+				(void)__memp_fput(mpf,
+				    dbc->thread_info, pagep, dbc->priority);
+			return (ret);
+		}
+
+		if (DBC_LOGGING(dbc)) {
+			tmp_dbt.data = (u_int8_t *)pagep + P_OVERHEAD(dbp);
+			tmp_dbt.size = OV_LEN(pagep);
+			ZERO_LSN(null_lsn);
+			if ((ret = __db_big_log(dbp, dbc->txn, &LSN(pagep), 0,
+			    OP_SET(DB_REM_BIG, pagep), PGNO(pagep),
+			    PREV_PGNO(pagep), NEXT_PGNO(pagep), &tmp_dbt,
+			    &LSN(pagep), &null_lsn, &null_lsn)) != 0) {
+				(void)__memp_fput(mpf,
+				    dbc->thread_info, pagep, dbc->priority);
+				return (ret);
+			}
+		} else
+			LSN_NOT_LOGGED(LSN(pagep));
+		pgno = pagep->next_pgno;
+		OV_LEN(pagep) = 0;
+		if ((ret = __db_free(dbc, pagep, 0)) != 0)
+			return (ret);
+	} while (pgno != PGNO_INVALID);
+
+	return (0);
+}
+
+/*
+ * __db_moff --
+ *	Match on overflow pages.
+ *
+ * Given a starting page number and a key, return <0, 0, >0 to indicate if the
+ * key on the page is less than, equal to or greater than the key specified.
+ * We optimize this by doing chunk at a time comparison unless the user has
+ * specified a comparison function.  In this case, we need to materialize
+ * the entire object and call their comparison routine.
+ *
+ * __db_moff and __db_coff are generic functions useful in searching and
+ * ordering off page items. __db_moff matches an overflow DBT with an offpage
+ * item. __db_coff compares two offpage items for lexicographic sort order.
+ *
+ * PUBLIC: int __db_moff __P((DBC *, const DBT *, db_pgno_t, u_int32_t,
+ * PUBLIC:     int (*)(DB *, const DBT *, const DBT *), int *));
+ */
+int
+__db_moff(dbc, dbt, pgno, tlen, cmpfunc, cmpp)
+	DBC *dbc;
+	const DBT *dbt;
+	db_pgno_t pgno;
+	u_int32_t tlen;
+	int (*cmpfunc) __P((DB *, const DBT *, const DBT *)), *cmpp;
+{
+	DB *dbp;
+	DBT local_dbt;
+	DB_MPOOLFILE *mpf;
+	DB_THREAD_INFO *ip;
+	PAGE *pagep;
+	void *buf;
+	u_int32_t bufsize, cmp_bytes, key_left;
+	u_int8_t *p1, *p2;
+	int ret;
+
+	dbp = dbc->dbp;
+	ip = dbc->thread_info;
+	mpf = dbp->mpf;
+
+	/*
+	 * If there is a user-specified comparison function, build a
+	 * contiguous copy of the key, and call it.
+	 */
+	if (cmpfunc != NULL) {
+		memset(&local_dbt, 0, sizeof(local_dbt));
+		buf = NULL;
+		bufsize = 0;
+
+		if ((ret = __db_goff(dbc,
+		    &local_dbt, tlen, pgno, &buf, &bufsize)) != 0)
+			return (ret);
+		/* Pass the key as the first argument */
+		*cmpp = cmpfunc(dbp, dbt, &local_dbt);
+		__os_free(dbp->env, buf);
+		return (0);
+	}
+
+	/* While there are both keys to compare. */
+	for (*cmpp = 0, p1 = dbt->data,
+	    key_left = dbt->size; key_left > 0 && pgno != PGNO_INVALID;) {
+		if ((ret =
+		    __memp_fget(mpf, &pgno, ip, dbc->txn, 0, &pagep)) != 0)
+			return (ret);
+
+		cmp_bytes = OV_LEN(pagep) < key_left ? OV_LEN(pagep) : key_left;
+		tlen -= cmp_bytes;
+		key_left -= cmp_bytes;
+		for (p2 = (u_int8_t *)pagep + P_OVERHEAD(dbp);
+		    cmp_bytes-- > 0; ++p1, ++p2)
+			if (*p1 != *p2) {
+				*cmpp = (long)*p1 - (long)*p2;
+				break;
+			}
+		pgno = NEXT_PGNO(pagep);
+		if ((ret = __memp_fput(mpf, ip, pagep, dbp->priority)) != 0)
+			return (ret);
+		if (*cmpp != 0)
+			return (0);
+	}
+	if (key_left > 0)		/* DBT is longer than the page key. */
+		*cmpp = 1;
+	else if (tlen > 0)		/* DBT is shorter than the page key. */
+		*cmpp = -1;
+	else
+		*cmpp = 0;
+
+	return (0);
+}
+
+/*
+ * __db_coff --
+ *	Match two offpage dbts.
+ *
+ * The DBTs must both refer to offpage items.
+ * The match happens a chunk (page) at a time unless a user defined comparison
+ * function exists. It is not possible to optimize this comparison away when
+ * a lexicographic sort order is required on mismatch.
+ *
+ * NOTE: For now this function only works for H_OFFPAGE type items. It would
+ * be simple to extend it for use with B_OVERFLOW type items. It would only
+ * require extracting the total length, and page number, dependent on the
+ * DBT type.
+ *
+ * PUBLIC: int __db_coff __P((DBC *, const DBT *, const DBT *,
+ * PUBLIC:     int (*)(DB *, const DBT *, const DBT *), int *));
+ */
+int
+__db_coff(dbc, dbt, match, cmpfunc, cmpp)
+	DBC *dbc;
+	const DBT *dbt, *match;
+	int (*cmpfunc) __P((DB *, const DBT *, const DBT *)), *cmpp;
+{
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_MPOOLFILE *mpf;
+	DB_TXN *txn;
+	DBT local_key, local_match;
+	PAGE *dbt_pagep, *match_pagep;
+	db_pgno_t dbt_pgno, match_pgno;
+	u_int32_t cmp_bytes, dbt_bufsz, dbt_len, match_bufsz;
+	u_int32_t match_len, max_data, page_space;
+	u_int8_t *p1, *p2;
+	int ret;
+	void *dbt_buf, *match_buf;
+
+	dbp = dbc->dbp;
+	ip = dbc->thread_info;
+	txn = dbc->txn;
+	mpf = dbp->mpf;
+	page_space = P_MAXSPACE(dbp, dbp->pgsize);
+	*cmpp = 0;
+	dbt_buf = match_buf = NULL;
+
+	DB_ASSERT(dbp->env, HPAGE_PTYPE(dbt->data) == H_OFFPAGE);
+	DB_ASSERT(dbp->env, HPAGE_PTYPE(match->data) == H_OFFPAGE);
+
+	/* Extract potentially unaligned length and pgno fields from DBTs */
+	memcpy(&dbt_len, HOFFPAGE_TLEN(dbt->data), sizeof(u_int32_t));
+	memcpy(&dbt_pgno, HOFFPAGE_PGNO(dbt->data), sizeof(db_pgno_t));
+	memcpy(&match_len, HOFFPAGE_TLEN(match->data), sizeof(u_int32_t));
+	memcpy(&match_pgno, HOFFPAGE_PGNO(match->data), sizeof(db_pgno_t));
+	max_data = (dbt_len < match_len ? dbt_len : match_len);
+
+	/*
+	 * If there is a custom comparator, fully resolve both DBTs.
+	 * Then call the users comparator.
+	 */
+	if (cmpfunc != NULL) {
+		memset(&local_key, 0, sizeof(local_key));
+		memset(&local_match, 0, sizeof(local_match));
+		dbt_buf = match_buf = NULL;
+		dbt_bufsz = match_bufsz = 0;
+
+		if ((ret = __db_goff(dbc, &local_key, dbt_len,
+		    dbt_pgno, &dbt_buf, &dbt_bufsz)) != 0)
+			goto err1;
+		if ((ret = __db_goff(dbc, &local_match, match_len,
+		    match_pgno, &match_buf, &match_bufsz)) != 0)
+			goto err1;
+		/* The key needs to be the first argument for sort order */
+		*cmpp = cmpfunc(dbp, &local_key, &local_match);
+
+err1:		if (dbt_buf != NULL)
+			__os_free(dbp->env, dbt_buf);
+		if (match_buf != NULL)
+			__os_free(dbp->env, match_buf);
+		return (ret);
+	}
+
+	/* Match the offpage DBTs a page at a time. */
+	while (dbt_pgno != PGNO_INVALID && match_pgno != PGNO_INVALID) {
+		if ((ret =
+		    __memp_fget(mpf, &dbt_pgno, ip, txn, 0, &dbt_pagep)) != 0)
+			return (ret);
+		if ((ret =
+		    __memp_fget(mpf, &match_pgno,
+			ip, txn, 0, &match_pagep)) != 0) {
+			(void)__memp_fput(
+			    mpf, ip, dbt_pagep, DB_PRIORITY_UNCHANGED);
+			return (ret);
+		}
+		cmp_bytes = page_space < max_data ? page_space : max_data;
+		for (p1 = (u_int8_t *)dbt_pagep + P_OVERHEAD(dbp),
+		    p2 = (u_int8_t *)match_pagep + P_OVERHEAD(dbp);
+		    cmp_bytes-- > 0; ++p1, ++p2)
+				if (*p1 != *p2) {
+					*cmpp = (long)*p1 - (long)*p2;
+					break;
+				}
+
+		dbt_pgno = NEXT_PGNO(dbt_pagep);
+		match_pgno = NEXT_PGNO(match_pagep);
+		max_data -= page_space;
+		if ((ret = __memp_fput(mpf,
+		     ip, dbt_pagep, DB_PRIORITY_UNCHANGED)) != 0) {
+			(void)__memp_fput(mpf,
+			    ip, match_pagep, DB_PRIORITY_UNCHANGED);
+			return (ret);
+		}
+		if ((ret = __memp_fput(mpf,
+		    ip, match_pagep, DB_PRIORITY_UNCHANGED)) != 0)
+			return (ret);
+		if (*cmpp != 0)
+			return (0);
+	}
+
+	/* If a lexicographic mismatch was found, then the result has already
+	 * been returned. If the DBTs matched, consider the lengths of the
+	 * items, and return appropriately.
+	 */
+	if (dbt_len > match_len) /* DBT is longer than the match key. */
+		*cmpp = 1;
+	else if (match_len > dbt_len) /* DBT is shorter than the match key. */
+		*cmpp = -1;
+	else
+		*cmpp = 0;
+
+	return (0);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_ovfl_vrfy.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,432 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/db_verify.h"
+#include "dbinc/mp.h"
+
+/*
+ * __db_vrfy_overflow --
+ *	Verify overflow page.
+ *
+ * PUBLIC: int __db_vrfy_overflow __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t,
+ * PUBLIC:     u_int32_t));
+ */
+int
+__db_vrfy_overflow(dbp, vdp, h, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	VRFY_PAGEINFO *pip;
+	int isbad, ret, t_ret;
+
+	isbad = 0;
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+
+	if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) {
+		if (ret == DB_VERIFY_BAD)
+			isbad = 1;
+		else
+			goto err;
+	}
+
+	pip->refcount = OV_REF(h);
+	if (pip->refcount < 1) {
+		EPRINT((dbp->env, DB_STR_A("0676",
+		    "Page %lu: overflow page has zero reference count", "%lu"),
+		    (u_long)pgno));
+		isbad = 1;
+	}
+
+	/* Just store for now. */
+	pip->olen = HOFFSET(h);
+
+err:	if ((t_ret = __db_vrfy_putpageinfo(dbp->env, vdp, pip)) != 0)
+		ret = t_ret;
+	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __db_vrfy_ovfl_structure --
+ *	Walk a list of overflow pages, avoiding cycles and marking
+ *	pages seen.
+ *
+ * PUBLIC: int __db_vrfy_ovfl_structure
+ * PUBLIC:     __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, u_int32_t));
+ */
+int
+__db_vrfy_ovfl_structure(dbp, vdp, pgno, tlen, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	u_int32_t tlen;
+	u_int32_t flags;
+{
+	DB *pgset;
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	db_pgno_t next, prev;
+	int isbad, ret, seen_cnt, t_ret;
+	u_int32_t refcount;
+
+	env = dbp->env;
+	pgset = vdp->pgset;
+	DB_ASSERT(env, pgset != NULL);
+	isbad = 0;
+
+	/* This shouldn't happen, but just to be sure. */
+	if (!IS_VALID_PGNO(pgno))
+		return (DB_VERIFY_BAD);
+
+	/*
+	 * Check the first prev_pgno;  it ought to be PGNO_INVALID,
+	 * since there's no prev page.
+	 */
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+
+	/* The refcount is stored on the first overflow page. */
+	refcount = pip->refcount;
+
+	if (pip->type != P_OVERFLOW) {
+		EPRINT((env, DB_STR_A("0677",
+		    "Page %lu: overflow page of invalid type %lu", "%lu %lu"),
+		    (u_long)pgno, (u_long)pip->type));
+		ret = DB_VERIFY_BAD;
+		goto err;		/* Unsafe to continue. */
+	}
+
+	prev = pip->prev_pgno;
+	if (prev != PGNO_INVALID) {
+		EPRINT((env, DB_STR_A("0678",
+	    "Page %lu: first page in overflow chain has a prev_pgno %lu",
+		    "%lu %lu"), (u_long)pgno, (u_long)prev));
+		isbad = 1;
+	}
+
+	for (;;) {
+		/*
+		 * We may have seen this page elsewhere, if the overflow entry
+		 * has been promoted to an internal page;  we just want to
+		 * make sure that each overflow page is seen exactly as many
+		 * times as its refcount dictates.
+		 *
+		 * Note that this code also serves to keep us from looping
+		 * infinitely if there's a cycle in an overflow chain.
+		 */
+		if ((ret = __db_vrfy_pgset_get(pgset,
+		    vdp->thread_info, vdp->txn, pgno, &seen_cnt)) != 0)
+			goto err;
+		if ((u_int32_t)seen_cnt > refcount) {
+			EPRINT((env, DB_STR_A("0679",
+		"Page %lu: encountered too many times in overflow traversal",
+			    "%lu"), (u_long)pgno));
+			ret = DB_VERIFY_BAD;
+			goto err;
+		}
+		if ((ret = __db_vrfy_pgset_inc(
+		    pgset, vdp->thread_info, vdp->txn, pgno)) != 0)
+			goto err;
+
+		/*
+		 * Each overflow page can be referenced multiple times,
+		 * because it's possible for overflow Btree keys to get
+		 * promoted to internal pages.  We want to make sure that
+		 * each page is referenced from a Btree leaf (or Hash data
+		 * page, which we consider a "leaf" here) exactly once; if
+		 * the parent was a leaf, set a flag to indicate that we've
+		 * seen this page in a leaf context.
+		 *
+		 * If the parent is not a leaf--in which case it's a Btree
+		 * internal page--we don't need to bother doing any further
+		 * verification, as we'll do it when we hit the leaf (or
+		 * complain that we never saw the leaf).  Only the first
+		 * page in an overflow chain should ever have a refcount
+		 * greater than 1, and the combination of the LEAFSEEN check
+		 * and the fact that we bail after the first page for
+		 * non-leaves should ensure this.
+		 *
+		 * Note that each "child" of a page, such as an overflow page,
+		 * is stored and verified in a structure check exactly once,
+		 * so this code does not need to contend with the fact that
+		 * overflow chains used as Btree duplicate keys may be
+		 * referenced multiply from a single Btree leaf page.
+		 */
+		if (LF_ISSET(DB_ST_OVFL_LEAF)) {
+			if (F_ISSET(pip, VRFY_OVFL_LEAFSEEN)) {
+				EPRINT((env, DB_STR_A("0680",
+		"Page %lu: overflow page linked twice from leaf or data page",
+				    "%lu"), (u_long)pgno));
+				ret = DB_VERIFY_BAD;
+				goto err;
+			}
+			F_SET(pip, VRFY_OVFL_LEAFSEEN);
+		}
+
+		/*
+		 * We want to verify each overflow chain only once, and
+		 * although no chain should be linked more than once from a
+		 * leaf page, we can't guarantee that it'll be linked that
+		 * once if it's linked from an internal page and the key
+		 * is gone.
+		 *
+		 * seen_cnt is the number of times we'd encountered this page
+		 * before calling this function.
+		 */
+		if (seen_cnt == 0) {
+			/*
+			 * Keep a running tab on how much of the item we've
+			 * seen.
+			 */
+			tlen -= pip->olen;
+
+			/* Send the application feedback about our progress. */
+			if (!LF_ISSET(DB_SALVAGE))
+				__db_vrfy_struct_feedback(dbp, vdp);
+		} else
+			goto done;
+
+		next = pip->next_pgno;
+
+		/* Are we there yet? */
+		if (next == PGNO_INVALID)
+			break;
+
+		/*
+		 * We've already checked this when we saved it, but just
+		 * to be sure...
+		 */
+		if (!IS_VALID_PGNO(next)) {
+			EPRINT((env, DB_STR_A("0681",
+			    "Page %lu: bad next_pgno %lu on overflow page",
+			    "%lu %lu"), (u_long)pgno, (u_long)next));
+			ret = DB_VERIFY_BAD;
+			goto err;
+		}
+
+		if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 ||
+		    (ret = __db_vrfy_getpageinfo(vdp, next, &pip)) != 0)
+			return (ret);
+		if (pip->prev_pgno != pgno) {
+			EPRINT((env, DB_STR_A("0682",
+		"Page %lu: bad prev_pgno %lu on overflow page (should be %lu)",
+			    "%lu %lu %lu"), (u_long)next,
+			    (u_long)pip->prev_pgno, (u_long)pgno));
+			isbad = 1;
+			/*
+			 * It's safe to continue because we have separate
+			 * cycle detection.
+			 */
+		}
+
+		pgno = next;
+	}
+
+	if (tlen > 0) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0683",
+		    "Page %lu: overflow item incomplete", "%lu"),
+		    (u_long)pgno));
+	}
+
+done:
+err:	if ((t_ret =
+	    __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __db_safe_goff --
+ *	Get an overflow item, very carefully, from an untrusted database,
+ *	in the context of the salvager.
+ *
+ * PUBLIC: int __db_safe_goff __P((DB *, VRFY_DBINFO *,
+ * PUBLIC:      db_pgno_t, DBT *, void *, u_int32_t *, u_int32_t));
+ */
+int
+__db_safe_goff(dbp, vdp, pgno, dbt, buf, bufsz, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	DBT *dbt;
+	void *buf;
+	u_int32_t *bufsz;
+	u_int32_t flags;
+{
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	int ret, t_ret;
+	u_int32_t bytesgot, bytes;
+	u_int8_t *src, *dest;
+
+	mpf = dbp->mpf;
+	h = NULL;
+	ret = t_ret = 0;
+	bytesgot = bytes = 0;
+
+    DB_ASSERT(dbp->env, bufsz != NULL);
+
+	/*
+	 * Back up to the start of the overflow chain (if necessary) via the
+	 * prev pointer of the overflow page.  This guarantees we transverse the
+	 * longest possible chains of overflow pages and won't be called again
+	 * with a pgno earlier in the chain, stepping on ourselves.
+	 */
+	for (;;) {
+		if ((ret = __memp_fget(
+		    mpf, &pgno, vdp->thread_info, NULL, 0, &h)) != 0)
+			return (ret);
+
+		if (PREV_PGNO(h) == PGNO_INVALID ||
+		    !IS_VALID_PGNO(PREV_PGNO(h)))
+			break;
+
+		pgno = PREV_PGNO(h);
+
+		if ((ret = __memp_fput(mpf,
+		    vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0)
+			return (ret);
+	}
+	if ((ret = __memp_fput(
+	    mpf, vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0)
+		return (ret);
+
+	h = NULL;
+
+	while ((pgno != PGNO_INVALID) && (IS_VALID_PGNO(pgno))) {
+		/*
+		 * Mark that we're looking at this page;  if we've seen it
+		 * already, quit.
+		 */
+		if ((ret = __db_salvage_markdone(vdp, pgno)) != 0)
+			break;
+
+		if ((ret = __memp_fget(mpf, &pgno,
+		    vdp->thread_info, NULL, 0, &h)) != 0)
+			break;
+
+		/*
+		 * Make sure it's really an overflow page, unless we're
+		 * being aggressive, in which case we pretend it is.
+		 */
+		if (!LF_ISSET(DB_AGGRESSIVE) && TYPE(h) != P_OVERFLOW) {
+			ret = DB_VERIFY_BAD;
+			break;
+		}
+
+		src = (u_int8_t *)h + P_OVERHEAD(dbp);
+		bytes = OV_LEN(h);
+
+		if (bytes + P_OVERHEAD(dbp) > dbp->pgsize)
+			bytes = dbp->pgsize - P_OVERHEAD(dbp);
+
+		/*
+		 * Realloc if buf is too small
+		 */
+		if (bytesgot + bytes > *bufsz) {
+			if ((ret =
+			    __os_realloc(dbp->env, bytesgot + bytes, buf)) != 0)
+				break;
+			*bufsz = bytesgot + bytes;
+		}
+
+		dest = *(u_int8_t **)buf + bytesgot;
+		bytesgot += bytes;
+
+		memcpy(dest, src, bytes);
+
+		pgno = NEXT_PGNO(h);
+
+		if ((ret = __memp_fput(mpf,
+		     vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0)
+			break;
+		h = NULL;
+	}
+
+	/*
+	 * If we're being aggressive, salvage a partial datum if there
+	 * was an error somewhere along the way.
+	 */
+	if (ret == 0 || LF_ISSET(DB_AGGRESSIVE)) {
+		dbt->size = bytesgot;
+		dbt->data = *(void **)buf;
+	}
+
+	/* If we broke out on error, don't leave pages pinned. */
+	if (h != NULL && (t_ret = __memp_fput(mpf,
+	    vdp->thread_info, h, DB_PRIORITY_UNCHANGED)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_pr.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1978 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+#include "dbinc/qam.h"
+#include "dbinc/db_verify.h"
+
+static int	 __db_bmeta __P((ENV *, DB *, BTMETA *, u_int32_t));
+static int	 __db_heapmeta __P((ENV *, DB *, HEAPMETA *, u_int32_t));
+static int	 __db_heapint __P((DB *, HEAPPG *, u_int32_t));
+static int	 __db_hmeta __P((ENV *, DB *, HMETA *, u_int32_t));
+static void	 __db_meta __P((ENV *, DB *, DBMETA *, FN const *, u_int32_t));
+static void	 __db_proff __P((ENV *, DB_MSGBUF *, void *));
+static int	 __db_qmeta __P((ENV *, DB *, QMETA *, u_int32_t));
+#ifdef HAVE_STATISTICS
+static void	 __db_prdb __P((DB *, u_int32_t));
+static int	 __db_prtree __P((DB *, DB_TXN *,
+		    u_int32_t, db_pgno_t, db_pgno_t));
+#endif
+
+/*
+ * __db_loadme --
+ *	A nice place to put a breakpoint.
+ *
+ * PUBLIC: void __db_loadme __P((void));
+ */
+void
+__db_loadme()
+{
+	pid_t pid;
+
+	__os_id(NULL, &pid, NULL);
+}
+
+#ifdef HAVE_STATISTICS
+/*
+ * __db_dumptree --
+ *	Dump the tree to a file.
+ *
+ * PUBLIC: int __db_dumptree __P((DB *, DB_TXN *,
+ * PUBLIC:     char *, char *, db_pgno_t, db_pgno_t));
+ */
+int
+__db_dumptree(dbp, txn, op, name, first, last)
+	DB *dbp;
+	DB_TXN *txn;
+	char *op, *name;
+	db_pgno_t first, last;
+{
+	ENV *env;
+	FILE *fp, *orig_fp;
+	u_int32_t flags;
+	int ret;
+
+	env = dbp->env;
+
+	for (flags = 0; *op != '\0'; ++op)
+		switch (*op) {
+		case 'a':
+			LF_SET(DB_PR_PAGE);
+			break;
+		case 'h':
+			break;
+		case 'r':
+			LF_SET(DB_PR_RECOVERYTEST);
+			break;
+		default:
+			return (EINVAL);
+		}
+
+	if (name != NULL) {
+		if ((fp = fopen(name, "w")) == NULL)
+			return (__os_get_errno());
+
+		orig_fp = dbp->dbenv->db_msgfile;
+		dbp->dbenv->db_msgfile = fp;
+	} else
+		fp = orig_fp = NULL;
+
+	__db_prdb(dbp, flags);
+
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+
+	ret = __db_prtree(dbp, txn, flags, first, last);
+
+	if (fp != NULL) {
+		(void)fclose(fp);
+		env->dbenv->db_msgfile = orig_fp;
+	}
+
+	return (ret);
+}
+
+static const FN __db_flags_fn[] = {
+	{ DB_AM_CHKSUM,			"checksumming" },
+	{ DB_AM_COMPENSATE,		"created by compensating transaction" },
+	{ DB_AM_CREATED,		"database created" },
+	{ DB_AM_CREATED_MSTR,		"encompassing file created" },
+	{ DB_AM_DBM_ERROR,		"dbm/ndbm error" },
+	{ DB_AM_DELIMITER,		"variable length" },
+	{ DB_AM_DISCARD,		"discard cached pages" },
+	{ DB_AM_DUP,			"duplicates" },
+	{ DB_AM_DUPSORT,		"sorted duplicates" },
+	{ DB_AM_ENCRYPT,		"encrypted" },
+	{ DB_AM_FIXEDLEN,		"fixed-length records" },
+	{ DB_AM_INMEM,			"in-memory" },
+	{ DB_AM_IN_RENAME,		"file is being renamed" },
+	{ DB_AM_NOT_DURABLE,		"changes not logged" },
+	{ DB_AM_OPEN_CALLED,		"open called" },
+	{ DB_AM_PAD,			"pad value" },
+	{ DB_AM_PGDEF,			"default page size" },
+	{ DB_AM_RDONLY,			"read-only" },
+	{ DB_AM_READ_UNCOMMITTED,	"read-uncommitted" },
+	{ DB_AM_RECNUM,			"Btree record numbers" },
+	{ DB_AM_RECOVER,		"opened for recovery" },
+	{ DB_AM_RENUMBER,		"renumber" },
+	{ DB_AM_REVSPLITOFF,		"no reverse splits" },
+	{ DB_AM_SECONDARY,		"secondary" },
+	{ DB_AM_SNAPSHOT,		"load on open" },
+	{ DB_AM_SUBDB,			"subdatabases" },
+	{ DB_AM_SWAP,			"needswap" },
+	{ DB_AM_TXN,			"transactional" },
+	{ DB_AM_VERIFYING,		"verifier" },
+	{ 0,				NULL }
+};
+
+/*
+ * __db_get_flags_fn --
+ *	Return the __db_flags_fn array.
+ *
+ * PUBLIC: const FN * __db_get_flags_fn __P((void));
+ */
+const FN *
+__db_get_flags_fn()
+{
+	return (__db_flags_fn);
+}
+
+/*
+ * __db_prdb --
+ *	Print out the DB structure information.
+ */
+static void
+__db_prdb(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	BTREE *bt;
+	DB_MSGBUF mb;
+	ENV *env;
+	HASH *h;
+	QUEUE *q;
+	HEAP *hp;
+
+	env = dbp->env;
+
+	DB_MSGBUF_INIT(&mb);
+	__db_msg(env, "In-memory DB structure:");
+	__db_msgadd(env, &mb, "%s: %#lx",
+	    __db_dbtype_to_string(dbp->type), (u_long)dbp->flags);
+	__db_prflags(env, &mb, dbp->flags, __db_flags_fn, " (", ")");
+	DB_MSGBUF_FLUSH(env, &mb);
+
+	switch (dbp->type) {
+	case DB_BTREE:
+	case DB_RECNO:
+		bt = dbp->bt_internal;
+		__db_msg(env, "bt_meta: %lu bt_root: %lu",
+		    (u_long)bt->bt_meta, (u_long)bt->bt_root);
+		__db_msg(env, "bt_minkey: %lu", (u_long)bt->bt_minkey);
+		if (!LF_ISSET(DB_PR_RECOVERYTEST))
+			__db_msg(env, "bt_compare: %#lx bt_prefix: %#lx",
+			    P_TO_ULONG(bt->bt_compare),
+			    P_TO_ULONG(bt->bt_prefix));
+#ifdef HAVE_COMPRESSION
+		if (!LF_ISSET(DB_PR_RECOVERYTEST))
+			__db_msg(env, "bt_compress: %#lx bt_decompress: %#lx",
+			    P_TO_ULONG(bt->bt_compress),
+			    P_TO_ULONG(bt->bt_decompress));
+#endif
+		__db_msg(env, "bt_lpgno: %lu", (u_long)bt->bt_lpgno);
+		if (dbp->type == DB_RECNO) {
+			__db_msg(env,
+		    "re_pad: %#lx re_delim: %#lx re_len: %lu re_source: %s",
+			    (u_long)bt->re_pad, (u_long)bt->re_delim,
+			    (u_long)bt->re_len,
+			    bt->re_source == NULL ? "" : bt->re_source);
+			__db_msg(env,
+			    "re_modified: %d re_eof: %d re_last: %lu",
+			    bt->re_modified, bt->re_eof, (u_long)bt->re_last);
+		}
+		break;
+	case DB_HASH:
+		h = dbp->h_internal;
+		__db_msg(env, "meta_pgno: %lu", (u_long)h->meta_pgno);
+		__db_msg(env, "h_ffactor: %lu", (u_long)h->h_ffactor);
+		__db_msg(env, "h_nelem: %lu", (u_long)h->h_nelem);
+		if (!LF_ISSET(DB_PR_RECOVERYTEST))
+			__db_msg(env, "h_hash: %#lx", P_TO_ULONG(h->h_hash));
+		break;
+	case DB_QUEUE:
+		q = dbp->q_internal;
+		__db_msg(env, "q_meta: %lu", (u_long)q->q_meta);
+		__db_msg(env, "q_root: %lu", (u_long)q->q_root);
+		__db_msg(env, "re_pad: %#lx re_len: %lu",
+		    (u_long)q->re_pad, (u_long)q->re_len);
+		__db_msg(env, "rec_page: %lu", (u_long)q->rec_page);
+		__db_msg(env, "page_ext: %lu", (u_long)q->page_ext);
+		break;
+	case DB_HEAP:
+		hp = dbp->heap_internal;
+		__db_msg(env, "gbytes: %lu", (u_long)hp->gbytes);
+		__db_msg(env, "bytes: %lu", (u_long)hp->bytes);
+		__db_msg(env, "curregion: %lu", (u_long)hp->curregion);
+		__db_msg(env, "region_size: %lu", (u_long)hp->region_size);
+		__db_msg(env, "maxpgno: %lu", (u_long)hp->maxpgno);
+		break;
+	case DB_UNKNOWN:
+	default:
+		break;
+	}
+}
+
+/*
+ * __db_prtree --
+ *	Print out the entire tree.
+ */
+static int
+__db_prtree(dbp, txn, flags, first, last)
+	DB *dbp;
+	DB_TXN *txn;
+	u_int32_t flags;
+	db_pgno_t first, last;
+{
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	db_pgno_t i;
+	int ret;
+
+	mpf = dbp->mpf;
+
+	if (dbp->type == DB_QUEUE)
+		return (__db_prqueue(dbp, flags));
+
+	/*
+	 * Find out the page number of the last page in the database, then
+	 * dump each page.
+	 */
+	if (last == PGNO_INVALID &&
+	    (ret = __memp_get_last_pgno(mpf, &last)) != 0)
+		return (ret);
+	for (i = first; i <= last; ++i) {
+		if ((ret = __memp_fget(mpf, &i, NULL, txn, 0, &h)) != 0)
+			return (ret);
+		(void)__db_prpage(dbp, h, flags);
+		if ((ret = __memp_fput(mpf, NULL, h, dbp->priority)) != 0)
+			return (ret);
+	}
+
+	return (0);
+}
+
+/*
+ * __db_prnpage
+ *	-- Print out a specific page.
+ *
+ * PUBLIC: int __db_prnpage __P((DB *, DB_TXN *, db_pgno_t));
+ */
+int
+__db_prnpage(dbp, txn, pgno)
+	DB *dbp;
+	DB_TXN *txn;
+	db_pgno_t pgno;
+{
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	int ret, t_ret;
+
+	mpf = dbp->mpf;
+
+	if ((ret = __memp_fget(mpf, &pgno, NULL, txn, 0, &h)) != 0)
+		return (ret);
+
+	ret = __db_prpage(dbp, h, DB_PR_PAGE);
+
+	if ((t_ret = __memp_fput(mpf, NULL, h, dbp->priority)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __db_prpage
+ *	-- Print out a page.
+ *
+ * PUBLIC: int __db_prpage __P((DB *, PAGE *, u_int32_t));
+ */
+int
+__db_prpage(dbp, h, flags)
+	DB *dbp;
+	PAGE *h;
+	u_int32_t flags;
+{
+	DB_MSGBUF mb;
+	u_int32_t pagesize;
+	/*
+	 * !!!
+	 * Find out the page size.  We don't want to do it the "right" way,
+	 * by reading the value from the meta-data page, that's going to be
+	 * slow.  Reach down into the mpool region.
+	 */
+	pagesize = (u_int32_t)dbp->mpf->mfp->pagesize;
+	DB_MSGBUF_INIT(&mb);
+	return (__db_prpage_int(dbp->env,
+	    &mb, dbp, "", h, pagesize, NULL, flags));
+}
+
+/*
+ * __db_lockmode_to_string --
+ *	Return the name of the lock mode.
+ *
+ * PUBLIC: const char * __db_lockmode_to_string __P((db_lockmode_t));
+ */
+const char *
+__db_lockmode_to_string(mode)
+	db_lockmode_t mode;
+{
+	switch (mode) {
+	case DB_LOCK_NG:
+		return ("Not granted");
+	case DB_LOCK_READ:
+		return ("Shared/read");
+	case DB_LOCK_WRITE:
+		return ("Exclusive/write");
+	case DB_LOCK_WAIT:
+		return ("Wait for event");
+	case DB_LOCK_IWRITE:
+		return ("Intent exclusive/write");
+	case DB_LOCK_IREAD:
+		return ("Intent shared/read");
+	case DB_LOCK_IWR:
+		return ("Intent to read/write");
+	case DB_LOCK_READ_UNCOMMITTED:
+		return ("Read uncommitted");
+	case DB_LOCK_WWRITE:
+		return ("Was written");
+	default:
+		break;
+	}
+	return ("UNKNOWN LOCK MODE");
+}
+
+#else /* !HAVE_STATISTICS */
+
+/*
+ * __db_dumptree --
+ *	Dump the tree to a file.
+ *
+ * PUBLIC: int __db_dumptree __P((DB *, DB_TXN *,
+ * PUBLIC:     char *, char *, db_pgno_t, db_pgno_t));
+ */
+int
+__db_dumptree(dbp, txn, op, name, first, last)
+	DB *dbp;
+	DB_TXN *txn;
+	char *op, *name;
+	db_pgno_t first, last;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(op, NULL);
+	COMPQUIET(name, NULL);
+	COMPQUIET(first, last);
+
+	return (__db_stat_not_built(dbp->env));
+}
+
+/*
+ * __db_get_flags_fn --
+ *	Return the __db_flags_fn array.
+ *
+ * PUBLIC: const FN * __db_get_flags_fn __P((void));
+ */
+const FN *
+__db_get_flags_fn()
+{
+	/*
+	 * !!!
+	 * The Tcl API uses this interface, stub it off.
+	 */
+	return (NULL);
+}
+#endif
+
+/*
+ * __db_meta --
+ *	Print out common metadata information.
+ */
+static void
+__db_meta(env, dbp, dbmeta, fn, flags)
+	DB *dbp;
+	ENV *env;
+	DBMETA *dbmeta;
+	FN const *fn;
+	u_int32_t flags;
+{
+	DB_MPOOLFILE *mpf;
+	DB_MSGBUF mb;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int8_t *p;
+	int cnt, ret;
+	const char *sep;
+
+	DB_MSGBUF_INIT(&mb);
+
+	__db_msg(env, "\tmagic: %#lx", (u_long)dbmeta->magic);
+	__db_msg(env, "\tversion: %lu", (u_long)dbmeta->version);
+	__db_msg(env, "\tpagesize: %lu", (u_long)dbmeta->pagesize);
+	__db_msg(env, "\ttype: %lu", (u_long)dbmeta->type);
+	__db_msg(env, "\tmetaflags %#lx", (u_long)dbmeta->metaflags);
+	__db_msg(env, "\tkeys: %lu\trecords: %lu",
+	    (u_long)dbmeta->key_count, (u_long)dbmeta->record_count);
+	if (dbmeta->nparts)
+		__db_msg(env, "\tnparts: %lu", (u_long)dbmeta->nparts);
+
+	/*
+	 * If we're doing recovery testing, don't display the free list,
+	 * it may have changed and that makes the dump diff not work.
+	 */
+	if (dbp != NULL && !LF_ISSET(DB_PR_RECOVERYTEST)) {
+		mpf = dbp->mpf;
+		__db_msgadd(
+		    env, &mb, "\tfree list: %lu", (u_long)dbmeta->free);
+		for (pgno = dbmeta->free,
+		    cnt = 0, sep = ", "; pgno != PGNO_INVALID;) {
+			if ((ret = __memp_fget(mpf,
+			     &pgno, NULL, NULL, 0, &h)) != 0) {
+				DB_MSGBUF_FLUSH(env, &mb);
+				__db_msg(env,
+			    "Unable to retrieve free-list page: %lu: %s",
+				    (u_long)pgno, db_strerror(ret));
+				break;
+			}
+			pgno = h->next_pgno;
+			(void)__memp_fput(mpf, NULL, h, dbp->priority);
+			__db_msgadd(env, &mb, "%s%lu", sep, (u_long)pgno);
+			if (++cnt % 10 == 0) {
+				DB_MSGBUF_FLUSH(env, &mb);
+				cnt = 0;
+				sep = "\t";
+			} else
+				sep = ", ";
+		}
+		DB_MSGBUF_FLUSH(env, &mb);
+		__db_msg(env, "\tlast_pgno: %lu", (u_long)dbmeta->last_pgno);
+	}
+
+	if (fn != NULL) {
+		DB_MSGBUF_FLUSH(env, &mb);
+		__db_msgadd(env, &mb, "\tflags: %#lx", (u_long)dbmeta->flags);
+		__db_prflags(env, &mb, dbmeta->flags, fn, " (", ")");
+	}
+
+	DB_MSGBUF_FLUSH(env, &mb);
+	__db_msgadd(env, &mb, "\tuid: ");
+	for (p = (u_int8_t *)dbmeta->uid,
+	    cnt = 0; cnt < DB_FILE_ID_LEN; ++cnt) {
+		__db_msgadd(env, &mb, "%x", *p++);
+		if (cnt < DB_FILE_ID_LEN - 1)
+			__db_msgadd(env, &mb, " ");
+	}
+	DB_MSGBUF_FLUSH(env, &mb);
+}
+
+/*
+ * __db_bmeta --
+ *	Print out the btree meta-data page.
+ */
+static int
+__db_bmeta(env, dbp, h, flags)
+	ENV *env;
+	DB *dbp;
+	BTMETA *h;
+	u_int32_t flags;
+{
+	static const FN fn[] = {
+		{ BTM_DUP,	"duplicates" },
+		{ BTM_RECNO,	"recno" },
+		{ BTM_RECNUM,	"btree:recnum" },
+		{ BTM_FIXEDLEN,	"recno:fixed-length" },
+		{ BTM_RENUMBER,	"recno:renumber" },
+		{ BTM_SUBDB,	"multiple-databases" },
+		{ BTM_DUPSORT,	"sorted duplicates" },
+		{ BTM_COMPRESS,	"compressed" },
+		{ 0,		NULL }
+	};
+
+	__db_meta(env, dbp, (DBMETA *)h, fn, flags);
+
+	__db_msg(env, "\tminkey: %lu", (u_long)h->minkey);
+	if (F_ISSET(&h->dbmeta, BTM_RECNO))
+		__db_msg(env, "\tre_len: %#lx re_pad: %#lx",
+		    (u_long)h->re_len, (u_long)h->re_pad);
+	__db_msg(env, "\troot: %lu", (u_long)h->root);
+
+	return (0);
+}
+
+/*
+ * __db_hmeta --
+ *	Print out the hash meta-data page.
+ */
+static int
+__db_hmeta(env, dbp, h, flags)
+	ENV *env;
+	DB *dbp;
+	HMETA *h;
+	u_int32_t flags;
+{
+	static const FN fn[] = {
+		{ DB_HASH_DUP,		"duplicates" },
+		{ DB_HASH_SUBDB,	"multiple-databases" },
+		{ DB_HASH_DUPSORT,	"sorted duplicates" },
+		{ 0,			NULL }
+	};
+	DB_MSGBUF mb;
+	int i;
+
+	DB_MSGBUF_INIT(&mb);
+
+	__db_meta(env, dbp, (DBMETA *)h, fn, flags);
+
+	__db_msg(env, "\tmax_bucket: %lu", (u_long)h->max_bucket);
+	__db_msg(env, "\thigh_mask: %#lx", (u_long)h->high_mask);
+	__db_msg(env, "\tlow_mask:  %#lx", (u_long)h->low_mask);
+	__db_msg(env, "\tffactor: %lu", (u_long)h->ffactor);
+	__db_msg(env, "\tnelem: %lu", (u_long)h->nelem);
+	__db_msg(env, "\th_charkey: %#lx", (u_long)h->h_charkey);
+	__db_msgadd(env, &mb, "\tspare points:\n\t");
+	for (i = 0; i < NCACHED; i++) {
+		__db_msgadd(env, &mb, "%lu (%lu) ", (u_long)h->spares[i],
+		    (u_long)(h->spares[i] == 0 ?
+		    0 : h->spares[i] + (i == 0 ? 0 : 1 << (i-1))));
+		if ((i + 1) % 8 == 0)
+			__db_msgadd(env, &mb, "\n\t");
+	}
+	DB_MSGBUF_FLUSH(env, &mb);
+
+	return (0);
+}
+
+/*
+ * __db_qmeta --
+ *	Print out the queue meta-data page.
+ */
+static int
+__db_qmeta(env, dbp, h, flags)
+	ENV *env;
+	DB *dbp;
+	QMETA *h;
+	u_int32_t flags;
+{
+
+	__db_meta(env, dbp, (DBMETA *)h, NULL, flags);
+
+	__db_msg(env, "\tfirst_recno: %lu", (u_long)h->first_recno);
+	__db_msg(env, "\tcur_recno: %lu", (u_long)h->cur_recno);
+	__db_msg(env, "\tre_len: %#lx re_pad: %lu",
+	    (u_long)h->re_len, (u_long)h->re_pad);
+	__db_msg(env, "\trec_page: %lu", (u_long)h->rec_page);
+	__db_msg(env, "\tpage_ext: %lu", (u_long)h->page_ext);
+
+	return (0);
+}
+
+/*
+ * __db_heapmeta --
+ *	Print out the heap meta-data page.
+ */
+static int
+__db_heapmeta(env, dbp, h, flags)
+	ENV *env;
+	DB *dbp;
+	HEAPMETA *h;
+	u_int32_t flags;
+{
+	__db_meta(env, dbp, (DBMETA *)h, NULL, flags);
+
+	__db_msg(env, "\tcurregion: %lu", (u_long)h->curregion);
+	__db_msg(env, "\tregion_size: %lu", (u_long)h->region_size);
+	__db_msg(env, "\tnregions: %lu", (u_long)h->nregions);
+	__db_msg(env, "\tgbytes: %lu", (u_long)h->gbytes);
+	__db_msg(env, "\tbytes: %lu", (u_long)h->bytes);
+
+	return (0);
+}
+
+/*
+ * __db_heapint --
+ *	Print out the heap internal-data page.
+ */
+static int
+__db_heapint(dbp, h, flags)
+	DB *dbp;
+	HEAPPG *h;
+	u_int32_t flags;
+{
+	DB_MSGBUF mb;
+	ENV *env;
+	int count, printed;
+	u_int32_t i, max;
+	u_int8_t avail;
+
+	env = dbp->env;
+	DB_MSGBUF_INIT(&mb);
+	count = printed = 0;
+	COMPQUIET(flags, 0);
+
+	__db_msgadd(env, &mb, "\thigh: %4lu\n", (u_long)h->high_pgno);
+	/* How many entries could there be on a page */
+	max = HEAP_REGION_SIZE(dbp);
+
+	for (i = 0; i < max; i++, count++) {
+		avail = HEAP_SPACE(dbp, h, i);
+		if (avail != 0) {
+			__db_msgadd(env, &mb,
+			    "%5lu:%1lu ", (u_long)i, (u_long)avail);
+			printed = 1;
+		}
+		/* We get 10 entries per line this way */
+		if (count == 9) {
+			DB_MSGBUF_FLUSH(env, &mb);
+			count = -1;
+		}
+	}
+	/* All pages were less than 33% full */
+	if (printed == 0)
+		 __db_msgadd(env, &mb,
+		    "All pages in this region less than 33 percent full");
+
+	DB_MSGBUF_FLUSH(env, &mb);
+	return (0);
+}
+
+/*
+ * For printing pages from the log we may be passed the data segment
+ * separate from the header, if so then it starts at HOFFSET.
+ */
+#define	PR_ENTRY(dbp, h, i, data)				\
+	(data == NULL ? P_ENTRY(dbp, h, i) :			\
+	    (u_int8_t *)data + P_INP(dbp, h)[i] - HOFFSET(h))
+/*
+ * __db_prpage_int
+ *	-- Print out a page.
+ *
+ * PUBLIC: int __db_prpage_int __P((ENV *, DB_MSGBUF *,
+ * PUBLIC:      DB *, char *, PAGE *, u_int32_t, u_int8_t *, u_int32_t));
+ */
+int
+__db_prpage_int(env, mbp, dbp, lead, h, pagesize, data, flags)
+	ENV *env;
+	DB_MSGBUF *mbp;
+	DB *dbp;
+	char *lead;
+	PAGE *h;
+	u_int32_t pagesize;
+	u_int8_t *data;
+	u_int32_t flags;
+{
+	BINTERNAL *bi;
+	BKEYDATA *bk;
+	HOFFPAGE a_hkd;
+	QAMDATA *qp, *qep;
+	RINTERNAL *ri;
+	HEAPHDR *hh;
+	HEAPSPLITHDR *hs;
+	db_indx_t dlen, len, i, *inp, max;
+	db_pgno_t pgno;
+	db_recno_t recno;
+	u_int32_t qlen;
+	u_int8_t *ep, *hk, *p;
+	int deleted, ret;
+	const char *s;
+	void *hdata, *sp;
+
+	/*
+	 * If we're doing recovery testing and this page is P_INVALID,
+	 * assume it's a page that's on the free list, and don't display it.
+	 */
+	if (LF_ISSET(DB_PR_RECOVERYTEST) && TYPE(h) == P_INVALID)
+		return (0);
+
+	if ((s = __db_pagetype_to_string(TYPE(h))) == NULL) {
+		__db_msg(env, "%sILLEGAL PAGE TYPE: page: %lu type: %lu",
+		    lead, (u_long)h->pgno, (u_long)TYPE(h));
+		return (EINVAL);
+	}
+
+	/* Page number, page type. */
+	__db_msgadd(env, mbp, "%spage %lu: %s:", lead, (u_long)h->pgno, s);
+
+	/*
+	 * LSNs on a metadata page will be different from the original after an
+	 * abort, in some cases.  Don't display them if we're testing recovery.
+	 */
+	if (!LF_ISSET(DB_PR_RECOVERYTEST) ||
+	    (TYPE(h) != P_BTREEMETA && TYPE(h) != P_HASHMETA &&
+	    TYPE(h) != P_QAMMETA && TYPE(h) != P_QAMDATA &&
+	    TYPE(h) != P_HEAPMETA))
+		__db_msgadd(env, mbp, " LSN [%lu][%lu]:",
+		    (u_long)LSN(h).file, (u_long)LSN(h).offset);
+
+	/*
+	 * Page level (only applicable for Btree/Recno, but we always display
+	 * it, for no particular reason, except for Heap.
+	 */
+	if (!HEAPTYPE(h))
+	    __db_msgadd(env, mbp, " level %lu", (u_long)h->level);
+
+	/* Record count. */
+	if (TYPE(h) == P_IBTREE || TYPE(h) == P_IRECNO ||
+	    (dbp != NULL && TYPE(h) == P_LRECNO &&
+	    h->pgno == ((BTREE *)dbp->bt_internal)->bt_root))
+		__db_msgadd(env, mbp, " records: %lu", (u_long)RE_NREC(h));
+	DB_MSGBUF_FLUSH(env, mbp);
+
+	switch (TYPE(h)) {
+	case P_BTREEMETA:
+		return (__db_bmeta(env, dbp, (BTMETA *)h, flags));
+	case P_HASHMETA:
+		return (__db_hmeta(env, dbp, (HMETA *)h, flags));
+	case P_QAMMETA:
+		return (__db_qmeta(env, dbp, (QMETA *)h, flags));
+	case P_QAMDATA:				/* Should be meta->start. */
+		if (!LF_ISSET(DB_PR_PAGE) || dbp == NULL)
+			return (0);
+
+		qlen = ((QUEUE *)dbp->q_internal)->re_len;
+		recno = (h->pgno - 1) * QAM_RECNO_PER_PAGE(dbp) + 1;
+		i = 0;
+		qep = (QAMDATA *)((u_int8_t *)h + pagesize - qlen);
+		for (qp = QAM_GET_RECORD(dbp, h, i); qp < qep;
+		    recno++, i++, qp = QAM_GET_RECORD(dbp, h, i)) {
+			if (!F_ISSET(qp, QAM_SET))
+				continue;
+
+			__db_msgadd(env, mbp, "%s",
+			    F_ISSET(qp, QAM_VALID) ? "\t" : "       D");
+			__db_msgadd(env, mbp, "[%03lu] %4lu ", (u_long)recno,
+			    (u_long)((u_int8_t *)qp - (u_int8_t *)h));
+			__db_prbytes(env, mbp, qp->data, qlen);
+		}
+		return (0);
+	case P_HEAPMETA:
+		return (__db_heapmeta(env, dbp, (HEAPMETA *)h, flags));
+	case P_IHEAP:
+		if (!LF_ISSET(DB_PR_PAGE) || dbp == NULL)
+			return (0);
+		return (__db_heapint(dbp, (HEAPPG *)h, flags));
+	default:
+		break;
+	}
+
+	s = "\t";
+	if (!HEAPTYPE(h) && TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO) {
+		__db_msgadd(env, mbp, "%sprev: %4lu next: %4lu",
+		    s, (u_long)PREV_PGNO(h), (u_long)NEXT_PGNO(h));
+		s = " ";
+	}
+
+	if (HEAPTYPE(h)) {
+		__db_msgadd(env, mbp, "%shigh indx: %4lu free indx: %4lu", s,
+		    (u_long)HEAP_HIGHINDX(h), (u_long)HEAP_FREEINDX(h));
+		s = " ";
+	}
+
+	if (TYPE(h) == P_OVERFLOW) {
+		__db_msgadd(env, mbp,
+		    "%sref cnt: %4lu ", s, (u_long)OV_REF(h));
+		if (dbp == NULL)
+			__db_msgadd(env, mbp,
+			    " len: %4lu ", (u_long)OV_LEN(h));
+		else
+			__db_prbytes(env,
+			    mbp, (u_int8_t *)h + P_OVERHEAD(dbp), OV_LEN(h));
+		return (0);
+	}
+	__db_msgadd(env, mbp, "%sentries: %4lu", s, (u_long)NUM_ENT(h));
+	__db_msgadd(env, mbp, " offset: %4lu", (u_long)HOFFSET(h));
+	DB_MSGBUF_FLUSH(env, mbp);
+
+	if (dbp == NULL || TYPE(h) == P_INVALID || !LF_ISSET(DB_PR_PAGE))
+		return (0);
+
+	if (data != NULL)
+		pagesize += HOFFSET(h);
+	else if (pagesize < HOFFSET(h))
+		return (0);
+
+	ret = 0;
+	inp = P_INP(dbp, h);
+	max = TYPE(h) == P_HEAP ? HEAP_HIGHINDX(h) + 1 : NUM_ENT(h);
+	for (i = 0; i < max; i++) {
+		if (TYPE(h) == P_HEAP && inp[i] == 0)
+			continue;
+		if ((uintptr_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) <
+		    (uintptr_t)(P_OVERHEAD(dbp)) ||
+		    (size_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) >= pagesize) {
+			__db_msg(env,
+			    "ILLEGAL PAGE OFFSET: indx: %lu of %lu",
+			    (u_long)i, (u_long)inp[i]);
+			ret = EINVAL;
+			continue;
+		}
+		deleted = 0;
+		switch (TYPE(h)) {
+		case P_HASH_UNSORTED:
+		case P_HASH:
+		case P_IBTREE:
+		case P_IRECNO:
+			sp = PR_ENTRY(dbp, h, i, data);
+			break;
+		case P_HEAP:
+			sp = P_ENTRY(dbp, h, i);
+			break;
+		case P_LBTREE:
+			sp = PR_ENTRY(dbp, h, i, data);
+			deleted = i % 2 == 0 &&
+			    B_DISSET(GET_BKEYDATA(dbp, h, i + O_INDX)->type);
+			break;
+		case P_LDUP:
+		case P_LRECNO:
+			sp = PR_ENTRY(dbp, h, i, data);
+			deleted = B_DISSET(GET_BKEYDATA(dbp, h, i)->type);
+			break;
+		default:
+			goto type_err;
+		}
+		__db_msgadd(env, mbp, "%s", deleted ? "       D" : "\t");
+		__db_msgadd(
+		    env, mbp, "[%03lu] %4lu ", (u_long)i, (u_long)inp[i]);
+		switch (TYPE(h)) {
+		case P_HASH_UNSORTED:
+		case P_HASH:
+			hk = sp;
+			switch (HPAGE_PTYPE(hk)) {
+			case H_OFFDUP:
+				memcpy(&pgno,
+				    HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
+				__db_msgadd(env, mbp,
+				    "%4lu [offpage dups]", (u_long)pgno);
+				DB_MSGBUF_FLUSH(env, mbp);
+				break;
+			case H_DUPLICATE:
+				/*
+				 * If this is the first item on a page, then
+				 * we cannot figure out how long it is, so
+				 * we only print the first one in the duplicate
+				 * set.
+				 */
+				if (i != 0)
+					len = LEN_HKEYDATA(dbp, h, 0, i);
+				else
+					len = 1;
+
+				__db_msgadd(env, mbp, "Duplicates:");
+				DB_MSGBUF_FLUSH(env, mbp);
+				for (p = HKEYDATA_DATA(hk),
+				    ep = p + len; p < ep;) {
+					memcpy(&dlen, p, sizeof(db_indx_t));
+					p += sizeof(db_indx_t);
+					__db_msgadd(env, mbp, "\t\t");
+					__db_prbytes(env, mbp, p, dlen);
+					p += sizeof(db_indx_t) + dlen;
+				}
+				break;
+			case H_KEYDATA:
+				__db_prbytes(env, mbp, HKEYDATA_DATA(hk),
+				    LEN_HKEYDATA(dbp, h, i == 0 ?
+				    pagesize : 0, i));
+				break;
+			case H_OFFPAGE:
+				memcpy(&a_hkd, hk, HOFFPAGE_SIZE);
+				__db_msgadd(env, mbp,
+				    "overflow: total len: %4lu page: %4lu",
+				    (u_long)a_hkd.tlen, (u_long)a_hkd.pgno);
+				DB_MSGBUF_FLUSH(env, mbp);
+				break;
+			default:
+				DB_MSGBUF_FLUSH(env, mbp);
+				__db_msg(env, "ILLEGAL HASH PAGE TYPE: %lu",
+				    (u_long)HPAGE_PTYPE(hk));
+				ret = EINVAL;
+				break;
+			}
+			break;
+		case P_IBTREE:
+			bi = sp;
+
+			if (F_ISSET(dbp, DB_AM_RECNUM))
+				__db_msgadd(env, mbp,
+				    "count: %4lu ", (u_long)bi->nrecs);
+			__db_msgadd(env, mbp,
+			    "pgno: %4lu type: %lu ",
+			    (u_long)bi->pgno, (u_long)bi->type);
+			switch (B_TYPE(bi->type)) {
+			case B_KEYDATA:
+				__db_prbytes(env, mbp, bi->data, bi->len);
+				break;
+			case B_DUPLICATE:
+			case B_OVERFLOW:
+				__db_proff(env, mbp, bi->data);
+				break;
+			default:
+				DB_MSGBUF_FLUSH(env, mbp);
+				__db_msg(env, "ILLEGAL BINTERNAL TYPE: %lu",
+				    (u_long)B_TYPE(bi->type));
+				ret = EINVAL;
+				break;
+			}
+			break;
+		case P_IRECNO:
+			ri = sp;
+			__db_msgadd(env, mbp, "entries %4lu pgno %4lu",
+			    (u_long)ri->nrecs, (u_long)ri->pgno);
+			DB_MSGBUF_FLUSH(env, mbp);
+			break;
+		case P_LBTREE:
+		case P_LDUP:
+		case P_LRECNO:
+			bk = sp;
+			switch (B_TYPE(bk->type)) {
+			case B_KEYDATA:
+				__db_prbytes(env, mbp, bk->data, bk->len);
+				break;
+			case B_DUPLICATE:
+			case B_OVERFLOW:
+				__db_proff(env, mbp, bk);
+				break;
+			default:
+				DB_MSGBUF_FLUSH(env, mbp);
+				__db_msg(env,
+			    "ILLEGAL DUPLICATE/LBTREE/LRECNO TYPE: %lu",
+				    (u_long)B_TYPE(bk->type));
+				ret = EINVAL;
+				break;
+			}
+			break;
+		case P_HEAP:
+			hh = sp;
+			if (!F_ISSET(hh,HEAP_RECSPLIT))
+				hdata = (u_int8_t *)hh + sizeof(HEAPHDR);
+			else {
+				hs = sp;
+				__db_msgadd(env, mbp,
+				     "split: 0x%02x tsize: %lu next: %lu.%lu ",
+				     hh->flags, (u_long)hs->tsize,
+				     (u_long)hs->nextpg, (u_long)hs->nextindx);
+
+				hdata = (u_int8_t *)hh + sizeof(HEAPSPLITHDR);
+			}
+			__db_prbytes(env, mbp, hdata, hh->size);
+			break;
+		default:
+type_err:		DB_MSGBUF_FLUSH(env, mbp);
+			__db_msg(env,
+			    "ILLEGAL PAGE TYPE: %lu", (u_long)TYPE(h));
+			ret = EINVAL;
+			continue;
+		}
+	}
+	return (ret);
+}
+
+/*
+ * __db_prbytes --
+ *	Print out a data element.
+ *
+ * PUBLIC: void __db_prbytes __P((ENV *, DB_MSGBUF *, u_int8_t *, u_int32_t));
+ */
+void
+__db_prbytes(env, mbp, bytes, len)
+	ENV *env;
+	DB_MSGBUF *mbp;
+	u_int8_t *bytes;
+	u_int32_t len;
+{
+	u_int8_t *p;
+	u_int32_t i, not_printable;
+	int msg_truncated;
+
+	__db_msgadd(env, mbp, "len: %3lu", (u_long)len);
+	if (len != 0) {
+		__db_msgadd(env, mbp, " data: ");
+
+		/*
+		 * Print the first N bytes of the data.   If that
+		 * chunk is at least 3/4  printable characters, print
+		 * it as text, else print it in hex.  We have this
+		 * heuristic because we're displaying things like
+		 * lock objects that could be either text or data.
+		 */
+		if (len > env->data_len) {
+			len = env->data_len;
+			msg_truncated = 1;
+		} else
+			msg_truncated = 0;
+		not_printable = 0;
+		for (p = bytes, i = 0; i < len; ++i, ++p) {
+			if (!isprint((int)*p) && *p != '\t' && *p != '\n') {
+				if (i == len - 1 && *p == '\0')
+					break;
+				if (++not_printable >= (len >> 2))
+					break;
+			}
+		}
+		if (not_printable < (len >> 2))
+			for (p = bytes, i = len; i > 0; --i, ++p) {
+				if (isprint((int)*p))
+					__db_msgadd(env, mbp, "%c", *p);
+				else
+					__db_msgadd(env,
+					    mbp, "\\%x", (u_int)*p);
+			}
+		else
+			for (p = bytes, i = len; i > 0; --i, ++p)
+				__db_msgadd(env, mbp, "%.2x", (u_int)*p);
+		if (msg_truncated)
+			__db_msgadd(env, mbp, "...");
+	}
+	DB_MSGBUF_FLUSH(env, mbp);
+}
+
+/*
+ * __db_proff --
+ *	Print out an off-page element.
+ */
+static void
+__db_proff(env, mbp, vp)
+	ENV *env;
+	DB_MSGBUF *mbp;
+	void *vp;
+{
+	BOVERFLOW *bo;
+
+	bo = vp;
+	switch (B_TYPE(bo->type)) {
+	case B_OVERFLOW:
+		__db_msgadd(env, mbp, "overflow: total len: %4lu page: %4lu",
+		    (u_long)bo->tlen, (u_long)bo->pgno);
+		break;
+	case B_DUPLICATE:
+		__db_msgadd(
+		    env, mbp, "duplicate: page: %4lu", (u_long)bo->pgno);
+		break;
+	default:
+		/* NOTREACHED */
+		break;
+	}
+	DB_MSGBUF_FLUSH(env, mbp);
+}
+
+/*
+ * __db_prflags --
+ *	Print out flags values.
+ *
+ * PUBLIC: void __db_prflags __P((ENV *, DB_MSGBUF *,
+ * PUBLIC:     u_int32_t, const FN *, const char *, const char *));
+ */
+void
+__db_prflags(env, mbp, flags, fn, prefix, suffix)
+	ENV *env;
+	DB_MSGBUF *mbp;
+	u_int32_t flags;
+	FN const *fn;
+	const char *prefix, *suffix;
+{
+	DB_MSGBUF mb;
+	const FN *fnp;
+	int found, standalone;
+	const char *sep;
+
+	if (fn == NULL)
+		return;
+
+	/*
+	 * If it's a standalone message, output the suffix (which will be the
+	 * label), regardless of whether we found anything or not, and flush
+	 * the line.
+	 */
+	if (mbp == NULL) {
+		standalone = 1;
+		mbp = &mb;
+		DB_MSGBUF_INIT(mbp);
+	} else
+		standalone = 0;
+
+	sep = prefix == NULL ? "" : prefix;
+	for (found = 0, fnp = fn; fnp->mask != 0; ++fnp)
+		if (LF_ISSET(fnp->mask)) {
+			__db_msgadd(env, mbp, "%s%s", sep, fnp->name);
+			sep = ", ";
+			found = 1;
+		}
+
+	if ((standalone || found) && suffix != NULL)
+		__db_msgadd(env, mbp, "%s", suffix);
+	if (standalone)
+		DB_MSGBUF_FLUSH(env, mbp);
+}
+
+/*
+ * __db_name_to_val --
+ *	Return the integral value associated with the string, or -1 if missing.
+ *	It is intended for looking up string names of enums and single bit
+ *	in order to get a numeric value.
+ *
+ * PUBLIC: int __db_name_to_val __P((FN const *, char *));
+ */
+int
+__db_name_to_val(strtable, s)
+	FN const *strtable;
+	char *s;
+{
+	if (s != NULL) {
+		do {
+			if (strcasecmp(strtable->name, s) == 0)
+				return ((int)strtable->mask);
+		} while ((++strtable)->name != NULL);
+	}
+	return (-1);
+}
+
+/*
+ * __db_pagetype_to_string --
+ *	Return the name of the specified page type.
+ * PUBLIC: const char *__db_pagetype_to_string __P((u_int32_t));
+ */
+const char *
+__db_pagetype_to_string(type)
+	u_int32_t type;
+{
+	char *s;
+
+	s = NULL;
+	switch (type) {
+	case P_BTREEMETA:
+		s = "btree metadata";
+		break;
+	case P_LDUP:
+		s = "duplicate";
+		break;
+	case P_HASH_UNSORTED:
+		s = "hash unsorted";
+		break;
+	case P_HASH:
+		s = "hash";
+		break;
+	case P_HASHMETA:
+		s = "hash metadata";
+		break;
+	case P_IBTREE:
+		s = "btree internal";
+		break;
+	case P_INVALID:
+		s = "invalid";
+		break;
+	case P_IRECNO:
+		s = "recno internal";
+		break;
+	case P_LBTREE:
+		s = "btree leaf";
+		break;
+	case P_LRECNO:
+		s = "recno leaf";
+		break;
+	case P_OVERFLOW:
+		s = "overflow";
+		break;
+	case P_QAMMETA:
+		s = "queue metadata";
+		break;
+	case P_QAMDATA:
+		s = "queue";
+		break;
+	case P_HEAPMETA:
+		s = "heap metadata";
+		break;
+	case P_HEAP:
+		s = "heap data";
+		break;
+	case P_IHEAP:
+		s = "heap internal";
+		break;
+	default:
+		/* Just return a NULL. */
+		break;
+	}
+	return (s);
+}
+
+/*
+ * __db_dump_pp --
+ *	DB->dump pre/post processing.
+ *
+ * PUBLIC: int __db_dump_pp __P((DB *, const char *,
+ * PUBLIC:     int (*)(void *, const void *), void *, int, int));
+ */
+int
+__db_dump_pp(dbp, subname, callback, handle, pflag, keyflag)
+	DB *dbp;
+	const char *subname;
+	int (*callback) __P((void *, const void *));
+	void *handle;
+	int pflag, keyflag;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret;
+
+	env = dbp->env;
+
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->dump");
+
+	ENV_ENTER(env, ip);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 1)) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	ret = __db_dump(dbp, subname, callback, handle, pflag, keyflag);
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+err:	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_dump --
+ *	DB->dump.
+ *
+ * PUBLIC: int __db_dump __P((DB *, const char *,
+ * PUBLIC:     int (*)(void *, const void *), void *, int, int));
+ */
+int
+__db_dump(dbp, subname, callback, handle, pflag, keyflag)
+	DB *dbp;
+	const char *subname;
+	int (*callback) __P((void *, const void *));
+	void *handle;
+	int pflag, keyflag;
+{
+	DBC *dbcp;
+	DBT key, data;
+	DBT keyret, dataret;
+	DB_HEAP_RID rid;
+	ENV *env;
+	db_recno_t recno;
+	int is_recno, is_heap, ret, t_ret;
+	void *pointer;
+
+	env = dbp->env;
+	is_heap = 0;
+
+	if ((ret = __db_prheader(
+	    dbp, subname, pflag, keyflag, handle, callback, NULL, 0)) != 0)
+		return (ret);
+
+	/*
+	 * Get a cursor and step through the database, printing out each
+	 * key/data pair.
+	 */
+	if ((ret = __db_cursor(dbp, NULL, NULL, &dbcp, 0)) != 0)
+		return (ret);
+
+	memset(&key, 0, sizeof(key));
+	memset(&data, 0, sizeof(data));
+	if ((ret = __os_malloc(env, 1024 * 1024, &data.data)) != 0)
+		goto err;
+	data.ulen = 1024 * 1024;
+	data.flags = DB_DBT_USERMEM;
+	is_recno = (dbp->type == DB_RECNO || dbp->type == DB_QUEUE);
+	keyflag = is_recno ? keyflag : 1;
+	if (is_recno) {
+		keyret.data = &recno;
+		keyret.size = sizeof(recno);
+	}
+
+	if (dbp->type == DB_HEAP) {
+		is_heap = 1;
+		key.data = &rid;
+		key.size = key.ulen = sizeof(DB_HEAP_RID);
+		key.flags = DB_DBT_USERMEM;
+	}
+
+retry: while ((ret =
+	    __dbc_get(dbcp, &key, &data,
+	    !is_heap ? DB_NEXT | DB_MULTIPLE_KEY : DB_NEXT )) == 0) {
+		if (is_heap) {
+			/* Never dump keys for HEAP */
+			if ((ret = __db_prdbt(
+			    &data, pflag, " ", handle, callback, 0, 0)) != 0)
+				goto err;
+			continue;
+		}
+		DB_MULTIPLE_INIT(pointer, &data);
+		for (;;) {
+			if (is_recno)
+				DB_MULTIPLE_RECNO_NEXT(pointer, &data,
+				    recno, dataret.data, dataret.size);
+			else
+				DB_MULTIPLE_KEY_NEXT(pointer, &data,
+				    keyret.data, keyret.size,
+				    dataret.data, dataret.size);
+
+			if (dataret.data == NULL)
+				break;
+
+			if ((keyflag &&
+			    (ret = __db_prdbt(&keyret, pflag, " ",
+			    handle, callback, is_recno, 0)) != 0) ||
+			    (ret = __db_prdbt(&dataret, pflag, " ",
+			    handle, callback, 0, 0)) != 0)
+					goto err;
+		}
+	}
+	if (ret == DB_BUFFER_SMALL) {
+		data.size = (u_int32_t)DB_ALIGN(data.size, 1024);
+		if ((ret = __os_realloc(env, data.size, &data.data)) != 0)
+			goto err;
+		data.ulen = data.size;
+		goto retry;
+	}
+	if (ret == DB_NOTFOUND)
+		ret = 0;
+
+	if ((t_ret = __db_prfooter(handle, callback)) != 0 && ret == 0)
+		ret = t_ret;
+
+err:	if ((t_ret = __dbc_close(dbcp)) != 0 && ret == 0)
+		ret = t_ret;
+	if (data.data != NULL)
+		__os_free(env, data.data);
+
+	return (ret);
+}
+
+/*
+ * __db_prdbt --
+ *	Print out a DBT data element.
+ *
+ * PUBLIC: int __db_prdbt __P((DBT *, int, const char *, void *,
+ * PUBLIC:     int (*)(void *, const void *), int, int));
+ */
+int
+__db_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno, is_heap)
+	DBT *dbtp;
+	int checkprint;
+	const char *prefix;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	int is_recno;
+	int is_heap;
+{
+	static const u_char hex[] = "0123456789abcdef";
+	db_recno_t recno;
+	DB_HEAP_RID rid;
+	size_t len;
+	int ret;
+#define	DBTBUFLEN	100
+	u_int8_t *p, *hp;
+	char buf[DBTBUFLEN], hbuf[DBTBUFLEN];
+
+	/*
+	 * !!!
+	 * This routine is the routine that dumps out items in the format
+	 * used by db_dump(1) and db_load(1).  This means that the format
+	 * cannot change.
+	 */
+	if (prefix != NULL && (ret = callback(handle, prefix)) != 0)
+		return (ret);
+	if (is_recno) {
+		/*
+		 * We're printing a record number, and this has to be done
+		 * in a platform-independent way.  So we use the numeral in
+		 * straight ASCII.
+		 */
+		(void)__ua_memcpy(&recno, dbtp->data, sizeof(recno));
+		snprintf(buf, DBTBUFLEN, "%lu", (u_long)recno);
+
+		/* If we're printing data as hex, print keys as hex too. */
+		if (!checkprint) {
+			for (len = strlen(buf), p = (u_int8_t *)buf,
+			    hp = (u_int8_t *)hbuf; len-- > 0; ++p) {
+				*hp++ = hex[(u_int8_t)(*p & 0xf0) >> 4];
+				*hp++ = hex[*p & 0x0f];
+			}
+			*hp = '\0';
+			ret = callback(handle, hbuf);
+		} else
+			ret = callback(handle, buf);
+
+		if (ret != 0)
+			return (ret);
+	} else if (is_heap) {
+		/*
+		 * We're printing a heap record number, and this has to be
+		 * done in a platform-independent way.  So we use the numeral
+		 * in straight ASCII.
+		 */
+		(void)__ua_memcpy(&rid, dbtp->data, sizeof(rid));
+		snprintf(buf, DBTBUFLEN, "%lu %hu",
+		    (u_long)rid.pgno, (u_short)rid.indx);
+
+		/* If we're printing data as hex, print keys as hex too. */
+		if (!checkprint) {
+			for (len = strlen(buf), p = (u_int8_t *)buf,
+			    hp = (u_int8_t *)hbuf; len-- > 0; ++p) {
+				*hp++ = hex[(u_int8_t)(*p & 0xf0) >> 4];
+				*hp++ = hex[*p & 0x0f];
+			}
+			*hp = '\0';
+			ret = callback(handle, hbuf);
+		} else
+			ret = callback(handle, buf);
+
+		if (ret != 0)
+			return (ret);
+	} else if (checkprint) {
+		for (len = dbtp->size, p = dbtp->data; len--; ++p)
+			if (isprint((int)*p)) {
+				if (*p == '\\' &&
+				    (ret = callback(handle, "\\")) != 0)
+					return (ret);
+				snprintf(buf, DBTBUFLEN, "%c", *p);
+				if ((ret = callback(handle, buf)) != 0)
+					return (ret);
+			} else {
+				snprintf(buf, DBTBUFLEN, "\\%c%c",
+				    hex[(u_int8_t)(*p & 0xf0) >> 4],
+				    hex[*p & 0x0f]);
+				if ((ret = callback(handle, buf)) != 0)
+					return (ret);
+			}
+	} else
+		for (len = dbtp->size, p = dbtp->data; len--; ++p) {
+			snprintf(buf, DBTBUFLEN, "%c%c",
+			    hex[(u_int8_t)(*p & 0xf0) >> 4],
+			    hex[*p & 0x0f]);
+			if ((ret = callback(handle, buf)) != 0)
+				return (ret);
+		}
+
+	return (callback(handle, "\n"));
+}
+
+/*
+ * __db_prheader --
+ *	Write out header information in the format expected by db_load.
+ *
+ * PUBLIC: int	__db_prheader __P((DB *, const char *, int, int, void *,
+ * PUBLIC:     int (*)(void *, const void *), VRFY_DBINFO *, db_pgno_t));
+ */
+int
+__db_prheader(dbp, subname, pflag, keyflag, handle, callback, vdp, meta_pgno)
+	DB *dbp;
+	const char *subname;
+	int pflag, keyflag;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	VRFY_DBINFO *vdp;
+	db_pgno_t meta_pgno;
+{
+	DBT dbt;
+	DBTYPE dbtype;
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	u_int32_t flags, tmp_u_int32;
+	size_t buflen;
+	char *buf;
+	int using_vdp, ret, t_ret, tmp_int;
+#ifdef HAVE_HEAP
+	u_int32_t tmp2_u_int32;
+#endif
+
+	ret = 0;
+	buf = NULL;
+	COMPQUIET(buflen, 0);
+
+	/*
+	 * If dbp is NULL, then pip is guaranteed to be non-NULL; we only ever
+	 * call __db_prheader with a NULL dbp from one case inside __db_prdbt,
+	 * and this is a special subdatabase for "lost" items.  In this case
+	 * we have a vdp (from which we'll get a pip).  In all other cases, we
+	 * will have a non-NULL dbp (and vdp may or may not be NULL depending
+	 * on whether we're salvaging).
+	 */
+	if (dbp == NULL)
+		env = NULL;
+	else
+		env = dbp->env;
+	DB_ASSERT(env, dbp != NULL || vdp != NULL);
+
+	/*
+	 * If we've been passed a verifier statistics object, use that;  we're
+	 * being called in a context where dbp->stat is unsafe.
+	 *
+	 * Also, the verifier may set the pflag on a per-salvage basis.  If so,
+	 * respect that.
+	 */
+	if (vdp != NULL) {
+		if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &pip)) != 0)
+			return (ret);
+
+		if (F_ISSET(vdp, SALVAGE_PRINTABLE))
+			pflag = 1;
+		using_vdp = 1;
+	} else {
+		pip = NULL;
+		using_vdp = 0;
+	}
+
+	/*
+	 * If dbp is NULL, make it a btree.  Otherwise, set dbtype to whatever
+	 * appropriate type for the specified meta page, or the type of the dbp.
+	 */
+	if (dbp == NULL)
+		dbtype = DB_BTREE;
+	else if (using_vdp)
+		switch (pip->type) {
+		case P_BTREEMETA:
+			if (F_ISSET(pip, VRFY_IS_RECNO))
+				dbtype = DB_RECNO;
+			else
+				dbtype = DB_BTREE;
+			break;
+		case P_HASHMETA:
+			dbtype = DB_HASH;
+			break;
+		case P_HEAPMETA:
+			dbtype = DB_HEAP;
+			break;
+		case P_QAMMETA:
+			dbtype = DB_QUEUE;
+			break;
+		default:
+			/*
+			 * If the meta page is of a bogus type, it's because
+			 * we have a badly corrupt database.  (We must be in
+			 * the verifier for pip to be non-NULL.) Pretend we're
+			 * a Btree and salvage what we can.
+			 */
+			DB_ASSERT(env, F_ISSET(dbp, DB_AM_VERIFYING));
+			dbtype = DB_BTREE;
+			break;
+		}
+	else
+		dbtype = dbp->type;
+
+	if ((ret = callback(handle, "VERSION=3\n")) != 0)
+		goto err;
+	if (pflag) {
+		if ((ret = callback(handle, "format=print\n")) != 0)
+			goto err;
+	} else if ((ret = callback(handle, "format=bytevalue\n")) != 0)
+		goto err;
+
+	/*
+	 * 64 bytes is long enough, as a minimum bound, for any of the
+	 * fields besides subname.  Subname uses __db_prdbt and therefore
+	 * does not need buffer space here.
+	 */
+	buflen = 64;
+	if ((ret = __os_malloc(env, buflen, &buf)) != 0)
+		goto err;
+	if (subname != NULL) {
+		snprintf(buf, buflen, "database=");
+		if ((ret = callback(handle, buf)) != 0)
+			goto err;
+		DB_INIT_DBT(dbt, subname, strlen(subname));
+		if ((ret = __db_prdbt(&dbt, 1,
+		    NULL, handle, callback, 0, 0)) != 0)
+			goto err;
+	}
+	switch (dbtype) {
+	case DB_BTREE:
+		if ((ret = callback(handle, "type=btree\n")) != 0)
+			goto err;
+		if (using_vdp)
+			tmp_int = F_ISSET(pip, VRFY_HAS_RECNUMS) ? 1 : 0;
+		else {
+			if ((ret = __db_get_flags(dbp, &flags)) != 0) {
+				__db_err(env, ret, "DB->get_flags");
+				goto err;
+			}
+			tmp_int = F_ISSET(dbp, DB_AM_RECNUM) ? 1 : 0;
+		}
+		if (tmp_int && (ret = callback(handle, "recnum=1\n")) != 0)
+			goto err;
+
+		if (using_vdp)
+			tmp_u_int32 = pip->bt_minkey;
+		else
+			if ((ret =
+			    __bam_get_bt_minkey(dbp, &tmp_u_int32)) != 0) {
+				__db_err(env, ret, "DB->get_bt_minkey");
+				goto err;
+			}
+		if (tmp_u_int32 != 0 && tmp_u_int32 != DEFMINKEYPAGE) {
+			snprintf(buf, buflen,
+			    "bt_minkey=%lu\n", (u_long)tmp_u_int32);
+			if ((ret = callback(handle, buf)) != 0)
+				goto err;
+		}
+		break;
+	case DB_HASH:
+#ifdef HAVE_HASH
+		if ((ret = callback(handle, "type=hash\n")) != 0)
+			goto err;
+		if (using_vdp)
+			tmp_u_int32 = pip->h_ffactor;
+		else
+			if ((ret =
+			    __ham_get_h_ffactor(dbp, &tmp_u_int32)) != 0) {
+				__db_err(env, ret, "DB->get_h_ffactor");
+				goto err;
+			}
+		if (tmp_u_int32 != 0) {
+			snprintf(buf, buflen,
+			    "h_ffactor=%lu\n", (u_long)tmp_u_int32);
+			if ((ret = callback(handle, buf)) != 0)
+				goto err;
+		}
+
+		if (using_vdp)
+			tmp_u_int32 = pip->h_nelem;
+		else
+			if ((ret = __ham_get_h_nelem(dbp, &tmp_u_int32)) != 0) {
+				__db_err(env, ret, "DB->get_h_nelem");
+				goto err;
+			}
+		/*
+		 * Hash databases have an h_nelem field of 0 or 1, neither
+		 * of those values is interesting.
+		 */
+		if (tmp_u_int32 > 1) {
+			snprintf(buf, buflen,
+			    "h_nelem=%lu\n", (u_long)tmp_u_int32);
+			if ((ret = callback(handle, buf)) != 0)
+				goto err;
+		}
+		break;
+#else
+		ret = __db_no_hash_am(env);
+		goto err;
+#endif
+	case DB_HEAP:
+#ifdef HAVE_HEAP
+		if ((ret = callback(handle, "type=heap\n")) != 0)
+			goto err;
+
+		if ((ret = __heap_get_heapsize(
+		    dbp, &tmp_u_int32, &tmp2_u_int32)) != 0) {
+			__db_err(env, ret, "DB->get_heapsize");
+			goto err;
+		}
+		if (tmp_u_int32 != 0) {
+			snprintf(buf,
+			    buflen, "heap_gbytes=%lu\n", (u_long)tmp_u_int32);
+			if ((ret = callback(handle, buf)) != 0)
+				goto err;
+		}
+		if (tmp2_u_int32 != 0) {
+			snprintf(buf,
+			    buflen, "heap_bytes=%lu\n", (u_long)tmp2_u_int32);
+			if ((ret = callback(handle, buf)) != 0)
+				goto err;
+		}
+
+		if ((ret =
+		    __heap_get_heap_regionsize(dbp, &tmp_u_int32)) != 0) {
+			__db_err(env, ret, "DB->get_heap_regionsize");
+			goto err;
+		}
+		if (tmp_u_int32 != 0) {
+			snprintf(buf, buflen,
+			    "heap_regionsize=%lu\n", (u_long)tmp_u_int32);
+			if ((ret = callback(handle, buf)) != 0)
+				goto err;
+		}
+		break;
+#else
+		ret = __db_no_heap_am(env);
+		goto err;
+#endif
+	case DB_QUEUE:
+#ifdef HAVE_QUEUE
+		if ((ret = callback(handle, "type=queue\n")) != 0)
+			goto err;
+		if (using_vdp)
+			tmp_u_int32 = vdp->re_len;
+		else
+			if ((ret = __ram_get_re_len(dbp, &tmp_u_int32)) != 0) {
+				__db_err(env, ret, "DB->get_re_len");
+				goto err;
+			}
+		snprintf(buf, buflen, "re_len=%lu\n", (u_long)tmp_u_int32);
+		if ((ret = callback(handle, buf)) != 0)
+			goto err;
+
+		if (using_vdp)
+			tmp_int = (int)vdp->re_pad;
+		else
+			if ((ret = __ram_get_re_pad(dbp, &tmp_int)) != 0) {
+				__db_err(env, ret, "DB->get_re_pad");
+				goto err;
+			}
+		if (tmp_int != 0 && tmp_int != ' ') {
+			snprintf(buf, buflen, "re_pad=%#x\n", tmp_int);
+			if ((ret = callback(handle, buf)) != 0)
+				goto err;
+		}
+
+		if (using_vdp)
+			tmp_u_int32 = vdp->page_ext;
+		else
+			if ((ret =
+			    __qam_get_extentsize(dbp, &tmp_u_int32)) != 0) {
+				__db_err(env, ret, "DB->get_q_extentsize");
+				goto err;
+			}
+		if (tmp_u_int32 != 0) {
+			snprintf(buf, buflen,
+			    "extentsize=%lu\n", (u_long)tmp_u_int32);
+			if ((ret = callback(handle, buf)) != 0)
+				goto err;
+		}
+		break;
+#else
+		ret = __db_no_queue_am(env);
+		goto err;
+#endif
+	case DB_RECNO:
+		if ((ret = callback(handle, "type=recno\n")) != 0)
+			goto err;
+		if (using_vdp)
+			tmp_int = F_ISSET(pip, VRFY_IS_RRECNO) ? 1 : 0;
+		else
+			tmp_int = F_ISSET(dbp, DB_AM_RENUMBER) ? 1 : 0;
+		if (tmp_int != 0 &&
+		    (ret = callback(handle, "renumber=1\n")) != 0)
+				goto err;
+
+		if (using_vdp)
+			tmp_int = F_ISSET(pip, VRFY_IS_FIXEDLEN) ? 1 : 0;
+		else
+			tmp_int = F_ISSET(dbp, DB_AM_FIXEDLEN) ? 1 : 0;
+		if (tmp_int) {
+			if (using_vdp)
+				tmp_u_int32 = pip->re_len;
+			else
+				if ((ret =
+				    __ram_get_re_len(dbp, &tmp_u_int32)) != 0) {
+					__db_err(env, ret, "DB->get_re_len");
+					goto err;
+				}
+			snprintf(buf, buflen,
+			    "re_len=%lu\n", (u_long)tmp_u_int32);
+			if ((ret = callback(handle, buf)) != 0)
+				goto err;
+
+			if (using_vdp)
+				tmp_int = (int)pip->re_pad;
+			else
+				if ((ret =
+				    __ram_get_re_pad(dbp, &tmp_int)) != 0) {
+					__db_err(env, ret, "DB->get_re_pad");
+					goto err;
+				}
+			if (tmp_int != 0 && tmp_int != ' ') {
+				snprintf(buf,
+				    buflen, "re_pad=%#x\n", (u_int)tmp_int);
+				if ((ret = callback(handle, buf)) != 0)
+					goto err;
+			}
+		}
+		break;
+	case DB_UNKNOWN:			/* Impossible. */
+		ret = __db_unknown_path(env, "__db_prheader");
+		goto err;
+	}
+
+	if (using_vdp) {
+		if (F_ISSET(pip, VRFY_HAS_CHKSUM))
+			if ((ret = callback(handle, "chksum=1\n")) != 0)
+				goto err;
+		if (F_ISSET(pip, VRFY_HAS_DUPS))
+			if ((ret = callback(handle, "duplicates=1\n")) != 0)
+				goto err;
+		if (F_ISSET(pip, VRFY_HAS_DUPSORT))
+			if ((ret = callback(handle, "dupsort=1\n")) != 0)
+				goto err;
+#ifdef HAVE_COMPRESSION
+		if (F_ISSET(pip, VRFY_HAS_COMPRESS))
+			if ((ret = callback(handle, "compressed=1\n")) != 0)
+				goto err;
+#endif
+		/*
+		 * !!!
+		 * We don't know if the page size was the default if we're
+		 * salvaging.  It doesn't seem that interesting to have, so
+		 * we ignore it for now.
+		 */
+	} else {
+		if (F_ISSET(dbp, DB_AM_CHKSUM))
+			if ((ret = callback(handle, "chksum=1\n")) != 0)
+				goto err;
+		if (F_ISSET(dbp, DB_AM_DUP))
+			if ((ret = callback(handle, "duplicates=1\n")) != 0)
+				goto err;
+		if (F_ISSET(dbp, DB_AM_DUPSORT))
+			if ((ret = callback(handle, "dupsort=1\n")) != 0)
+				goto err;
+#ifdef HAVE_COMPRESSION
+		if (DB_IS_COMPRESSED(dbp))
+			if ((ret = callback(handle, "compressed=1\n")) != 0)
+				goto err;
+#endif
+		if (!F_ISSET(dbp, DB_AM_PGDEF)) {
+			snprintf(buf, buflen,
+			    "db_pagesize=%lu\n", (u_long)dbp->pgsize);
+			if ((ret = callback(handle, buf)) != 0)
+				goto err;
+		}
+	}
+
+#ifdef HAVE_PARTITION
+	if (dbp != NULL && DB_IS_PARTITIONED(dbp) &&
+	    F_ISSET((DB_PARTITION *)dbp->p_internal, PART_RANGE)) {
+		DBT *keys;
+		u_int32_t i;
+
+		if ((ret = __partition_get_keys(dbp, &tmp_u_int32, &keys)) != 0)
+			goto err;
+		if (tmp_u_int32 != 0) {
+			snprintf(buf,
+			     buflen, "nparts=%lu\n", (u_long)tmp_u_int32);
+			if ((ret = callback(handle, buf)) != 0)
+				goto err;
+			for (i = 0; i < tmp_u_int32 - 1; i++)
+			    if ((ret = __db_prdbt(&keys[i],
+				pflag, " ", handle, callback, 0, 0)) != 0)
+					goto err;
+		}
+	}
+#endif
+
+	if (keyflag && (ret = callback(handle, "keys=1\n")) != 0)
+		goto err;
+
+	ret = callback(handle, "HEADER=END\n");
+
+err:	if (using_vdp &&
+	    (t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+	if (buf != NULL)
+		__os_free(env, buf);
+
+	return (ret);
+}
+
+/*
+ * __db_prfooter --
+ *	Print the footer that marks the end of a DB dump.  This is trivial,
+ *	but for consistency's sake we don't want to put its literal contents
+ *	in multiple places.
+ *
+ * PUBLIC: int __db_prfooter __P((void *, int (*)(void *, const void *)));
+ */
+int
+__db_prfooter(handle, callback)
+	void *handle;
+	int (*callback) __P((void *, const void *));
+{
+	return (callback(handle, "DATA=END\n"));
+}
+
+/*
+ * __db_pr_callback --
+ *	Callback function for using pr_* functions from C.
+ *
+ * PUBLIC: int  __db_pr_callback __P((void *, const void *));
+ */
+int
+__db_pr_callback(handle, str_arg)
+	void *handle;
+	const void *str_arg;
+{
+	char *str;
+	FILE *f;
+
+	str = (char *)str_arg;
+	f = (FILE *)handle;
+
+	if (fprintf(f, "%s", str) != (int)strlen(str))
+		return (EIO);
+
+	return (0);
+}
+
+/*
+ * __db_dbtype_to_string --
+ *	Return the name of the database type.
+ *
+ * PUBLIC: const char * __db_dbtype_to_string __P((DBTYPE));
+ */
+const char *
+__db_dbtype_to_string(type)
+	DBTYPE type;
+{
+	switch (type) {
+	case DB_BTREE:
+		return ("btree");
+	case DB_HASH:
+		return ("hash");
+	case DB_RECNO:
+		return ("recno");
+	case DB_QUEUE:
+		return ("queue");
+	case DB_HEAP:
+		return ("heap");
+	case DB_UNKNOWN:
+	default:
+		break;
+	}
+	return ("UNKNOWN TYPE");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_reclaim.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,267 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/mp.h"
+
+/*
+ * __db_traverse_big
+ *	Traverse a chain of overflow pages and call the callback routine
+ * on each one.  The calling convention for the callback is:
+ *	callback(dbc, page, cookie, did_put),
+ * where did_put is a return value indicating if the page in question has
+ * already been returned to the mpool.
+ *
+ * PUBLIC: int __db_traverse_big __P((DBC *, db_pgno_t,
+ * PUBLIC:	int (*)(DBC *, PAGE *, void *, int *), void *));
+ */
+int
+__db_traverse_big(dbc, pgno, callback, cookie)
+	DBC *dbc;
+	db_pgno_t pgno;
+	int (*callback) __P((DBC *, PAGE *, void *, int *));
+	void *cookie;
+{
+	DB_MPOOLFILE *mpf;
+	PAGE *p;
+	int did_put, ret;
+
+	mpf = dbc->dbp->mpf;
+
+	do {
+		did_put = 0;
+		if ((ret = __memp_fget(mpf,
+		     &pgno, dbc->thread_info, dbc->txn, 0, &p)) != 0)
+			return (ret);
+		/*
+		 * If we are freeing pages only process the overflow
+		 * chain if the head of the chain has a refcount of 1.
+		 */
+		pgno = NEXT_PGNO(p);
+		if (callback == __db_truncate_callback && OV_REF(p) != 1)
+			pgno = PGNO_INVALID;
+		if ((ret = callback(dbc, p, cookie, &did_put)) == 0 &&
+		    !did_put)
+			ret = __memp_fput(mpf,
+			     dbc->thread_info, p, dbc->priority);
+	} while (ret == 0 && pgno != PGNO_INVALID);
+
+	return (ret);
+}
+
+/*
+ * __db_reclaim_callback
+ * This is the callback routine used during a delete of a subdatabase.
+ * we are traversing a btree or hash table and trying to free all the
+ * pages.  Since they share common code for duplicates and overflow
+ * items, we traverse them identically and use this routine to do the
+ * actual free.  The reason that this is callback is because hash uses
+ * the same traversal code for statistics gathering.
+ *
+ * PUBLIC: int __db_reclaim_callback __P((DBC *, PAGE *, void *, int *));
+ */
+int
+__db_reclaim_callback(dbc, p, cookie, putp)
+	DBC *dbc;
+	PAGE *p;
+	void *cookie;
+	int *putp;
+{
+	DB *dbp;
+	int ret;
+
+	dbp = dbc->dbp;
+
+	/*
+	 * We don't want to log the free of the root with the subdb.
+	 * If we abort then the subdb may not be openable to undo
+	 * the free.
+	 */
+	if ((dbp->type == DB_BTREE || dbp->type == DB_RECNO) &&
+	    PGNO(p) == ((BTREE *)dbp->bt_internal)->bt_root)
+		return (0);
+	if ((ret = __db_free(dbc, p, *(u_int32_t *)cookie)) != 0)
+		return (ret);
+	*putp = 1;
+
+	return (0);
+}
+
+/*
+ * __db_truncate_callback
+ * This is the callback routine used during a truncate.
+ * we are traversing a btree or hash table and trying to free all the
+ * pages.
+ *
+ * PUBLIC: int __db_truncate_callback __P((DBC *, PAGE *, void *, int *));
+ */
+int
+__db_truncate_callback(dbc, p, cookie, putp)
+	DBC *dbc;
+	PAGE *p;
+	void *cookie;
+	int *putp;
+{
+	DB *dbp;
+	DBT ddbt, ldbt;
+	DB_MPOOLFILE *mpf;
+	db_indx_t indx, len, off, tlen, top;
+	u_int8_t *hk, type;
+	u_int32_t *countp;
+	int ret;
+
+	top = NUM_ENT(p);
+	dbp = dbc->dbp;
+	mpf = dbp->mpf;
+	countp = cookie;
+	*putp = 1;
+
+	switch (TYPE(p)) {
+	case P_LBTREE:
+		/* Skip for off-page duplicates and deleted items. */
+		for (indx = 0; indx < top; indx += P_INDX) {
+			type = GET_BKEYDATA(dbp, p, indx + O_INDX)->type;
+			if (!B_DISSET(type) && B_TYPE(type) != B_DUPLICATE)
+				++*countp;
+		}
+		/* FALLTHROUGH */
+	case P_IBTREE:
+	case P_IRECNO:
+	case P_INVALID:
+		if (dbp->type != DB_HASH &&
+		    ((BTREE *)dbp->bt_internal)->bt_root == PGNO(p)) {
+			type = dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE;
+			goto reinit;
+		}
+		break;
+	case P_OVERFLOW:
+		if ((ret = __memp_dirty(mpf,
+		    &p, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+			return (ret);
+		if (DBC_LOGGING(dbc)) {
+			if ((ret = __db_ovref_log(dbp, dbc->txn,
+			    &LSN(p), 0, p->pgno, -1, &LSN(p))) != 0)
+				return (ret);
+		} else
+			LSN_NOT_LOGGED(LSN(p));
+		if (--OV_REF(p) != 0)
+			*putp = 0;
+		break;
+	case P_LRECNO:
+		for (indx = 0; indx < top; indx += O_INDX) {
+			type = GET_BKEYDATA(dbp, p, indx)->type;
+			if (!B_DISSET(type))
+				++*countp;
+		}
+
+		if (((BTREE *)dbp->bt_internal)->bt_root == PGNO(p)) {
+			type = P_LRECNO;
+			goto reinit;
+		}
+		break;
+	case P_LDUP:
+		/* Correct for deleted items. */
+		for (indx = 0; indx < top; indx += O_INDX)
+			if (!B_DISSET(GET_BKEYDATA(dbp, p, indx)->type))
+				++*countp;
+
+		break;
+	case P_HASH:
+		/* Correct for on-page duplicates and deleted items. */
+		for (indx = 0; indx < top; indx += P_INDX) {
+			switch (*H_PAIRDATA(dbp, p, indx)) {
+			case H_OFFDUP:
+				break;
+			case H_OFFPAGE:
+			case H_KEYDATA:
+				++*countp;
+				break;
+			case H_DUPLICATE:
+				tlen = LEN_HDATA(dbp, p, 0, indx);
+				hk = H_PAIRDATA(dbp, p, indx);
+				for (off = 0; off < tlen;
+				    off += len + 2 * sizeof(db_indx_t)) {
+					++*countp;
+					memcpy(&len,
+					    HKEYDATA_DATA(hk)
+					    + off, sizeof(db_indx_t));
+				}
+				break;
+			default:
+				return (__db_pgfmt(dbp->env, p->pgno));
+			}
+		}
+		/* Don't free the head of the bucket. */
+		if (PREV_PGNO(p) == PGNO_INVALID) {
+			type = P_HASH;
+
+reinit:			if ((ret = __memp_dirty(mpf, &p,
+			    dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0)
+				return (ret);
+			*putp = 0;
+			if (DBC_LOGGING(dbc)) {
+				memset(&ldbt, 0, sizeof(ldbt));
+				memset(&ddbt, 0, sizeof(ddbt));
+				ldbt.data = p;
+				ldbt.size = P_OVERHEAD(dbp);
+				ldbt.size += p->entries * sizeof(db_indx_t);
+				ddbt.data = (u_int8_t *)p + HOFFSET(p);
+				ddbt.size = dbp->pgsize - HOFFSET(p);
+				if ((ret = __db_pg_init_log(dbp,
+				    dbc->txn, &LSN(p), 0,
+				    p->pgno, &ldbt, &ddbt)) != 0)
+					return (ret);
+			} else
+				LSN_NOT_LOGGED(LSN(p));
+
+			P_INIT(p, dbp->pgsize, PGNO(p), PGNO_INVALID,
+			    PGNO_INVALID, type == P_HASH ? 0 : 1, type);
+		}
+		break;
+	default:
+		return (__db_pgfmt(dbp->env, p->pgno));
+	}
+
+	if (*putp == 1) {
+		if ((ret = __db_free(dbc, p, 0)) != 0)
+			return (ret);
+	} else {
+		if ((ret = __memp_fput(mpf, dbc->thread_info, p,
+		    dbc->priority)) != 0)
+			return (ret);
+		*putp = 1;
+	}
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_remove.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,480 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/fop.h"
+#include "dbinc/btree.h"
+#include "dbinc/hash.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+static int __db_subdb_remove __P((DB *,
+    DB_THREAD_INFO *, DB_TXN *, const char *, const char *, u_int32_t));
+
+/*
+ * __env_dbremove_pp
+ *	ENV->dbremove pre/post processing.
+ *
+ * PUBLIC: int __env_dbremove_pp __P((DB_ENV *,
+ * PUBLIC:     DB_TXN *, const char *, const char *, u_int32_t));
+ */
+int
+__env_dbremove_pp(dbenv, txn, name, subdb, flags)
+	DB_ENV *dbenv;
+	DB_TXN *txn;
+	const char *name, *subdb;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret, txn_local;
+
+	dbp = NULL;
+	env = dbenv->env;
+	txn_local = 0;
+	handle_check = 0;
+
+	ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->dbremove");
+
+	/*
+	 * The actual argument checking is simple, do it inline, outside of
+	 * the replication block.
+	 */
+	if ((ret = __db_fchk(env, "DB->remove", flags,
+		DB_AUTO_COMMIT | DB_LOG_NO_DATA |
+		DB_NOSYNC | DB_TXN_NOT_DURABLE)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+	XA_NO_TXN(ip, ret);
+	if (ret != 0)
+		goto err;
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check && (ret = __env_rep_enter(env, 1)) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	/*
+	 * Create local transaction as necessary, check for consistent
+	 * transaction usage.
+	 */
+	if (IS_ENV_AUTO_COMMIT(env, txn, flags)) {
+		if ((ret = __db_txn_auto_init(env, ip, &txn)) != 0)
+			goto err;
+		txn_local = 1;
+	} else if (txn != NULL && !TXN_ON(env) &&
+	    (!CDB_LOCKING(env) || !F_ISSET(txn, TXN_FAMILY))) {
+		ret = __db_not_txn_env(env);
+		goto err;
+	} else if (txn != NULL && LF_ISSET(DB_LOG_NO_DATA)) {
+		ret = EINVAL;
+		__db_errx(env, DB_STR("0690",
+	    "DB_LOG_NO_DATA may not be specified within a transaction."));
+		goto err;
+	}
+	LF_CLR(DB_AUTO_COMMIT);
+
+	if ((ret = __db_create_internal(&dbp, env, 0)) != 0)
+		goto err;
+	if (LF_ISSET(DB_TXN_NOT_DURABLE) &&
+	    (ret = __db_set_flags(dbp, DB_TXN_NOT_DURABLE)) != 0)
+		goto err;
+	LF_CLR(DB_TXN_NOT_DURABLE);
+
+	ret = __db_remove_int(dbp, ip, txn, name, subdb, flags);
+
+	if (txn_local) {
+		/*
+		 * We created the DBP here and when we commit/abort, we'll
+		 * release all the transactional locks, including the handle
+		 * lock; mark the handle cleared explicitly.
+		 */
+		LOCK_INIT(dbp->handle_lock);
+		dbp->locker = NULL;
+	} else if (IS_REAL_TXN(txn)) {
+		/*
+		 * We created this handle locally so we need to close it
+		 * and clean it up.  Unfortunately, it's holding transactional
+		 * locks that need to persist until the end of transaction.
+		 * If we invalidate the locker id (dbp->locker), then the close
+		 * won't free these locks prematurely.
+		 */
+		 dbp->locker = NULL;
+	}
+
+err:	if (txn_local && (t_ret =
+	    __db_txn_auto_resolve(env, txn, 0, ret)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * We never opened this dbp for real, so don't include a transaction
+	 * handle, and use NOSYNC to avoid calling into mpool.
+	 *
+	 * !!!
+	 * Note we're reversing the order of operations: we started the txn and
+	 * then opened the DB handle; we're resolving the txn and then closing
+	 * closing the DB handle -- a DB handle cannot be closed before
+	 * resolving the txn.
+	 */
+	if (dbp != NULL &&
+	    (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_remove_pp
+ *	DB->remove pre/post processing.
+ *
+ * PUBLIC: int __db_remove_pp
+ * PUBLIC:     __P((DB *, const char *, const char *, u_int32_t));
+ */
+int
+__db_remove_pp(dbp, name, subdb, flags)
+	DB *dbp;
+	const char *name, *subdb;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret;
+
+	env = dbp->env;
+
+	/*
+	 * Validate arguments, continuing to destroy the handle on failure.
+	 *
+	 * Cannot use DB_ILLEGAL_AFTER_OPEN directly because it returns.
+	 *
+	 * !!!
+	 * We have a serious problem if we're here with a handle used to open
+	 * a database -- we'll destroy the handle, and the application won't
+	 * ever be able to close the database.
+	 */
+	if (F_ISSET(dbp, DB_AM_OPEN_CALLED))
+		return (__db_mi_open(env, "DB->remove", 1));
+
+	/* Validate arguments. */
+	if ((ret = __db_fchk(env, "DB->remove", flags, DB_NOSYNC)) != 0)
+		return (ret);
+
+	/* Check for consistent transaction usage. */
+	if ((ret = __db_check_txn(dbp, NULL, DB_LOCK_INVALIDID, 0)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check && (ret = __db_rep_enter(dbp, 1, 1, 0)) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	/* Remove the file. */
+	ret = __db_remove(dbp, ip, NULL, name, subdb, flags);
+
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+err:	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_remove
+ *	DB->remove method.
+ *
+ * PUBLIC: int __db_remove __P((DB *, DB_THREAD_INFO *,
+ * PUBLIC:     DB_TXN *, const char *, const char *, u_int32_t));
+ */
+int
+__db_remove(dbp, ip, txn, name, subdb, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name, *subdb;
+	u_int32_t flags;
+{
+	int ret, t_ret;
+
+	ret = __db_remove_int(dbp, ip, txn, name, subdb, flags);
+
+	if ((t_ret = __db_close(dbp, txn, DB_NOSYNC)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __db_remove_int
+ *	Worker function for the DB->remove method.
+ *
+ * PUBLIC: int __db_remove_int __P((DB *, DB_THREAD_INFO *,
+ * PUBLIC:    DB_TXN *, const char *, const char *, u_int32_t));
+ */
+int
+__db_remove_int(dbp, ip, txn, name, subdb, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name, *subdb;
+	u_int32_t flags;
+{
+	ENV *env;
+	int ret;
+	char *real_name, *tmpname;
+
+	env = dbp->env;
+	real_name = tmpname = NULL;
+
+	if (name == NULL && subdb == NULL) {
+		__db_errx(env, DB_STR("0691",
+		    "Remove on temporary files invalid"));
+		ret = EINVAL;
+		goto err;
+	}
+
+	if (name == NULL) {
+		MAKE_INMEM(dbp);
+		real_name = (char *)subdb;
+	} else if (subdb != NULL) {
+		ret = __db_subdb_remove(dbp, ip, txn, name, subdb, flags);
+		goto err;
+	}
+
+	/* Handle transactional file removes separately. */
+	if (IS_REAL_TXN(txn)) {
+		ret = __db_dbtxn_remove(dbp, ip, txn, name, subdb);
+		goto err;
+	}
+
+	/*
+	 * The remaining case is a non-transactional file remove.
+	 *
+	 * Find the real name of the file.
+	 */
+	if (!F_ISSET(dbp, DB_AM_INMEM) && (ret = __db_appname(env,
+	    DB_APP_DATA, name, &dbp->dirname, &real_name)) != 0)
+		goto err;
+
+	/*
+	 * If this is a file and force is set, remove the temporary file, which
+	 * may have been left around.  Ignore errors because the temporary file
+	 * might not exist.
+	 */
+	if (!F_ISSET(dbp, DB_AM_INMEM) && LF_ISSET(DB_FORCE) &&
+	    (ret = __db_backup_name(env, real_name, NULL, &tmpname)) == 0)
+		(void)__os_unlink(env, tmpname, 0);
+
+	if ((ret = __fop_remove_setup(dbp, NULL, real_name, 0)) != 0)
+		goto err;
+
+	if (dbp->db_am_remove != NULL &&
+	    (ret = dbp->db_am_remove(dbp, ip, NULL, name, subdb, flags)) != 0)
+		goto err;
+
+	ret = F_ISSET(dbp, DB_AM_INMEM) ?
+	    __db_inmem_remove(dbp, NULL, real_name) :
+	    __fop_remove(env,
+	    NULL, dbp->fileid, name, &dbp->dirname, DB_APP_DATA,
+	    F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0);
+
+err:	if (!F_ISSET(dbp, DB_AM_INMEM) && real_name != NULL)
+		__os_free(env, real_name);
+	if (tmpname != NULL)
+		__os_free(env, tmpname);
+
+	return (ret);
+}
+
+/*
+ * __db_inmem_remove --
+ *	Removal of a named in-memory database.
+ *
+ * PUBLIC: int __db_inmem_remove __P((DB *, DB_TXN *, const char *));
+ */
+int
+__db_inmem_remove(dbp, txn, name)
+	DB *dbp;
+	DB_TXN *txn;
+	const char *name;
+{
+	DBT fid_dbt, name_dbt;
+	DB_LOCKER *locker;
+	DB_LSN lsn;
+	ENV *env;
+	int ret;
+
+	env = dbp->env;
+	locker = NULL;
+
+	DB_ASSERT(env, name != NULL);
+
+	/* This had better exist if we are trying to do a remove. */
+	(void)__memp_set_flags(dbp->mpf, DB_MPOOL_NOFILE, 1);
+	if ((ret = __memp_fopen(dbp->mpf, NULL,
+	    name, &dbp->dirname, 0, 0, 0)) != 0)
+		return (ret);
+	if ((ret = __memp_get_fileid(dbp->mpf, dbp->fileid)) != 0)
+		return (ret);
+	dbp->preserve_fid = 1;
+
+	if (LOCKING_ON(env)) {
+		if (dbp->locker == NULL &&
+		    (ret = __lock_id(env, NULL, &dbp->locker)) != 0)
+			return (ret);
+		if (!CDB_LOCKING(env) &&
+		    txn != NULL && F_ISSET(txn, TXN_INFAMILY)) {
+			if ((ret = __lock_addfamilylocker(env,
+			    txn->txnid, dbp->locker->id, 1)) != 0)
+				return (ret);
+			txn = NULL;
+		}
+		locker = txn == NULL ? dbp->locker : txn->locker;
+	}
+
+	/*
+	 * In a transactional environment, we'll play the same game we play
+	 * for databases in the file system -- create a temporary database
+	 * and put it in with the current name and then rename this one to
+	 * another name.  We'll then use a commit-time event to remove the
+	 * entry.
+	 */
+	if ((ret =
+	    __fop_lock_handle(env, dbp, locker, DB_LOCK_WRITE, NULL, 0)) != 0)
+		return (ret);
+
+	if (!IS_REAL_TXN(txn))
+		ret = __memp_nameop(env, dbp->fileid, NULL, name, NULL, 1);
+	else if (LOGGING_ON(env)) {
+		if (txn != NULL && (ret =
+		    __txn_remevent(env, txn, name, dbp->fileid, 1)) != 0)
+			return (ret);
+
+		DB_INIT_DBT(name_dbt, name, strlen(name) + 1);
+		DB_INIT_DBT(fid_dbt, dbp->fileid, DB_FILE_ID_LEN);
+		ret = __crdel_inmem_remove_log(
+		    env, txn, &lsn, 0, &name_dbt, &fid_dbt);
+	}
+
+	return (ret);
+}
+
+/*
+ * __db_subdb_remove --
+ *	Remove a subdatabase.
+ */
+static int
+__db_subdb_remove(dbp, ip, txn, name, subdb, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name, *subdb;
+	u_int32_t flags;
+{
+	DB *mdbp, *sdbp;
+	int ret, t_ret;
+
+	mdbp = sdbp = NULL;
+
+	/* Open the subdatabase. */
+	if ((ret = __db_create_internal(&sdbp, dbp->env, 0)) != 0)
+		goto err;
+	if (F_ISSET(dbp, DB_AM_NOT_DURABLE) &&
+		(ret = __db_set_flags(sdbp, DB_TXN_NOT_DURABLE)) != 0)
+		goto err;
+	if ((ret = __db_open(sdbp, ip,
+	    txn, name, subdb, DB_UNKNOWN, DB_WRITEOPEN, 0, PGNO_BASE_MD)) != 0)
+		goto err;
+
+	DB_TEST_RECOVERY(sdbp, DB_TEST_PREDESTROY, ret, name);
+
+	/* Have the handle locked so we will not lock pages. */
+	LOCK_CHECK_OFF(ip);
+
+	/* Free up the pages in the subdatabase. */
+	switch (sdbp->type) {
+		case DB_BTREE:
+		case DB_RECNO:
+			if ((ret = __bam_reclaim(sdbp, ip, txn, flags)) != 0)
+				goto err;
+			break;
+		case DB_HASH:
+			if ((ret = __ham_reclaim(sdbp, ip, txn, flags)) != 0)
+				goto err;
+			break;
+		case DB_QUEUE:
+		case DB_UNKNOWN:
+		default:
+			ret = __db_unknown_type(
+			    sdbp->env, "__db_subdb_remove", sdbp->type);
+			goto err;
+	}
+
+	/*
+	 * Remove the entry from the main database and free the subdatabase
+	 * metadata page.
+	 */
+	if ((ret = __db_master_open(sdbp, ip, txn, name, 0, 0, &mdbp)) != 0)
+		goto err;
+
+	if ((ret = __db_master_update(mdbp,
+	    sdbp, ip, txn, subdb, sdbp->type, MU_REMOVE, NULL, 0)) != 0)
+		goto err;
+
+	DB_TEST_RECOVERY(sdbp, DB_TEST_POSTDESTROY, ret, name);
+
+DB_TEST_RECOVERY_LABEL
+err:
+	/* Close the main and subdatabases. */
+	if ((t_ret = __db_close(sdbp, txn, DB_NOSYNC)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (mdbp != NULL && (t_ret = __db_close(mdbp, txn,
+	    (LF_ISSET(DB_NOSYNC) || txn != NULL) ? DB_NOSYNC : 0)) != 0 &&
+	    ret == 0)
+		ret = t_ret;
+
+	LOCK_CHECK_ON(ip);
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_rename.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,405 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/fop.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+static int __db_rename __P((DB *, DB_THREAD_INFO *,
+	     DB_TXN *, const char *, const char *, const char *, u_int32_t));
+static int __db_subdb_rename __P((DB *, DB_THREAD_INFO *,
+	     DB_TXN *, const char *, const char *, const char *, u_int32_t));
+
+/*
+ * __env_dbrename_pp
+ *	ENV->dbrename pre/post processing.
+ *
+ * PUBLIC: int __env_dbrename_pp __P((DB_ENV *, DB_TXN *,
+ * PUBLIC:     const char *, const char *, const char *, u_int32_t));
+ */
+int
+__env_dbrename_pp(dbenv, txn, name, subdb, newname, flags)
+	DB_ENV *dbenv;
+	DB_TXN *txn;
+	const char *name, *subdb, *newname;
+	u_int32_t flags;
+{
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret, txn_local;
+
+	env = dbenv->env;
+	dbp = NULL;
+	txn_local = 0;
+	handle_check = 0;
+
+	ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->dbrename");
+
+	/*
+	 * The actual argument checking is simple, do it inline, outside of
+	 * the replication block.
+	 */
+	if ((ret = __db_fchk(env, "DB->rename", flags,
+	    DB_AUTO_COMMIT | DB_NOSYNC)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+	XA_NO_TXN(ip, ret);
+	if (ret != 0)
+		goto err;
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check && (ret = __env_rep_enter(env, 1)) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	/*
+	 * Create local transaction as necessary, check for consistent
+	 * transaction usage.
+	 */
+	if (IS_ENV_AUTO_COMMIT(env, txn, flags)) {
+		if ((ret = __db_txn_auto_init(env, ip, &txn)) != 0)
+			goto err;
+		txn_local = 1;
+	} else
+		if (txn != NULL && !TXN_ON(env) &&
+		    (!CDB_LOCKING(env) || !F_ISSET(txn, TXN_FAMILY))) {
+			ret = __db_not_txn_env(env);
+			goto err;
+		}
+
+	LF_CLR(DB_AUTO_COMMIT);
+
+	if ((ret = __db_create_internal(&dbp, env, 0)) != 0)
+		goto err;
+
+	ret = __db_rename_int(dbp, ip, txn, name, subdb, newname, flags);
+
+	if (txn_local) {
+		/*
+		 * We created the DBP here and when we commit/abort, we'll
+		 * release all the transactional locks, including the handle
+		 * lock; mark the handle cleared explicitly.
+		 */
+		LOCK_INIT(dbp->handle_lock);
+		dbp->locker = NULL;
+	} else if (IS_REAL_TXN(txn)) {
+		/*
+		 * We created this handle locally so we need to close it and
+		 * clean it up.  Unfortunately, it's holding transactional
+		 * or CDS group locks that need to persist until the end of
+		 * transaction.  If we invalidate the locker (dbp->locker),
+		 * then the close won't free these locks prematurely.
+		 */
+		 dbp->locker = NULL;
+	}
+
+err:	if (txn_local && (t_ret =
+	    __db_txn_auto_resolve(env, txn, 0, ret)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * We never opened this dbp for real, so don't include a transaction
+	 * handle, and use NOSYNC to avoid calling into mpool.
+	 *
+	 * !!!
+	 * Note we're reversing the order of operations: we started the txn and
+	 * then opened the DB handle; we're resolving the txn and then closing
+	 * closing the DB handle -- it's safer.
+	 */
+	if (dbp != NULL &&
+	    (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_rename_pp
+ *	DB->rename pre/post processing.
+ *
+ * PUBLIC: int __db_rename_pp __P((DB *,
+ * PUBLIC:     const char *, const char *, const char *, u_int32_t));
+ */
+int
+__db_rename_pp(dbp, name, subdb, newname, flags)
+	DB *dbp;
+	const char *name, *subdb, *newname;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret;
+
+	env = dbp->env;
+	handle_check = 0;
+
+	/*
+	 * Validate arguments, continuing to destroy the handle on failure.
+	 *
+	 * Cannot use DB_ILLEGAL_AFTER_OPEN directly because it returns.
+	 *
+	 * !!!
+	 * We have a serious problem if we're here with a handle used to open
+	 * a database -- we'll destroy the handle, and the application won't
+	 * ever be able to close the database.
+	 */
+	if (F_ISSET(dbp, DB_AM_OPEN_CALLED))
+		return (__db_mi_open(env, "DB->rename", 1));
+
+	/* Validate arguments. */
+	if ((ret = __db_fchk(env, "DB->rename", flags, DB_NOSYNC)) != 0)
+		return (ret);
+
+	/* Check for consistent transaction usage. */
+	if ((ret = __db_check_txn(dbp, NULL, DB_LOCK_INVALIDID, 0)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check && (ret = __db_rep_enter(dbp, 1, 1, 0)) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	/* Rename the file. */
+	ret = __db_rename(dbp, ip, NULL, name, subdb, newname, flags);
+
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+err:	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_rename
+ *	DB->rename method.
+ *
+ */
+static int
+__db_rename(dbp, ip, txn, name, subdb, newname, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name, *subdb, *newname;
+	u_int32_t flags;
+{
+	int ret, t_ret;
+
+	ret = __db_rename_int(dbp, ip, txn, name, subdb, newname, flags);
+
+	if ((t_ret = __db_close(dbp, txn, DB_NOSYNC)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __db_rename_int
+ *	Worker function for DB->rename method; the close of the dbp is
+ * left in the wrapper routine.
+ *
+ * PUBLIC: int __db_rename_int __P((DB *, DB_THREAD_INFO *,
+ * PUBLIC:      DB_TXN *, const char *, const char *, const char *, u_int32_t));
+ */
+int
+__db_rename_int(dbp, ip, txn, name, subdb, newname, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name, *subdb, *newname;
+	u_int32_t flags;
+{
+	ENV *env;
+	int ret;
+	char *old, *real_name;
+
+	env = dbp->env;
+	real_name = NULL;
+
+	DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, name);
+
+	if (name == NULL && subdb == NULL) {
+		__db_errx(env, DB_STR("0503",
+		    "Rename on temporary files invalid"));
+		ret = EINVAL;
+		goto err;
+	}
+
+	if (name == NULL)
+		MAKE_INMEM(dbp);
+	else if (subdb != NULL) {
+		ret = __db_subdb_rename(dbp, ip,
+		    txn, name, subdb, newname, flags);
+		goto err;
+	}
+
+	/*
+	 * From here on down, this pertains to files or in-memory databases.
+	 *
+	 * Find the real name of the file.
+	 */
+	if (F_ISSET(dbp, DB_AM_INMEM)) {
+		old = (char *)subdb;
+		real_name = (char *)subdb;
+	} else {
+		if ((ret = __db_appname(env, DB_APP_DATA,
+		    name, &dbp->dirname, &real_name)) != 0)
+			goto err;
+		old = (char *)name;
+	}
+	DB_ASSERT(env, old != NULL);
+
+	if ((ret = __fop_remove_setup(dbp, txn, real_name, 0)) != 0)
+		goto err;
+
+	if (dbp->db_am_rename != NULL &&
+	    (ret = dbp->db_am_rename(dbp, ip, txn, name, subdb, newname)) != 0)
+		goto err;
+
+	/*
+	 * The transactional case and non-transactional case are
+	 * quite different.  In the non-transactional case, we simply
+	 * do the rename.  In the transactional case, since we need
+	 * the ability to back out and maintain locking, we have to
+	 * create a temporary object as a placeholder.  This is all
+	 * taken care of in the fop layer.
+	 */
+	if (IS_REAL_TXN(txn)) {
+		if ((ret = __fop_dummy(dbp, txn, old, newname)) != 0)
+			goto err;
+	} else {
+		if ((ret = __fop_dbrename(dbp, old, newname)) != 0)
+			goto err;
+	}
+
+	/*
+	 * I am pretty sure that we haven't gotten a dbreg id, so calling
+	 * dbreg_filelist_update is not necessary.
+	 */
+	DB_ASSERT(env, dbp->log_filename == NULL ||
+	    dbp->log_filename->id == DB_LOGFILEID_INVALID);
+
+	DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, newname);
+
+DB_TEST_RECOVERY_LABEL
+err:	if (!F_ISSET(dbp, DB_AM_INMEM) && real_name != NULL)
+		__os_free(env, real_name);
+
+	return (ret);
+}
+
+/*
+ * __db_subdb_rename --
+ *	Rename a subdatabase.
+ */
+static int
+__db_subdb_rename(dbp, ip, txn, name, subdb, newname, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name, *subdb, *newname;
+	u_int32_t flags;
+{
+	DB *mdbp;
+	ENV *env;
+	PAGE *meta;
+	int ret, t_ret;
+
+	mdbp = NULL;
+	meta = NULL;
+	env = dbp->env;
+
+	/*
+	 * We have not opened this dbp so it isn't marked as a subdb,
+	 * but it ought to be.
+	 */
+	F_SET(dbp, DB_AM_SUBDB);
+
+	/*
+	 * Rename the entry in the main database.  We need to first
+	 * get the meta-data page number (via MU_OPEN) so that we can
+	 * read the meta-data page and obtain a handle lock.  Once we've
+	 * done that, we can proceed to do the rename in the master.
+	 */
+	if ((ret = __db_master_open(dbp, ip, txn, name, 0, 0, &mdbp)) != 0)
+		goto err;
+
+	if ((ret = __db_master_update(mdbp, dbp, ip, txn, subdb, dbp->type,
+	    MU_OPEN, NULL, 0)) != 0)
+		goto err;
+
+	if ((ret = __memp_fget(mdbp->mpf, &dbp->meta_pgno,
+	    ip, txn, 0, &meta)) != 0)
+		goto err;
+	memcpy(dbp->fileid, ((DBMETA *)meta)->uid, DB_FILE_ID_LEN);
+	if ((ret = __fop_lock_handle(env, dbp,
+	    (mdbp->cur_locker != NULL) ? mdbp->cur_locker : mdbp->locker,
+	    DB_LOCK_WRITE, NULL, NOWAIT_FLAG(txn))) != 0)
+		goto err;
+
+	ret = __memp_fput(mdbp->mpf, ip, meta, dbp->priority);
+	meta = NULL;
+	if (ret != 0)
+		goto err;
+
+	if ((ret = __db_master_update(mdbp, dbp, ip, txn,
+	    subdb, dbp->type, MU_RENAME, newname, 0)) != 0)
+		goto err;
+
+	DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, name);
+
+DB_TEST_RECOVERY_LABEL
+err:
+	if (meta != NULL && (t_ret =
+	    __memp_fput(mdbp->mpf, ip, meta, dbp->priority)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (mdbp != NULL && (t_ret = __db_close(mdbp, txn,
+	    (LF_ISSET(DB_NOSYNC) || txn != NULL) ? DB_NOSYNC : 0)) != 0 &&
+	    ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_ret.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,259 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/heap.h"
+
+/*
+ * __db_ret --
+ *	Build return DBT.
+ *
+ * PUBLIC: int __db_ret __P((DBC *,
+ * PUBLIC:    PAGE *, u_int32_t, DBT *, void **, u_int32_t *));
+ */
+int
+__db_ret(dbc, h, indx, dbt, memp, memsize)
+	DBC *dbc;
+	PAGE *h;
+	u_int32_t indx;
+	DBT *dbt;
+	void **memp;
+	u_int32_t *memsize;
+{
+	BKEYDATA *bk;
+	BOVERFLOW *bo;
+	DB *dbp;
+	HEAPHDR *hdr;
+	HOFFPAGE ho;
+	u_int32_t len;
+	u_int8_t *hk;
+	void *data;
+
+	if (F_ISSET(dbt, DB_DBT_READONLY))
+		return (0);
+	dbp = dbc->dbp;
+
+	switch (TYPE(h)) {
+	case P_HASH_UNSORTED:
+	case P_HASH:
+		hk = P_ENTRY(dbp, h, indx);
+		if (HPAGE_PTYPE(hk) == H_OFFPAGE) {
+			memcpy(&ho, hk, sizeof(HOFFPAGE));
+			return (__db_goff(dbc, dbt,
+			    ho.tlen, ho.pgno, memp, memsize));
+		}
+		len = LEN_HKEYDATA(dbp, h, dbp->pgsize, indx);
+		data = HKEYDATA_DATA(hk);
+		break;
+	case P_HEAP:
+		hdr = (HEAPHDR *)P_ENTRY(dbp, h, indx);
+		if (F_ISSET(hdr,(HEAP_RECSPLIT | HEAP_RECFIRST)))
+			return (__heapc_gsplit(dbc, dbt, memp, memsize));
+		len = hdr->size;
+		data = (u_int8_t *)hdr + sizeof(HEAPHDR);
+		break;
+	case P_LBTREE:
+	case P_LDUP:
+	case P_LRECNO:
+		bk = GET_BKEYDATA(dbp, h, indx);
+		if (B_TYPE(bk->type) == B_OVERFLOW) {
+			bo = (BOVERFLOW *)bk;
+			return (__db_goff(dbc, dbt,
+			    bo->tlen, bo->pgno, memp, memsize));
+		}
+		len = bk->len;
+		data = bk->data;
+		break;
+	default:
+		return (__db_pgfmt(dbp->env, h->pgno));
+	}
+
+	return (__db_retcopy(dbp->env, dbt, data, len, memp, memsize));
+}
+
+/*
+ * __db_retcopy --
+ *	Copy the returned data into the user's DBT, handling special flags.
+ *
+ * PUBLIC: int __db_retcopy __P((ENV *, DBT *,
+ * PUBLIC:    void *, u_int32_t, void **, u_int32_t *));
+ */
+int
+__db_retcopy(env, dbt, data, len, memp, memsize)
+	ENV *env;
+	DBT *dbt;
+	void *data;
+	u_int32_t len;
+	void **memp;
+	u_int32_t *memsize;
+{
+	int ret;
+
+	if (F_ISSET(dbt, DB_DBT_READONLY))
+		return (0);
+	ret = 0;
+
+	/* If returning a partial record, reset the length. */
+	if (F_ISSET(dbt, DB_DBT_PARTIAL)) {
+		data = (u_int8_t *)data + dbt->doff;
+		if (len > dbt->doff) {
+			len -= dbt->doff;
+			if (len > dbt->dlen)
+				len = dbt->dlen;
+		} else
+			len = 0;
+	}
+
+	/*
+	 * Allocate memory to be owned by the application: DB_DBT_MALLOC,
+	 * DB_DBT_REALLOC.
+	 *
+	 * !!!
+	 * We always allocate memory, even if we're copying out 0 bytes. This
+	 * guarantees consistency, i.e., the application can always free memory
+	 * without concern as to how many bytes of the record were requested.
+	 *
+	 * Use the memory specified by the application: DB_DBT_USERMEM.
+	 *
+	 * !!!
+	 * If the length we're going to copy is 0, the application-supplied
+	 * memory pointer is allowed to be NULL.
+	 */
+	if (F_ISSET(dbt, DB_DBT_USERCOPY)) {
+		dbt->size = len;
+		return (len == 0 ? 0 : env->dbt_usercopy(dbt, 0, data,
+		    len, DB_USERCOPY_SETDATA));
+
+	} else if (F_ISSET(dbt, DB_DBT_MALLOC))
+		ret = __os_umalloc(env, len, &dbt->data);
+	else if (F_ISSET(dbt, DB_DBT_REALLOC)) {
+		if (dbt->data == NULL || dbt->size == 0 || dbt->size < len)
+			ret = __os_urealloc(env, len, &dbt->data);
+	} else if (F_ISSET(dbt, DB_DBT_USERMEM)) {
+		if (len != 0 && (dbt->data == NULL || dbt->ulen < len))
+			ret = DB_BUFFER_SMALL;
+	} else if (memp == NULL || memsize == NULL)
+		ret = EINVAL;
+	else {
+		if (len != 0 && (*memsize == 0 || *memsize < len)) {
+			if ((ret = __os_realloc(env, len, memp)) == 0)
+				*memsize = len;
+			else
+				*memsize = 0;
+		}
+		if (ret == 0)
+			dbt->data = *memp;
+	}
+
+	if (ret == 0 && len != 0)
+		memcpy(dbt->data, data, len);
+
+	/*
+	 * Return the length of the returned record in the DBT size field.
+	 * This satisfies the requirement that if we're using user memory
+	 * and insufficient memory was provided, return the amount necessary
+	 * in the size field.
+	 */
+	dbt->size = len;
+
+	return (ret);
+}
+
+/*
+ * __db_dbt_clone --
+ *	Clone a DBT from another DBT.
+ * The input dest DBT must be a zero initialized DBT that will be populated.
+ * The function does not allocate a dest DBT to allow for cloning into stack
+ * or locally allocated variables. It is the callers responsibility to free
+ * the memory allocated in dest->data. 
+ *
+ * PUBLIC: int __db_dbt_clone __P((ENV *, DBT *, const DBT *));
+ */
+int
+__db_dbt_clone(env, dest, src)
+	ENV *env;
+	DBT *dest;
+	const DBT *src;
+{
+	u_int32_t err_flags;
+	int ret;
+
+	DB_ASSERT(env, dest->data == NULL);
+
+	ret = 0;
+
+	/* The function does not support the following DBT flags. */
+	err_flags = DB_DBT_MALLOC | DB_DBT_REALLOC |
+	    DB_DBT_MULTIPLE | DB_DBT_PARTIAL;
+	if (F_ISSET(src, err_flags)) {
+		__db_errx(env, DB_STR("0750",
+		    "Unsupported flags when cloning the DBT."));
+		return (EINVAL);
+	}
+	
+	if ((ret = __os_malloc(env, src->size, &dest->data)) != 0)
+		return (ret);
+
+	memcpy(dest->data, src->data, src->size);
+	dest->ulen = src->size;
+	dest->size = src->size;
+	dest->flags = DB_DBT_USERMEM;
+
+	return (ret);
+}
+
+/*
+ * __db_dbt_clone_free --
+ *	Free a DBT cloned by __db_dbt_clone
+ *
+ * PUBLIC: int __db_dbt_clone_free __P((ENV *, DBT *));
+ */
+int
+__db_dbt_clone_free(env, dbt)
+	ENV *env;
+	DBT *dbt;
+{
+	/* Currently only DB_DBT_USERMEM is supported. */
+	if (dbt->flags != DB_DBT_USERMEM) {
+		__db_errx(env, DB_STR("0751",
+		    "Unsupported flags when freeing the cloned DBT."));
+		return (EINVAL);
+	}
+
+	if (dbt->data != NULL)
+		__os_free(env, dbt->data);
+	dbt->size = dbt->ulen = 0;
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_setid.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,235 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2000, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_swap.h"
+#include "dbinc/db_am.h"
+#include "dbinc/mp.h"
+
+/*
+ * __env_fileid_reset_pp --
+ *	ENV->fileid_reset pre/post processing.
+ *
+ * PUBLIC: int __env_fileid_reset_pp __P((DB_ENV *, const char *, u_int32_t));
+ */
+int
+__env_fileid_reset_pp(dbenv, name, flags)
+	DB_ENV *dbenv;
+	const char *name;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->fileid_reset");
+
+	/*
+	 * !!!
+	 * The actual argument checking is simple, do it inline, outside of
+	 * the replication block.
+	 */
+	if (flags != 0 && flags != DB_ENCRYPT)
+		return (__db_ferr(env, "DB_ENV->fileid_reset", 0));
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env,
+	    (__env_fileid_reset(env, ip, name, LF_ISSET(DB_ENCRYPT) ? 1 : 0)),
+	    1, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __env_fileid_reset --
+ *	Reset the file IDs for every database in the file.
+ * PUBLIC: int __env_fileid_reset
+ * PUBLIC:	 __P((ENV *, DB_THREAD_INFO *, const char *, int));
+ */
+int
+__env_fileid_reset(env, ip, name, encrypted)
+	ENV *env;
+	DB_THREAD_INFO *ip;
+	const char *name;
+	int encrypted;
+{
+	DB *dbp;
+	DBC *dbcp;
+	DBMETA *meta;
+	DBT key, data;
+	DB_FH *fhp;
+	DB_MPOOLFILE *mpf;
+	DB_PGINFO cookie;
+	db_pgno_t pgno;
+	int subdb, t_ret, ret;
+	size_t n;
+	char *real_name;
+	u_int8_t fileid[DB_FILE_ID_LEN], mbuf[DBMETASIZE];
+	void *pagep;
+
+	dbp = NULL;
+	dbcp = NULL;
+	fhp = NULL;
+	real_name = NULL;
+
+	/* Get the real backing file name. */
+	if ((ret = __db_appname(env,
+	    DB_APP_DATA, name, NULL, &real_name)) != 0)
+		return (ret);
+
+	/* Get a new file ID. */
+	if ((ret = __os_fileid(env, real_name, 1, fileid)) != 0)
+		goto err;
+
+	/*
+	 * The user may have physically copied a file currently open in the
+	 * cache, which means if we open this file through the cache before
+	 * updating the file ID on page 0, we might connect to the file from
+	 * which the copy was made.
+	 */
+	if ((ret = __os_open(env, real_name, 0, 0, 0, &fhp)) != 0) {
+		__db_err(env, ret, "%s", real_name);
+		goto err;
+	}
+	if ((ret = __os_read(env, fhp, mbuf, sizeof(mbuf), &n)) != 0)
+		goto err;
+
+	if (n != sizeof(mbuf)) {
+		ret = EINVAL;
+		__db_errx(env, DB_STR_A("0675",
+		    "__env_fileid_reset: %s: unexpected file type or format",
+		    "%s"), real_name);
+		goto err;
+	}
+
+	/*
+	 * Create the DB object.
+	 */
+	if ((ret = __db_create_internal(&dbp, env, 0)) != 0)
+		goto err;
+
+	/* If configured with a password, the databases are encrypted. */
+	if (encrypted && (ret = __db_set_flags(dbp, DB_ENCRYPT)) != 0)
+		goto err;
+
+	if ((ret = __db_meta_setup(env,
+	    dbp, real_name, (DBMETA *)mbuf, 0, DB_CHK_META)) != 0)
+		goto err;
+
+	meta = (DBMETA *)mbuf;
+	if (FLD_ISSET(meta->metaflags,
+	    DBMETA_PART_RANGE | DBMETA_PART_CALLBACK) && (ret =
+	    __part_fileid_reset(env, ip, name, meta->nparts, encrypted)) != 0)
+		goto err;
+
+	subdb = meta->type == P_BTREEMETA && F_ISSET(meta, BTM_SUBDB);
+
+	memcpy(meta->uid, fileid, DB_FILE_ID_LEN);
+	cookie.db_pagesize = sizeof(mbuf);
+	cookie.flags = dbp->flags;
+	cookie.type = dbp->type;
+	key.data = &cookie;
+
+	if ((ret = __db_pgout(env->dbenv, 0, mbuf, &key)) != 0)
+		goto err;
+	if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0)
+		goto err;
+	if ((ret = __os_write(env, fhp, mbuf, sizeof(mbuf), &n)) != 0)
+		goto err;
+	if ((ret = __os_fsync(env, fhp)) != 0)
+		goto err;
+
+	/*
+	 * Page 0 of the file has an updated file ID, and we can open it in
+	 * the cache without connecting to a different, existing file.  Open
+	 * the file in the cache, and update the file IDs for subdatabases.
+	 */
+
+	/*
+	 * If the database file doesn't support subdatabases, we only have
+	 * to update a single metadata page.  Otherwise, we have to open a
+	 * cursor and step through the master database, and update all of
+	 * the subdatabases' metadata pages.
+	 */
+	if (!subdb)
+		goto err;
+
+	/*
+	 * Open the DB file.
+	 *
+	 * !!!
+	 * Note DB_RDWRMASTER flag, we need to open the master database file
+	 * for writing in this case.
+	 */
+	if ((ret = __db_open(dbp, ip, NULL,
+	    name, NULL, DB_UNKNOWN, DB_RDWRMASTER, 0, PGNO_BASE_MD)) != 0)
+		goto err;
+
+	mpf = dbp->mpf;
+	memset(&key, 0, sizeof(key));
+	memset(&data, 0, sizeof(data));
+	if ((ret = __db_cursor(dbp, ip, NULL, &dbcp, 0)) != 0)
+		goto err;
+	while ((ret = __dbc_get(dbcp, &key, &data, DB_NEXT)) == 0) {
+		/*
+		 * XXX
+		 * We're handling actual data, not on-page meta-data, so it
+		 * hasn't been converted to/from opposite endian architectures.
+		 * Do it explicitly, now.
+		 */
+		memcpy(&pgno, data.data, sizeof(db_pgno_t));
+		DB_NTOHL_SWAP(env, &pgno);
+		if ((ret = __memp_fget(mpf, &pgno, ip, NULL,
+		    DB_MPOOL_DIRTY, &pagep)) != 0)
+			goto err;
+		memcpy(((DBMETA *)pagep)->uid, fileid, DB_FILE_ID_LEN);
+		if ((ret = __memp_fput(mpf, ip, pagep, dbcp->priority)) != 0)
+			goto err;
+	}
+	if (ret == DB_NOTFOUND)
+		ret = 0;
+
+err:	if (dbcp != NULL && (t_ret = __dbc_close(dbcp)) != 0 && ret == 0)
+		ret = t_ret;
+	if (dbp != NULL && (t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0)
+		ret = t_ret;
+	if (fhp != NULL &&
+	    (t_ret = __os_closehandle(env, fhp)) != 0 && ret == 0)
+		ret = t_ret;
+	if (real_name != NULL)
+		__os_free(env, real_name);
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_setlsn.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,159 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2000, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+#include "dbinc/qam.h"
+
+static int __env_lsn_reset __P((ENV *, DB_THREAD_INFO *, const char *, int));
+
+/*
+ * __env_lsn_reset_pp --
+ *	ENV->lsn_reset pre/post processing.
+ *
+ * PUBLIC: int __env_lsn_reset_pp __P((DB_ENV *, const char *, u_int32_t));
+ */
+int
+__env_lsn_reset_pp(dbenv, name, flags)
+	DB_ENV *dbenv;
+	const char *name;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->lsn_reset");
+
+	/*
+	 * !!!
+	 * The actual argument checking is simple, do it inline, outside of
+	 * the replication block.
+	 */
+	if (flags != 0 && flags != DB_ENCRYPT)
+		return (__db_ferr(env, "DB_ENV->lsn_reset", 0));
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env,
+	    (__env_lsn_reset(env, ip, name, LF_ISSET(DB_ENCRYPT) ? 1 : 0)),
+	    1, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __env_lsn_reset --
+ *	Reset the LSNs for every page in the file.
+ */
+static int
+__env_lsn_reset(env, ip, name, encrypted)
+	ENV *env;
+	DB_THREAD_INFO *ip;
+	const char *name;
+	int encrypted;
+{
+	DB *dbp;
+	int t_ret, ret;
+
+	/* Create the DB object. */
+	if ((ret = __db_create_internal(&dbp, env, 0)) != 0)
+		return (ret);
+
+	/* If configured with a password, the databases are encrypted. */
+	if (encrypted && (ret = __db_set_flags(dbp, DB_ENCRYPT)) != 0)
+		goto err;
+
+	/*
+	 * Open the DB file.
+	 *
+	 * !!!
+	 * Note DB_RDWRMASTER flag, we need to open the master database file
+	 * for writing in this case.
+	 */
+	if ((ret = __db_open(dbp, ip, NULL,
+	    name, NULL, DB_UNKNOWN, DB_RDWRMASTER, 0, PGNO_BASE_MD)) != 0) {
+		__db_err(env, ret, "%s", name);
+		goto err;
+	}
+
+	ret = __db_lsn_reset(dbp->mpf, ip);
+#ifdef HAVE_PARTITION
+	if (ret == 0 && DB_IS_PARTITIONED(dbp))
+		ret = __part_lsn_reset(dbp, ip);
+	else
+#endif
+	if (ret == 0 && dbp->type == DB_QUEUE)
+#ifdef HAVE_QUEUE
+		ret = __qam_lsn_reset(dbp, ip);
+#else
+		ret = __db_no_queue_am(env);
+#endif
+
+err:	if ((t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+/*
+ * __db_lsn_reset -- reset the lsn for a db mpool handle.
+ * PUBLIC: int __db_lsn_reset __P((DB_MPOOLFILE *, DB_THREAD_INFO *));
+ */
+int
+__db_lsn_reset(mpf, ip)
+	DB_MPOOLFILE *mpf;
+	DB_THREAD_INFO *ip;
+{
+	PAGE *pagep;
+	db_pgno_t pgno;
+	int ret;
+
+	/* Reset the LSN on every page of the database file. */
+	for (pgno = 0;
+	    (ret = __memp_fget(mpf,
+	    &pgno, ip, NULL, DB_MPOOL_DIRTY, &pagep)) == 0;
+	    ++pgno) {
+		LSN_NOT_LOGGED(pagep->lsn);
+		if ((ret = __memp_fput(mpf,
+		    ip, pagep, DB_PRIORITY_UNCHANGED)) != 0)
+			break;
+	}
+
+	if (ret == DB_PAGE_NOTFOUND)
+		ret = 0;
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_sort_multiple.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,349 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+
+static int __db_quicksort __P((DB *, DBT *, DBT *, u_int32_t *, u_int32_t *,
+		u_int32_t *, u_int32_t *, u_int32_t));
+
+/*
+ * __db_compare_both --
+ *	Use the comparison functions from db to compare akey and bkey, and if
+ *	DB_DUPSORT adata and bdata.
+ *
+ * PUBLIC: int __db_compare_both __P((DB *, const DBT *, const DBT *,
+ * PUBLIC:   const DBT *, const DBT *));
+ */
+int
+__db_compare_both(db, akey, adata, bkey, bdata)
+	DB *db;
+	const DBT *akey;
+	const DBT *adata;
+	const DBT *bkey;
+	const DBT *bdata;
+{
+	BTREE *t;
+	int cmp;
+
+	t = (BTREE *)db->bt_internal;
+
+	cmp = t->bt_compare(db, akey, bkey);
+	if (cmp != 0) return cmp;
+	if (!F_ISSET(db, DB_AM_DUPSORT))
+	    return (0);
+
+	if (adata == 0) return bdata == 0 ? 0 : -1;
+	if (bdata == 0) return 1;
+
+#ifdef HAVE_COMPRESSION
+	if (DB_IS_COMPRESSED(db))
+		return t->compress_dup_compare(db, adata, bdata);
+#endif
+	return db->dup_compare(db, adata, bdata);
+}
+
+#define	DB_SORT_SWAP(a, ad, b, bd)					\
+do {									\
+	tmp = (a)[0]; (a)[0] = (b)[0]; (b)[0] = tmp;			\
+	tmp = (a)[-1]; (a)[-1] = (b)[-1]; (b)[-1] = tmp;		\
+	if (data != NULL) {						\
+		tmp = (ad)[0]; (ad)[0] = (bd)[0]; (bd)[0] = tmp;	\
+		tmp = (ad)[-1]; (ad)[-1] = (bd)[-1]; (bd)[-1] = tmp;	\
+	}								\
+} while (0)
+
+#define	DB_SORT_LOAD_DBT(a, ad, aptr, adptr)				\
+do {									\
+	(a).data = (u_int8_t*)key->data + (aptr)[0];			\
+	(a).size = (aptr)[-1];						\
+	if (data != NULL) {						\
+		(ad).data = (u_int8_t*)data->data + (adptr)[0];		\
+		(ad).size = (adptr)[-1];				\
+	}								\
+} while (0)
+
+#define	DB_SORT_COMPARE(a, ad, b, bd) (data != NULL ?			\
+	__db_compare_both(db, &(a), &(ad), &(b), &(bd)) :		\
+	__db_compare_both(db, &(a), 0, &(b), 0))
+
+#define	DB_SORT_STACKSIZE 32
+
+/*
+ * __db_quicksort --
+ *	The quicksort implementation for __db_sort_multiple() and
+ *	__db_sort_multiple_key().
+ */
+static int
+__db_quicksort(db, key, data, kstart, kend, dstart, dend, size)
+	DB *db;
+	DBT *key, *data;
+	u_int32_t *kstart, *kend, *dstart, *dend;
+	u_int32_t size;
+{
+	int ret, cmp;
+	u_int32_t tmp, len;
+	u_int32_t *kptr, *dptr, *kl, *dl, *kr, *dr;
+	DBT a, ad, b, bd, m, md;
+	ENV *env;
+
+	struct DB_SORT_quicksort_stack {
+		u_int32_t *kstart;
+		u_int32_t *kend;
+		u_int32_t *dstart;
+		u_int32_t *dend;
+	} stackbuf[DB_SORT_STACKSIZE], *stack;
+	u_int32_t soff, slen;
+
+	ret = 0;
+	env = db->env;
+
+	memset(&a, 0, sizeof(DBT));
+	memset(&ad, 0, sizeof(DBT));
+	memset(&b, 0, sizeof(DBT));
+	memset(&bd, 0, sizeof(DBT));
+	memset(&m, 0, sizeof(DBT));
+	memset(&md, 0, sizeof(DBT));
+
+	/* NB end is smaller than start */
+
+	stack = stackbuf;
+	soff = 0;
+	slen = DB_SORT_STACKSIZE;
+
+ start:
+	if (kend >= kstart) goto pop;
+
+	/* If there's only one value, it's already sorted */
+	len = (u_int32_t)(kstart - kend) / size;
+	if (len == 1) goto pop;
+
+	DB_SORT_LOAD_DBT(a, ad, kstart, dstart);
+	DB_SORT_LOAD_DBT(b, bd, kend + size, dend + size);
+
+	if (len == 2) {
+		/* Special case the sorting of two value sequences */
+		if (DB_SORT_COMPARE(a, ad, b, bd) > 0) {
+			DB_SORT_SWAP(kstart, dstart, kend + size,
+				dend + size);
+		}
+		goto pop;
+	}
+
+	kptr = kstart - (len / 2) * size;
+	dptr = dstart - (len / 2) * size;
+	DB_SORT_LOAD_DBT(m, md, kptr, dptr);
+
+	/* Find the median of three */
+	if (DB_SORT_COMPARE(a, ad, b, bd) < 0) {
+		if (DB_SORT_COMPARE(m, md, a, ad) < 0) {
+			/* m < a < b */
+			if (len == 3) {
+				DB_SORT_SWAP(kstart, dstart, kptr, dptr);
+				goto pop;
+			}
+			DB_SORT_SWAP(kstart, dstart, kend + size, dend + size);
+		} else if (DB_SORT_COMPARE(m, md, b, bd) < 0) {
+			/* a <= m < b */
+			if (len == 3) {
+				goto pop;
+			}
+			DB_SORT_SWAP(kptr, dptr, kend + size, dend + size);
+		} else {
+			/* a < b <= m */
+			if (len == 3) {
+				DB_SORT_SWAP(kptr, dptr, kend + size,
+					dend + size);
+				goto pop;
+			}
+			/* Do nothing */
+		}
+	} else {
+		if (DB_SORT_COMPARE(a, ad, m, md) < 0) {
+			/* b <= a < m */
+			DB_SORT_SWAP(kstart, dstart, kend + size,
+			    dend + size);
+			if (len == 3) {
+				DB_SORT_SWAP(kptr, dptr, kend + size,
+				    dend + size);
+				goto pop;
+			}
+		} else if (DB_SORT_COMPARE(b, bd, m, md) < 0) {
+			/* b < m <= a */
+			if (len == 3) {
+				DB_SORT_SWAP(kstart, dstart, kend + size,
+					dend + size);
+				goto pop;
+			}
+			DB_SORT_SWAP(kptr, dptr, kend + size, dend + size);
+		} else {
+			/* m <= b <= a */
+			if (len == 3) {
+				DB_SORT_SWAP(kstart, dstart, kptr, dptr);
+				DB_SORT_SWAP(kptr, dptr, kend + size,
+					dend + size);
+				goto pop;
+			}
+			/* Do nothing */
+		}
+	}
+
+	/* partition */
+	DB_SORT_LOAD_DBT(b, bd, kend + size, dend + size);
+	kl = kstart;
+	dl = dstart;
+	kr = kend + size;
+	dr = dend + size;
+	kptr = kstart;
+	dptr = dstart;
+	while (kptr >= kr) {
+		DB_SORT_LOAD_DBT(a, ad, kptr, dptr);
+		cmp = DB_SORT_COMPARE(a, ad, b, bd);
+		if (cmp < 0) {
+			DB_SORT_SWAP(kl, dl, kptr, dptr);
+			kl -= size;
+			dl -= size;
+			kptr -= size;
+			dptr -= size;
+		} else if (cmp > 0) {
+			DB_SORT_SWAP(kr, dr, kptr, dptr);
+			kr += size;
+			dr += size;
+		} else {
+			kptr -= size;
+			dptr -= size;
+		}
+	}
+
+	if (soff == slen) {
+		/* Grow the stack */
+		slen = slen * 2;
+		if (stack == stackbuf) {
+			ret = __os_malloc(env, slen *
+				sizeof(struct DB_SORT_quicksort_stack), &stack);
+			if (ret != 0) goto error;
+			memcpy(stack, stackbuf, soff *
+				sizeof(struct DB_SORT_quicksort_stack));
+		} else {
+			ret = __os_realloc(env, slen *
+				sizeof(struct DB_SORT_quicksort_stack), &stack);
+			if (ret != 0) goto error;
+		}
+	}
+
+	/* divide and conquer */
+	stack[soff].kstart = kr - size;
+	stack[soff].kend = kend;
+	stack[soff].dstart = dr - size;
+	stack[soff].dend = dend;
+	++soff;
+
+	kend = kl;
+	dend = dl;
+
+	goto start;
+
+ pop:
+	if (soff != 0) {
+		--soff;
+		kstart = stack[soff].kstart;
+		kend = stack[soff].kend;
+		dstart = stack[soff].dstart;
+		dend = stack[soff].dend;
+		goto start;
+	}
+
+ error:
+	if (stack != stackbuf)
+		__os_free(env, stack);
+
+	return (ret);
+}
+
+#undef DB_SORT_SWAP
+#undef DB_SORT_LOAD_DBT
+
+/*
+ * __db_sort_multiple --
+ *	If flags == DB_MULTIPLE_KEY, sorts a DB_MULTIPLE_KEY format DBT using
+ *	the BTree comparison function and duplicate comparison function.
+ *
+ *	If flags == DB_MULTIPLE, sorts one or two DB_MULTIPLE format DBTs using
+ *	the BTree comparison function and duplicate comparison function. Will
+ *	assume key and data specifies pairs of key/data to sort together. If
+ *	data is NULL, will just sort key according to the btree comparison
+ *	function.
+ *
+ *	Uses an in-place quicksort algorithm, with median of three for the pivot
+ *	point.
+ *
+ * PUBLIC: int __db_sort_multiple __P((DB *, DBT *, DBT *, u_int32_t));
+ */
+int
+__db_sort_multiple(db, key, data, flags)
+	DB *db;
+	DBT *key, *data;
+	u_int32_t flags;
+{
+	u_int32_t *kstart, *kend, *dstart, *dend;
+
+	/* TODO: sanity checks on the DBTs */
+	/* DB_ILLEGAL_METHOD(db, DB_OK_BTREE); */
+
+	kstart = (u_int32_t*)((u_int8_t *)key->data + key->ulen) - 1;
+
+	switch (flags) {
+	case DB_MULTIPLE:
+		if (data != NULL)
+			dstart = (u_int32_t*)((u_int8_t *)data->data +
+				data->ulen) - 1;
+		else
+			dstart = kstart;
+
+		/* Find the end */
+		for (kend = kstart, dend = dstart;
+		    *kend != (u_int32_t)-1 && *dend != (u_int32_t)-1;
+		    kend -= 2, dend -= 2)
+			;
+
+		return (__db_quicksort(db, key, data, kstart, kend, dstart,
+			dend, 2));
+	case DB_MULTIPLE_KEY:
+		/* Find the end */
+		for (kend = kstart; *kend != (u_int32_t)-1; kend -= 4)
+			;
+
+		return (__db_quicksort(db, key, key, kstart, kend, kstart - 2,
+			kend - 2, 4));
+	default:
+		return (__db_ferr(db->env, "DB->sort_multiple", 0));
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_stati.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,524 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/qam.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+
+#ifdef HAVE_STATISTICS
+static int __db_print_all __P((DB *, u_int32_t));
+static int __db_print_citem __P((DBC *));
+static int __db_print_cursor __P((DB *));
+static int __db_print_stats __P((DB *, DB_THREAD_INFO *, u_int32_t));
+static int __db_stat __P((DB *, DB_THREAD_INFO *, DB_TXN *, void *, u_int32_t));
+static int __db_stat_arg __P((DB *, u_int32_t));
+
+/*
+ * __db_stat_pp --
+ *	DB->stat pre/post processing.
+ *
+ * PUBLIC: int __db_stat_pp __P((DB *, DB_TXN *, void *, u_int32_t));
+ */
+int
+__db_stat_pp(dbp, txn, spp, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	void *spp;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret;
+
+	env = dbp->env;
+
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat");
+
+	if ((ret = __db_stat_arg(dbp, flags)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check && (ret = __db_rep_enter(dbp, 1, 0,
+	    IS_REAL_TXN(txn))) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	ret = __db_stat(dbp, ip, txn, spp, flags);
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+err:	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_stat --
+ *	DB->stat.
+ *
+ */
+static int
+__db_stat(dbp, ip, txn, spp, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	void *spp;
+	u_int32_t flags;
+{
+	DBC *dbc;
+	ENV *env;
+	int ret, t_ret;
+
+	env = dbp->env;
+
+	/* Acquire a cursor. */
+	if ((ret = __db_cursor(dbp, ip, txn,
+	     &dbc, LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED))) != 0)
+		return (ret);
+
+	DEBUG_LWRITE(dbc, NULL, "DB->stat", NULL, NULL, flags);
+	LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED);
+#ifdef HAVE_PARTITION
+	if (DB_IS_PARTITIONED(dbp))
+		ret = __partition_stat(dbc, spp, flags);
+	else
+#endif
+	switch (dbp->type) {
+	case DB_BTREE:
+	case DB_RECNO:
+		ret = __bam_stat(dbc, spp, flags);
+		break;
+	case DB_HASH:
+		ret = __ham_stat(dbc, spp, flags);
+		break;
+	case DB_HEAP:
+		ret = __heap_stat(dbc, spp, flags);
+		break;
+	case DB_QUEUE:
+		ret = __qam_stat(dbc, spp, flags);
+		break;
+	case DB_UNKNOWN:
+	default:
+		ret = (__db_unknown_type(env, "DB->stat", dbp->type));
+		break;
+	}
+
+	if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __db_stat_arg --
+ *	Check DB->stat arguments.
+ */
+static int
+__db_stat_arg(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	ENV *env;
+
+	env = dbp->env;
+
+	/* Check for invalid function flags. */
+	LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED);
+	switch (flags) {
+	case 0:
+	case DB_FAST_STAT:
+		break;
+	default:
+		return (__db_ferr(env, "DB->stat", 0));
+	}
+
+	return (0);
+}
+
+/*
+ * __db_stat_print_pp --
+ *	DB->stat_print pre/post processing.
+ *
+ * PUBLIC: int __db_stat_print_pp __P((DB *, u_int32_t));
+ */
+int
+__db_stat_print_pp(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret;
+
+	env = dbp->env;
+
+	DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat_print");
+
+	/*
+	 * !!!
+	 * The actual argument checking is simple, do it inline.
+	 */
+	if ((ret = __db_fchk(env,
+	    "DB->stat_print", flags, DB_FAST_STAT | DB_STAT_ALL)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	ret = __db_stat_print(dbp, ip, flags);
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+err:	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_stat_print --
+ *	DB->stat_print.
+ *
+ * PUBLIC: int __db_stat_print __P((DB *, DB_THREAD_INFO *, u_int32_t));
+ */
+int
+__db_stat_print(dbp, ip, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	u_int32_t flags;
+{
+	time_t now;
+	int ret;
+	char time_buf[CTIME_BUFLEN];
+
+	(void)time(&now);
+	__db_msg(dbp->env, "%.24s\tLocal time", __os_ctime(&now, time_buf));
+
+	if (LF_ISSET(DB_STAT_ALL) && (ret = __db_print_all(dbp, flags)) != 0)
+		return (ret);
+
+	if ((ret = __db_print_stats(dbp, ip, flags)) != 0)
+		return (ret);
+
+	return (0);
+}
+
+/*
+ * __db_print_stats --
+ *	Display default DB handle statistics.
+ */
+static int
+__db_print_stats(dbp, ip, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	u_int32_t flags;
+{
+	DBC *dbc;
+	ENV *env;
+	int ret, t_ret;
+
+	env = dbp->env;
+
+	/* Acquire a cursor. */
+	if ((ret = __db_cursor(dbp, ip, NULL, &dbc, 0)) != 0)
+		return (ret);
+
+	DEBUG_LWRITE(dbc, NULL, "DB->stat_print", NULL, NULL, 0);
+
+	switch (dbp->type) {
+	case DB_BTREE:
+	case DB_RECNO:
+		ret = __bam_stat_print(dbc, flags);
+		break;
+	case DB_HASH:
+		ret = __ham_stat_print(dbc, flags);
+		break;
+	case DB_HEAP:
+		ret = __heap_stat_print(dbc, flags);
+		break;
+	case DB_QUEUE:
+		ret = __qam_stat_print(dbc, flags);
+		break;
+	case DB_UNKNOWN:
+	default:
+		ret = (__db_unknown_type(env, "DB->stat_print", dbp->type));
+		break;
+	}
+
+	if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __db_print_all --
+ *	Display debugging DB handle statistics.
+ */
+static int
+__db_print_all(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	static const FN fn[] = {
+		{ DB_AM_CHKSUM,			"DB_AM_CHKSUM" },
+		{ DB_AM_COMPENSATE,		"DB_AM_COMPENSATE" },
+		{ DB_AM_CREATED,		"DB_AM_CREATED" },
+		{ DB_AM_CREATED_MSTR,		"DB_AM_CREATED_MSTR" },
+		{ DB_AM_DBM_ERROR,		"DB_AM_DBM_ERROR" },
+		{ DB_AM_DELIMITER,		"DB_AM_DELIMITER" },
+		{ DB_AM_DISCARD,		"DB_AM_DISCARD" },
+		{ DB_AM_DUP,			"DB_AM_DUP" },
+		{ DB_AM_DUPSORT,		"DB_AM_DUPSORT" },
+		{ DB_AM_ENCRYPT,		"DB_AM_ENCRYPT" },
+		{ DB_AM_FIXEDLEN,		"DB_AM_FIXEDLEN" },
+		{ DB_AM_INMEM,			"DB_AM_INMEM" },
+		{ DB_AM_IN_RENAME,		"DB_AM_IN_RENAME" },
+		{ DB_AM_NOT_DURABLE,		"DB_AM_NOT_DURABLE" },
+		{ DB_AM_OPEN_CALLED,		"DB_AM_OPEN_CALLED" },
+		{ DB_AM_PAD,			"DB_AM_PAD" },
+		{ DB_AM_PGDEF,			"DB_AM_PGDEF" },
+		{ DB_AM_RDONLY,			"DB_AM_RDONLY" },
+		{ DB_AM_READ_UNCOMMITTED,	"DB_AM_READ_UNCOMMITTED" },
+		{ DB_AM_RECNUM,			"DB_AM_RECNUM" },
+		{ DB_AM_RECOVER,		"DB_AM_RECOVER" },
+		{ DB_AM_RENUMBER,		"DB_AM_RENUMBER" },
+		{ DB_AM_REVSPLITOFF,		"DB_AM_REVSPLITOFF" },
+		{ DB_AM_SECONDARY,		"DB_AM_SECONDARY" },
+		{ DB_AM_SNAPSHOT,		"DB_AM_SNAPSHOT" },
+		{ DB_AM_SUBDB,			"DB_AM_SUBDB" },
+		{ DB_AM_SWAP,			"DB_AM_SWAP" },
+		{ DB_AM_TXN,			"DB_AM_TXN" },
+		{ DB_AM_VERIFYING,		"DB_AM_VERIFYING" },
+		{ 0,				NULL }
+	};
+	ENV *env;
+	char time_buf[CTIME_BUFLEN];
+
+	env = dbp->env;
+
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	__db_msg(env, "DB handle information:");
+	STAT_ULONG("Page size", dbp->pgsize);
+	STAT_ISSET("Append recno", dbp->db_append_recno);
+	STAT_ISSET("Feedback", dbp->db_feedback);
+	STAT_ISSET("Dup compare", dbp->dup_compare);
+	STAT_ISSET("App private", dbp->app_private);
+	STAT_ISSET("DbEnv", dbp->env);
+	STAT_STRING("Type", __db_dbtype_to_string(dbp->type));
+
+	__mutex_print_debug_single(env, "Thread mutex", dbp->mutex, flags);
+
+	STAT_STRING("File", dbp->fname);
+	STAT_STRING("Database", dbp->dname);
+	STAT_HEX("Open flags", dbp->open_flags);
+
+	__db_print_fileid(env, dbp->fileid, "\tFile ID");
+
+	STAT_ULONG("Cursor adjust ID", dbp->adj_fileid);
+	STAT_ULONG("Meta pgno", dbp->meta_pgno);
+	if (dbp->locker != NULL)
+		STAT_ULONG("Locker ID", dbp->locker->id);
+	if (dbp->cur_locker != NULL)
+		STAT_ULONG("Handle lock", dbp->cur_locker->id);
+	if (dbp->associate_locker != NULL)
+		STAT_ULONG("Associate lock", dbp->associate_locker->id);
+
+	__db_msg(env,
+	    "%.24s\tReplication handle timestamp",
+	    dbp->timestamp == 0 ? "0" : __os_ctime(&dbp->timestamp, time_buf));
+
+	STAT_ISSET("Secondary callback", dbp->s_callback);
+	STAT_ISSET("Primary handle", dbp->s_primary);
+
+	STAT_ISSET("api internal", dbp->api_internal);
+	STAT_ISSET("Btree/Recno internal", dbp->bt_internal);
+	STAT_ISSET("Hash internal", dbp->h_internal);
+	STAT_ISSET("Queue internal", dbp->q_internal);
+
+	__db_prflags(env, NULL, dbp->flags, fn, NULL, "\tFlags");
+
+	if (dbp->log_filename == NULL)
+		STAT_ISSET("File naming information", dbp->log_filename);
+	else
+		__dbreg_print_fname(env, dbp->log_filename);
+
+	(void)__db_print_cursor(dbp);
+
+	return (0);
+}
+
+/*
+ * __db_print_cursor --
+ *	Display the cursor active and free queues.
+ */
+static int
+__db_print_cursor(dbp)
+	DB *dbp;
+{
+	DBC *dbc;
+	ENV *env;
+	int ret, t_ret;
+
+	env = dbp->env;
+
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	__db_msg(env, "DB handle cursors:");
+
+	ret = 0;
+	MUTEX_LOCK(dbp->env, dbp->mutex);
+	__db_msg(env, "Active queue:");
+	TAILQ_FOREACH(dbc, &dbp->active_queue, links)
+		if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0)
+			ret = t_ret;
+	__db_msg(env, "Join queue:");
+	TAILQ_FOREACH(dbc, &dbp->join_queue, links)
+		if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0)
+			ret = t_ret;
+	__db_msg(env, "Free queue:");
+	TAILQ_FOREACH(dbc, &dbp->free_queue, links)
+		if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0)
+			ret = t_ret;
+	MUTEX_UNLOCK(dbp->env, dbp->mutex);
+
+	return (ret);
+}
+
+static int
+__db_print_citem(dbc)
+	DBC *dbc;
+{
+	static const FN fn[] = {
+		{ DBC_ACTIVE,		"DBC_ACTIVE" },
+		{ DBC_DONTLOCK,		"DBC_DONTLOCK" },
+		{ DBC_MULTIPLE,		"DBC_MULTIPLE" },
+		{ DBC_MULTIPLE_KEY,	"DBC_MULTIPLE_KEY" },
+		{ DBC_OPD,		"DBC_OPD" },
+		{ DBC_OWN_LID,		"DBC_OWN_LID" },
+		{ DBC_READ_COMMITTED,	"DBC_READ_COMMITTED" },
+		{ DBC_READ_UNCOMMITTED,	"DBC_READ_UNCOMMITTED" },
+		{ DBC_RECOVER,		"DBC_RECOVER" },
+		{ DBC_RMW,		"DBC_RMW" },
+		{ DBC_TRANSIENT,	"DBC_TRANSIENT" },
+		{ DBC_WAS_READ_COMMITTED,"DBC_WAS_READ_COMMITTED" },
+		{ DBC_WRITECURSOR,	"DBC_WRITECURSOR" },
+		{ DBC_WRITER,		"DBC_WRITER" },
+		{ 0,			NULL }
+	};
+	DB *dbp;
+	DBC_INTERNAL *cp;
+	ENV *env;
+
+	dbp = dbc->dbp;
+	env = dbp->env;
+	cp = dbc->internal;
+
+	STAT_POINTER("DBC", dbc);
+	STAT_POINTER("Associated dbp", dbc->dbp);
+	STAT_POINTER("Associated txn", dbc->txn);
+	STAT_POINTER("Internal", cp);
+	STAT_HEX("Default locker ID", dbc->lref == NULL ? 0 : dbc->lref->id);
+	STAT_HEX("Locker", dbc->locker == NULL ? 0 : dbc->locker->id);
+	STAT_STRING("Type", __db_dbtype_to_string(dbc->dbtype));
+
+	STAT_POINTER("Off-page duplicate cursor", cp->opd);
+	STAT_POINTER("Referenced page", cp->page);
+	STAT_ULONG("Root", cp->root);
+	STAT_ULONG("Page number", cp->pgno);
+	STAT_ULONG("Page index", cp->indx);
+	STAT_STRING("Lock mode", __db_lockmode_to_string(cp->lock_mode));
+	__db_prflags(env, NULL, dbc->flags, fn, NULL, "\tFlags");
+
+	switch (dbc->dbtype) {
+	case DB_BTREE:
+	case DB_RECNO:
+		__bam_print_cursor(dbc);
+		break;
+	case DB_HASH:
+		__ham_print_cursor(dbc);
+		break;
+	case DB_HEAP:
+		__heap_print_cursor(dbc);
+		break;
+	case DB_UNKNOWN:
+		DB_ASSERT(env, dbp->type != DB_UNKNOWN);
+		/* FALLTHROUGH */
+	case DB_QUEUE:
+	default:
+		break;
+	}
+	return (0);
+}
+
+#else /* !HAVE_STATISTICS */
+
+int
+__db_stat_pp(dbp, txn, spp, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	void *spp;
+	u_int32_t flags;
+{
+	COMPQUIET(spp, NULL);
+	COMPQUIET(txn, NULL);
+	COMPQUIET(flags, 0);
+
+	return (__db_stat_not_built(dbp->env));
+}
+
+int
+__db_stat_print_pp(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+
+	return (__db_stat_not_built(dbp->env));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_truncate.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,255 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/qam.h"
+#include "dbinc/lock.h"
+#include "dbinc/partition.h"
+#include "dbinc/txn.h"
+
+static int __db_cursor_check_func
+    __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *));
+static int __db_cursor_check __P((DB *));
+
+/*
+ * __db_truncate_pp
+ *	DB->truncate pre/post processing.
+ *
+ * PUBLIC: int __db_truncate_pp __P((DB *, DB_TXN *, u_int32_t *, u_int32_t));
+ */
+int
+__db_truncate_pp(dbp, txn, countp, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	u_int32_t *countp, flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int handle_check, ret, t_ret, txn_local;
+
+	env = dbp->env;
+	handle_check = txn_local = 0;
+
+	STRIP_AUTO_COMMIT(flags);
+
+	/* Check for invalid flags. */
+	if (F_ISSET(dbp, DB_AM_SECONDARY)) {
+		__db_errx(env, DB_STR("0685",
+		    "DB->truncate forbidden on secondary indices"));
+		return (EINVAL);
+	}
+	if ((ret = __db_fchk(env, "DB->truncate", flags, 0)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+	XA_CHECK_TXN(ip, txn);
+
+	/*
+	 * Make sure there are no active cursors on this db.  Since we drop
+	 * pages we cannot really adjust cursors.
+	 */
+	if ((ret = __db_cursor_check(dbp)) != 0) {
+		__db_errx(env, DB_STR("0686",
+		    "DB->truncate not permitted with active cursors"));
+		goto err;
+	}
+
+#ifdef CONFIG_TEST
+	if (IS_REP_MASTER(env))
+		DB_TEST_WAIT(env, env->test_check);
+#endif
+	/* Check for replication block. */
+	handle_check = IS_ENV_REPLICATED(env);
+	if (handle_check &&
+	    (ret = __db_rep_enter(dbp, 1, 0, IS_REAL_TXN(txn))) != 0) {
+		handle_check = 0;
+		goto err;
+	}
+
+	/*
+	 * Check for changes to a read-only database.  This must be after the
+	 * replication block so that we cannot race master/client state changes.
+	 */
+	if (DB_IS_READONLY(dbp)) {
+		ret = __db_rdonly(env, "DB->truncate");
+		goto err;
+	}
+
+	/*
+	 * Create local transaction as necessary, check for consistent
+	 * transaction usage.
+	 */
+	if (IS_DB_AUTO_COMMIT(dbp, txn)) {
+		if ((ret = __txn_begin(env, ip, NULL, &txn, 0)) != 0)
+			goto err;
+		txn_local = 1;
+	}
+
+	/* Check for consistent transaction usage. */
+	if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0)
+		goto err;
+
+	ret = __db_truncate(dbp, ip, txn, countp);
+
+err:	if (txn_local &&
+	    (t_ret = __db_txn_auto_resolve(env, txn, 0, ret)) && ret == 0)
+		ret = t_ret;
+
+	/* Release replication block. */
+	if (handle_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_truncate
+ *	DB->truncate.
+ *
+ * PUBLIC: int __db_truncate __P((DB *, DB_THREAD_INFO *, DB_TXN *,
+ * PUBLIC:     u_int32_t *));
+ */
+int
+__db_truncate(dbp, ip, txn, countp)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	u_int32_t *countp;
+{
+	DB *sdbp;
+	DBC *dbc;
+	ENV *env;
+	u_int32_t scount;
+	int ret, t_ret;
+
+	env = dbp->env;
+	dbc = NULL;
+	ret = 0;
+
+	/*
+	 * Run through all secondaries and truncate them first.  The count
+	 * returned is the count of the primary only.  QUEUE uses normal
+	 * processing to truncate so it will update the secondaries normally.
+	 */
+	if (dbp->type != DB_QUEUE && DB_IS_PRIMARY(dbp)) {
+		if ((ret = __db_s_first(dbp, &sdbp)) != 0)
+			return (ret);
+		for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp, txn))
+			if ((ret = __db_truncate(sdbp, ip, txn, &scount)) != 0)
+				break;
+		if (sdbp != NULL)
+			(void)__db_s_done(sdbp, txn);
+		if (ret != 0)
+			return (ret);
+	}
+
+	DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, NULL);
+
+	/* Acquire a cursor. */
+	if ((ret = __db_cursor(dbp, ip, txn, &dbc, 0)) != 0)
+		return (ret);
+
+	DEBUG_LWRITE(dbc, txn, "DB->truncate", NULL, NULL, 0);
+#ifdef HAVE_PARTITION
+	if (DB_IS_PARTITIONED(dbp))
+		ret = __part_truncate(dbc, countp);
+	else
+#endif
+	switch (dbp->type) {
+	case DB_BTREE:
+	case DB_RECNO:
+		ret = __bam_truncate(dbc, countp);
+		break;
+	case DB_HASH:
+		ret = __ham_truncate(dbc, countp);
+		break;
+	case DB_HEAP:
+		ret = __heap_truncate(dbc, countp);
+		break;
+	case DB_QUEUE:
+		ret = __qam_truncate(dbc, countp);
+		break;
+	case DB_UNKNOWN:
+	default:
+		ret = __db_unknown_type(env, "DB->truncate", dbp->type);
+		break;
+	}
+
+	/* Discard the cursor. */
+	if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, NULL);
+
+DB_TEST_RECOVERY_LABEL
+
+	return (ret);
+}
+
+static int
+__db_cursor_check_func(dbc, my_dbc, foundp, pgno, indx, args)
+	DBC *dbc, *my_dbc;
+	u_int32_t *foundp;
+	db_pgno_t pgno;
+	u_int32_t indx;
+	void *args;
+{
+	COMPQUIET(my_dbc, NULL);
+	COMPQUIET(args, NULL);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(indx, 0);
+	if (IS_INITIALIZED(dbc)) {
+		*foundp = 1;
+		return (EEXIST);
+	}
+	return (0);
+}
+/*
+ * __db_cursor_check --
+ *	See if there are any active cursors on this db.
+ */
+static int
+__db_cursor_check(dbp)
+	DB *dbp;
+{
+	int ret;
+	u_int32_t found;
+
+	ret = __db_walk_cursors(dbp, NULL,
+	    __db_cursor_check_func, &found, 0, 0, NULL);
+	return (ret == EEXIST ? EINVAL : ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_vrfy.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,3081 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2000, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_swap.h"
+#include "dbinc/db_verify.h"
+#include "dbinc/btree.h"
+#include "dbinc/fop.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/qam.h"
+#include "dbinc/txn.h"
+
+/*
+ * This is the code for DB->verify, the DB database consistency checker.
+ * For now, it checks all subdatabases in a database, and verifies
+ * everything it knows how to (i.e. it's all-or-nothing, and one can't
+ * check only for a subset of possible problems).
+ */
+
+static u_int __db_guesspgsize __P((ENV *, DB_FH *));
+static int   __db_is_valid_magicno __P((u_int32_t, DBTYPE *));
+static int   __db_meta2pgset
+		__P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, DB *));
+static int   __db_salvage __P((DB *, VRFY_DBINFO *,
+		db_pgno_t, void *, int (*)(void *, const void *), u_int32_t));
+static int   __db_salvage_subdbpg __P((DB *, VRFY_DBINFO *,
+		PAGE *, void *, int (*)(void *, const void *), u_int32_t));
+static int   __db_salvage_all __P((DB *, VRFY_DBINFO *, void *,
+		int(*)(void *, const void *), u_int32_t, int *));
+static int   __db_salvage_unknowns __P((DB *, VRFY_DBINFO *, void *,
+		int (*)(void *, const void *), u_int32_t));
+static int   __db_verify_arg __P((DB *, const char *, void *, u_int32_t));
+static int   __db_vrfy_freelist
+		__P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t));
+static int   __db_vrfy_getpagezero
+		__P((DB *, DB_FH *, const char *, u_int8_t *, u_int32_t));
+static int   __db_vrfy_invalid
+		__P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
+static int   __db_vrfy_orderchkonly __P((DB *,
+		VRFY_DBINFO *, const char *, const char *, u_int32_t));
+static int   __db_vrfy_pagezero __P((DB *,
+		VRFY_DBINFO *, DB_FH *, const char *, u_int32_t));
+static int   __db_vrfy_subdbs
+		__P((DB *, VRFY_DBINFO *, const char *, u_int32_t));
+static int   __db_vrfy_structure __P((DB *, VRFY_DBINFO *,
+		const char *, db_pgno_t, void *, void *, u_int32_t));
+static int   __db_vrfy_walkpages __P((DB *, VRFY_DBINFO *,
+		void *, int (*)(void *, const void *), u_int32_t));
+
+#define	VERIFY_FLAGS							\
+    (DB_AGGRESSIVE |							\
+     DB_NOORDERCHK | DB_ORDERCHKONLY | DB_PRINTABLE | DB_SALVAGE | DB_UNREF)
+
+/*
+ * __db_verify_pp --
+ *	DB->verify public interface.
+ *
+ * PUBLIC: int __db_verify_pp
+ * PUBLIC:     __P((DB *, const char *, const char *, FILE *, u_int32_t));
+ */
+int
+__db_verify_pp(dbp, file, database, outfile, flags)
+	DB *dbp;
+	const char *file, *database;
+	FILE *outfile;
+	u_int32_t flags;
+{
+	/*
+	 * __db_verify_pp is a wrapper to __db_verify_internal, which lets
+	 * us pass appropriate equivalents to FILE * in from the non-C APIs.
+	 * That's why the usual ENV_ENTER macros are in __db_verify_internal,
+	 * not here.
+	 */
+	return (__db_verify_internal(dbp,
+	    file, database, outfile, __db_pr_callback, flags));
+}
+
+/*
+ * __db_verify_internal --
+ *
+ * PUBLIC: int __db_verify_internal __P((DB *, const char *,
+ * PUBLIC:     const char *, void *, int (*)(void *, const void *), u_int32_t));
+ */
+int
+__db_verify_internal(dbp, fname, dname, handle, callback, flags)
+	DB *dbp;
+	const char *fname, *dname;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret, t_ret;
+
+	env = dbp->env;
+
+	DB_ILLEGAL_AFTER_OPEN(dbp, "DB->verify");
+
+	if (!LF_ISSET(DB_SALVAGE))
+		LF_SET(DB_UNREF);
+
+	ENV_ENTER(env, ip);
+
+	if ((ret = __db_verify_arg(dbp, dname, handle, flags)) == 0)
+		ret = __db_verify(dbp, ip,
+		     fname, dname, handle, callback, NULL, NULL, flags);
+
+	/* Db.verify is a DB handle destructor. */
+	if ((t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __db_verify_arg --
+ *	Check DB->verify arguments.
+ */
+static int
+__db_verify_arg(dbp, dname, handle, flags)
+	DB *dbp;
+	const char *dname;
+	void *handle;
+	u_int32_t flags;
+{
+	ENV *env;
+	int ret;
+
+	env = dbp->env;
+
+	if ((ret = __db_fchk(env, "DB->verify", flags, VERIFY_FLAGS)) != 0)
+		return (ret);
+
+	/*
+	 * DB_SALVAGE is mutually exclusive with the other flags except
+	 * DB_AGGRESSIVE, DB_PRINTABLE.
+	 *
+	 * DB_AGGRESSIVE and DB_PRINTABLE are only meaningful when salvaging.
+	 *
+	 * DB_SALVAGE requires an output stream.
+	 */
+	if (LF_ISSET(DB_SALVAGE)) {
+		if (LF_ISSET(~(DB_AGGRESSIVE | DB_PRINTABLE | DB_SALVAGE)))
+			return (__db_ferr(env, "DB->verify", 1));
+		if (handle == NULL) {
+			__db_errx(env, DB_STR("0518",
+			    "DB_SALVAGE requires a an output handle"));
+			return (EINVAL);
+		}
+	} else
+		if (LF_ISSET(DB_AGGRESSIVE | DB_PRINTABLE))
+			return (__db_ferr(env, "DB->verify", 1));
+
+	/*
+	 * DB_ORDERCHKONLY is mutually exclusive with DB_SALVAGE and
+	 * DB_NOORDERCHK, and requires a database name.
+	 */
+	if ((ret = __db_fcchk(env, "DB->verify", flags,
+	    DB_ORDERCHKONLY, DB_SALVAGE | DB_NOORDERCHK)) != 0)
+		return (ret);
+	if (LF_ISSET(DB_ORDERCHKONLY) && dname == NULL) {
+		__db_errx(env, DB_STR("0519",
+		    "DB_ORDERCHKONLY requires a database name"));
+		return (EINVAL);
+	}
+	return (0);
+}
+
+/*
+ * __db_verify --
+ *	Walk the entire file page-by-page, either verifying with or without
+ *	dumping in db_dump -d format, or DB_SALVAGE-ing whatever key/data
+ *	pairs can be found and dumping them in standard (db_load-ready)
+ *	dump format.
+ *
+ *	(Salvaging isn't really a verification operation, but we put it
+ *	here anyway because it requires essentially identical top-level
+ *	code.)
+ *
+ *	flags may be 0, DB_NOORDERCHK, DB_ORDERCHKONLY, or DB_SALVAGE
+ *	(and optionally DB_AGGRESSIVE).
+ * PUBLIC: int   __db_verify __P((DB *, DB_THREAD_INFO *, const char *,
+ * PUBLIC:		const char *, void *, int (*)(void *, const void *),
+ * PUBLIC:		void *, void *, u_int32_t));
+ */
+int
+__db_verify(dbp, ip, name, subdb, handle, callback, lp, rp, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	const char *name, *subdb;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	void *lp, *rp;
+	u_int32_t flags;
+{
+	DB_FH *fhp;
+	ENV *env;
+	VRFY_DBINFO *vdp;
+	u_int32_t sflags;
+	int has_subdbs, isbad, ret, t_ret;
+	char *real_name;
+
+	env = dbp->env;
+	fhp = NULL;
+	vdp = NULL;
+	real_name = NULL;
+	has_subdbs = isbad = ret = t_ret = 0;
+
+	F_SET(dbp, DB_AM_VERIFYING);
+
+	/* Initialize any feedback function. */
+	if (!LF_ISSET(DB_SALVAGE) && dbp->db_feedback != NULL)
+		dbp->db_feedback(dbp, DB_VERIFY, 0);
+
+	/*
+	 * We don't know how large the cache is, and if the database
+	 * in question uses a small page size--which we don't know
+	 * yet!--it may be uncomfortably small for the default page
+	 * size [#2143].  However, the things we need temporary
+	 * databases for in dbinfo are largely tiny, so using a
+	 * 1024-byte pagesize is probably not going to be a big hit,
+	 * and will make us fit better into small spaces.
+	 */
+	if ((ret = __db_vrfy_dbinfo_create(env, ip,  1024, &vdp)) != 0)
+		goto err;
+
+	/*
+	 * Note whether the user has requested that we use printable
+	 * chars where possible.  We won't get here with this flag if
+	 * we're not salvaging.
+	 */
+	if (LF_ISSET(DB_PRINTABLE))
+		F_SET(vdp, SALVAGE_PRINTABLE);
+
+	if (name != NULL) {
+		/* Find the real name of the file. */
+		if ((ret = __db_appname(env,
+		    DB_APP_DATA, name, &dbp->dirname, &real_name)) != 0)
+			goto err;
+
+		/*
+		 * Our first order of business is to verify page 0, which is the
+		 * metadata page for the master database of subdatabases or of
+		 * the only database in the file.  We want to do this by hand
+		 * rather than just calling __db_open in case it's
+		 * corrupt--various things in __db_open might act funny.
+		 *
+		 * Once we know the metadata page is healthy, I believe that
+		 * it's safe to open the database normally and then use the page
+		 * swapping code, which makes life easier.
+		 */
+		if ((ret = __os_open(env,
+		    real_name, 0, DB_OSO_RDONLY, 0, &fhp)) != 0)
+			goto err;
+	} else {
+		MAKE_INMEM(dbp);
+	}
+
+	/* Verify the metadata page 0; set pagesize and type. */
+	if ((ret = __db_vrfy_pagezero(dbp, vdp, fhp, subdb, flags)) != 0) {
+		if (ret == DB_VERIFY_BAD)
+			isbad = 1;
+		else
+			goto err;
+	}
+
+	/*
+	 * We can assume at this point that dbp->pagesize and dbp->type are
+	 * set correctly, or at least as well as they can be, and that
+	 * locking, logging, and txns are not in use.  Thus we can trust
+	 * the memp code not to look at the page, and thus to be safe
+	 * enough to use.
+	 *
+	 * The dbp is not open, but the file is open in the fhp, and we
+	 * cannot assume that __db_open is safe.  Call __env_setup,
+	 * the [safe] part of __db_open that initializes the environment--
+	 * and the mpool--manually.
+	 */
+	if ((ret = __env_setup(dbp, NULL,
+	    name, subdb, TXN_INVALID, DB_ODDFILESIZE | DB_RDONLY)) != 0)
+		goto err;
+
+	/*
+	 * Set our name in the Queue subsystem;  we may need it later
+	 * to deal with extents.  In-memory databases are not allowed to have
+	 * extents.
+	 */
+	if (dbp->type == DB_QUEUE && name != NULL &&
+	    (ret = __qam_set_ext_data(dbp, name)) != 0)
+		goto err;
+
+	/* Mark the dbp as opened, so that we correctly handle its close. */
+	F_SET(dbp, DB_AM_OPEN_CALLED);
+
+	/*
+	 * Find out the page number of the last page in the database.  We'll
+	 * use this later to verify the metadata page.  We don't verify now
+	 * because the data from __db_vrfy_pagezero could be stale.
+	 */
+	if ((ret = __memp_get_last_pgno(dbp->mpf, &vdp->last_pgno)) != 0)
+		goto err;
+	/*
+	 * DB_ORDERCHKONLY is a special case;  our file consists of
+	 * several subdatabases, which use different hash, bt_compare,
+	 * and/or dup_compare functions.  Consequently, we couldn't verify
+	 * sorting and hashing simply by calling DB->verify() on the file.
+	 * DB_ORDERCHKONLY allows us to come back and check those things;  it
+	 * requires a subdatabase, and assumes that everything but that
+	 * database's sorting/hashing is correct.
+	 */
+	if (LF_ISSET(DB_ORDERCHKONLY)) {
+		ret = __db_vrfy_orderchkonly(dbp, vdp, name, subdb, flags);
+		goto done;
+	}
+
+	sflags = flags;
+	if (dbp->p_internal != NULL)
+		LF_CLR(DB_SALVAGE);
+
+	/*
+	 * When salvaging, we use a db to keep track of whether we've seen a
+	 * given overflow or dup page in the course of traversing normal data.
+	 * If in the end we have not, we assume its key got lost and print it
+	 * with key "UNKNOWN".
+	 */
+	if (LF_ISSET(DB_SALVAGE)) {
+		if ((ret = __db_salvage_init(vdp)) != 0)
+			goto err;
+
+		/*
+		 * If we're not being aggressive, salvage by walking the tree
+		 * and only printing the leaves we find.  "has_subdbs" will
+		 * indicate whether we found subdatabases.
+		 */
+		if (!LF_ISSET(DB_AGGRESSIVE) && __db_salvage_all(
+		    dbp, vdp, handle, callback, flags, &has_subdbs) != 0)
+			isbad = 1;
+
+		/*
+		 * If we have subdatabases, flag if any keys are found that
+		 * don't belong to a subdatabase -- they'll need to have an
+		 * "__OTHER__" subdatabase header printed first.
+		 */
+		if (has_subdbs) {
+			F_SET(vdp, SALVAGE_PRINTHEADER);
+			F_SET(vdp, SALVAGE_HASSUBDBS);
+		}
+	}
+
+	/* Walk all the pages, if a page cannot be read, verify structure. */
+	if ((ret =
+	    __db_vrfy_walkpages(dbp, vdp, handle, callback, flags)) != 0) {
+		if (ret == DB_VERIFY_BAD)
+			isbad = 1;
+		else if (ret != DB_PAGE_NOTFOUND)
+			goto err;
+	}
+
+	/* If we're verifying, verify inter-page structure. */
+	if (!LF_ISSET(DB_SALVAGE) && isbad == 0)
+		if ((t_ret = __db_vrfy_structure(dbp,
+		    vdp, name, 0, lp, rp, flags)) != 0) {
+			if (t_ret == DB_VERIFY_BAD)
+				isbad = 1;
+			else
+				goto err;
+		}
+
+	/*
+	 * If we're salvaging, output with key UNKNOWN any overflow or dup pages
+	 * we haven't been able to put in context.  Then destroy the salvager's
+	 * state-saving database.
+	 */
+	if (LF_ISSET(DB_SALVAGE)) {
+		if ((ret = __db_salvage_unknowns(dbp,
+		    vdp, handle, callback, flags)) != 0)
+			isbad = 1;
+	}
+
+	flags = sflags;
+
+#ifdef HAVE_PARTITION
+	if (t_ret == 0 && dbp->p_internal != NULL)
+		t_ret = __part_verify(dbp, vdp, name, handle, callback, flags);
+#endif
+
+	if (ret == 0)
+		ret = t_ret;
+
+	/* Don't display a footer for a database holding other databases. */
+	if (LF_ISSET(DB_SALVAGE | DB_VERIFY_PARTITION) == DB_SALVAGE &&
+	    (!has_subdbs || F_ISSET(vdp, SALVAGE_PRINTFOOTER)))
+		(void)__db_prfooter(handle, callback);
+
+done: err:
+	/* Send feedback that we're done. */
+	if (!LF_ISSET(DB_SALVAGE) && dbp->db_feedback != NULL)
+		dbp->db_feedback(dbp, DB_VERIFY, 100);
+
+	if (LF_ISSET(DB_SALVAGE) &&
+	    (t_ret = __db_salvage_destroy(vdp)) != 0 && ret == 0)
+		ret = t_ret;
+	if (fhp != NULL &&
+	    (t_ret = __os_closehandle(env, fhp)) != 0 && ret == 0)
+		ret = t_ret;
+	if (vdp != NULL &&
+	    (t_ret = __db_vrfy_dbinfo_destroy(env, vdp)) != 0 && ret == 0)
+		ret = t_ret;
+	if (real_name != NULL)
+		__os_free(env, real_name);
+
+	/*
+	 * DB_VERIFY_FATAL is a private error, translate to a public one.
+	 *
+	 * If we didn't find a page, it's probably a page number was corrupted.
+	 * Return the standard corruption error.
+	 *
+	 * Otherwise, if we found corruption along the way, set the return.
+	 */
+	if (ret == DB_VERIFY_FATAL ||
+	    ret == DB_PAGE_NOTFOUND || (ret == 0 && isbad == 1))
+		ret = DB_VERIFY_BAD;
+
+	/* Make sure there's a public complaint if we found corruption. */
+	if (ret != 0)
+		__db_err(env, ret, "%s", name);
+
+	return (ret);
+}
+
+/*
+ * __db_vrfy_getpagezero --
+ *      Store the master metadata page into a local buffer.  For safety, skip
+ *      the DB paging code and read the page directly from disk (via seek and
+ *      read) or the mpool.
+ */
+static int
+__db_vrfy_getpagezero(dbp, fhp, name, mbuf, flags)
+	DB *dbp;
+	DB_FH *fhp;
+	const char *name;
+	u_int8_t *mbuf;
+	u_int32_t flags;
+{
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h;
+	db_pgno_t pgno;
+	int ret, t_ret;
+	size_t nr;
+
+	env = dbp->env;
+
+	if (F_ISSET(dbp, DB_AM_INMEM)) {
+		/*
+		 * Now get the metadata page from the cache, if possible.  If
+		 * we're verifying an in-memory db, this is the only metadata
+		 * page we have.
+		 *
+		 *
+		 * Open the in-memory db file and get the metadata page.
+		 */
+		if ((ret = __memp_fcreate_pp(env->dbenv, &mpf, DB_VERIFY)) != 0)
+			return (ret);
+		if ((ret = __memp_set_flags(mpf, DB_MPOOL_NOFILE, 1)) != 0)
+			goto mpf_err;
+		if ((ret = __memp_fopen_pp(mpf,
+		    name, DB_ODDFILESIZE | DB_RDONLY, 0, 0)) != 0)
+			goto mpf_err;
+		pgno = PGNO_BASE_MD;
+		if ((ret = __memp_fget_pp(mpf, &pgno, NULL, 0, &h)) != 0) {
+			__db_err(env, ret, DB_STR_A("0747",
+			    "Metadata page %lu cannot be read from mpool",
+			    "%lu"), (u_long)pgno);
+			goto mpf_err;
+		}
+		memcpy(mbuf, (u_int8_t *)h, DBMETASIZE);
+		ret = __memp_fput_pp(mpf, h, DB_PRIORITY_UNCHANGED, 0);
+mpf_err:	if ((t_ret = __memp_fclose_pp(mpf, 0)) != 0 || ret != 0) {
+			return (ret == 0 ? t_ret : ret);
+		}
+	} else {
+		/*
+		 * Seek to the metadata page.
+		 *
+		 * Note that if we're just starting a verification, dbp->pgsize
+		 * may be zero;  this is okay, as we want page zero anyway and
+		 * 0*0 == 0.
+		 */
+		if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0 ||
+		    (ret = __os_read(env, fhp, mbuf, DBMETASIZE, &nr)) != 0) {
+			__db_err(env, ret, DB_STR_A("0520",
+			    "Metadata page %lu cannot be read", "%lu"),
+			    (u_long)PGNO_BASE_MD);
+			return (ret);
+		}
+
+		if (nr != DBMETASIZE) {
+			EPRINT((env, DB_STR_A("0521",
+			    "Page %lu: Incomplete metadata page", "%lu"),
+			    (u_long)PGNO_BASE_MD));
+			return (DB_VERIFY_FATAL);
+		}
+	}
+
+	return (ret);
+}
+
+/*
+ * __db_vrfy_pagezero --
+ *	Verify the master metadata page.  Use seek, read, and a local buffer
+ *	rather than the DB paging code, for safety.
+ *
+ *	Must correctly (or best-guess) set dbp->type and dbp->pagesize.
+ */
+static int
+__db_vrfy_pagezero(dbp, vdp, fhp, name, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	DB_FH *fhp;
+	const char *name;
+	u_int32_t flags;
+{
+	DBMETA *meta;
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	db_pgno_t freelist;
+	int isbad, ret, swapped;
+	u_int8_t mbuf[DBMETASIZE];
+
+	isbad = ret = swapped = 0;
+	freelist = 0;
+	env = dbp->env;
+	meta = (DBMETA *)mbuf;
+	dbp->type = DB_UNKNOWN;
+
+	if ((ret = __db_vrfy_getpagezero(dbp, fhp, name, mbuf, flags)) != 0)
+		return (ret);
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, PGNO_BASE_MD, &pip)) != 0)
+		return (ret);
+
+	if ((ret = __db_chk_meta(env, dbp, meta, 1)) != 0) {
+		EPRINT((env, DB_STR_A("0522",
+		    "Page %lu: metadata page corrupted", "%lu"),
+		    (u_long)PGNO_BASE_MD));
+		isbad = 1;
+		if (ret != DB_CHKSUM_FAIL) {
+			EPRINT((env, DB_STR_A("0523",
+			    "Page %lu: could not check metadata page", "%lu"),
+			    (u_long)PGNO_BASE_MD));
+			return (DB_VERIFY_FATAL);
+		}
+	}
+
+	/*
+	 * Check all of the fields that we can.
+	 *
+	 * 08-11: Current page number.  Must == pgno.
+	 * Note that endianness doesn't matter--it's zero.
+	 */
+	if (meta->pgno != PGNO_BASE_MD) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0524",
+		    "Page %lu: pgno incorrectly set to %lu", "%lu %lu"),
+		    (u_long)PGNO_BASE_MD, (u_long)meta->pgno));
+	}
+
+	/* 12-15: Magic number.  Must be one of valid set. */
+	if (__db_is_valid_magicno(meta->magic, &dbp->type))
+		swapped = 0;
+	else {
+		M_32_SWAP(meta->magic);
+		if (__db_is_valid_magicno(meta->magic,
+		    &dbp->type))
+			swapped = 1;
+		else {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("0525",
+			    "Page %lu: bad magic number %lu", "%lu %lu"),
+			    (u_long)PGNO_BASE_MD, (u_long)meta->magic));
+		}
+	}
+
+	/*
+	 * 16-19: Version.  Must be current;  for now, we
+	 * don't support verification of old versions.
+	 */
+	if (swapped)
+		M_32_SWAP(meta->version);
+	if ((dbp->type == DB_BTREE &&
+	    (meta->version > DB_BTREEVERSION ||
+	    meta->version < DB_BTREEOLDVER)) ||
+	    (dbp->type == DB_HASH &&
+	    (meta->version > DB_HASHVERSION ||
+	    meta->version < DB_HASHOLDVER)) ||
+	    (dbp->type == DB_HEAP &&
+	    (meta->version > DB_HEAPVERSION ||
+	    meta->version < DB_HEAPOLDVER)) ||
+	    (dbp->type == DB_QUEUE &&
+	    (meta->version > DB_QAMVERSION ||
+	    meta->version < DB_QAMOLDVER))) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0526",
+    "Page %lu: unsupported DB version %lu; extraneous errors may result",
+		    "%lu %lu"), (u_long)PGNO_BASE_MD, (u_long)meta->version));
+	}
+
+	/*
+	 * 20-23: Pagesize.  Must be power of two,
+	 * greater than 512, and less than 64K.
+	 */
+	if (swapped)
+		M_32_SWAP(meta->pagesize);
+	if (IS_VALID_PAGESIZE(meta->pagesize))
+		dbp->pgsize = meta->pagesize;
+	else {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0527", "Page %lu: bad page size %lu",
+		    "%lu %lu"), (u_long)PGNO_BASE_MD, (u_long)meta->pagesize));
+
+		/*
+		 * Now try to settle on a pagesize to use.
+		 * If the user-supplied one is reasonable,
+		 * use it;  else, guess.
+		 */
+		if (!IS_VALID_PAGESIZE(dbp->pgsize))
+			dbp->pgsize = __db_guesspgsize(env, fhp);
+	}
+
+	/*
+	 * 25: Page type.  Must be correct for dbp->type,
+	 * which is by now set as well as it can be.
+	 */
+	/* Needs no swapping--only one byte! */
+	if ((dbp->type == DB_BTREE && meta->type != P_BTREEMETA) ||
+	    (dbp->type == DB_HASH && meta->type != P_HASHMETA) ||
+	    (dbp->type == DB_HEAP && meta->type != P_HEAPMETA) ||
+	    (dbp->type == DB_QUEUE && meta->type != P_QAMMETA)) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0528", "Page %lu: bad page type %lu",
+		    "%lu %lu"), (u_long)PGNO_BASE_MD, (u_long)meta->type));
+	}
+
+	/*
+	 * 26: Meta-flags.
+	 */
+	if (meta->metaflags != 0) {
+		if (FLD_ISSET(meta->metaflags,
+		    ~(DBMETA_CHKSUM|DBMETA_PART_RANGE|DBMETA_PART_CALLBACK))) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("0529",
+			    "Page %lu: bad meta-data flags value %#lx",
+			    "%lu %#lx"), (u_long)PGNO_BASE_MD,
+			    (u_long)meta->metaflags));
+		}
+		if (FLD_ISSET(meta->metaflags, DBMETA_CHKSUM))
+			F_SET(pip, VRFY_HAS_CHKSUM);
+		if (FLD_ISSET(meta->metaflags, DBMETA_PART_RANGE))
+			F_SET(pip, VRFY_HAS_PART_RANGE);
+		if (FLD_ISSET(meta->metaflags, DBMETA_PART_CALLBACK))
+			F_SET(pip, VRFY_HAS_PART_CALLBACK);
+
+		if (FLD_ISSET(meta->metaflags,
+		    DBMETA_PART_RANGE | DBMETA_PART_CALLBACK) &&
+		    (ret = __partition_init(dbp, meta->metaflags)) != 0)
+			return (ret);
+	}
+
+	/*
+	 * 28-31: Free list page number.
+	 * 32-35: Last page in database file.
+	 * We'll verify last_pgno once we open the db in the mpool;
+	 * for now, just store it.
+	 */
+	if (swapped)
+	    M_32_SWAP(meta->free);
+	freelist = meta->free;
+	if (swapped)
+	    M_32_SWAP(meta->last_pgno);
+	vdp->meta_last_pgno = meta->last_pgno;
+
+	/*
+	 * Initialize vdp->pages to fit a single pageinfo structure for
+	 * this one page.  We'll realloc later when we know how many
+	 * pages there are.
+	 */
+	pip->pgno = PGNO_BASE_MD;
+	pip->type = meta->type;
+
+	/*
+	 * Signal that we still have to check the info specific to
+	 * a given type of meta page.
+	 */
+	F_SET(pip, VRFY_INCOMPLETE);
+
+	pip->free = freelist;
+
+	if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0)
+		return (ret);
+
+	/* Set up the dbp's fileid.  We don't use the regular open path. */
+	memcpy(dbp->fileid, meta->uid, DB_FILE_ID_LEN);
+	dbp->preserve_fid = 1;
+
+	if (swapped == 1)
+		F_SET(dbp, DB_AM_SWAP);
+
+	return (isbad ? DB_VERIFY_BAD : 0);
+}
+
+/*
+ * __db_vrfy_walkpages --
+ *	Main loop of the verifier/salvager.  Walks through,
+ *	page by page, and verifies all pages and/or prints all data pages.
+ */
+static int
+__db_vrfy_walkpages(dbp, vdp, handle, callback, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h;
+	VRFY_PAGEINFO *pip;
+	db_pgno_t i;
+	int ret, t_ret, isbad;
+
+	env = dbp->env;
+	mpf = dbp->mpf;
+	h = NULL;
+	ret = isbad = t_ret = 0;
+
+	for (i = 0; i <= vdp->last_pgno; i++) {
+		/*
+		 * If DB_SALVAGE is set, we inspect our database of completed
+		 * pages, and skip any we've already printed in the subdb pass.
+		 */
+		if (LF_ISSET(DB_SALVAGE) && (__db_salvage_isdone(vdp, i) != 0))
+			continue;
+
+		/*
+		 * An individual page get can fail if:
+		 *  * This is a hash database, it is expected to find
+		 *    empty buckets, which don't have allocated pages. Create
+		 *    a dummy page so the verification can proceed.
+		 *  * We are salvaging, flag the error and continue.
+		 */
+		if ((t_ret = __memp_fget(mpf, &i,
+		    vdp->thread_info, NULL, 0, &h)) != 0) {
+			if (dbp->type == DB_HASH ||
+			    (dbp->type == DB_QUEUE &&
+			    F_ISSET(dbp, DB_AM_INMEM))) {
+				if ((t_ret =
+				    __db_vrfy_getpageinfo(vdp, i, &pip)) != 0)
+					goto err1;
+				pip->type = P_INVALID;
+				pip->pgno = i;
+				F_CLR(pip, VRFY_IS_ALLZEROES);
+				F_SET(pip, VRFY_NONEXISTENT);
+				if ((t_ret = __db_vrfy_putpageinfo(
+				    env, vdp, pip)) != 0)
+					goto err1;
+				continue;
+			}
+			if (t_ret == DB_PAGE_NOTFOUND) {
+				EPRINT((env, DB_STR_A("0530",
+    "Page %lu: beyond the end of the file, metadata page has last page as %lu",
+				    "%lu %lu"), (u_long)i,
+				    (u_long)vdp->last_pgno));
+				if (ret == 0)
+					return (t_ret);
+			}
+
+err1:			if (ret == 0)
+				ret = t_ret;
+			if (LF_ISSET(DB_SALVAGE))
+				continue;
+			return (ret);
+		}
+
+		if (LF_ISSET(DB_SALVAGE)) {
+			/*
+			 * We pretty much don't want to quit unless a
+			 * bomb hits.  May as well return that something
+			 * was screwy, however.
+			 */
+			if ((t_ret = __db_salvage_pg(dbp,
+			    vdp, i, h, handle, callback, flags)) != 0) {
+				if (ret == 0)
+					ret = t_ret;
+				isbad = 1;
+			}
+		} else {
+			/*
+			 * If we are not salvaging, and we get any error
+			 * other than DB_VERIFY_BAD, return immediately;
+			 * it may not be safe to proceed.  If we get
+			 * DB_VERIFY_BAD, keep going;  listing more errors
+			 * may make it easier to diagnose problems and
+			 * determine the magnitude of the corruption.
+			 *
+			 * Verify info common to all page types.
+			 */
+			if (i != PGNO_BASE_MD) {
+				ret = __db_vrfy_common(dbp, vdp, h, i, flags);
+				if (ret == DB_VERIFY_BAD)
+					isbad = 1;
+				else if (ret != 0)
+					goto err;
+			}
+
+			switch (TYPE(h)) {
+			case P_INVALID:
+				ret = __db_vrfy_invalid(dbp, vdp, h, i, flags);
+				break;
+			case __P_DUPLICATE:
+				isbad = 1;
+				EPRINT((env, DB_STR_A("0531",
+				    "Page %lu: old-style duplicate page",
+				    "%lu"), (u_long)i));
+				break;
+			case P_HASH_UNSORTED:
+			case P_HASH:
+				ret = __ham_vrfy(dbp, vdp, h, i, flags);
+				break;
+			case P_HEAP:
+			case P_IHEAP:
+				ret = __heap_vrfy(dbp, vdp, h, i, flags);
+				break;
+			case P_IBTREE:
+			case P_IRECNO:
+			case P_LBTREE:
+			case P_LDUP:
+				ret = __bam_vrfy(dbp, vdp, h, i, flags);
+				break;
+			case P_LRECNO:
+				ret = __ram_vrfy_leaf(dbp, vdp, h, i, flags);
+				break;
+			case P_OVERFLOW:
+				ret = __db_vrfy_overflow(dbp, vdp, h, i, flags);
+				break;
+			case P_HASHMETA:
+				ret = __ham_vrfy_meta(dbp,
+				    vdp, (HMETA *)h, i, flags);
+				break;
+			case P_HEAPMETA:
+				ret = __heap_vrfy_meta(dbp,
+				    vdp, (HEAPMETA *)h, i, flags);
+				break;
+			case P_BTREEMETA:
+				ret = __bam_vrfy_meta(dbp,
+				    vdp, (BTMETA *)h, i, flags);
+				break;
+			case P_QAMMETA:
+				ret = __qam_vrfy_meta(dbp,
+				    vdp, (QMETA *)h, i, flags);
+				break;
+			case P_QAMDATA:
+				ret = __qam_vrfy_data(dbp,
+				    vdp, (QPAGE *)h, i, flags);
+				break;
+			default:
+				EPRINT((env, DB_STR_A("0532",
+				    "Page %lu: unknown page type %lu",
+				    "%lu %lu"), (u_long)i, (u_long)TYPE(h)));
+				isbad = 1;
+				break;
+			}
+
+			/*
+			 * Set up error return.
+			 */
+			if (ret == DB_VERIFY_BAD)
+				isbad = 1;
+			else if (ret != 0)
+				goto err;
+
+			/*
+			 * Provide feedback to the application about our
+			 * progress.  The range 0-50% comes from the fact
+			 * that this is the first of two passes through the
+			 * database (front-to-back, then top-to-bottom).
+			 */
+			if (dbp->db_feedback != NULL)
+				dbp->db_feedback(dbp, DB_VERIFY,
+				    (int)((i + 1) * 50 / (vdp->last_pgno + 1)));
+		}
+
+		/*
+		 * Just as with the page get, bail if and only if we're
+		 * not salvaging.
+		 */
+		if ((t_ret = __memp_fput(mpf,
+		    vdp->thread_info, h, dbp->priority)) != 0) {
+			if (ret == 0)
+				ret = t_ret;
+			if (!LF_ISSET(DB_SALVAGE))
+				return (ret);
+		}
+	}
+
+	/*
+	 * If we've seen a Queue metadata page, we may need to walk Queue
+	 * extent pages that won't show up between 0 and vdp->last_pgno.
+	 */
+	if (F_ISSET(vdp, VRFY_QMETA_SET) && (t_ret =
+	    __qam_vrfy_walkqueue(dbp, vdp, handle, callback, flags)) != 0) {
+		if (ret == 0)
+			ret = t_ret;
+		if (t_ret == DB_VERIFY_BAD)
+			isbad = 1;
+		else if (!LF_ISSET(DB_SALVAGE))
+			return (ret);
+	}
+
+	if (0) {
+err:		if (h != NULL && (t_ret = __memp_fput(mpf,
+		    vdp->thread_info, h, dbp->priority)) != 0)
+			return (ret == 0 ? t_ret : ret);
+	}
+
+	return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __db_vrfy_structure--
+ *	After a beginning-to-end walk through the database has been
+ *	completed, put together the information that has been collected
+ *	to verify the overall database structure.
+ *
+ *	Should only be called if we want to do a database verification,
+ *	i.e. if DB_SALVAGE is not set.
+ */
+static int
+__db_vrfy_structure(dbp, vdp, dbname, meta_pgno, lp, rp, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	const char *dbname;
+	db_pgno_t meta_pgno;
+	void *lp, *rp;
+	u_int32_t flags;
+{
+	DB *pgset;
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	db_pgno_t i;
+	int ret, isbad, hassubs, p;
+
+	isbad = 0;
+	pip = NULL;
+	env = dbp->env;
+	pgset = vdp->pgset;
+
+	/*
+	 * Providing feedback here is tricky;  in most situations,
+	 * we fetch each page one more time, but we do so in a top-down
+	 * order that depends on the access method.  Worse, we do this
+	 * recursively in btree, such that on any call where we're traversing
+	 * a subtree we don't know where that subtree is in the whole database;
+	 * worse still, any given database may be one of several subdbs.
+	 *
+	 * The solution is to decrement a counter vdp->pgs_remaining each time
+	 * we verify (and call feedback on) a page.  We may over- or
+	 * under-count, but the structure feedback function will ensure that we
+	 * never give a percentage under 50 or over 100.  (The first pass
+	 * covered the range 0-50%.)
+	 */
+	if (dbp->db_feedback != NULL)
+		vdp->pgs_remaining = vdp->last_pgno + 1;
+
+	/*
+	 * Call the appropriate function to downwards-traverse the db type.
+	 */
+	switch (dbp->type) {
+	case DB_BTREE:
+	case DB_RECNO:
+		if ((ret =
+		    __bam_vrfy_structure(dbp, vdp, 0, lp, rp, flags)) != 0) {
+			if (ret == DB_VERIFY_BAD)
+				isbad = 1;
+			else
+				goto err;
+		}
+
+		/*
+		 * If we have subdatabases and we know that the database is,
+		 * thus far, sound, it's safe to walk the tree of subdatabases.
+		 * Do so, and verify the structure of the databases within.
+		 */
+		if ((ret = __db_vrfy_getpageinfo(vdp, 0, &pip)) != 0)
+			goto err;
+		hassubs = F_ISSET(pip, VRFY_HAS_SUBDBS) ? 1 : 0;
+		if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0)
+			goto err;
+		pip = NULL;
+
+		if (isbad == 0 && hassubs)
+			if ((ret =
+			    __db_vrfy_subdbs(dbp, vdp, dbname, flags)) != 0) {
+				if (ret == DB_VERIFY_BAD)
+					isbad = 1;
+				else
+					goto err;
+			}
+		break;
+	case DB_HASH:
+		if ((ret = __ham_vrfy_structure(dbp, vdp, 0, flags)) != 0) {
+			if (ret == DB_VERIFY_BAD)
+				isbad = 1;
+			else
+				goto err;
+		}
+		break;
+	case DB_HEAP:
+		if ((ret = __heap_vrfy_structure(dbp, vdp, flags)) != 0) {
+			if (ret == DB_VERIFY_BAD)
+				isbad = 1;
+		}
+		/* Skip the freelist check for heap, it doesn't apply. */
+		goto err;
+	case DB_QUEUE:
+		if ((ret = __qam_vrfy_structure(dbp, vdp, flags)) != 0) {
+			if (ret == DB_VERIFY_BAD)
+				isbad = 1;
+		}
+
+		/*
+		 * Queue pages may be unreferenced and totally zeroed, if
+		 * they're empty;  queue doesn't have much structure, so
+		 * this is unlikely to be wrong in any troublesome sense.
+		 * Skip to "err".
+		 */
+		goto err;
+	case DB_UNKNOWN:
+	default:
+		ret = __db_unknown_path(env, "__db_vrfy_structure");
+		goto err;
+	}
+
+	/* Walk free list. */
+	if ((ret =
+	    __db_vrfy_freelist(dbp, vdp, meta_pgno, flags)) == DB_VERIFY_BAD)
+		isbad = 1;
+
+	/*
+	 * If structure checks up until now have failed, it's likely that
+	 * checking what pages have been missed will result in oodles of
+	 * extraneous error messages being EPRINTed.  Skip to the end
+	 * if this is the case;  we're going to be printing at least one
+	 * error anyway, and probably all the more salient ones.
+	 */
+	if (ret != 0 || isbad == 1)
+		goto err;
+
+	/*
+	 * Make sure no page has been missed and that no page is still marked
+	 * "all zeroes" unless we are looking at unused hash bucket pages or
+	 * pagesoff the end of database.
+	 */
+	for (i = 0; i < vdp->last_pgno + 1; i++) {
+		if ((ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0)
+			goto err;
+		if ((ret = __db_vrfy_pgset_get(pgset,
+		    vdp->thread_info, vdp->txn, i, &p)) != 0)
+			goto err;
+		if (pip->type == P_OVERFLOW) {
+			if ((u_int32_t)p != pip->refcount) {
+				EPRINT((env, DB_STR_A("0533",
+		    "Page %lu: overflow refcount %lu, referenced %lu times",
+				    "%lu %lu %lu"), (u_long)i,
+				    (u_long)pip->refcount, (u_long)p));
+				isbad = 1;
+			}
+		} else if (p == 0 &&
+#ifndef HAVE_FTRUNCATE
+		    !(i > vdp->meta_last_pgno &&
+		    (F_ISSET(pip, VRFY_IS_ALLZEROES) || pip->type == P_HASH)) &&
+#endif
+		    !(dbp->type == DB_HASH &&
+		    (pip->type == P_HASH || pip->type == P_INVALID))) {
+			/*
+			 * It is OK for unreferenced hash buckets to be
+			 * marked invalid and unreferenced.
+			 */
+			EPRINT((env, DB_STR_A("0534",
+			    "Page %lu: unreferenced page", "%lu"), (u_long)i));
+			isbad = 1;
+		}
+
+		if (F_ISSET(pip, VRFY_IS_ALLZEROES)
+#ifndef HAVE_FTRUNCATE
+		    && i <= vdp->meta_last_pgno
+#endif
+		    ) {
+			EPRINT((env, DB_STR_A("0535",
+			    "Page %lu: totally zeroed page", "%lu"),
+			    (u_long)i));
+			isbad = 1;
+		}
+		if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0)
+			goto err;
+		pip = NULL;
+	}
+
+err:	if (pip != NULL)
+		(void)__db_vrfy_putpageinfo(env, vdp, pip);
+
+	return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __db_is_valid_magicno
+ */
+static int
+__db_is_valid_magicno(magic, typep)
+	u_int32_t magic;
+	DBTYPE *typep;
+{
+	switch (magic) {
+	case DB_BTREEMAGIC:
+		*typep = DB_BTREE;
+		return (1);
+	case DB_HASHMAGIC:
+		*typep = DB_HASH;
+		return (1);
+	case DB_HEAPMAGIC:
+		*typep = DB_HEAP;
+		return (1);
+	case DB_QAMMAGIC:
+		*typep = DB_QUEUE;
+		return (1);
+	default:
+		break;
+	}
+	*typep = DB_UNKNOWN;
+	return (0);
+}
+
+/*
+ * __db_vrfy_common --
+ *	Verify info common to all page types.
+ *
+ * PUBLIC: int  __db_vrfy_common
+ * PUBLIC:     __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
+ */
+int
+__db_vrfy_common(dbp, vdp, h, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	int ret, t_ret;
+	u_int8_t *p;
+
+	env = dbp->env;
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+
+	pip->pgno = pgno;
+	F_CLR(pip, VRFY_IS_ALLZEROES);
+
+	/*
+	 * Hash expands the table by leaving some pages between the
+	 * old last and the new last totally zeroed.  These pages may
+	 * not be all zero if they were used, freed and then reallocated.
+	 *
+	 * Queue will create sparse files if sparse record numbers are used.
+	 */
+	if (pgno != 0 && PGNO(h) == 0) {
+		F_SET(pip, VRFY_IS_ALLZEROES);
+		for (p = (u_int8_t *)h; p < (u_int8_t *)h + dbp->pgsize; p++)
+			if (*p != 0) {
+				F_CLR(pip, VRFY_IS_ALLZEROES);
+				break;
+			}
+		/*
+		 * Mark it as a hash, and we'll
+		 * check that that makes sense structurally later.
+		 * (The queue verification doesn't care, since queues
+		 * don't really have much in the way of structure.)
+		 */
+		if (dbp->type != DB_HEAP)
+			pip->type = P_HASH;
+		ret = 0;
+		goto err;	/* well, not really an err. */
+	}
+
+	if (PGNO(h) != pgno) {
+		EPRINT((env, DB_STR_A("0536", "Page %lu: bad page number %lu",
+		    "%lu %lu"), (u_long)pgno, (u_long)h->pgno));
+		ret = DB_VERIFY_BAD;
+	}
+
+	switch (h->type) {
+	case P_INVALID:			/* Order matches ordinal value. */
+	case P_HASH_UNSORTED:
+	case P_IBTREE:
+	case P_IRECNO:
+	case P_LBTREE:
+	case P_LRECNO:
+	case P_OVERFLOW:
+	case P_HASHMETA:
+	case P_BTREEMETA:
+	case P_QAMMETA:
+	case P_QAMDATA:
+	case P_LDUP:
+	case P_HASH:
+	case P_HEAP:
+	case P_IHEAP:
+	case P_HEAPMETA:
+		break;
+	default:
+		EPRINT((env, DB_STR_A("0537", "Page %lu: bad page type %lu",
+		    "%lu %lu"), (u_long)pgno, (u_long)h->type));
+		ret = DB_VERIFY_BAD;
+	}
+	pip->type = h->type;
+
+err:	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __db_vrfy_invalid --
+ *	Verify P_INVALID page.
+ *	(Yes, there's not much to do here.)
+ */
+static int
+__db_vrfy_invalid(dbp, vdp, h, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	int ret, t_ret;
+
+	env = dbp->env;
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+	pip->next_pgno = pip->prev_pgno = 0;
+
+	if (!IS_VALID_PGNO(NEXT_PGNO(h))) {
+		EPRINT((env, DB_STR_A("0538", "Page %lu: invalid next_pgno %lu",
+		    "%lu %lu"), (u_long)pgno, (u_long)NEXT_PGNO(h)));
+		ret = DB_VERIFY_BAD;
+	} else
+		pip->next_pgno = NEXT_PGNO(h);
+
+	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+/*
+ * __db_vrfy_datapage --
+ *	Verify elements common to data pages (P_HASH, P_LBTREE,
+ *	P_IBTREE, P_IRECNO, P_LRECNO, P_OVERFLOW, P_DUPLICATE)--i.e.,
+ *	those defined in the PAGE structure.
+ *
+ *	Called from each of the per-page routines, after the
+ *	all-page-type-common elements of pip have been verified and filled
+ *	in.
+ *
+ * PUBLIC: int __db_vrfy_datapage
+ * PUBLIC:     __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
+ */
+int
+__db_vrfy_datapage(dbp, vdp, h, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	u_int32_t smallest_entry;
+	int isbad, ret, t_ret;
+
+	env = dbp->env;
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+	isbad = 0;
+
+	/*
+	 * prev_pgno and next_pgno:  store for inter-page checks,
+	 * verify that they point to actual pages and not to self.
+	 *
+	 * !!!
+	 * Internal btree pages, as well as heap pages, do not maintain these
+	 * fields (indeed, they overload them).  Skip.
+	 */
+	if (TYPE(h) != P_IBTREE &&
+	    TYPE(h) != P_IRECNO && TYPE(h) != P_HEAP && TYPE(h) != P_IHEAP) {
+		if (!IS_VALID_PGNO(PREV_PGNO(h)) || PREV_PGNO(h) == pip->pgno) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("0539",
+			    "Page %lu: invalid prev_pgno %lu", "%lu %lu"),
+			    (u_long)pip->pgno, (u_long)PREV_PGNO(h)));
+		}
+		if (!IS_VALID_PGNO(NEXT_PGNO(h)) || NEXT_PGNO(h) == pip->pgno) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("0540",
+			    "Page %lu: invalid next_pgno %lu", "%lu %lu"),
+			    (u_long)pip->pgno, (u_long)NEXT_PGNO(h)));
+		}
+		pip->prev_pgno = PREV_PGNO(h);
+		pip->next_pgno = NEXT_PGNO(h);
+	}
+
+	/*
+	 * Verify the number of entries on the page: there's no good way to
+	 * determine if this is accurate.  The best we can do is verify that
+	 * it's not more than can, in theory, fit on the page.  Then, we make
+	 * sure there are at least this many valid elements in inp[], and
+	 * hope the test catches most cases.
+	 */
+	switch (TYPE(h)) {
+	case P_HASH_UNSORTED:
+	case P_HASH:
+		smallest_entry = HKEYDATA_PSIZE(0);
+		break;
+	case P_HEAP:
+		smallest_entry = sizeof(HEAPHDR) + sizeof(db_indx_t);
+		break;
+	case P_IHEAP:
+		/* Really high_pgno. */
+		pip->prev_pgno = PREV_PGNO(h);
+		smallest_entry = 0;
+		break;
+	case P_IBTREE:
+		smallest_entry = BINTERNAL_PSIZE(0);
+		break;
+	case P_IRECNO:
+		smallest_entry = RINTERNAL_PSIZE;
+		break;
+	case P_LBTREE:
+	case P_LDUP:
+	case P_LRECNO:
+		smallest_entry = BKEYDATA_PSIZE(0);
+		break;
+	default:
+		smallest_entry = 0;
+		break;
+	}
+	if (smallest_entry * NUM_ENT(h) / 2 > dbp->pgsize) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0541",
+		    "Page %lu: too many entries: %lu",
+		    "%lu %lu"), (u_long)pgno, (u_long)NUM_ENT(h)));
+	}
+
+	if (TYPE(h) != P_OVERFLOW)
+		pip->entries = NUM_ENT(h);
+
+	/*
+	 * btree level.  Should be zero unless we're a btree;
+	 * if we are a btree, should be between LEAFLEVEL and MAXBTREELEVEL,
+	 * and we need to save it off.
+	 */
+	switch (TYPE(h)) {
+	case P_IBTREE:
+	case P_IRECNO:
+		if (LEVEL(h) < LEAFLEVEL + 1) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("0542",
+			    "Page %lu: bad btree level %lu", "%lu %lu"),
+			    (u_long)pgno, (u_long)LEVEL(h)));
+		}
+		pip->bt_level = LEVEL(h);
+		break;
+	case P_LBTREE:
+	case P_LDUP:
+	case P_LRECNO:
+		if (LEVEL(h) != LEAFLEVEL) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("0543",
+			    "Page %lu: btree leaf page has incorrect level %lu",
+			    "%lu %lu"), (u_long)pgno, (u_long)LEVEL(h)));
+		}
+		break;
+	default:
+		if (LEVEL(h) != 0) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("0544",
+			    "Page %lu: nonzero level %lu in non-btree database",
+			    "%lu %lu"), (u_long)pgno, (u_long)LEVEL(h)));
+		}
+		break;
+	}
+
+	/*
+	 * Even though inp[] occurs in all PAGEs, we look at it in the
+	 * access-method-specific code, since btree and hash treat
+	 * item lengths very differently, and one of the most important
+	 * things we want to verify is that the data--as specified
+	 * by offset and length--cover the right part of the page
+	 * without overlaps, gaps, or violations of the page boundary.
+	 */
+	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __db_vrfy_meta --
+ *	Verify the access-method common parts of a meta page, using
+ *	normal mpool routines.
+ *
+ * PUBLIC: int __db_vrfy_meta
+ * PUBLIC:     __P((DB *, VRFY_DBINFO *, DBMETA *, db_pgno_t, u_int32_t));
+ */
+int
+__db_vrfy_meta(dbp, vdp, meta, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	DBMETA *meta;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	DBTYPE dbtype, magtype;
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	int isbad, ret, t_ret;
+
+	isbad = 0;
+	env = dbp->env;
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+
+	/* type plausible for a meta page */
+	switch (meta->type) {
+	case P_BTREEMETA:
+		dbtype = DB_BTREE;
+		break;
+	case P_HASHMETA:
+		dbtype = DB_HASH;
+		break;
+	case P_HEAPMETA:
+		dbtype = DB_HEAP;
+		break;
+	case P_QAMMETA:
+		dbtype = DB_QUEUE;
+		break;
+	default:
+		ret = __db_unknown_path(env, "__db_vrfy_meta");
+		goto err;
+	}
+
+	/* magic number valid */
+	if (!__db_is_valid_magicno(meta->magic, &magtype)) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0545", "Page %lu: invalid magic number",
+		    "%lu"), (u_long)pgno));
+	}
+	if (magtype != dbtype) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0546",
+		    "Page %lu: magic number does not match database type",
+		    "%lu"), (u_long)pgno));
+	}
+
+	/* version */
+	if ((dbtype == DB_BTREE &&
+	    (meta->version > DB_BTREEVERSION ||
+	    meta->version < DB_BTREEOLDVER)) ||
+	    (dbtype == DB_HASH &&
+	    (meta->version > DB_HASHVERSION ||
+	    meta->version < DB_HASHOLDVER)) ||
+	    (dbtype == DB_HEAP &&
+	    (meta->version > DB_HEAPVERSION ||
+	    meta->version < DB_HEAPOLDVER)) ||
+	    (dbtype == DB_QUEUE &&
+	    (meta->version > DB_QAMVERSION ||
+	    meta->version < DB_QAMOLDVER))) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0547",
+    "Page %lu: unsupported database version %lu; extraneous errors may result",
+		    "%lu %lu"), (u_long)pgno, (u_long)meta->version));
+	}
+
+	/* pagesize */
+	if (meta->pagesize != dbp->pgsize) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0548", "Page %lu: invalid pagesize %lu",
+		    "%lu %lu"), (u_long)pgno, (u_long)meta->pagesize));
+	}
+
+	/* Flags */
+	if (meta->metaflags != 0) {
+		if (FLD_ISSET(meta->metaflags,
+		    ~(DBMETA_CHKSUM|DBMETA_PART_RANGE|DBMETA_PART_CALLBACK))) {
+			isbad = 1;
+			EPRINT((env, DB_STR_A("0549",
+			    "Page %lu: bad meta-data flags value %#lx",
+			    "%lu %#lx"), (u_long)PGNO_BASE_MD,
+			    (u_long)meta->metaflags));
+		}
+		if (FLD_ISSET(meta->metaflags, DBMETA_CHKSUM))
+			F_SET(pip, VRFY_HAS_CHKSUM);
+		if (FLD_ISSET(meta->metaflags, DBMETA_PART_RANGE))
+			F_SET(pip, VRFY_HAS_PART_RANGE);
+		if (FLD_ISSET(meta->metaflags, DBMETA_PART_CALLBACK))
+			F_SET(pip, VRFY_HAS_PART_CALLBACK);
+	}
+
+	/*
+	 * Free list.
+	 *
+	 * If this is not the main, master-database meta page, it
+	 * should not have a free list.
+	 */
+	if (pgno != PGNO_BASE_MD && meta->free != PGNO_INVALID) {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0550",
+		    "Page %lu: nonempty free list on subdatabase metadata page",
+		    "%lu"), (u_long)pgno));
+	}
+
+	/* Can correctly be PGNO_INVALID--that's just the end of the list. */
+	if (IS_VALID_PGNO(meta->free))
+		pip->free = meta->free;
+	else {
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0551",
+		    "Page %lu: nonsensical free list pgno %lu", "%lu %lu"),
+		    (u_long)pgno, (u_long)meta->free));
+	}
+
+	/*
+	 * Check that the meta page agrees with what we got from mpool.
+	 * If we don't have FTRUNCATE then mpool could include some
+	 * zeroed pages at the end of the file, we assume the meta page
+	 * is correct.  Queue does not update the meta page's last_pgno.
+	 *
+	 * We have seen one false positive after a failure while rolling the log
+	 * forward, last_pgno was updated and the file had not yet been
+	 * extended.  [#18418]
+	 */
+	if (pgno == PGNO_BASE_MD &&
+	    dbtype != DB_QUEUE && meta->last_pgno != vdp->last_pgno) {
+#ifdef HAVE_FTRUNCATE
+		isbad = 1;
+		EPRINT((env, DB_STR_A("0552",
+		    "Page %lu: last_pgno is not correct: %lu != %lu",
+		    "%lu %lu %lu"), (u_long)pgno,
+		    (u_long)meta->last_pgno, (u_long)vdp->last_pgno));
+#endif
+		vdp->meta_last_pgno = meta->last_pgno;
+	}
+
+	/*
+	 * We have now verified the common fields of the metadata page.
+	 * Clear the flag that told us they had been incompletely checked.
+	 */
+	F_CLR(pip, VRFY_INCOMPLETE);
+
+err:	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __db_vrfy_freelist --
+ *	Walk free list, checking off pages and verifying absence of
+ *	loops.
+ */
+static int
+__db_vrfy_freelist(dbp, vdp, meta, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t meta;
+	u_int32_t flags;
+{
+	DB *pgset;
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	db_pgno_t cur_pgno, next_pgno;
+	int p, ret, t_ret;
+
+	env = dbp->env;
+	pgset = vdp->pgset;
+	DB_ASSERT(env, pgset != NULL);
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, meta, &pip)) != 0)
+		return (ret);
+	for (next_pgno = pip->free;
+	    next_pgno != PGNO_INVALID; next_pgno = pip->next_pgno) {
+		cur_pgno = pip->pgno;
+		if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0)
+			return (t_ret);
+
+		/* This shouldn't happen, but just in case. */
+		if (!IS_VALID_PGNO(next_pgno)) {
+			EPRINT((env, DB_STR_A("0553",
+			    "Page %lu: invalid next_pgno %lu on free list page",
+			    "%lu %lu"), (u_long)cur_pgno, (u_long)next_pgno));
+			return (DB_VERIFY_BAD);
+		}
+
+		if (next_pgno > vdp->last_pgno) {
+			EPRINT((env, DB_STR_A("0713",
+			 "Page %lu: page %lu on free list beyond last_pgno %lu",
+			    "%lu %lu %lu"), (u_long)cur_pgno,
+			    (u_long)next_pgno, (u_long)vdp->last_pgno));
+			ret = DB_VERIFY_BAD;
+		}
+		/* Detect cycles. */
+		if ((t_ret = __db_vrfy_pgset_get(pgset,
+		    vdp->thread_info, vdp->txn, next_pgno, &p)) != 0)
+			return (t_ret);
+		if (p != 0) {
+			EPRINT((env, DB_STR_A("0554",
+		    "Page %lu: page %lu encountered a second time on free list",
+			    "%lu %lu"), (u_long)cur_pgno, (u_long)next_pgno));
+			return (DB_VERIFY_BAD);
+		}
+		if ((t_ret = __db_vrfy_pgset_inc(pgset,
+		    vdp->thread_info, vdp->txn, next_pgno)) != 0)
+			return (t_ret);
+
+		if ((t_ret = __db_vrfy_getpageinfo(vdp, next_pgno, &pip)) != 0)
+			return (t_ret);
+
+		if (pip->type != P_INVALID) {
+			EPRINT((env, DB_STR_A("0555",
+			    "Page %lu: non-invalid page %lu on free list",
+			    "%lu %lu"), (u_long)cur_pgno, (u_long)next_pgno));
+			ret = DB_VERIFY_BAD;	  /* unsafe to continue */
+			break;
+		}
+	}
+
+	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+/*
+ * __db_vrfy_subdbs --
+ *	Walk the known-safe master database of subdbs with a cursor,
+ *	verifying the structure of each subdatabase we encounter.
+ */
+static int
+__db_vrfy_subdbs(dbp, vdp, dbname, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	const char *dbname;
+	u_int32_t flags;
+{
+	DB *mdbp;
+	DBC *dbc;
+	DBT key, data;
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	db_pgno_t meta_pgno;
+	int ret, t_ret, isbad;
+	u_int8_t type;
+
+	isbad = 0;
+	dbc = NULL;
+	env = dbp->env;
+
+	if ((ret = __db_master_open(dbp,
+	    vdp->thread_info, NULL, dbname, DB_RDONLY, 0, &mdbp)) != 0)
+		return (ret);
+
+	if ((ret = __db_cursor_int(mdbp, NULL,
+	    vdp->txn, DB_BTREE, PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0)
+		goto err;
+
+	memset(&key, 0, sizeof(key));
+	memset(&data, 0, sizeof(data));
+	while ((ret = __dbc_get(dbc, &key, &data, DB_NEXT)) == 0) {
+		if (data.size != sizeof(db_pgno_t)) {
+			EPRINT((env, DB_STR("0556",
+			    "Subdatabase entry not page-number size")));
+			isbad = 1;
+			goto err;
+		}
+		memcpy(&meta_pgno, data.data, data.size);
+		/*
+		 * Subdatabase meta pgnos are stored in network byte
+		 * order for cross-endian compatibility.  Swap if appropriate.
+		 */
+		DB_NTOHL_SWAP(env, &meta_pgno);
+		if (meta_pgno == PGNO_INVALID || meta_pgno > vdp->last_pgno) {
+			EPRINT((env, DB_STR_A("0557",
+			    "Subdatabase entry references invalid page %lu",
+			    "%lu"), (u_long)meta_pgno));
+			isbad = 1;
+			goto err;
+		}
+		if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &pip)) != 0)
+			goto err;
+		type = pip->type;
+		if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0)
+			goto err;
+		switch (type) {
+		case P_BTREEMETA:
+			if ((ret = __bam_vrfy_structure(
+			    dbp, vdp, meta_pgno, NULL, NULL, flags)) != 0) {
+				if (ret == DB_VERIFY_BAD)
+					isbad = 1;
+				else
+					goto err;
+			}
+			break;
+		case P_HASHMETA:
+			if ((ret = __ham_vrfy_structure(
+			    dbp, vdp, meta_pgno, flags)) != 0) {
+				if (ret == DB_VERIFY_BAD)
+					isbad = 1;
+				else
+					goto err;
+			}
+			break;
+		case P_QAMMETA:
+		default:
+			EPRINT((env, DB_STR_A("0558",
+		    "Subdatabase entry references page %lu of invalid type %lu",
+			    "%lu %lu"), (u_long)meta_pgno, (u_long)type));
+			ret = DB_VERIFY_BAD;
+			goto err;
+		}
+	}
+
+	if (ret == DB_NOTFOUND)
+		ret = 0;
+
+err:	if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if ((t_ret = __db_close(mdbp, NULL, 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);
+}
+
+/*
+ * __db_vrfy_struct_feedback --
+ *	Provide feedback during top-down database structure traversal.
+ *	(See comment at the beginning of __db_vrfy_structure.)
+ *
+ * PUBLIC: void __db_vrfy_struct_feedback __P((DB *, VRFY_DBINFO *));
+ */
+void
+__db_vrfy_struct_feedback(dbp, vdp)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+{
+	int progress;
+
+	if (dbp->db_feedback == NULL)
+		return;
+
+	if (vdp->pgs_remaining > 0)
+		vdp->pgs_remaining--;
+
+	/* Don't allow a feedback call of 100 until we're really done. */
+	progress = 100 - (int)(vdp->pgs_remaining * 50 / (vdp->last_pgno + 1));
+	dbp->db_feedback(dbp, DB_VERIFY, progress == 100 ? 99 : progress);
+}
+
+/*
+ * __db_vrfy_orderchkonly --
+ *	Do an sort-order/hashing check on a known-otherwise-good subdb.
+ */
+static int
+__db_vrfy_orderchkonly(dbp, vdp, name, subdb, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	const char *name, *subdb;
+	u_int32_t flags;
+{
+	BTMETA *btmeta;
+	DB *mdbp, *pgset;
+	DBC *pgsc;
+	DBT key, data;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	HASH *h_internal;
+	HMETA *hmeta;
+	PAGE *h, *currpg;
+	db_pgno_t meta_pgno, p, pgno;
+	u_int32_t bucket;
+	int t_ret, ret;
+
+	pgset = NULL;
+	pgsc = NULL;
+	env = dbp->env;
+	mpf = dbp->mpf;
+	currpg = h = NULL;
+
+	LF_CLR(DB_NOORDERCHK);
+
+	/* Open the master database and get the meta_pgno for the subdb. */
+	if ((ret = __db_master_open(dbp,
+	    vdp->thread_info, NULL, name, DB_RDONLY, 0, &mdbp)) != 0)
+		goto err;
+
+	DB_INIT_DBT(key, subdb, strlen(subdb));
+	memset(&data, 0, sizeof(data));
+	if ((ret = __db_get(mdbp,
+	    vdp->thread_info, NULL, &key, &data, 0)) != 0) {
+		if (ret == DB_NOTFOUND)
+			ret = ENOENT;
+		goto err;
+	}
+
+	if (data.size != sizeof(db_pgno_t)) {
+		EPRINT((env, DB_STR("0559",
+		    "Subdatabase entry of invalid size")));
+		ret = DB_VERIFY_BAD;
+		goto err;
+	}
+
+	memcpy(&meta_pgno, data.data, data.size);
+
+	/*
+	 * Subdatabase meta pgnos are stored in network byte
+	 * order for cross-endian compatibility.  Swap if appropriate.
+	 */
+	DB_NTOHL_SWAP(env, &meta_pgno);
+
+	if ((ret = __memp_fget(mpf,
+	     &meta_pgno, vdp->thread_info, NULL, 0, &h)) != 0)
+		goto err;
+
+	if ((ret = __db_vrfy_pgset(env,
+	    vdp->thread_info, dbp->pgsize, &pgset)) != 0)
+		goto err;
+
+	switch (TYPE(h)) {
+	case P_BTREEMETA:
+		btmeta = (BTMETA *)h;
+		if (F_ISSET(&btmeta->dbmeta, BTM_RECNO)) {
+			/* Recnos have no order to check. */
+			ret = 0;
+			goto err;
+		}
+		if ((ret =
+		    __db_meta2pgset(dbp, vdp, meta_pgno, flags, pgset)) != 0)
+			goto err;
+		if ((ret = __db_cursor_int(pgset, NULL, vdp->txn, dbp->type,
+		    PGNO_INVALID, 0, DB_LOCK_INVALIDID, &pgsc)) != 0)
+			goto err;
+		while ((ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) {
+			if ((ret = __memp_fget(mpf, &p,
+			     vdp->thread_info, NULL, 0, &currpg)) != 0)
+				goto err;
+			if ((ret = __bam_vrfy_itemorder(dbp, NULL,
+			    vdp->thread_info, currpg, p, NUM_ENT(currpg), 1,
+			    F_ISSET(&btmeta->dbmeta, BTM_DUP), flags)) != 0)
+				goto err;
+			if ((ret = __memp_fput(mpf,
+			    vdp->thread_info, currpg, dbp->priority)) != 0)
+				goto err;
+			currpg = NULL;
+		}
+
+		/*
+		 * The normal exit condition for the loop above is DB_NOTFOUND.
+		 * If we see that, zero it and continue on to cleanup.
+		 * Otherwise, it's a real error and will be returned.
+		 */
+		if (ret == DB_NOTFOUND)
+			ret = 0;
+		break;
+	case P_HASHMETA:
+		hmeta = (HMETA *)h;
+		h_internal = (HASH *)dbp->h_internal;
+		/*
+		 * Make sure h_charkey is right.
+		 */
+		if (h_internal == NULL) {
+			EPRINT((env, DB_STR_A("0560",
+			    "Page %lu: DB->h_internal field is NULL", "%lu"),
+			    (u_long)meta_pgno));
+			ret = DB_VERIFY_BAD;
+			goto err;
+		}
+		if (h_internal->h_hash == NULL)
+			h_internal->h_hash = hmeta->dbmeta.version < 5
+			? __ham_func4 : __ham_func5;
+		if (hmeta->h_charkey !=
+		    h_internal->h_hash(dbp, CHARKEY, sizeof(CHARKEY))) {
+			EPRINT((env, DB_STR_A("0561",
+			    "Page %lu: incorrect hash function for database",
+			    "%lu"), (u_long)meta_pgno));
+			ret = DB_VERIFY_BAD;
+			goto err;
+		}
+
+		/*
+		 * Foreach bucket, verify hashing on each page in the
+		 * corresponding chain of pages.
+		 */
+		if ((ret = __db_cursor_int(dbp, NULL, vdp->txn, dbp->type,
+		    PGNO_INVALID, 0, DB_LOCK_INVALIDID, &pgsc)) != 0)
+			goto err;
+		for (bucket = 0; bucket <= hmeta->max_bucket; bucket++) {
+			pgno = BS_TO_PAGE(bucket, hmeta->spares);
+			while (pgno != PGNO_INVALID) {
+				if ((ret = __memp_fget(mpf, &pgno,
+				    vdp->thread_info, NULL, 0, &currpg)) != 0)
+					goto err;
+				if ((ret = __ham_vrfy_hashing(pgsc,
+				    NUM_ENT(currpg), hmeta, bucket, pgno,
+				    flags, h_internal->h_hash)) != 0)
+					goto err;
+				pgno = NEXT_PGNO(currpg);
+				if ((ret = __memp_fput(mpf, vdp->thread_info,
+				    currpg, dbp->priority)) != 0)
+					goto err;
+				currpg = NULL;
+			}
+		}
+		break;
+	default:
+		EPRINT((env, DB_STR_A("0562",
+		    "Page %lu: database metapage of bad type %lu",
+		    "%lu %lu"), (u_long)meta_pgno, (u_long)TYPE(h)));
+		ret = DB_VERIFY_BAD;
+		break;
+	}
+
+err:	if (pgsc != NULL && (t_ret = __dbc_close(pgsc)) != 0 && ret == 0)
+		ret = t_ret;
+	if (pgset != NULL &&
+	    (t_ret = __db_close(pgset, NULL, 0)) != 0 && ret == 0)
+		ret = t_ret;
+	if (h != NULL && (t_ret = __memp_fput(mpf,
+	    vdp->thread_info, h, dbp->priority)) != 0)
+		ret = t_ret;
+	if (currpg != NULL &&
+	    (t_ret = __memp_fput(mpf,
+		vdp->thread_info, currpg, dbp->priority)) != 0)
+		ret = t_ret;
+	if ((t_ret = __db_close(mdbp, NULL, 0)) != 0)
+		ret = t_ret;
+	return (ret);
+}
+
+/*
+ * __db_salvage_pg --
+ *	Walk through a page, salvaging all likely or plausible (w/
+ *	DB_AGGRESSIVE) key/data pairs and marking seen pages in vdp.
+ *
+ * PUBLIC: int __db_salvage_pg __P((DB *, VRFY_DBINFO *, db_pgno_t,
+ * PUBLIC:     PAGE *, void *, int (*)(void *, const void *), u_int32_t));
+ */
+int
+__db_salvage_pg(dbp, vdp, pgno, h, handle, callback, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	PAGE *h;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	int keyflag, ret, t_ret;
+
+	env = dbp->env;
+	DB_ASSERT(env, LF_ISSET(DB_SALVAGE));
+
+	/*
+	 * !!!
+	 * We dump record numbers when salvaging Queue databases, but not for
+	 * immutable Recno databases.  The problem is we can't figure out the
+	 * record number from the database page in the Recno case, while the
+	 * offset in the file is sufficient for Queue.
+	 */
+	keyflag = 0;
+
+	/* If we got this page in the subdb pass, we can safely skip it. */
+	if (__db_salvage_isdone(vdp, pgno))
+		return (0);
+
+	switch (TYPE(h)) {
+	case P_BTREEMETA:
+		ret = __bam_vrfy_meta(dbp, vdp, (BTMETA *)h, pgno, flags);
+		break;
+	case P_HASH:
+	case P_HASH_UNSORTED:
+	case P_HEAP:
+	case P_LBTREE:
+	case P_QAMDATA:
+		return (__db_salvage_leaf(dbp,
+		    vdp, pgno, h, handle, callback, flags));
+	case P_HASHMETA:
+		ret = __ham_vrfy_meta(dbp, vdp, (HMETA *)h, pgno, flags);
+		break;
+	case P_HEAPMETA:
+		ret = __heap_vrfy_meta(dbp, vdp, (HEAPMETA *)h, pgno, flags);
+		break;
+	case P_IBTREE:
+		/*
+		 * We need to mark any overflow keys on internal pages as seen,
+		 * so we don't print them out in __db_salvage_unknowns.  But if
+		 * we're an upgraded database, a P_LBTREE page may very well
+		 * have a reference to the same overflow pages (this practice
+		 * stopped somewhere around db4.5).  To give P_LBTREEs a chance
+		 * to print out any keys on shared pages, mark the page now and
+		 * deal with it at the end.
+		 */
+		return (__db_salvage_markneeded(vdp, pgno, SALVAGE_IBTREE));
+	case P_IHEAP:
+		/*
+		 * There's nothing to salvage from heap region pages.  Just mark
+		 * that we've seen the page.
+		 */
+		return (__db_salvage_markdone(vdp, pgno));
+	case P_LDUP:
+		return (__db_salvage_markneeded(vdp, pgno, SALVAGE_LDUP));
+	case P_LRECNO:
+		/*
+		 * Recno leaves are tough, because the leaf could be (1) a dup
+		 * page, or it could be (2) a regular database leaf page.
+		 * Fortunately, RECNO databases are not allowed to have
+		 * duplicates.
+		 *
+		 * If there are no subdatabases, dump the page immediately if
+		 * it's a leaf in a RECNO database, otherwise wait and hopefully
+		 * it will be dumped by the leaf page that refers to it,
+		 * otherwise we'll get it with the unknowns.
+		 *
+		 * If there are subdatabases, there might be mixed types and
+		 * dbp->type can't be trusted.  We'll only get here after
+		 * salvaging each database, though, so salvaging this page
+		 * immediately isn't important.  If this page is a dup, it might
+		 * get salvaged later on, otherwise the unknowns pass will pick
+		 * it up.  Note that SALVAGE_HASSUBDBS won't get set if we're
+		 * salvaging aggressively.
+		 *
+		 * If we're salvaging aggressively, we don't know whether or not
+		 * there's subdatabases, so we wait on all recno pages.
+		 */
+		if (!LF_ISSET(DB_AGGRESSIVE) &&
+		    !F_ISSET(vdp, SALVAGE_HASSUBDBS) && dbp->type == DB_RECNO)
+			return (__db_salvage_leaf(dbp,
+			    vdp, pgno, h, handle, callback, flags));
+		return (__db_salvage_markneeded(vdp, pgno, SALVAGE_LRECNODUP));
+	case P_OVERFLOW:
+		return (__db_salvage_markneeded(vdp, pgno, SALVAGE_OVERFLOW));
+	case P_QAMMETA:
+		keyflag = 1;
+		ret = __qam_vrfy_meta(dbp, vdp, (QMETA *)h, pgno, flags);
+		break;
+	case P_INVALID:
+	case P_IRECNO:
+	case __P_DUPLICATE:
+	default:
+		/*
+		 * There's no need to display an error, the page type was
+		 * already checked and reported on.
+		 */
+		return (0);
+	}
+	if (ret != 0)
+		return (ret);
+
+	/*
+	 * We have to display the dump header if it's a metadata page.  It's
+	 * our last chance as the page was marked "seen" in the vrfy routine,
+	 * and  we won't see the page again.  We don't display headers for
+	 * the first database in a multi-database file, that database simply
+	 * contains a list of subdatabases.
+	 */
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+	if (!F_ISSET(pip, VRFY_HAS_SUBDBS) && !LF_ISSET(DB_VERIFY_PARTITION))
+		ret = __db_prheader(
+		    dbp, NULL, 0, keyflag, handle, callback, vdp, pgno);
+	if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+/*
+ * __db_salvage_leaf --
+ *	Walk through a leaf, salvaging all likely key/data pairs and marking
+ *	seen pages in vdp.
+ *
+ * PUBLIC: int __db_salvage_leaf __P((DB *, VRFY_DBINFO *, db_pgno_t,
+ * PUBLIC:     PAGE *, void *, int (*)(void *, const void *), u_int32_t));
+ */
+int
+__db_salvage_leaf(dbp, vdp, pgno, h, handle, callback, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	PAGE *h;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	ENV *env;
+
+	env = dbp->env;
+	DB_ASSERT(env, LF_ISSET(DB_SALVAGE));
+
+	/* If we got this page in the subdb pass, we can safely skip it. */
+	if (__db_salvage_isdone(vdp, pgno))
+		return (0);
+
+	switch (TYPE(h)) {
+	case P_HASH_UNSORTED:
+	case P_HASH:
+		return (__ham_salvage(dbp, vdp,
+		    pgno, h, handle, callback, flags));
+	case P_HEAP:
+		return (__heap_salvage(dbp, vdp,
+		    pgno, h, handle, callback, flags));
+	case P_LBTREE:
+	case P_LRECNO:
+		return (__bam_salvage(dbp, vdp,
+		    pgno, TYPE(h), h, handle, callback, NULL, flags));
+	case P_QAMDATA:
+		return (__qam_salvage(dbp, vdp,
+		    pgno, h, handle, callback, flags));
+	default:
+		/*
+		 * There's no need to display an error, the page type was
+		 * already checked and reported on.
+		 */
+		return (0);
+	}
+}
+
+/*
+ * __db_salvage_unknowns --
+ *	Walk through the salvager database, printing with key "UNKNOWN"
+ *	any pages we haven't dealt with.
+ */
+static int
+__db_salvage_unknowns(dbp, vdp, handle, callback, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	DBC *dbc;
+	DBT unkdbt, key, *dbt;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int32_t pgtype, ovfl_bufsz, tmp_flags;
+	int ret, t_ret;
+	void *ovflbuf;
+
+	dbc = NULL;
+	env = dbp->env;
+	mpf = dbp->mpf;
+
+	DB_INIT_DBT(unkdbt, "UNKNOWN", sizeof("UNKNOWN") - 1);
+
+	if ((ret = __os_malloc(env, dbp->pgsize, &ovflbuf)) != 0)
+		return (ret);
+	ovfl_bufsz = dbp->pgsize;
+
+	/*
+	 * We make two passes -- in the first pass, skip SALVAGE_OVERFLOW
+	 * pages, because they may be referenced by the standard database
+	 * pages that we're resolving.
+	 */
+	while ((t_ret =
+	    __db_salvage_getnext(vdp, &dbc, &pgno, &pgtype, 1)) == 0) {
+		if ((t_ret = __memp_fget(mpf,
+		    &pgno, vdp->thread_info, NULL, 0, &h)) != 0) {
+			if (ret == 0)
+				ret = t_ret;
+			continue;
+		}
+
+		dbt = NULL;
+		tmp_flags = 0;
+		switch (pgtype) {
+		case SALVAGE_LDUP:
+		case SALVAGE_LRECNODUP:
+			dbt = &unkdbt;
+			tmp_flags = DB_SA_UNKNOWNKEY;
+			/* FALLTHROUGH */
+		case SALVAGE_IBTREE:
+		case SALVAGE_LBTREE:
+		case SALVAGE_LRECNO:
+			if ((t_ret = __bam_salvage(
+			    dbp, vdp, pgno, pgtype, h, handle,
+			    callback, dbt, tmp_flags | flags)) != 0 && ret == 0)
+				ret = t_ret;
+			break;
+		case SALVAGE_OVERFLOW:
+			DB_ASSERT(env, 0);	/* Shouldn't ever happen. */
+			break;
+		case SALVAGE_HASH:
+			if ((t_ret = __ham_salvage(dbp, vdp,
+			    pgno, h, handle, callback, flags)) != 0 && ret == 0)
+				ret = t_ret;
+			break;
+		case SALVAGE_INVALID:
+		case SALVAGE_IGNORE:
+		default:
+			/*
+			 * Shouldn't happen, but if it does, just do what the
+			 * nice man says.
+			 */
+			DB_ASSERT(env, 0);
+			break;
+		}
+		if ((t_ret = __memp_fput(mpf,
+		    vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+
+	/* We should have reached the end of the database. */
+	if (t_ret == DB_NOTFOUND)
+		t_ret = 0;
+	if (t_ret != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Re-open the cursor so we traverse the database again. */
+	if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+	dbc = NULL;
+
+	/* Now, deal with any remaining overflow pages. */
+	while ((t_ret =
+	    __db_salvage_getnext(vdp, &dbc, &pgno, &pgtype, 0)) == 0) {
+		if ((t_ret = __memp_fget(mpf,
+		    &pgno, vdp->thread_info, NULL, 0, &h)) != 0) {
+			if (ret == 0)
+				ret = t_ret;
+			continue;
+		}
+
+		switch (pgtype) {
+		case SALVAGE_OVERFLOW:
+			/*
+			 * XXX:
+			 * This may generate multiple "UNKNOWN" keys in
+			 * a database with no dups.  What to do?
+			 */
+			if ((t_ret = __db_safe_goff(dbp, vdp,
+			    pgno, &key, &ovflbuf, &ovfl_bufsz, flags)) != 0 ||
+			    ((vdp->type == DB_BTREE || vdp->type == DB_HASH) &&
+			    (t_ret = __db_vrfy_prdbt(&unkdbt,
+			    0, " ", handle, callback, 0, 0, vdp)) != 0) ||
+			    (t_ret = __db_vrfy_prdbt(
+			    &key, 0, " ", handle, callback, 0, 0, vdp)) != 0)
+				if (ret == 0)
+					ret = t_ret;
+			break;
+		default:
+			DB_ASSERT(env, 0);	/* Shouldn't ever happen. */
+			break;
+		}
+		if ((t_ret = __memp_fput(mpf,
+		    vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+
+	/* We should have reached the end of the database. */
+	if (t_ret == DB_NOTFOUND)
+		t_ret = 0;
+	if (t_ret != 0 && ret == 0)
+		ret = t_ret;
+
+	if ((t_ret = __dbc_close(dbc)) != 0 && ret == 0)
+		ret = t_ret;
+
+	__os_free(env, ovflbuf);
+
+	return (ret);
+}
+
+/*
+ * Offset of the ith inp array entry, which we can compare to the offset
+ * the entry stores.
+ */
+#define	INP_OFFSET(dbp, h, i)	\
+    ((db_indx_t)((u_int8_t *)((P_INP(dbp,(h))) + (i)) - (u_int8_t *)(h)))
+
+/*
+ * __db_vrfy_inpitem --
+ *	Verify that a single entry in the inp array is sane, and update
+ *	the high water mark and current item offset.  (The former of these is
+ *	used for state information between calls, and is required;  it must
+ *	be initialized to the pagesize before the first call.)
+ *
+ *	Returns DB_VERIFY_FATAL if inp has collided with the data,
+ *	since verification can't continue from there;  returns DB_VERIFY_BAD
+ *	if anything else is wrong.
+ *
+ * PUBLIC: int __db_vrfy_inpitem __P((DB *, PAGE *,
+ * PUBLIC:     db_pgno_t, u_int32_t, int, u_int32_t, u_int32_t *, u_int32_t *));
+ */
+int
+__db_vrfy_inpitem(dbp, h, pgno, i, is_btree, flags, himarkp, offsetp)
+	DB *dbp;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int32_t i;
+	int is_btree;
+	u_int32_t flags, *himarkp, *offsetp;
+{
+	BKEYDATA *bk;
+	ENV *env;
+	db_indx_t *inp, offset, len;
+
+	env = dbp->env;
+
+	DB_ASSERT(env, himarkp != NULL);
+	inp = P_INP(dbp, h);
+
+	/*
+	 * Check that the inp array, which grows from the beginning of the
+	 * page forward, has not collided with the data, which grow from the
+	 * end of the page backward.
+	 */
+	if (inp + i >= (db_indx_t *)((u_int8_t *)h + *himarkp)) {
+		/* We've collided with the data.  We need to bail. */
+		EPRINT((env, DB_STR_A("0563",
+		    "Page %lu: entries listing %lu overlaps data",
+		    "%lu %lu"), (u_long)pgno, (u_long)i));
+		return (DB_VERIFY_FATAL);
+	}
+
+	offset = inp[i];
+
+	/*
+	 * Check that the item offset is reasonable:  it points somewhere
+	 * after the inp array and before the end of the page.
+	 */
+	if (offset <= INP_OFFSET(dbp, h, i) || offset >= dbp->pgsize) {
+		EPRINT((env, DB_STR_A("0564",
+		    "Page %lu: bad offset %lu at page index %lu",
+		    "%lu %lu %lu"), (u_long)pgno, (u_long)offset, (u_long)i));
+		return (DB_VERIFY_BAD);
+	}
+
+	/* Update the high-water mark (what HOFFSET should be) */
+	if (offset < *himarkp)
+		*himarkp = offset;
+
+	if (is_btree) {
+		/*
+		 * Check alignment;  if it's unaligned, it's unsafe to
+		 * manipulate this item.
+		 */
+		if (offset != DB_ALIGN(offset, sizeof(u_int32_t))) {
+			EPRINT((env, DB_STR_A("0565",
+			    "Page %lu: unaligned offset %lu at page index %lu",
+			    "%lu %lu %lu"), (u_long)pgno, (u_long)offset,
+			    (u_long)i));
+			return (DB_VERIFY_BAD);
+		}
+
+		/*
+		 * Check that the item length remains on-page.
+		 */
+		bk = GET_BKEYDATA(dbp, h, i);
+
+		/*
+		 * We need to verify the type of the item here;
+		 * we can't simply assume that it will be one of the
+		 * expected three.  If it's not a recognizable type,
+		 * it can't be considered to have a verifiable
+		 * length, so it's not possible to certify it as safe.
+		 */
+		switch (B_TYPE(bk->type)) {
+		case B_KEYDATA:
+			len = bk->len;
+			break;
+		case B_DUPLICATE:
+		case B_OVERFLOW:
+			len = BOVERFLOW_SIZE;
+			break;
+		default:
+			EPRINT((env, DB_STR_A("0566",
+			    "Page %lu: item %lu of unrecognizable type",
+			    "%lu %lu"), (u_long)pgno, (u_long)i));
+			return (DB_VERIFY_BAD);
+		}
+
+		if ((size_t)(offset + len) > dbp->pgsize) {
+			EPRINT((env, DB_STR_A("0567",
+			    "Page %lu: item %lu extends past page boundary",
+			    "%lu %lu"), (u_long)pgno, (u_long)i));
+			return (DB_VERIFY_BAD);
+		}
+	}
+
+	if (offsetp != NULL)
+		*offsetp = offset;
+	return (0);
+}
+
+/*
+ * __db_vrfy_duptype--
+ *	Given a page number and a set of flags to __bam_vrfy_subtree,
+ *	verify that the dup tree type is correct--i.e., it's a recno
+ *	if DUPSORT is not set and a btree if it is.
+ *
+ * PUBLIC: int __db_vrfy_duptype
+ * PUBLIC:     __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t));
+ */
+int
+__db_vrfy_duptype(dbp, vdp, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	int ret, isbad;
+
+	env = dbp->env;
+	isbad = 0;
+
+	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)
+		return (ret);
+
+	switch (pip->type) {
+	case P_IBTREE:
+	case P_LDUP:
+		if (!LF_ISSET(DB_ST_DUPSORT)) {
+			EPRINT((env, DB_STR_A("0568",
+	    "Page %lu: sorted duplicate set in unsorted-dup database",
+			    "%lu"), (u_long)pgno));
+			isbad = 1;
+		}
+		break;
+	case P_IRECNO:
+	case P_LRECNO:
+		if (LF_ISSET(DB_ST_DUPSORT)) {
+			EPRINT((env, DB_STR_A("0569",
+	    "Page %lu: unsorted duplicate set in sorted-dup database",
+			    "%lu"), (u_long)pgno));
+			isbad = 1;
+		}
+		break;
+	default:
+		/*
+		 * If the page is entirely zeroed, its pip->type will be a lie
+		 * (we assumed it was a hash page, as they're allowed to be
+		 * zeroed);  handle this case specially.
+		 */
+		if (F_ISSET(pip, VRFY_IS_ALLZEROES))
+			ZEROPG_ERR_PRINT(env, pgno, DB_STR_P("duplicate page"));
+		else
+			EPRINT((env, DB_STR_A("0570",
+		    "Page %lu: duplicate page of inappropriate type %lu",
+			    "%lu %lu"), (u_long)pgno, (u_long)pip->type));
+		isbad = 1;
+		break;
+	}
+
+	if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0)
+		return (ret);
+	return (isbad == 1 ? DB_VERIFY_BAD : 0);
+}
+
+/*
+ * __db_salvage_duptree --
+ *	Attempt to salvage a given duplicate tree, given its alleged root.
+ *
+ *	The key that corresponds to this dup set has been passed to us
+ *	in DBT *key.  Because data items follow keys, though, it has been
+ *	printed once already.
+ *
+ *	The basic idea here is that pgno ought to be a P_LDUP, a P_LRECNO, a
+ *	P_IBTREE, or a P_IRECNO.  If it's an internal page, use the verifier
+ *	functions to make sure it's safe;  if it's not, we simply bail and the
+ *	data will have to be printed with no key later on.  if it is safe,
+ *	recurse on each of its children.
+ *
+ *	Whether or not it's safe, if it's a leaf page, __bam_salvage it.
+ *
+ *	At all times, use the DB hanging off vdp to mark and check what we've
+ *	done, so each page gets printed exactly once and we don't get caught
+ *	in any cycles.
+ *
+ * PUBLIC: int __db_salvage_duptree __P((DB *, VRFY_DBINFO *, db_pgno_t,
+ * PUBLIC:     DBT *, void *, int (*)(void *, const void *), u_int32_t));
+ */
+int
+__db_salvage_duptree(dbp, vdp, pgno, key, handle, callback, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	DBT *key;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	int ret, t_ret;
+
+	mpf = dbp->mpf;
+
+	if (pgno == PGNO_INVALID || !IS_VALID_PGNO(pgno))
+		return (DB_VERIFY_BAD);
+
+	/* We have a plausible page.  Try it. */
+	if ((ret = __memp_fget(mpf, &pgno, vdp->thread_info, NULL, 0, &h)) != 0)
+		return (ret);
+
+	switch (TYPE(h)) {
+	case P_IBTREE:
+	case P_IRECNO:
+		if ((ret = __db_vrfy_common(dbp, vdp, h, pgno, flags)) != 0)
+			goto err;
+		if ((ret = __bam_vrfy(dbp,
+		    vdp, h, pgno, flags | DB_NOORDERCHK)) != 0 ||
+		    (ret = __db_salvage_markdone(vdp, pgno)) != 0)
+			goto err;
+		/*
+		 * We have a known-healthy internal page.  Walk it.
+		 */
+		if ((ret = __bam_salvage_walkdupint(dbp, vdp, h, key,
+		    handle, callback, flags)) != 0)
+			goto err;
+		break;
+	case P_LRECNO:
+	case P_LDUP:
+		if ((ret = __bam_salvage(dbp,
+		    vdp, pgno, TYPE(h), h, handle, callback, key, flags)) != 0)
+			goto err;
+		break;
+	default:
+		ret = DB_VERIFY_BAD;
+		goto err;
+	}
+
+err:	if ((t_ret = __memp_fput(mpf,
+	     vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+/*
+ * __db_salvage_all --
+ *	Salvage only the leaves we find by walking the tree.  If we have subdbs,
+ *	salvage each of them individually.
+ */
+static int
+__db_salvage_all(dbp, vdp, handle, callback, flags, hassubsp)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+	int *hassubsp;
+{
+	DB *pgset;
+	DBC *pgsc;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *h;
+	VRFY_PAGEINFO *pip;
+	db_pgno_t p, meta_pgno;
+	int ret, t_ret;
+
+	*hassubsp = 0;
+
+	env = dbp->env;
+	pgset = NULL;
+	pgsc = NULL;
+	mpf = dbp->mpf;
+	h = NULL;
+	pip = NULL;
+	ret = 0;
+
+	/*
+	 * Check to make sure the page is OK and find out if it contains
+	 * subdatabases.
+	 */
+	meta_pgno = PGNO_BASE_MD;
+	if ((t_ret = __memp_fget(mpf,
+	    &meta_pgno, vdp->thread_info, NULL, 0, &h)) == 0 &&
+	    (t_ret = __db_vrfy_common(dbp, vdp, h, PGNO_BASE_MD, flags)) == 0 &&
+	    (t_ret = __db_salvage_pg(
+		dbp, vdp, PGNO_BASE_MD, h, handle, callback, flags)) == 0 &&
+	    (t_ret = __db_vrfy_getpageinfo(vdp, 0, &pip)) == 0)
+		if (F_ISSET(pip, VRFY_HAS_SUBDBS))
+			*hassubsp = 1;
+	if (pip != NULL &&
+	    (t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0)
+		ret = t_ret;
+	if (h != NULL) {
+		if ((t_ret = __memp_fput(mpf,
+		     vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
+			ret = t_ret;
+		h = NULL;
+	}
+	if (ret != 0)
+		return (ret);
+
+	/* Without subdatabases, we can just dump from the meta pgno. */
+	if (*hassubsp == 0)
+		return (__db_salvage(dbp,
+		    vdp, PGNO_BASE_MD, handle, callback, flags));
+
+	/*
+	 * We have subdbs.  Try to crack them.
+	 *
+	 * To do so, get a set of leaf pages in the master database, and then
+	 * walk each of the valid ones, salvaging subdbs as we go.  If any
+	 * prove invalid, just drop them;  we'll pick them up on a later pass.
+	 */
+	if ((ret = __db_vrfy_pgset(env,
+	    vdp->thread_info, dbp->pgsize, &pgset)) != 0)
+		goto err;
+	if ((ret = __db_meta2pgset(dbp, vdp, PGNO_BASE_MD, flags, pgset)) != 0)
+		goto err;
+	if ((ret = __db_cursor(pgset, vdp->thread_info, NULL, &pgsc, 0)) != 0)
+		goto err;
+	while ((t_ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) {
+		if ((t_ret = __memp_fget(mpf,
+		    &p, vdp->thread_info, NULL, 0, &h)) == 0 &&
+		    (t_ret = __db_vrfy_common(dbp, vdp, h, p, flags)) == 0 &&
+		    (t_ret =
+		    __bam_vrfy(dbp, vdp, h, p, flags | DB_NOORDERCHK)) == 0)
+			t_ret = __db_salvage_subdbpg(
+			    dbp, vdp, h, handle, callback, flags);
+		if (t_ret != 0 && ret == 0)
+			ret = t_ret;
+		if (h != NULL) {
+			if ((t_ret = __memp_fput(mpf, vdp->thread_info,
+			    h, dbp->priority)) != 0 && ret == 0)
+				ret = t_ret;
+			h = NULL;
+		}
+	}
+
+	if (t_ret != DB_NOTFOUND && ret == 0)
+		ret = t_ret;
+
+err:	if (pgsc != NULL && (t_ret = __dbc_close(pgsc)) != 0 && ret == 0)
+		ret = t_ret;
+	if (pgset != NULL &&
+	    (t_ret = __db_close(pgset, NULL, 0)) != 0 && ret ==0)
+		ret = t_ret;
+	if (h != NULL &&
+	    (t_ret = __memp_fput(mpf,
+		vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
+		ret = t_ret;
+	return (ret);
+}
+
+/*
+ * __db_salvage_subdbpg --
+ *	Given a known-good leaf page in the master database, salvage all
+ *	leaf pages corresponding to each subdb.
+ */
+static int
+__db_salvage_subdbpg(dbp, vdp, master, handle, callback, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	PAGE *master;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	BKEYDATA *bkkey, *bkdata;
+	BOVERFLOW *bo;
+	DB *pgset;
+	DBC *pgsc;
+	DBT key;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *subpg;
+	db_indx_t i;
+	db_pgno_t meta_pgno;
+	int ret, err_ret, t_ret;
+	char *subdbname;
+	u_int32_t ovfl_bufsz;
+
+	env = dbp->env;
+	mpf = dbp->mpf;
+	ret = err_ret = 0;
+	subdbname = NULL;
+	pgsc = NULL;
+	pgset = NULL;
+	ovfl_bufsz = 0;
+
+	/*
+	 * For each entry, get and salvage the set of pages
+	 * corresponding to that entry.
+	 */
+	for (i = 0; i < NUM_ENT(master); i += P_INDX) {
+		bkkey = GET_BKEYDATA(dbp, master, i);
+		bkdata = GET_BKEYDATA(dbp, master, i + O_INDX);
+
+		/* Get the subdatabase name. */
+		if (B_TYPE(bkkey->type) == B_OVERFLOW) {
+			/*
+			 * We can, in principle anyway, have a subdb
+			 * name so long it overflows.  Ick.
+			 */
+			bo = (BOVERFLOW *)bkkey;
+			if ((ret = __db_safe_goff(dbp, vdp, bo->pgno,
+			    &key, &subdbname, &ovfl_bufsz, flags)) != 0) {
+				err_ret = DB_VERIFY_BAD;
+				continue;
+			}
+
+			/* Nul-terminate it. */
+			if (ovfl_bufsz < key.size + 1) {
+				if ((ret = __os_realloc(env,
+				    key.size + 1, &subdbname)) != 0)
+					goto err;
+				ovfl_bufsz = key.size + 1;
+			}
+			subdbname[key.size] = '\0';
+		} else if (B_TYPE(bkkey->type) == B_KEYDATA) {
+			if (ovfl_bufsz < (u_int32_t)bkkey->len + 1) {
+				if ((ret = __os_realloc(env,
+				    bkkey->len + 1, &subdbname)) != 0)
+					goto err;
+				ovfl_bufsz = bkkey->len + 1;
+			}
+			DB_ASSERT(env, subdbname != NULL);
+			memcpy(subdbname, bkkey->data, bkkey->len);
+			subdbname[bkkey->len] = '\0';
+		}
+
+		/* Get the corresponding pgno. */
+		if (bkdata->len != sizeof(db_pgno_t)) {
+			err_ret = DB_VERIFY_BAD;
+			continue;
+		}
+		memcpy(&meta_pgno,
+		    (db_pgno_t *)bkdata->data, sizeof(db_pgno_t));
+
+		/*
+		 * Subdatabase meta pgnos are stored in network byte
+		 * order for cross-endian compatibility.  Swap if appropriate.
+		 */
+		DB_NTOHL_SWAP(env, &meta_pgno);
+
+		/* If we can't get the subdb meta page, just skip the subdb. */
+		if (!IS_VALID_PGNO(meta_pgno) || (ret = __memp_fget(mpf,
+		    &meta_pgno, vdp->thread_info, NULL, 0, &subpg)) != 0) {
+			err_ret = ret;
+			continue;
+		}
+
+		/*
+		 * Verify the subdatabase meta page.  This has two functions.
+		 * First, if it's bad, we have no choice but to skip the subdb
+		 * and let the pages just get printed on a later pass.  Second,
+		 * the access-method-specific meta verification routines record
+		 * the various state info (such as the presence of dups)
+		 * that we need for __db_prheader().
+		 */
+		if ((ret =
+		    __db_vrfy_common(dbp, vdp, subpg, meta_pgno, flags)) != 0) {
+			err_ret = ret;
+			(void)__memp_fput(mpf,
+			    vdp->thread_info, subpg, dbp->priority);
+			continue;
+		}
+		switch (TYPE(subpg)) {
+		case P_BTREEMETA:
+			if ((ret = __bam_vrfy_meta(dbp,
+			    vdp, (BTMETA *)subpg, meta_pgno, flags)) != 0) {
+				err_ret = ret;
+				(void)__memp_fput(mpf,
+				    vdp->thread_info, subpg, dbp->priority);
+				continue;
+			}
+			break;
+		case P_HASHMETA:
+			if ((ret = __ham_vrfy_meta(dbp,
+			    vdp, (HMETA *)subpg, meta_pgno, flags)) != 0) {
+				err_ret = ret;
+				(void)__memp_fput(mpf,
+				    vdp->thread_info, subpg, dbp->priority);
+				continue;
+			}
+			break;
+		default:
+			/* This isn't an appropriate page;  skip this subdb. */
+			err_ret = DB_VERIFY_BAD;
+			continue;
+		}
+
+		if ((ret = __memp_fput(mpf,
+		    vdp->thread_info, subpg, dbp->priority)) != 0) {
+			err_ret = ret;
+			continue;
+		}
+
+		/* Print a subdatabase header. */
+		if ((ret = __db_prheader(dbp,
+		    subdbname, 0, 0, handle, callback, vdp, meta_pgno)) != 0)
+			goto err;
+
+		/* Salvage meta_pgno's tree. */
+		if ((ret = __db_salvage(dbp,
+		    vdp, meta_pgno, handle, callback, flags)) != 0)
+			err_ret = ret;
+
+		/* Print a subdatabase footer. */
+		if ((ret = __db_prfooter(handle, callback)) != 0)
+			goto err;
+	}
+
+err:	if (subdbname)
+		__os_free(env, subdbname);
+
+	if (pgsc != NULL && (t_ret = __dbc_close(pgsc)) != 0)
+		ret = t_ret;
+
+	if (pgset != NULL && (t_ret = __db_close(pgset, NULL, 0)) != 0)
+		ret = t_ret;
+
+	if ((t_ret = __db_salvage_markdone(vdp, PGNO(master))) != 0)
+		return (t_ret);
+
+	return ((err_ret != 0) ? err_ret : ret);
+}
+
+/*
+ * __db_salvage --
+ *      Given a meta page number, salvage all data from leaf pages found by
+ *      walking the meta page's tree.
+ */
+static int
+__db_salvage(dbp, vdp, meta_pgno, handle, callback, flags)
+     DB *dbp;
+     VRFY_DBINFO *vdp;
+     db_pgno_t meta_pgno;
+     void *handle;
+     int (*callback) __P((void *, const void *));
+     u_int32_t flags;
+
+{
+	DB *pgset;
+	DBC *dbc, *pgsc;
+	DB_MPOOLFILE *mpf;
+	ENV *env;
+	PAGE *subpg;
+	db_pgno_t p;
+	int err_ret, ret, t_ret;
+
+	env = dbp->env;
+	mpf = dbp->mpf;
+	err_ret = ret = t_ret = 0;
+	pgsc = NULL;
+	pgset = NULL;
+	dbc = NULL;
+
+	if ((ret = __db_vrfy_pgset(env,
+	    vdp->thread_info, dbp->pgsize, &pgset)) != 0)
+		goto err;
+
+	/* Get all page numbers referenced from this meta page. */
+	if ((ret = __db_meta2pgset(dbp, vdp, meta_pgno,
+	    flags, pgset)) != 0) {
+		err_ret = ret;
+		goto err;
+	}
+
+	if ((ret = __db_cursor(pgset,
+	    vdp->thread_info, NULL, &pgsc, 0)) != 0)
+		goto err;
+
+	if (dbp->type == DB_QUEUE &&
+	    (ret = __db_cursor(dbp, vdp->thread_info, NULL, &dbc, 0)) != 0)
+		goto err;
+
+	/* Salvage every page in pgset. */
+	while ((ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) {
+		if (dbp->type == DB_QUEUE) {
+#ifdef HAVE_QUEUE
+			ret = __qam_fget(dbc, &p, 0, &subpg);
+#else
+			ret = __db_no_queue_am(env);
+#endif
+			/* Don't report an error for pages not found in a queue.
+			 * The pgset is a best guess, it doesn't know about
+			 * deleted extents which leads to this error.
+			 */
+			if (ret == ENOENT || ret == DB_PAGE_NOTFOUND)
+				continue;
+		} else
+			ret = __memp_fget(mpf,
+			    &p, vdp->thread_info, NULL, 0, &subpg);
+		if (ret != 0) {
+			err_ret = ret;
+			continue;
+		}
+
+		if ((ret = __db_salvage_pg(dbp, vdp, p, subpg,
+		    handle, callback, flags)) != 0)
+			err_ret = ret;
+
+		if (dbp->type == DB_QUEUE)
+#ifdef HAVE_QUEUE
+			ret = __qam_fput(dbc, p, subpg, dbp->priority);
+#else
+			ret = __db_no_queue_am(env);
+#endif
+		else
+			ret = __memp_fput(mpf,
+			    vdp->thread_info, subpg, dbp->priority);
+		if (ret != 0)
+			err_ret = ret;
+	}
+
+	if (ret == DB_NOTFOUND)
+		ret = 0;
+
+err:
+	if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0)
+		ret = t_ret;
+	if (pgsc != NULL && (t_ret = __dbc_close(pgsc)) != 0)
+		ret = t_ret;
+	if (pgset != NULL && (t_ret = __db_close(pgset, NULL, 0)) != 0)
+		ret = t_ret;
+
+	return ((err_ret != 0) ? err_ret : ret);
+}
+
+/*
+ * __db_meta2pgset --
+ *	Given a known-safe meta page number, return the set of pages
+ *	corresponding to the database it represents.  Return DB_VERIFY_BAD if
+ *	it's not a suitable meta page or is invalid.
+ */
+static int
+__db_meta2pgset(dbp, vdp, pgno, flags, pgset)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	u_int32_t flags;
+	DB *pgset;
+{
+	DB_MPOOLFILE *mpf;
+	PAGE *h;
+	int ret, t_ret;
+
+	mpf = dbp->mpf;
+
+	if ((ret = __memp_fget(mpf, &pgno, vdp->thread_info, NULL, 0, &h)) != 0)
+		return (ret);
+
+	switch (TYPE(h)) {
+	case P_BTREEMETA:
+		ret = __bam_meta2pgset(dbp, vdp, (BTMETA *)h, flags, pgset);
+		break;
+	case P_HASHMETA:
+		ret = __ham_meta2pgset(dbp, vdp, (HMETA *)h, flags, pgset);
+		break;
+	case P_HEAPMETA:
+		ret = __heap_meta2pgset(dbp, vdp, (HEAPMETA *)h, pgset);
+		break;
+	case P_QAMMETA:
+#ifdef HAVE_QUEUE
+		ret = __qam_meta2pgset(dbp, vdp, pgset);
+		break;
+#endif
+	default:
+		ret = DB_VERIFY_BAD;
+		break;
+	}
+
+	if ((t_ret = __memp_fput(mpf, vdp->thread_info, h, dbp->priority)) != 0)
+		return (t_ret);
+	return (ret);
+}
+
+/*
+ * __db_guesspgsize --
+ *	Try to guess what the pagesize is if the one on the meta page
+ *	and the one in the db are invalid.
+ */
+static u_int
+__db_guesspgsize(env, fhp)
+	ENV *env;
+	DB_FH *fhp;
+{
+	db_pgno_t i;
+	size_t nr;
+	u_int32_t guess;
+	u_int8_t type;
+
+	for (guess = DB_MAX_PGSIZE; guess >= DB_MIN_PGSIZE; guess >>= 1) {
+		/*
+		 * We try to read three pages ahead after the first one
+		 * and make sure we have plausible types for all of them.
+		 * If the seeks fail, continue with a smaller size;
+		 * we're probably just looking past the end of the database.
+		 * If they succeed and the types are reasonable, also continue
+		 * with a size smaller;  we may be looking at pages N,
+		 * 2N, and 3N for some N > 1.
+		 *
+		 * As soon as we hit an invalid type, we stop and return
+		 * our previous guess; that last one was probably the page size.
+		 */
+		for (i = 1; i <= 3; i++) {
+			if (__os_seek(
+			    env, fhp, i, guess, SSZ(DBMETA, type)) != 0)
+				break;
+			if (__os_read(env,
+			    fhp, &type, 1, &nr) != 0 || nr == 0)
+				break;
+			if (type == P_INVALID || type >= P_PAGETYPE_MAX)
+				return (guess << 1);
+		}
+	}
+
+	/*
+	 * If we're just totally confused--the corruption takes up most of the
+	 * beginning pages of the database--go with the default size.
+	 */
+	return (DB_DEF_IOSIZE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_vrfy_stub.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,142 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+#ifndef HAVE_VERIFY
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/db_verify.h"
+
+/*
+ * If the library wasn't compiled with the verification support, various
+ * routines aren't available.  Stub them here, returning an appropriate
+ * error.
+ */
+
+static int __db_novrfy __P((ENV *));
+
+/*
+ * __db_novrfy --
+ *	Error when a Berkeley DB build doesn't include the access method.
+ */
+static int
+__db_novrfy(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("0571",
+    "library build did not include support for database verification"));
+	return (DB_OPNOTSUP);
+}
+
+int
+__db_verify_pp(dbp, file, database, outfile, flags)
+	DB *dbp;
+	const char *file, *database;
+	FILE *outfile;
+	u_int32_t flags;
+{
+	int ret;
+
+	COMPQUIET(file, NULL);
+	COMPQUIET(database, NULL);
+	COMPQUIET(outfile, NULL);
+	COMPQUIET(flags, 0);
+
+	ret = __db_novrfy(dbp->env);
+
+	/* The verify method is a destructor. */
+	(void)__db_close(dbp, NULL, 0);
+
+	return (ret);
+}
+
+int
+__db_verify_internal(dbp, name, subdb, handle, callback, flags)
+	DB *dbp;
+	const char *name, *subdb;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	COMPQUIET(dbp, NULL);
+	COMPQUIET(name, NULL);
+	COMPQUIET(subdb, NULL);
+	COMPQUIET(handle, NULL);
+	COMPQUIET(callback, NULL);
+	COMPQUIET(flags, 0);
+	return (0);
+}
+
+int
+__db_vrfy_getpageinfo(vdp, pgno, pipp)
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	VRFY_PAGEINFO **pipp;
+{
+	COMPQUIET(pgno, 0);
+	COMPQUIET(pipp, NULL);
+	return (__db_novrfy(vdp->pgdbp->env));
+}
+
+int
+__db_vrfy_putpageinfo(env, vdp, pip)
+	ENV *env;
+	VRFY_DBINFO *vdp;
+	VRFY_PAGEINFO *pip;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(pip, NULL);
+	return (__db_novrfy(env));
+}
+
+int
+__db_vrfy_prdbt(dbtp, checkprint, prefix,
+    handle, callback, is_recno, is_heap, vdp)
+	DBT *dbtp;
+	int checkprint;
+	const char *prefix;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	int is_recno;
+	int is_heap;
+	VRFY_DBINFO *vdp;
+{
+	COMPQUIET(dbtp, NULL);
+	COMPQUIET(checkprint, 0);
+	COMPQUIET(prefix, NULL);
+	COMPQUIET(handle, NULL);
+	COMPQUIET(callback, NULL);
+	COMPQUIET(is_recno, 0);
+	COMPQUIET(is_heap, 0);
+	return (__db_novrfy(vdp->pgdbp->env));
+}
+#endif /* !HAVE_VERIFY */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/db_vrfyutil.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,958 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2000, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_verify.h"
+#include "dbinc/db_am.h"
+
+static int __db_vrfy_childinc __P((DBC *, VRFY_CHILDINFO *));
+static int __db_vrfy_pageinfo_create __P((ENV *, VRFY_PAGEINFO **));
+
+/*
+ * __db_vrfy_dbinfo_create --
+ *	Allocate and initialize a VRFY_DBINFO structure.
+ *
+ * PUBLIC: int __db_vrfy_dbinfo_create
+ * PUBLIC:     __P((ENV *, DB_THREAD_INFO *, u_int32_t, VRFY_DBINFO **));
+ */
+int
+__db_vrfy_dbinfo_create(env, ip, pgsize, vdpp)
+	ENV *env;
+	DB_THREAD_INFO *ip;
+	u_int32_t pgsize;
+	VRFY_DBINFO **vdpp;
+{
+	DB *cdbp, *pgdbp, *pgset;
+	VRFY_DBINFO *vdp;
+	int ret;
+
+	vdp = NULL;
+	cdbp = pgdbp = pgset = NULL;
+
+	if ((ret = __os_calloc(NULL, 1, sizeof(VRFY_DBINFO), &vdp)) != 0)
+		goto err;
+
+	if ((ret = __db_create_internal(&cdbp, env, 0)) != 0)
+		goto err;
+
+	if ((ret = __db_set_flags(cdbp, DB_DUP)) != 0)
+		goto err;
+
+	if ((ret = __db_set_pagesize(cdbp, pgsize)) != 0)
+		goto err;
+
+	/* If transactional, make sure we don't log. */
+	if (TXN_ON(env) &&
+	    (ret = __db_set_flags(cdbp, DB_TXN_NOT_DURABLE)) != 0)
+		goto err;
+	if ((ret = __db_open(cdbp, ip,
+	    NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) != 0)
+		goto err;
+
+	if ((ret = __db_create_internal(&pgdbp, env, 0)) != 0)
+		goto err;
+
+	if ((ret = __db_set_pagesize(pgdbp, pgsize)) != 0)
+		goto err;
+
+	/* If transactional, make sure we don't log. */
+	if (TXN_ON(env) &&
+	    (ret = __db_set_flags(pgdbp, DB_TXN_NOT_DURABLE)) != 0)
+		goto err;
+
+	if ((ret = __db_open(pgdbp, ip,
+	    NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) != 0)
+		goto err;
+
+	if ((ret = __db_vrfy_pgset(env, ip, pgsize, &pgset)) != 0)
+		goto err;
+
+	if (CDB_LOCKING(env) &&
+	    (ret = __cdsgroup_begin(env, &vdp->txn)) != 0)
+		goto err;
+
+	LIST_INIT(&vdp->subdbs);
+	LIST_INIT(&vdp->activepips);
+
+	vdp->cdbp = cdbp;
+	vdp->pgdbp = pgdbp;
+	vdp->pgset = pgset;
+	vdp->thread_info = ip;
+	*vdpp = vdp;
+	return (0);
+
+err:	if (cdbp != NULL)
+		(void)__db_close(cdbp, NULL, 0);
+	if (pgdbp != NULL)
+		(void)__db_close(pgdbp, NULL, 0);
+#ifdef HAVE_TRANSACTIONS
+	if (vdp->txn != NULL)
+		(void)vdp->txn->commit(vdp->txn, 0);
+#endif
+	if (vdp != NULL)
+		__os_free(env, vdp);
+	return (ret);
+}
+
+/*
+ * __db_vrfy_dbinfo_destroy --
+ *	Destructor for VRFY_DBINFO.  Destroys VRFY_PAGEINFOs and deallocates
+ *	structure.
+ *
+ * PUBLIC: int __db_vrfy_dbinfo_destroy __P((ENV *, VRFY_DBINFO *));
+ */
+int
+__db_vrfy_dbinfo_destroy(env, vdp)
+	ENV *env;
+	VRFY_DBINFO *vdp;
+{
+	VRFY_CHILDINFO *c;
+	int t_ret, ret;
+
+	ret = 0;
+
+	/*
+	 * Discard active page structures.  Ideally there wouldn't be any,
+	 * but in some error cases we may not have cleared them all out.
+	 */
+	while (LIST_FIRST(&vdp->activepips) != NULL)
+		if ((t_ret = __db_vrfy_putpageinfo(
+		    env, vdp, LIST_FIRST(&vdp->activepips))) != 0) {
+			if (ret == 0)
+				ret = t_ret;
+			break;
+		}
+
+	/* Discard subdatabase list structures. */
+	while ((c = LIST_FIRST(&vdp->subdbs)) != NULL) {
+		LIST_REMOVE(c, links);
+		__os_free(NULL, c);
+	}
+
+	if ((t_ret = __db_close(vdp->pgdbp, NULL, 0)) != 0)
+		ret = t_ret;
+
+	if ((t_ret = __db_close(vdp->cdbp, NULL, 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if ((t_ret = __db_close(vdp->pgset, NULL, 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+#ifdef HAVE_TRANSACTIONS
+	if (vdp->txn != NULL &&
+	    (t_ret = vdp->txn->commit(vdp->txn, 0)) != 0 && ret == 0)
+		ret = t_ret;
+#endif
+
+	if (vdp->extents != NULL)
+		__os_free(env, vdp->extents);
+	__os_free(env, vdp);
+	return (ret);
+}
+
+/*
+ * __db_vrfy_getpageinfo --
+ *	Get a PAGEINFO structure for a given page, creating it if necessary.
+ *
+ * PUBLIC: int __db_vrfy_getpageinfo
+ * PUBLIC:     __P((VRFY_DBINFO *, db_pgno_t, VRFY_PAGEINFO **));
+ */
+int
+__db_vrfy_getpageinfo(vdp, pgno, pipp)
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	VRFY_PAGEINFO **pipp;
+{
+	DB *pgdbp;
+	DBT key, data;
+	ENV *env;
+	VRFY_PAGEINFO *pip;
+	int ret;
+
+	/*
+	 * We want a page info struct.  There are three places to get it from,
+	 * in decreasing order of preference:
+	 *
+	 * 1. vdp->activepips.  If it's already "checked out", we're
+	 *	already using it, we return the same exact structure with a
+	 *	bumped refcount.  This is necessary because this code is
+	 *	replacing array accesses, and it's common for f() to make some
+	 *	changes to a pip, and then call g() and h() which each make
+	 *	changes to the same pip.  vdps are never shared between threads
+	 *	(they're never returned to the application), so this is safe.
+	 * 2. The pgdbp.  It's not in memory, but it's in the database, so
+	 *	get it, give it a refcount of 1, and stick it on activepips.
+	 * 3. malloc.  It doesn't exist yet;  create it, then stick it on
+	 *	activepips.  We'll put it in the database when we putpageinfo
+	 *	later.
+	 */
+
+	/* Case 1. */
+	LIST_FOREACH(pip, &vdp->activepips, links)
+		if (pip->pgno == pgno)
+			goto found;
+
+	/* Case 2. */
+	pgdbp = vdp->pgdbp;
+	env = pgdbp->env;
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+	F_SET(&data, DB_DBT_MALLOC);
+	key.data = &pgno;
+	key.size = sizeof(db_pgno_t);
+
+	if ((ret = __db_get(pgdbp,
+	    vdp->thread_info, vdp->txn, &key, &data, 0)) == 0) {
+		/* Found it. */
+		DB_ASSERT(env, data.size == sizeof(VRFY_PAGEINFO));
+		pip = data.data;
+		LIST_INSERT_HEAD(&vdp->activepips, pip, links);
+		goto found;
+	} else if (ret != DB_NOTFOUND)	/* Something nasty happened. */
+		return (ret);
+
+	/* Case 3 */
+	if ((ret = __db_vrfy_pageinfo_create(env, &pip)) != 0)
+		return (ret);
+
+	LIST_INSERT_HEAD(&vdp->activepips, pip, links);
+found:	pip->pi_refcount++;
+
+	*pipp = pip;
+	return (0);
+}
+
+/*
+ * __db_vrfy_putpageinfo --
+ *	Put back a VRFY_PAGEINFO that we're done with.
+ *
+ * PUBLIC: int __db_vrfy_putpageinfo __P((ENV *,
+ * PUBLIC:     VRFY_DBINFO *, VRFY_PAGEINFO *));
+ */
+int
+__db_vrfy_putpageinfo(env, vdp, pip)
+	ENV *env;
+	VRFY_DBINFO *vdp;
+	VRFY_PAGEINFO *pip;
+{
+	DB *pgdbp;
+	DBT key, data;
+	VRFY_PAGEINFO *p;
+	int ret;
+
+	if (--pip->pi_refcount > 0)
+		return (0);
+
+	pgdbp = vdp->pgdbp;
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+
+	key.data = &pip->pgno;
+	key.size = sizeof(db_pgno_t);
+	data.data = pip;
+	data.size = sizeof(VRFY_PAGEINFO);
+
+	if ((ret = __db_put(pgdbp,
+	     vdp->thread_info, vdp->txn, &key, &data, 0)) != 0)
+		return (ret);
+
+	LIST_FOREACH(p, &vdp->activepips, links)
+		if (p == pip)
+			break;
+	if (p != NULL)
+		LIST_REMOVE(p, links);
+
+	__os_ufree(env, p);
+	return (0);
+}
+
+/*
+ * __db_vrfy_pgset --
+ *	Create a temporary database for the storing of sets of page numbers.
+ *	(A mapping from page number to int, used by the *_meta2pgset functions,
+ *	as well as for keeping track of which pages the verifier has seen.)
+ *
+ * PUBLIC: int __db_vrfy_pgset __P((ENV *,
+ * PUBLIC:     DB_THREAD_INFO *, u_int32_t, DB **));
+ */
+int
+__db_vrfy_pgset(env, ip, pgsize, dbpp)
+	ENV *env;
+	DB_THREAD_INFO *ip;
+	u_int32_t pgsize;
+	DB **dbpp;
+{
+	DB *dbp;
+	int ret;
+
+	if ((ret = __db_create_internal(&dbp, env, 0)) != 0)
+		return (ret);
+	if ((ret = __db_set_pagesize(dbp, pgsize)) != 0)
+		goto err;
+
+	/* If transactional, make sure we don't log. */
+	if (TXN_ON(env) &&
+	    (ret = __db_set_flags(dbp, DB_TXN_NOT_DURABLE)) != 0)
+		goto err;
+	if ((ret = __db_open(dbp, ip,
+	    NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) == 0)
+		*dbpp = dbp;
+	else
+err:		(void)__db_close(dbp, NULL, 0);
+
+	return (ret);
+}
+
+/*
+ * __db_vrfy_pgset_get --
+ *	Get the value associated in a page set with a given pgno.  Return
+ *	a 0 value (and succeed) if we've never heard of this page.
+ *
+ * PUBLIC: int __db_vrfy_pgset_get __P((DB *, DB_THREAD_INFO *, DB_TXN *,
+ * PUBLIC:     db_pgno_t, int *));
+ */
+int
+__db_vrfy_pgset_get(dbp, ip, txn, pgno, valp)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	db_pgno_t pgno;
+	int *valp;
+{
+	DBT key, data;
+	int ret, val;
+
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+
+	key.data = &pgno;
+	key.size = sizeof(db_pgno_t);
+	data.data = &val;
+	data.ulen = sizeof(int);
+	F_SET(&data, DB_DBT_USERMEM);
+
+	if ((ret = __db_get(dbp, ip, txn, &key, &data, 0)) == 0) {
+		DB_ASSERT(dbp->env, data.size == sizeof(int));
+	} else if (ret == DB_NOTFOUND)
+		val = 0;
+	else
+		return (ret);
+
+	*valp = val;
+	return (0);
+}
+
+/*
+ * __db_vrfy_pgset_inc --
+ *	Increment the value associated with a pgno by 1.
+ *
+ * PUBLIC: int __db_vrfy_pgset_inc __P((DB *, DB_THREAD_INFO *, DB_TXN *,
+ * PUBLIC:	db_pgno_t));
+ */
+int
+__db_vrfy_pgset_inc(dbp, ip, txn, pgno)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	db_pgno_t pgno;
+{
+	DBT key, data;
+	int ret;
+	int val;
+
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+
+	val = 0;
+
+	key.data = &pgno;
+	key.size = sizeof(db_pgno_t);
+	data.data = &val;
+	data.ulen = sizeof(int);
+	F_SET(&data, DB_DBT_USERMEM);
+
+	if ((ret = __db_get(dbp, ip, txn, &key, &data, 0)) == 0) {
+		DB_ASSERT(dbp->env, data.size == sizeof(int));
+	} else if (ret != DB_NOTFOUND)
+		return (ret);
+
+	data.size = sizeof(int);
+	++val;
+
+	return (__db_put(dbp, ip, txn, &key, &data, 0));
+}
+
+/*
+ * __db_vrfy_pgset_next --
+ *	Given a cursor open in a pgset database, get the next page in the
+ *	set.
+ *
+ * PUBLIC: int __db_vrfy_pgset_next __P((DBC *, db_pgno_t *));
+ */
+int
+__db_vrfy_pgset_next(dbc, pgnop)
+	DBC *dbc;
+	db_pgno_t *pgnop;
+{
+	DBT key, data;
+	db_pgno_t pgno;
+	int ret;
+
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+	/* We don't care about the data, just the keys. */
+	F_SET(&data, DB_DBT_USERMEM | DB_DBT_PARTIAL);
+	F_SET(&key, DB_DBT_USERMEM);
+	key.data = &pgno;
+	key.ulen = sizeof(db_pgno_t);
+
+	if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT)) != 0)
+		return (ret);
+
+	DB_ASSERT(dbc->env, key.size == sizeof(db_pgno_t));
+	*pgnop = pgno;
+
+	return (0);
+}
+
+/*
+ * __db_vrfy_childcursor --
+ *	Create a cursor to walk the child list with.  Returns with a nonzero
+ *	final argument if the specified page has no children.
+ *
+ * PUBLIC: int __db_vrfy_childcursor __P((VRFY_DBINFO *, DBC **));
+ */
+int
+__db_vrfy_childcursor(vdp, dbcp)
+	VRFY_DBINFO *vdp;
+	DBC **dbcp;
+{
+	DB *cdbp;
+	DBC *dbc;
+	int ret;
+
+	cdbp = vdp->cdbp;
+
+	if ((ret = __db_cursor(cdbp, vdp->thread_info, vdp->txn, &dbc, 0)) == 0)
+		*dbcp = dbc;
+
+	return (ret);
+}
+
+/*
+ * __db_vrfy_childput --
+ *	Add a child structure to the set for a given page.
+ *
+ * PUBLIC: int __db_vrfy_childput
+ * PUBLIC:     __P((VRFY_DBINFO *, db_pgno_t, VRFY_CHILDINFO *));
+ */
+int
+__db_vrfy_childput(vdp, pgno, cip)
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	VRFY_CHILDINFO *cip;
+{
+	DB *cdbp;
+	DBC *cc;
+	DBT key, data;
+	VRFY_CHILDINFO *oldcip;
+	int ret;
+
+	cdbp = vdp->cdbp;
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+
+	key.data = &pgno;
+	key.size = sizeof(db_pgno_t);
+
+	/*
+	 * We want to avoid adding multiple entries for a single child page;
+	 * we only need to verify each child once, even if a child (such
+	 * as an overflow key) is multiply referenced.
+	 *
+	 * However, we also need to make sure that when walking the list
+	 * of children, we encounter them in the order they're referenced
+	 * on a page.  (This permits us, for example, to verify the
+	 * prev_pgno/next_pgno chain of Btree leaf pages.)
+	 *
+	 * Check the child database to make sure that this page isn't
+	 * already a child of the specified page number.  If it's not,
+	 * put it at the end of the duplicate set.
+	 */
+	if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0)
+		return (ret);
+	for (ret = __db_vrfy_ccset(cc, pgno, &oldcip); ret == 0;
+	    ret = __db_vrfy_ccnext(cc, &oldcip))
+		if (oldcip->pgno == cip->pgno) {
+			/*
+			 * Found a matching child.  Increment its reference
+			 * count--we've run into it again--but don't put it
+			 * again.
+			 */
+			if ((ret = __db_vrfy_childinc(cc, oldcip)) != 0 ||
+			    (ret = __db_vrfy_ccclose(cc)) != 0)
+				return (ret);
+			return (0);
+		}
+	if (ret != DB_NOTFOUND) {
+		(void)__db_vrfy_ccclose(cc);
+		return (ret);
+	}
+	if ((ret = __db_vrfy_ccclose(cc)) != 0)
+		return (ret);
+
+	cip->refcnt = 1;
+	data.data = cip;
+	data.size = sizeof(VRFY_CHILDINFO);
+
+	return (__db_put(cdbp, vdp->thread_info, vdp->txn, &key, &data, 0));
+}
+
+/*
+ * __db_vrfy_childinc --
+ *	Increment the refcount of the VRFY_CHILDINFO struct that the child
+ * cursor is pointing to.  (The caller has just retrieved this struct, and
+ * passes it in as cip to save us a get.)
+ */
+static int
+__db_vrfy_childinc(dbc, cip)
+	DBC *dbc;
+	VRFY_CHILDINFO *cip;
+{
+	DBT key, data;
+
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+
+	cip->refcnt++;
+	data.data = cip;
+	data.size = sizeof(VRFY_CHILDINFO);
+
+	return (__dbc_put(dbc, &key, &data, DB_CURRENT));
+}
+
+/*
+ * __db_vrfy_ccset --
+ *	Sets a cursor created with __db_vrfy_childcursor to the first
+ *	child of the given pgno, and returns it in the third arg.
+ *
+ * PUBLIC: int __db_vrfy_ccset __P((DBC *, db_pgno_t, VRFY_CHILDINFO **));
+ */
+int
+__db_vrfy_ccset(dbc, pgno, cipp)
+	DBC *dbc;
+	db_pgno_t pgno;
+	VRFY_CHILDINFO **cipp;
+{
+	DBT key, data;
+	int ret;
+
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+
+	key.data = &pgno;
+	key.size = sizeof(db_pgno_t);
+
+	if ((ret = __dbc_get(dbc, &key, &data, DB_SET)) != 0)
+		return (ret);
+
+	DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO));
+	*cipp = (VRFY_CHILDINFO *)data.data;
+
+	return (0);
+}
+
+/*
+ * __db_vrfy_ccnext --
+ *	Gets the next child of the given cursor created with
+ *	__db_vrfy_childcursor, and returns it in the memory provided in the
+ *	second arg.
+ *
+ * PUBLIC: int __db_vrfy_ccnext __P((DBC *, VRFY_CHILDINFO **));
+ */
+int
+__db_vrfy_ccnext(dbc, cipp)
+	DBC *dbc;
+	VRFY_CHILDINFO **cipp;
+{
+	DBT key, data;
+	int ret;
+
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+
+	if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT_DUP)) != 0)
+		return (ret);
+
+	DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO));
+	*cipp = (VRFY_CHILDINFO *)data.data;
+
+	return (0);
+}
+
+/*
+ * __db_vrfy_ccclose --
+ *	Closes the cursor created with __db_vrfy_childcursor.
+ *
+ *	This doesn't actually do anything interesting now, but it's
+ *	not inconceivable that we might change the internal database usage
+ *	and keep the interfaces the same, and a function call here or there
+ *	seldom hurts anyone.
+ *
+ * PUBLIC: int __db_vrfy_ccclose __P((DBC *));
+ */
+int
+__db_vrfy_ccclose(dbc)
+	DBC *dbc;
+{
+
+	return (__dbc_close(dbc));
+}
+
+/*
+ * __db_vrfy_pageinfo_create --
+ *	Constructor for VRFY_PAGEINFO;  allocates and initializes.
+ */
+static int
+__db_vrfy_pageinfo_create(env, pipp)
+	ENV *env;
+	VRFY_PAGEINFO **pipp;
+{
+	VRFY_PAGEINFO *pip;
+	int ret;
+
+	/*
+	 * pageinfo structs are sometimes allocated here and sometimes
+	 * allocated by fetching them from a database with DB_DBT_MALLOC.
+	 * There's no easy way for the destructor to tell which was
+	 * used, and so we always allocate with __os_umalloc so we can free
+	 * with __os_ufree.
+	 */
+	if ((ret = __os_umalloc(env, sizeof(VRFY_PAGEINFO), &pip)) != 0)
+		return (ret);
+	memset(pip, 0, sizeof(VRFY_PAGEINFO));
+
+	*pipp = pip;
+	return (0);
+}
+
+/*
+ * __db_salvage_init --
+ *	Set up salvager database.
+ *
+ * PUBLIC: int  __db_salvage_init __P((VRFY_DBINFO *));
+ */
+int
+__db_salvage_init(vdp)
+	VRFY_DBINFO *vdp;
+{
+	DB *dbp;
+	int ret;
+
+	if ((ret = __db_create_internal(&dbp, NULL, 0)) != 0)
+		return (ret);
+
+	if ((ret = __db_set_pagesize(dbp, 1024)) != 0)
+		goto err;
+
+	if ((ret = __db_open(dbp, vdp->thread_info,
+	    NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0, PGNO_BASE_MD)) != 0)
+		goto err;
+
+	vdp->salvage_pages = dbp;
+	return (0);
+
+err:	(void)__db_close(dbp, NULL, 0);
+	return (ret);
+}
+
+/*
+ * __db_salvage_destroy --
+ *	Close salvager database.
+ * PUBLIC: int  __db_salvage_destroy __P((VRFY_DBINFO *));
+ */
+int
+__db_salvage_destroy(vdp)
+	VRFY_DBINFO *vdp;
+{
+	return (vdp->salvage_pages == NULL ? 0 :
+	    __db_close(vdp->salvage_pages, NULL, 0));
+}
+
+/*
+ * __db_salvage_getnext --
+ *	Get the next (first) unprinted page in the database of pages we need to
+ *	print still.  Delete entries for any already-printed pages we encounter
+ *	in this search, as well as the page we're returning.
+ *
+ * PUBLIC: int __db_salvage_getnext
+ * PUBLIC:     __P((VRFY_DBINFO *, DBC **, db_pgno_t *, u_int32_t *, int));
+ */
+int
+__db_salvage_getnext(vdp, dbcp, pgnop, pgtypep, skip_overflow)
+	VRFY_DBINFO *vdp;
+	DBC **dbcp;
+	db_pgno_t *pgnop;
+	u_int32_t *pgtypep;
+	int skip_overflow;
+{
+	DB *dbp;
+	DBT key, data;
+	int ret;
+	u_int32_t pgtype;
+
+	dbp = vdp->salvage_pages;
+
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+
+	if (*dbcp == NULL &&
+	    (ret = __db_cursor(dbp, vdp->thread_info, vdp->txn, dbcp, 0)) != 0)
+		return (ret);
+
+	while ((ret = __dbc_get(*dbcp, &key, &data, DB_NEXT)) == 0) {
+		DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t));
+		memcpy(&pgtype, data.data, sizeof(pgtype));
+
+		if (skip_overflow && pgtype == SALVAGE_OVERFLOW)
+			continue;
+
+		if ((ret = __dbc_del(*dbcp, 0)) != 0)
+			return (ret);
+		if (pgtype != SALVAGE_IGNORE) {
+			DB_ASSERT(dbp->env, key.size == sizeof(db_pgno_t));
+			DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t));
+
+			*pgnop = *(db_pgno_t *)key.data;
+			*pgtypep = *(u_int32_t *)data.data;
+			break;
+		}
+	}
+
+	return (ret);
+}
+
+/*
+ * __db_salvage_isdone --
+ *	Return whether or not the given pgno is already marked
+ *	SALVAGE_IGNORE (meaning that we don't need to print it again).
+ *
+ *	Returns DB_KEYEXIST if it is marked, 0 if not, or another error on
+ *	error.
+ *
+ * PUBLIC: int __db_salvage_isdone __P((VRFY_DBINFO *, db_pgno_t));
+ */
+int
+__db_salvage_isdone(vdp, pgno)
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+{
+	DB *dbp;
+	DBT key, data;
+	int ret;
+	u_int32_t currtype;
+
+	dbp = vdp->salvage_pages;
+
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+
+	currtype = SALVAGE_INVALID;
+	data.data = &currtype;
+	data.ulen = sizeof(u_int32_t);
+	data.flags = DB_DBT_USERMEM;
+
+	key.data = &pgno;
+	key.size = sizeof(db_pgno_t);
+
+	/*
+	 * Put an entry for this page, with pgno as key and type as data,
+	 * unless it's already there and is marked done.
+	 * If it's there and is marked anything else, that's fine--we
+	 * want to mark it done.
+	 */
+	if ((ret = __db_get(dbp,
+	    vdp->thread_info, vdp->txn, &key, &data, 0)) == 0) {
+		/*
+		 * The key's already here.  Check and see if it's already
+		 * marked done.  If it is, return DB_KEYEXIST.  If it's not,
+		 * return 0.
+		 */
+		if (currtype == SALVAGE_IGNORE)
+			return (DB_KEYEXIST);
+		else
+			return (0);
+	} else if (ret != DB_NOTFOUND)
+		return (ret);
+
+	/* The pgno is not yet marked anything; return 0. */
+	return (0);
+}
+
+/*
+ * __db_salvage_markdone --
+ *	Mark as done a given page.
+ *
+ * PUBLIC: int __db_salvage_markdone __P((VRFY_DBINFO *, db_pgno_t));
+ */
+int
+__db_salvage_markdone(vdp, pgno)
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+{
+	DB *dbp;
+	DBT key, data;
+	int pgtype, ret;
+	u_int32_t currtype;
+
+	pgtype = SALVAGE_IGNORE;
+	dbp = vdp->salvage_pages;
+
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+
+	currtype = SALVAGE_INVALID;
+	data.data = &currtype;
+	data.ulen = sizeof(u_int32_t);
+	data.flags = DB_DBT_USERMEM;
+
+	key.data = &pgno;
+	key.size = sizeof(db_pgno_t);
+
+	/*
+	 * Put an entry for this page, with pgno as key and type as data,
+	 * unless it's already there and is marked done.
+	 * If it's there and is marked anything else, that's fine--we
+	 * want to mark it done, but db_salvage_isdone only lets
+	 * us know if it's marked IGNORE.
+	 *
+	 * We don't want to return DB_KEYEXIST, though;  this will
+	 * likely get passed up all the way and make no sense to the
+	 * application.  Instead, use DB_VERIFY_BAD to indicate that
+	 * we've seen this page already--it probably indicates a
+	 * multiply-linked page.
+	 */
+	if ((ret = __db_salvage_isdone(vdp, pgno)) != 0)
+		return (ret == DB_KEYEXIST ? DB_VERIFY_BAD : ret);
+
+	data.size = sizeof(u_int32_t);
+	data.data = &pgtype;
+
+	return (__db_put(dbp, vdp->thread_info, vdp->txn, &key, &data, 0));
+}
+
+/*
+ * __db_salvage_markneeded --
+ *	If it has not yet been printed, make note of the fact that a page
+ *	must be dealt with later.
+ *
+ * PUBLIC: int __db_salvage_markneeded
+ * PUBLIC:     __P((VRFY_DBINFO *, db_pgno_t, u_int32_t));
+ */
+int
+__db_salvage_markneeded(vdp, pgno, pgtype)
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	u_int32_t pgtype;
+{
+	DB *dbp;
+	DBT key, data;
+	int ret;
+
+	dbp = vdp->salvage_pages;
+
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+
+	key.data = &pgno;
+	key.size = sizeof(db_pgno_t);
+
+	data.data = &pgtype;
+	data.size = sizeof(u_int32_t);
+
+	/*
+	 * Put an entry for this page, with pgno as key and type as data,
+	 * unless it's already there, in which case it's presumably
+	 * already been marked done.
+	 */
+	ret = __db_put(dbp,
+	     vdp->thread_info, vdp->txn, &key, &data, DB_NOOVERWRITE);
+	return (ret == DB_KEYEXIST ? 0 : ret);
+}
+
+/*
+ * __db_vrfy_prdbt --
+ *	Print out a DBT data element from a verification routine.
+ *
+ * PUBLIC: int __db_vrfy_prdbt __P((DBT *, int, const char *, void *,
+ * PUBLIC:     int (*)(void *, const void *), int, int, VRFY_DBINFO *));
+ */
+int
+__db_vrfy_prdbt(dbtp, checkprint, prefix,
+    handle, callback, is_recno, is_heap, vdp)
+	DBT *dbtp;
+	int checkprint;
+	const char *prefix;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	int is_recno;
+	int is_heap;
+	VRFY_DBINFO *vdp;
+{
+	if (vdp != NULL) {
+		/*
+		 * If vdp is non-NULL, we might be the first key in the
+		 * "fake" subdatabase used for key/data pairs we can't
+		 * associate with a known subdb.
+		 *
+		 * Check and clear the SALVAGE_PRINTHEADER flag;  if
+		 * it was set, print a subdatabase header.
+		 */
+		if (F_ISSET(vdp, SALVAGE_PRINTHEADER)) {
+			(void)__db_prheader(
+			    NULL, "__OTHER__", 0, 0, handle, callback, vdp, 0);
+			F_CLR(vdp, SALVAGE_PRINTHEADER);
+			F_SET(vdp, SALVAGE_PRINTFOOTER);
+		}
+
+		/*
+		 * Even if the printable flag wasn't set by our immediate
+		 * caller, it may be set on a salvage-wide basis.
+		 */
+		if (F_ISSET(vdp, SALVAGE_PRINTABLE))
+			checkprint = 1;
+	}
+	return (
+	    __db_prdbt(dbtp, checkprint,
+	    prefix, handle, callback, is_recno, is_heap));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/db/partition_stub.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,153 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2011 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * If the library wasn't compiled with partitions support, various routines
+ * aren't available.  Stub them here, returning an appropriate error.
+ */
+
+/*
+ * __db_no_partition --
+ *	Error when a Berkeley DB build doesn't include partitioning.
+ *
+ * PUBLIC: int __db_no_partition __P((ENV *));
+ */
+int
+__db_no_partition(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("0664",
+    "library build did not include support for the database partitioning"));
+	return (DB_OPNOTSUP);
+}
+
+/*
+ * __partition_get_dirs --
+ */
+int
+__partition_get_dirs(dbp, dirpp)
+	DB *dbp;
+	const char ***dirpp;
+{
+	COMPQUIET(dirpp, NULL);
+	return (__db_no_partition(dbp->env));
+}
+
+/*
+ * __partition_get_callback --
+ */
+int
+__partition_get_callback(dbp, parts, callback)
+	DB *dbp;
+	u_int32_t *parts;
+	u_int32_t (**callback)(DB *, DBT *key);
+{
+	COMPQUIET(parts, NULL);
+	COMPQUIET(callback, NULL);
+	return (__db_no_partition(dbp->env));
+}
+
+/*
+ * __partition_get_keys --
+ */
+int
+__partition_get_keys(dbp, parts, keys)
+	DB *dbp;
+	u_int32_t *parts;
+	DBT **keys;
+{
+	COMPQUIET(parts, NULL);
+	COMPQUIET(keys, NULL);
+	return (__db_no_partition(dbp->env));
+}
+
+/*
+ * __partition_init --
+ */
+int
+__partition_init(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_no_partition(dbp->env));
+}
+
+/*
+ * __partition_set --
+ */
+
+int
+__partition_set(dbp, parts, keys, callback)
+	DB *dbp;
+	u_int32_t parts;
+	DBT *keys;
+	u_int32_t (*callback)(DB *, DBT *key);
+{
+	COMPQUIET(parts, 0);
+	COMPQUIET(keys, NULL);
+	COMPQUIET(callback, NULL);
+	return (__db_no_partition(dbp->env));
+}
+
+/*
+ * __partition_set_dirs --
+ */
+int
+__partition_set_dirs(dbp, dirp)
+	DB *dbp;
+	const char **dirp;
+{
+	COMPQUIET(dirp, NULL);
+	return (__db_no_partition(dbp->env));
+}
+
+/*
+ * __part_fileid_reset --
+ */
+int
+__part_fileid_reset(env, ip, fname, nparts, encrypted)
+	ENV *env;
+	DB_THREAD_INFO *ip;
+	const char *fname;
+	u_int32_t nparts;
+	int encrypted;
+{
+	COMPQUIET(ip, NULL);
+	COMPQUIET(fname, NULL);
+	COMPQUIET(nparts, 0);
+	COMPQUIET(encrypted, 0);
+	return (__db_no_partition(env));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/atomic.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,242 @@
+/*
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2009, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_ATOMIC_H_
+#define	_DB_ATOMIC_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ *	Atomic operation support for Oracle Berkeley DB
+ *
+ * HAVE_ATOMIC_SUPPORT configures whether to use the assembly language
+ * or system calls to perform:
+ *
+ *	 atomic_inc(env, valueptr)
+ *	    Adds 1 to the db_atomic_t value, returning the new value.
+ *
+ *	 atomic_dec(env, valueptr)
+ *	    Subtracts 1 from the db_atomic_t value, returning the new value.
+ *
+ *	 atomic_compare_exchange(env, valueptr, oldval, newval)
+ *	    If the db_atomic_t's value is still oldval, set it to newval.
+ *	    It returns 1 for success or 0 for failure.
+ *
+ * The ENV * parameter is used only when HAVE_ATOMIC_SUPPORT is undefined.
+ *
+ * If the platform does not natively support any one of these operations,
+ * then atomic operations will be emulated with this sequence:
+ *		MUTEX_LOCK()
+ *		<op>
+ *		MUTEX_UNLOCK();
+ * Uses where mutexes are not available (e.g. the environment has not yet
+ * attached to the mutex region) must be avoided.
+ */
+#if defined(DB_WIN32)
+typedef DWORD	atomic_value_t;
+#else
+typedef int32_t	 atomic_value_t;
+#endif
+
+/*
+ * Windows CE has strange issues using the Interlocked APIs with variables
+ * stored in shared memory. It seems like the page needs to have been written
+ * prior to the API working as expected. Work around this by allocating an
+ * additional 32-bit value that can be harmlessly written for each value
+ * used in Interlocked instructions.
+ */
+#if defined(DB_WINCE)
+typedef struct {
+	volatile atomic_value_t value;
+	volatile atomic_value_t dummy;
+} db_atomic_t;
+#else
+typedef struct {
+	volatile atomic_value_t value;
+} db_atomic_t;
+#endif
+
+/*
+ * These macro hide the db_atomic_t structure layout and help detect
+ * non-atomic_t actual argument to the atomic_xxx() calls. DB requires
+ * aligned 32-bit reads to be atomic even outside of explicit 'atomic' calls.
+ * These have no memory barriers; the caller must include them when necessary.
+ */
+#define	atomic_read(p)		((p)->value)
+#define	atomic_init(p, val)	((p)->value = (val))
+
+#ifdef HAVE_ATOMIC_SUPPORT
+
+#if defined(DB_WIN32)
+#if defined(DB_WINCE)
+#define	WINCE_ATOMIC_MAGIC(p)						\
+	/*								\
+	 * Memory mapped regions on Windows CE cause problems with	\
+	 * InterlockedXXX calls. Each page in a mapped region needs to	\
+	 * have been written to prior to an InterlockedXXX call, or the	\
+	 * InterlockedXXX call hangs. This does not seem to be		\
+	 * documented anywhere. For now, read/write a non-critical	\
+	 * piece of memory from the shared region prior to attempting	\
+	 * shared region prior to attempting an InterlockedExchange	\
+	 * InterlockedXXX operation.					\
+	 */								\
+	(p)->dummy = 0
+#else
+#define	WINCE_ATOMIC_MAGIC(p) 0
+#endif
+
+#if defined(DB_WINCE) || (defined(_MSC_VER) && _MSC_VER < 1300)
+/*
+ * The Interlocked instructions on Windows CE have different parameter
+ * definitions. The parameters lost their 'volatile' qualifier,
+ * cast it away, to avoid compiler warnings.
+ * These definitions should match those in dbinc/mutex_int.h for tsl_t, except
+ * that the WINCE version drops the volatile qualifier.
+ */
+typedef PLONG interlocked_val;
+#define	atomic_inc(env, p)						\
+	(WINCE_ATOMIC_MAGIC(p),						\
+	InterlockedIncrement((interlocked_val)(&(p)->value)))
+
+#else
+typedef LONG volatile *interlocked_val;
+#define	atomic_inc(env, p)	\
+	InterlockedIncrement((interlocked_val)(&(p)->value))
+#endif
+
+#define	atomic_dec(env, p)						\
+	(WINCE_ATOMIC_MAGIC(p),						\
+	InterlockedDecrement((interlocked_val)(&(p)->value)))
+#if defined(_MSC_VER) && _MSC_VER < 1300
+#define	atomic_compare_exchange(env, p, oldval, newval)			\
+	(WINCE_ATOMIC_MAGIC(p),						\
+	(InterlockedCompareExchange((PVOID *)(&(p)->value),		\
+	(PVOID)(newval), (PVOID)(oldval)) == (PVOID)(oldval)))
+#else
+#define	atomic_compare_exchange(env, p, oldval, newval)			\
+	(WINCE_ATOMIC_MAGIC(p),						\
+	(InterlockedCompareExchange((interlocked_val)(&(p)->value),	\
+	(newval), (oldval)) == (oldval)))
+#endif
+#endif
+
+#if defined(HAVE_ATOMIC_SOLARIS)
+/* Solaris sparc & x86/64 */
+#include <atomic.h>
+#define	atomic_inc(env, p)	\
+	atomic_inc_uint_nv((volatile unsigned int *) &(p)->value)
+#define	atomic_dec(env, p)	\
+	atomic_dec_uint_nv((volatile unsigned int *) &(p)->value)
+#define	atomic_compare_exchange(env, p, oval, nval)		\
+	(atomic_cas_32((volatile unsigned int *) &(p)->value,	\
+	    (oval), (nval)) == (oval))
+#endif
+
+#if defined(HAVE_ATOMIC_X86_GCC_ASSEMBLY)
+/* x86/x86_64 gcc  */
+#define	atomic_inc(env, p)	__atomic_inc(p)
+#define	atomic_dec(env, p)	__atomic_dec(p)
+#define	atomic_compare_exchange(env, p, o, n)	\
+	__atomic_compare_exchange((p), (o), (n))
+static inline int __atomic_inc(db_atomic_t *p)
+{
+	int	temp;
+
+	temp = 1;
+	__asm__ __volatile__("lock; xadd %0, (%1)"
+		: "+r"(temp)
+		: "r"(p));
+	return (temp + 1);
+}
+
+static inline int __atomic_dec(db_atomic_t *p)
+{
+	int	temp;
+
+	temp = -1;
+	__asm__ __volatile__("lock; xadd %0, (%1)"
+		: "+r"(temp)
+		: "r"(p));
+	return (temp - 1);
+}
+
+/*
+ * x86/gcc Compare exchange for shared latches. i486+
+ *	Returns 1 for success, 0 for failure
+ *
+ * GCC 4.1+ has an equivalent  __sync_bool_compare_and_swap() as well as
+ * __sync_val_compare_and_swap() which returns the value read from *dest
+ * http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
+ * which configure could be changed to use.
+ */
+static inline int __atomic_compare_exchange(
+	db_atomic_t *p, atomic_value_t oldval, atomic_value_t newval)
+{
+	atomic_value_t was;
+
+	if (p->value != oldval)	/* check without expensive cache line locking */
+		return 0;
+	__asm__ __volatile__("lock; cmpxchgl %1, (%2);"
+	    :"=a"(was)
+	    :"r"(newval), "r"(p), "a"(oldval)
+	    :"memory", "cc");
+	return (was == oldval);
+}
+#endif
+
+#else
+/*
+ * No native hardware support for atomic increment, decrement, and
+ * compare-exchange. Emulate them when mutexes are supported;
+ * do them without concern for atomicity when no mutexes.
+ */
+#ifndef HAVE_MUTEX_SUPPORT
+/*
+ * These minimal versions are correct to use only for single-threaded,
+ * single-process environments.
+ */
+#define	atomic_inc(env, p)	(++(p)->value)
+#define	atomic_dec(env, p)	(--(p)->value)
+#define	atomic_compare_exchange(env, p, oldval, newval)		\
+	(DB_ASSERT(env, atomic_read(p) == (oldval)),		\
+	atomic_init(p, (newval)), 1)
+#else
+#define atomic_inc(env, p)	__atomic_inc(env, p)
+#define atomic_dec(env, p)	__atomic_dec(env, p)
+#endif
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_DB_ATOMIC_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/btree.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,575 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ *	Keith Bostic.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Olson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+#ifndef	_DB_BTREE_H_
+#define	_DB_BTREE_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Forward structure declarations. */
+struct __btree;		typedef struct __btree BTREE;
+struct __cursor;	typedef struct __cursor BTREE_CURSOR;
+struct __epg;		typedef struct __epg EPG;
+
+#define	DEFMINKEYPAGE	 (2)
+
+/*
+ * A recno order of 0 indicates that we don't have an order, not that we've
+ * an order less than 1.
+ */
+#define	INVALID_ORDER	0
+
+#define	ISINTERNAL(p)	(TYPE(p) == P_IBTREE || TYPE(p) == P_IRECNO)
+#define	ISLEAF(p)	(TYPE(p) == P_LBTREE ||				\
+			    TYPE(p) == P_LRECNO || TYPE(p) == P_LDUP)
+
+/* Flags for __bam_cadjust_log(). */
+#define	CAD_UPDATEROOT	0x01		/* Root page count was updated. */
+
+/* Flags for __bam_split_log(). */
+#define	SPL_NRECS	0x01		/* Split tree has record count. */
+#define	SPL_RECNO	0x02		/* This is a Recno cursor. */
+
+/* Flags for __bam_iitem(). */
+#define	BI_DELETED	0x01		/* Key/data pair only placeholder. */
+
+/* Flags for __bam_stkrel(). */
+#define	STK_CLRDBC	0x01		/* Clear dbc->page reference. */
+#define	STK_NOLOCK	0x02		/* Don't retain locks. */
+#define	STK_PGONLY	0x04
+
+/* Flags for __ram_ca(). These get logged, so make the values explicit. */
+typedef enum {
+	CA_DELETE = 0,			/* Delete the current record. */
+	CA_IAFTER = 1,			/* Insert before the current record. */
+	CA_IBEFORE = 2,			/* Insert after the current record. */
+	CA_ICURRENT = 3			/* Overwrite the current record. */
+} ca_recno_arg;
+
+/*
+ * Flags for __bam_search() and __bam_rsearch().
+ *
+ * Note, internal page searches must find the largest record less than key in
+ * the tree so that descents work.  Leaf page searches must find the smallest
+ * record greater than key so that the returned index is the record's correct
+ * position for insertion.
+ *
+ * The flags parameter to the search routines describes three aspects of the
+ * search: the type of locking required (including if we're locking a pair of
+ * pages), the item to return in the presence of duplicates and whether or not
+ * to return deleted entries.  To simplify both the mnemonic representation
+ * and the code that checks for various cases, we construct a set of bitmasks.
+ */
+#define	SR_READ		0x00001		/* Read locks. */
+#define	SR_WRITE	0x00002		/* Write locks. */
+
+#define	SR_APPEND	0x00040		/* Append to the tree. */
+#define	SR_DELNO	0x00080		/* Don't return deleted items. */
+#define	SR_DUPFIRST	0x00100		/* Return first duplicate. */
+#define	SR_DUPLAST	0x00200		/* Return last duplicate. */
+#define	SR_EXACT	0x00400		/* Exact items only. */
+#define	SR_PARENT	0x00800		/* Lock page pair. */
+#define	SR_STACK	0x01000		/* Need a complete stack. */
+#define	SR_PAST_EOF	0x02000		/* If doing insert search (or keyfirst
+					 * or keylast operations), or a split
+					 * on behalf of an insert, it's okay to
+					 * return an entry one past end-of-page.
+					 */
+#define	SR_STK_ONLY	0x04000		/* Just return info in the stack */
+#define	SR_MAX		0x08000		/* Get the right most key */
+#define	SR_MIN		0x10000		/* Get the left most key */
+#define	SR_NEXT		0x20000		/* Get the page after this key */
+#define	SR_DEL		0x40000		/* Get the tree to delete this key. */
+#define	SR_START	0x80000		/* Level to start stack. */
+#define	SR_BOTH		0x100000	/* Get this and the NEXT page */
+
+#define	SR_DELETE							\
+	(SR_WRITE | SR_DUPFIRST | SR_DELNO | SR_EXACT | SR_STACK)
+#define	SR_FIND		(SR_READ | SR_DUPFIRST | SR_DELNO)
+#define	SR_FIND_WR	(SR_WRITE | SR_DUPFIRST | SR_DELNO)
+#define	SR_INSERT	(SR_WRITE | SR_DUPLAST | SR_PAST_EOF | SR_STACK)
+#define	SR_KEYFIRST	(SR_WRITE | SR_DUPFIRST | SR_PAST_EOF | SR_STACK)
+#define	SR_KEYLAST	(SR_WRITE | SR_DUPLAST | SR_PAST_EOF | SR_STACK)
+#define	SR_WRPAIR	(SR_WRITE | SR_DUPLAST | SR_PAST_EOF | SR_PARENT)
+
+/*
+ * Various routines pass around page references.  A page reference is
+ * a pointer to the page, and the indx indicates an item on the page.
+ * Each page reference may include a lock.
+ */
+struct __epg {
+	PAGE	     *page;		/* The page. */
+	db_indx_t     indx;		/* The index on the page. */
+	db_indx_t     entries;		/* The number of entries on page */
+	DB_LOCK	      lock;		/* The page's lock. */
+	db_lockmode_t lock_mode;	/* The lock mode. */
+};
+
+/*
+ * We maintain a stack of the pages that we're locking in the tree.  Grow
+ * the stack as necessary.
+ *
+ * XXX
+ * Temporary fix for #3243 -- clear the page and lock from the stack entry.
+ * The correct fix is to never release a stack that doesn't hold items.
+ */
+#define	BT_STK_CLR(c) do {						\
+	(c)->csp = (c)->sp;						\
+	(c)->csp->page = NULL;						\
+	LOCK_INIT((c)->csp->lock);					\
+} while (0)
+
+#define	BT_STK_ENTER(env, c, pagep, page_indx, l, mode, ret) do {	\
+	if ((ret = ((c)->csp == (c)->esp ?				\
+	    __bam_stkgrow(env, c) : 0)) == 0) {				\
+		(c)->csp->page = pagep;					\
+		(c)->csp->indx = (page_indx);				\
+		(c)->csp->entries = NUM_ENT(pagep);			\
+		(c)->csp->lock = l;					\
+		(c)->csp->lock_mode = mode;				\
+	}								\
+} while (0)
+
+#define	BT_STK_PUSH(env, c, pagep, page_indx, lock, mode, ret) do {	\
+	BT_STK_ENTER(env, c, pagep, page_indx, lock, mode, ret);	\
+	++(c)->csp;							\
+} while (0)
+
+#define	BT_STK_NUM(env, c, pagep, page_indx, ret) do {		\
+	if ((ret = ((c)->csp ==						\
+	    (c)->esp ? __bam_stkgrow(env, c) : 0)) == 0) {		\
+		(c)->csp->page = NULL;					\
+		(c)->csp->indx = (page_indx);				\
+		(c)->csp->entries = NUM_ENT(pagep);			\
+		LOCK_INIT((c)->csp->lock);				\
+		(c)->csp->lock_mode = DB_LOCK_NG;			\
+	}								\
+} while (0)
+
+#define	BT_STK_NUMPUSH(env, c, pagep, page_indx, ret) do {		\
+	BT_STK_NUM(env, cp, pagep, page_indx, ret);			\
+	++(c)->csp;							\
+} while (0)
+
+#define	BT_STK_POP(c)							\
+	((c)->csp == (c)->sp ? NULL : --(c)->csp)
+
+/*
+ * Flags for __bam_dpages.
+ */
+#define	BTD_UPDATE	0x0001		/* Update parents. */
+#define	BTD_RELINK	0x0002		/* Relink leaf pages. */
+
+/*
+ * TRY_LOCK
+ *	When holding a stack we have pages latched but not locked so
+ * we must avoid an undetectable deadlock by not then blocking on a
+ * lock.
+ */
+#define	TRY_LOCK(dbc, pgno, saved_pgno, saved_lock, lock_mode, label) \
+	TRY_LOCK2(dbc, NULL, pgno, saved_pgno, saved_lock, lock_mode, label)
+/*
+ * TRY_LOCK2
+ *	This is a special call for __bam_compact_int which uses 2
+ * overlapping stacks.
+ */
+
+#ifdef BTREE_DEBUG
+#define	TRY_LOCK2(dbc, ndbc, pgno,					\
+    saved_pgno, saved_lock, lock_mode, label) do {			\
+	static int BTcount = 0;						\
+	if ((pgno) != (saved_pgno) &&					\
+	    ((BTcount++ % 5) == 0 ||					\
+	    (ret = __db_lget(dbc, LCK_COUPLE_ALWAYS, pgno,		\
+	    lock_mode, DB_LOCK_NOWAIT, &(saved_lock))) != 0)) {		\
+		if (ret != 0 && ret != DB_LOCK_NOTGRANTED &&		\
+		     ret != DB_LOCK_DEADLOCK)				\
+			break;						\
+		if ((ndbc) != NULL) {					\
+			BTREE_CURSOR *__cp;				\
+			__cp = (BTREE_CURSOR *) (dbc)->internal;	\
+			__cp->sp->page = NULL;				\
+			LOCK_INIT(__cp->sp->lock);			\
+			if ((ret = __bam_stkrel(ndbc, 0)) != 0)		\
+				break;					\
+		}							\
+		if ((ret = __bam_stkrel(dbc, 0)) != 0)			\
+			break;						\
+		if ((ret = __db_lget(dbc, LCK_COUPLE_ALWAYS, pgno,	\
+		    lock_mode, 0, &(saved_lock))) != 0)			\
+			break;						\
+		saved_pgno = pgno;					\
+		goto label;						\
+	}								\
+	saved_pgno = pgno;						\
+} while (0)
+#else
+#define	TRY_LOCK2(dbc, ndbc, pgno,					\
+    saved_pgno, saved_lock, lock_mode, label) do {			\
+	if ((pgno) != (saved_pgno) &&					\
+	    (ret = __db_lget(dbc, LCK_COUPLE_ALWAYS, pgno,		\
+	    lock_mode, DB_LOCK_NOWAIT, &(saved_lock))) != 0) {		\
+		if (ret != DB_LOCK_NOTGRANTED &&			\
+		     ret != DB_LOCK_DEADLOCK)				\
+			break;						\
+		if ((ndbc) != NULL) {					\
+			BTREE_CURSOR *__cp;				\
+			__cp = (BTREE_CURSOR *) (dbc)->internal;	\
+			__cp->sp->page = NULL;				\
+			LOCK_INIT(__cp->sp->lock);			\
+			if ((ret = __bam_stkrel(ndbc, 0)) != 0)		\
+				break;					\
+		}							\
+		if ((ret = __bam_stkrel(dbc, 0)) != 0)			\
+			break;						\
+		if ((ret = __db_lget(dbc, LCK_COUPLE_ALWAYS, pgno,	\
+		    lock_mode, 0, &(saved_lock))) != 0)	\
+			break;						\
+		saved_pgno = pgno;					\
+		goto label;						\
+	}								\
+	saved_pgno = pgno;						\
+} while (0)
+#endif
+
+/* Btree/Recno cursor. */
+struct __cursor {
+	/* struct __dbc_internal */
+	__DBC_INTERNAL
+
+	/* btree private part */
+	EPG		*sp;		/* Stack pointer. */
+	EPG		*csp;		/* Current stack entry. */
+	EPG		*esp;		/* End stack pointer. */
+	EPG		 stack[5];
+
+	db_indx_t	 ovflsize;	/* Maximum key/data on-page size. */
+
+	db_recno_t	 recno;		/* Current record number. */
+	u_int32_t	 order;		/* Relative order among deleted curs. */
+
+#ifdef HAVE_COMPRESSION
+	/*
+	 * Compression:
+	 *
+	 * We need to hold the current compressed chunk, as well as the previous
+	 * key/data, in order to decompress the next key/data. We do that by
+	 * swapping whether prevKey/Data and currentKey/Data point to
+	 * key1/data1, or key2/data2.
+	 *
+	 * We store prevcursor in order to be able to perform one level of
+	 * DB_PREV by returning prevKey/prevData. We need prev2cursor to more
+	 * efficiently do a subsequent DB_PREV with a linear search from the
+	 * beginning of the compressed chunk.
+	 *
+	 * When we delete entries, we set the cursor to point to the next entry
+	 * after the last deleted key, and set C_COMPRESS_DELETED. The del_key
+	 * DBT holds the key of the deleted entry supposedly pointed to by a
+	 * compressed cursor, and is used to implement DB_PREV_DUP,
+	 * DB_PREV_NODUP, DB_NEXT_DUP, and DB_NEXT_NODUP on a deleted entry.
+	 */
+	DBT		 compressed;	/* Current compressed chunk */
+	DBT		 key1;		/* Holds prevKey or currentKey */
+	DBT		 key2;		/* Holds prevKey or currentKey */
+	DBT		 data1;		/* Holds prevData or currentData */
+	DBT		 data2;		/* Holds prevData or currentData */
+	DBT		 del_key;	/* Holds key from the deleted entry */
+	DBT		 del_data;	/* Holds data from the deleted entry */
+	DBT		*prevKey;	/* Previous key decompressed */
+	DBT		*prevData;	/* Previous data decompressed */
+	DBT		*currentKey;	/* Current key decompressed */
+	DBT		*currentData;	/* Current data decompressed */
+	u_int8_t	*compcursor;	/* Current position in compressed */
+	u_int8_t	*compend;	/* End of compressed */
+	u_int8_t	*prevcursor;	/* Previous current position */
+	u_int8_t	*prev2cursor;	/* Previous previous current position */
+#endif
+
+	/*
+	 * Btree:
+	 * We set a flag in the cursor structure if the underlying object has
+	 * been deleted.  It's not strictly necessary, we could get the same
+	 * information by looking at the page itself, but this method doesn't
+	 * require us to retrieve the page on cursor delete.
+	 *
+	 * Recno:
+	 * When renumbering recno databases during deletes, cursors referencing
+	 * "deleted" records end up positioned between two records, and so must
+	 * be specially adjusted on the next operation.
+	 */
+#define	C_DELETED		0x0001	/* Record was deleted. */
+	/*
+	 * There are three tree types that require maintaining record numbers.
+	 * Recno AM trees, Btree AM trees for which the DB_RECNUM flag was set,
+	 * and Btree off-page duplicate trees.
+	 */
+#define	C_RECNUM		0x0002	/* Tree requires record counts. */
+	/*
+	 * Recno trees have immutable record numbers by default, but optionally
+	 * support mutable record numbers.  Off-page duplicate Recno trees have
+	 * mutable record numbers.  All Btrees with record numbers (including
+	 * off-page duplicate trees) are mutable by design, no flag is needed.
+	 */
+#define	C_RENUMBER		0x0004	/* Tree records are mutable. */
+	/*
+	 * The current compressed key/data could be deleted, as well as the
+	 * key/data that the underlying BTree cursor points to.
+	 */
+#define	C_COMPRESS_DELETED	0x0008	/* Compressed record was deleted. */
+	/*
+	 * The current compressed chunk has been modified by another DBC. A
+	 * compressed cursor will have to seek it's position again if necessary
+	 * when it is next accessed.
+	 */
+#define	C_COMPRESS_MODIFIED	0x0010	/* Compressed record was modified. */
+	u_int32_t	 flags;
+};
+
+/*
+ * Threshhold value, as a function of bt_minkey, of the number of
+ * bytes a key/data pair can use before being placed on an overflow
+ * page.  Assume every item requires the maximum alignment for
+ * padding, out of sheer paranoia.
+ */
+#define	B_MINKEY_TO_OVFLSIZE(dbp, minkey, pgsize)			\
+	((u_int16_t)(((pgsize) - P_OVERHEAD(dbp)) / ((minkey) * P_INDX) -\
+	    (BKEYDATA_PSIZE(0) + DB_ALIGN(1, sizeof(int32_t)))))
+
+/*
+ * The maximum space that a single item can ever take up on one page.
+ * Used by __bam_split to determine whether a split is still necessary.
+ */
+#define	B_MAX(a,b)	(((a) > (b)) ? (a) : (b))
+#define	B_MAXSIZEONPAGE(ovflsize)					\
+	(B_MAX(BOVERFLOW_PSIZE, BKEYDATA_PSIZE(ovflsize)))
+
+/*
+ * BAM_GET_ROOT --
+ *	This macro is used to isolate the fact that the root page of
+ * a subdatabase may move if DB->compact is called on it.
+ * The dbp->mpf->mfp->revision will be incremented every time
+ * a subdatabase root or meta page moves.  If this is the case then
+ * we must call __db_reopen to read the master database to find it.
+ * We leave the loop only by breaking out if we do not have a subdb
+ * or we are sure the have the right revision.
+ *
+ * It must be guaranteed that we cannot read an old root pgno and a
+ * current revision number.  We note that the global revision number
+ * and DB handle information are only updated while holding the latches
+ * and locks of the master database pages.
+ * If another thread is synchronizing the DB handle with the master
+ * database it will exclusively latch both the old and new pages so we will
+ * synchronize on that.
+ */
+#define BAM_GET_ROOT(dbc, root_pgno, 					\
+	     page, get_mode, lock_mode, lock, ret) do {			\
+	BTREE *__t = (dbc)->dbp->bt_internal;				\
+	BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal;		\
+	db_pgno_t __root;						\
+	u_int32_t __rev = 0;						\
+	if ((root_pgno) == PGNO_INVALID) {				\
+		if (__cp->root == PGNO_INVALID) {			\
+			__root = __t->bt_root;				\
+			__rev = __t->revision;				\
+		} else 							\
+			__root = root_pgno = __cp->root;		\
+	} else								\
+		__root = root_pgno;					\
+	if (STD_LOCKING(dbc) &&						\
+	    ((lock_mode) == DB_LOCK_WRITE || F_ISSET(dbc, DBC_DOWNREV)	\
+	    || dbc->dbtype == DB_RECNO || F_ISSET(__cp, C_RECNUM)) &&	\
+	    (ret =							\
+	    __db_lget(dbc, 0, __root, lock_mode, 0, &(lock))) != 0)	\
+		break;							\
+	if ((ret = __memp_fget((dbc)->dbp->mpf, &__root,		\
+	     (dbc)->thread_info, dbc->txn, get_mode, &page)) == 0) {	\
+		if (__root == root_pgno)				\
+			break;						\
+		if (F_ISSET(dbc, DBC_OPD) ||				\
+		    !F_ISSET((dbc)->dbp, DB_AM_SUBDB) ||		\
+		     (__t->bt_root == __root &&				\
+		     (LEVEL(page) == LEAFLEVEL || TYPE(page) == 	\
+		     (dbc->dbtype == DB_BTREE ? P_IBTREE : P_IRECNO)) &&\
+		     __rev == (dbc)->dbp->mpf->mfp->revision)) {	\
+			root_pgno = __root;				\
+			break;						\
+		}							\
+		if ((ret = __memp_fput((dbc)->dbp->mpf, 		\
+		     (dbc)->thread_info, page, (dbc)->priority)) != 0)	\
+			break;						\
+	} else if (ret != DB_PAGE_NOTFOUND)				\
+		break;							\
+	if ((ret = __LPUT(dbc, lock)) != 0)				\
+		break;							\
+	if ((ret = __db_reopen(dbc)) != 0)				\
+		break;							\
+} while (1)
+
+/*
+ * Return the root of this tree. If this is an off page duplicate tree
+ * then its in the cursor, otherwise we must look in the db handle.
+ */
+#define BAM_ROOT_PGNO(dbc)						\
+	(((BTREE_CURSOR *)(dbc)->internal)->root == PGNO_INVALID ?	\
+	    ((BTREE*)(dbc)->dbp->bt_internal)->bt_root :		\
+	    ((BTREE_CURSOR *)(dbc)->internal)->root)
+
+	
+
+/*
+ * The in-memory, per-tree btree/recno data structure.
+ */
+struct __btree {			/* Btree access method. */
+	/*
+	 * These fields may change if this is a subdatabase and
+	 * it gets compacted.
+	 */
+	db_pgno_t bt_meta;		/* Database meta-data page. */
+	db_pgno_t bt_root;		/* Database root page. */
+	u_int32_t revision;		/* Revision of root/meta. */
+
+	u_int32_t bt_minkey;		/* Minimum keys per page. */
+
+					/* Btree comparison function. */
+	int (*bt_compare) __P((DB *, const DBT *, const DBT *));
+					/* Btree prefix function. */
+	size_t (*bt_prefix) __P((DB *, const DBT *, const DBT *));
+					/* Btree compress function. */
+#ifdef HAVE_COMPRESSION
+	int (*bt_compress) __P((DB *, const DBT *, const DBT *, const DBT *,
+				       const DBT *, DBT *));
+					/* Btree decompress function. */
+	int (*bt_decompress) __P((DB *, const DBT *, const DBT *, DBT *, DBT *,
+					 DBT *));
+					/* dup_compare for compression */
+	int (*compress_dup_compare) __P((DB *, const DBT *, const DBT *));
+#endif
+
+					/* Recno access method. */
+	int	  re_pad;		/* Fixed-length padding byte. */
+	int	  re_delim;		/* Variable-length delimiting byte. */
+	u_int32_t re_len;		/* Length for fixed-length records. */
+	char	 *re_source;		/* Source file name. */
+
+	/*
+	 * !!!
+	 * The bt_lpgno field is NOT protected by any mutex, and for this
+	 * reason must be advisory only, so, while it is read/written by
+	 * multiple threads, DB is completely indifferent to the quality
+	 * of its information.
+	 */
+	db_pgno_t bt_lpgno;		/* Last insert location. */
+	DB_LSN	  bt_llsn;		/* Last insert LSN. */
+
+	/*
+	 * !!!
+	 * The re_modified field is NOT protected by any mutex, and for this
+	 * reason cannot be anything more complicated than a zero/non-zero
+	 * value.  The actual writing of the backing source file cannot be
+	 * threaded, so clearing the flag isn't a problem.
+	 */
+	int	  re_modified;		/* If the tree was modified. */
+
+	/*
+	 * !!!
+	 * These fields are ignored as far as multi-threading is concerned.
+	 * There are no transaction semantics associated with backing files,
+	 * nor is there any thread protection.
+	 */
+	FILE		*re_fp;		/* Source file handle. */
+	int		 re_eof;	/* Backing source file EOF reached. */
+	db_recno_t	 re_last;	/* Last record number read. */
+
+};
+
+/*
+ * Modes for the __bam_curadj recovery records (btree_curadj).
+ * These appear in log records, so we wire the values and
+ * do not leave it up to the compiler.
+ */
+typedef enum {
+	DB_CA_DI	= 1,
+	DB_CA_DUP	= 2,
+	DB_CA_RSPLIT	= 3,
+	DB_CA_SPLIT	= 4
+} db_ca_mode;
+
+/*
+ * Flags for __bam_pinsert.
+ */
+#define	BPI_SPACEONLY	0x01		/* Only check for space to update. */
+#define	BPI_NORECNUM	0x02		/* Not update the recnum on the left. */
+#define	BPI_NOLOGGING	0x04		/* Don't log the update. */
+#define	BPI_REPLACE	0x08		/* Replace the record. */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/btree_auto.h"
+#include "dbinc_auto/btree_ext.h"
+#include "dbinc/db_am.h"
+#endif /* !_DB_BTREE_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/clock.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,153 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2005, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)time.h	8.5 (Berkeley) 5/4/95
+ * FreeBSD: src/sys/sys/time.h,v 1.65 2004/04/07 04:19:49 imp Exp
+ */
+
+#ifndef _DB_CLOCK_H_
+#define	_DB_CLOCK_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * This declaration is POSIX-compatible.  Because there are lots of different
+ * time.h include file patterns out there, it's easier to declare our own name
+ * in all cases than to try and discover if a system has a struct timespec.
+ * For the same reason, and because we'd have to #include <sys/time.h> in db.h,
+ * we don't export any timespec structures in the DB API, even in places where
+ * it would make sense, like the replication statistics information.
+ */
+typedef struct {
+	time_t	tv_sec;				/* seconds */
+#ifdef HAVE_MIXED_SIZE_ADDRESSING
+	int32_t tv_nsec;
+#else
+	long	tv_nsec;			/* nanoseconds */
+#endif
+} db_timespec;
+
+/* Operations on timespecs */
+#undef	timespecclear
+#define	timespecclear(tvp)	((tvp)->tv_sec = (tvp)->tv_nsec = 0)
+#undef	timespecisset
+#define	timespecisset(tvp)	((tvp)->tv_sec || (tvp)->tv_nsec)
+#undef	timespeccmp
+#define	timespeccmp(tvp, uvp, cmp)					\
+	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
+	    ((tvp)->tv_nsec cmp (uvp)->tv_nsec) :			\
+	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
+#undef timespecadd
+/*
+ * Note that using timespecadd to add to yourself (i.e. doubling)
+ * must be supported.
+ */
+#define	timespecadd(vvp, uvp)						\
+	do {								\
+		(vvp)->tv_sec += (uvp)->tv_sec;				\
+		(vvp)->tv_nsec += (uvp)->tv_nsec;			\
+		if ((vvp)->tv_nsec >= 1000000000) {			\
+			(vvp)->tv_sec++;				\
+			(vvp)->tv_nsec -= 1000000000;			\
+		}							\
+	} while (0)
+#undef timespecsub
+#define	timespecsub(vvp, uvp)						\
+	do {								\
+		(vvp)->tv_sec -= (uvp)->tv_sec;				\
+		(vvp)->tv_nsec -= (uvp)->tv_nsec;			\
+		if ((vvp)->tv_nsec < 0) {				\
+			(vvp)->tv_sec--;				\
+			(vvp)->tv_nsec += 1000000000;			\
+		}							\
+	} while (0)
+
+#undef timespecset
+#define	timespecset(vvp, sec, nsec)					\
+	do {								\
+		(vvp)->tv_sec = (time_t)(sec);				\
+		(vvp)->tv_nsec = (long)(nsec);				\
+	} while (0)
+
+#define	DB_TIMEOUT_TO_TIMESPEC(t, vvp)					\
+	do {								\
+		(vvp)->tv_sec = (time_t)((t) / 1000000);		\
+		(vvp)->tv_nsec = (long)(((t) % 1000000) * 1000);	\
+	} while (0)
+
+#define	DB_TIMESPEC_TO_TIMEOUT(t, vvp, prec)				\
+	do {								\
+		t = (u_long)((vvp)->tv_sec * 1000000);			\
+		t += (u_long)((vvp)->tv_nsec / 1000);			\
+		/* Add in 1 usec for lost nsec precision if wanted. */	\
+		if (prec)						\
+			t++;						\
+	} while (0)
+
+#define	TIMESPEC_ADD_DB_TIMEOUT(vvp, t)			        \
+	do {							        \
+		db_timespec __tmp;				        \
+		DB_TIMEOUT_TO_TIMESPEC(t, &__tmp);		        \
+		timespecadd((vvp), &__tmp);			        \
+	} while (0)
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_CLOCK_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/crypto.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,115 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef	_DB_CRYPTO_H_
+#define	_DB_CRYPTO_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#ifdef HAVE_CRYPTO_IPP
+#include <ippcp.h>
+#endif
+
+/*
+ * !!!
+ * These are the internal representations of the algorithm flags.
+ * They are used in both the DB_CIPHER structure and the CIPHER
+ * structure so we can tell if users specified both passwd and alg
+ * correctly.
+ *
+ * CIPHER_ANY is used when an app joins an existing env but doesn't
+ * know the algorithm originally used.  This is only valid in the
+ * DB_CIPHER structure until we open and can set the alg.
+ */
+/*
+ * We store the algorithm in an 8-bit field on the meta-page.  So we
+ * use a numeric value, not bit fields.
+ * now we are limited to 8 algorithms before we cannot use bits and
+ * need numeric values.  That should be plenty.  It is okay for the
+ * CIPHER_ANY flag to go beyond that since that is never stored on disk.
+ */
+
+/*
+ * This structure is per-process, not in shared memory.
+ */
+struct __db_cipher {
+	u_int	(*adj_size) __P((size_t));
+	int	(*close) __P((ENV *, void *));
+	int	(*decrypt) __P((ENV *, void *, void *, u_int8_t *, size_t));
+	int	(*encrypt) __P((ENV *, void *, void *, u_int8_t *, size_t));
+	int	(*init) __P((ENV *, DB_CIPHER *));
+
+	u_int8_t mac_key[DB_MAC_KEY];	/* MAC key. */
+	void	*data;			/* Algorithm-specific information */
+
+#define	CIPHER_AES	1		/* AES algorithm */
+	u_int8_t	alg;		/* Algorithm used - See above */
+	u_int8_t	spare[3];	/* Spares */
+
+#define	CIPHER_ANY	0x00000001	/* Only for DB_CIPHER */
+	u_int32_t	flags;		/* Other flags */
+};
+
+#ifdef HAVE_CRYPTO
+
+#include "crypto/rijndael/rijndael-api-fst.h"
+
+/*
+ * Shared ciphering structure
+ * No mutex needed because all information is read-only after creation.
+ */
+typedef struct __cipher {
+	roff_t		passwd;		/* Offset to shared passwd */
+	size_t		passwd_len;	/* Length of passwd */
+	u_int32_t	flags;		/* Algorithm used - see above */
+} CIPHER;
+
+#define	DB_AES_KEYLEN	128	/* AES key length */
+#define	DB_AES_CHUNK	16	/* AES byte unit size */
+
+typedef struct __aes_cipher {
+#ifdef	HAVE_CRYPTO_IPP
+	void		*ipp_ctx;	/* IPP key instance */
+#else
+	keyInstance	decrypt_ki;	/* Decryption key instance */
+	keyInstance	encrypt_ki;	/* Encryption key instance */
+#endif
+	u_int32_t	flags;		/* AES-specific flags */
+} AES_CIPHER;
+
+#include "dbinc_auto/crypto_ext.h"
+#endif /* HAVE_CRYPTO */
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_CRYPTO_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/cxx_int.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,99 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_CXX_INT_H_
+#define	_DB_CXX_INT_H_
+
+// private data structures known to the implementation only
+
+//
+// Using FooImp classes will allow the implementation to change in the
+// future without any modification to user code or even to header files
+// that the user includes. FooImp * is just like void * except that it
+// provides a little extra protection, since you cannot randomly assign
+// any old pointer to a FooImp* as you can with void *.  Currently, a
+// pointer to such an opaque class is always just a pointer to the
+// appropriate underlying implementation struct.  These are converted
+// back and forth using the various overloaded wrap()/unwrap() methods.
+// This is essentially a use of the "Bridge" Design Pattern.
+//
+// WRAPPED_CLASS implements the appropriate wrap() and unwrap() methods
+// for a wrapper class that has an underlying pointer representation.
+//
+#define	WRAPPED_CLASS(_WRAPPER_CLASS, _IMP_CLASS, _WRAPPED_TYPE)           \
+	class _IMP_CLASS {};                                               \
+									   \
+	inline _WRAPPED_TYPE *unwrap(_WRAPPER_CLASS *val)                  \
+	{                                                                  \
+		if (!val) return (0);                                      \
+		return (val->get_##_WRAPPED_TYPE());                       \
+	}                                                                  \
+									   \
+	inline const _WRAPPED_TYPE *unwrapConst(const _WRAPPER_CLASS *val) \
+	{                                                                  \
+		if (!val) return (0);                                      \
+		return (val->get_const_##_WRAPPED_TYPE());                 \
+	}
+
+WRAPPED_CLASS(Db, DbImp, DB)
+WRAPPED_CLASS(DbChannel, DbChannelImp, DB_CHANNEL)
+WRAPPED_CLASS(DbEnv, DbEnvImp, DB_ENV)
+WRAPPED_CLASS(DbMpoolFile, DbMpoolFileImp, DB_MPOOLFILE)
+WRAPPED_CLASS(DbSequence, DbSequenceImp, DB_SEQUENCE)
+WRAPPED_CLASS(DbSite, DbSiteImp, DB_SITE)
+WRAPPED_CLASS(DbTxn, DbTxnImp, DB_TXN)
+
+// A tristate integer value used by the DB_ERROR macro below.
+// We chose not to make this an enumerated type so it can
+// be kept private, even though methods that return the
+// tristate int can be declared in db_cxx.h .
+//
+#define	ON_ERROR_THROW     1
+#define	ON_ERROR_RETURN    0
+#define	ON_ERROR_UNKNOWN   (-1)
+
+// Macros that handle detected errors, in case we want to
+// change the default behavior.  The 'policy' is one of
+// the tristate values given above.  If UNKNOWN is specified,
+// the behavior is taken from the last initialized DbEnv.
+//
+#define	DB_ERROR(dbenv, caller, ecode, policy) \
+    DbEnv::runtime_error(dbenv, caller, ecode, policy)
+
+#define	DB_ERROR_DBT(dbenv, caller, dbt, policy) \
+    DbEnv::runtime_error_dbt(dbenv, caller, dbt, policy)
+
+#define	DB_OVERFLOWED_DBT(dbt) \
+	(F_ISSET(dbt, DB_DBT_USERMEM) && dbt->size > dbt->ulen)
+
+/* values for Db::flags_ */
+#define	DB_CXX_PRIVATE_ENV      0x00000001
+
+#endif /* !_DB_CXX_INT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/db.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,2595 @@
+/*
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ *
+ * db.h include file layout:
+ *	General.
+ *	Database Environment.
+ *	Locking subsystem.
+ *	Logging subsystem.
+ *	Shared buffer cache (mpool) subsystem.
+ *	Transaction subsystem.
+ *	Access methods.
+ *	Access method cursors.
+ *	Dbm/Ndbm, Hsearch historic interfaces.
+ */
+
+#ifndef _DB_H_
+#define	_DB_H_
+
+#ifndef	__NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+@inttypes_h_decl@
+@stdint_h_decl@
+@stddef_h_decl@
+#include <stdio.h>
+@unistd_h_decl@
+@thread_h_decl@
+#endif
+
+@platform_header@
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+@DB_CONST@
+@DB_PROTO1@
+@DB_PROTO2@
+
+/*
+ * Berkeley DB version information.
+ */
+#define	DB_VERSION_FAMILY	@DB_VERSION_FAMILY@
+#define	DB_VERSION_RELEASE	@DB_VERSION_RELEASE@
+#define	DB_VERSION_MAJOR	@DB_VERSION_MAJOR@
+#define	DB_VERSION_MINOR	@DB_VERSION_MINOR@
+#define	DB_VERSION_PATCH	@DB_VERSION_PATCH@
+#define	DB_VERSION_STRING	@DB_VERSION_STRING@
+#define	DB_VERSION_FULL_STRING	@DB_VERSION_FULL_STRING@
+
+/*
+ * !!!
+ * Berkeley DB uses specifically sized types.  If they're not provided by
+ * the system, typedef them here.
+ *
+ * We protect them against multiple inclusion using __BIT_TYPES_DEFINED__,
+ * as does BIND and Kerberos, since we don't know for sure what #include
+ * files the user is using.
+ *
+ * !!!
+ * We also provide the standard u_int, u_long etc., if they're not provided
+ * by the system.
+ */
+#ifndef	__BIT_TYPES_DEFINED__
+#define	__BIT_TYPES_DEFINED__
+@u_int8_decl@
+@int16_decl@
+@u_int16_decl@
+@int32_decl@
+@u_int32_decl@
+@int64_decl@
+@u_int64_decl@
+#endif
+
+@u_char_decl@
+@u_int_decl@
+@u_long_decl@
+@u_short_decl@
+
+/*
+ * Missing ANSI types.
+ *
+ * uintmax_t --
+ * Largest unsigned type, used to align structures in memory.  We don't store
+ * floating point types in structures, so integral types should be sufficient
+ * (and we don't have to worry about systems that store floats in other than
+ * power-of-2 numbers of bytes).  Additionally this fixes compilers that rewrite
+ * structure assignments and ANSI C memcpy calls to be in-line instructions
+ * that happen to require alignment.
+ *
+ * uintptr_t --
+ * Unsigned type that's the same size as a pointer.  There are places where
+ * DB modifies pointers by discarding the bottom bits to guarantee alignment.
+ * We can't use uintmax_t, it may be larger than the pointer, and compilers
+ * get upset about that.  So far we haven't run on any machine where there's
+ * no unsigned type the same size as a pointer -- here's hoping.
+ */
+@uintmax_t_decl@
+@uintptr_t_decl@
+
+@FILE_t_decl@
+@off_t_decl@
+@pid_t_decl@
+@size_t_decl@
+#ifdef HAVE_MIXED_SIZE_ADDRESSING
+typedef u_int32_t db_size_t;
+#else
+typedef size_t db_size_t;
+#endif
+@ssize_t_decl@
+#ifdef HAVE_MIXED_SIZE_ADDRESSING
+typedef int32_t db_ssize_t;
+#else
+typedef ssize_t db_ssize_t;
+#endif
+@time_t_decl@
+
+/*
+ * Sequences are only available on machines with 64-bit integral types.
+ */
+@db_seq_decl@
+
+/* Thread and process identification. */
+@db_threadid_t_decl@
+
+/* Basic types that are exported or quasi-exported. */
+typedef	u_int32_t	db_pgno_t;	/* Page number type. */
+typedef	u_int16_t	db_indx_t;	/* Page offset type. */
+#define	DB_MAX_PAGES	0xffffffff	/* >= # of pages in a file */
+
+typedef	u_int32_t	db_recno_t;	/* Record number type. */
+#define	DB_MAX_RECORDS	0xffffffff	/* >= # of records in a tree */
+
+typedef u_int32_t	db_timeout_t;	/* Type of a timeout. */
+
+/*
+ * Region offsets are the difference between a pointer in a region and the
+ * region's base address.  With private environments, both addresses are the
+ * result of calling malloc, and we can't assume anything about what malloc
+ * will return, so region offsets have to be able to hold differences between
+ * arbitrary pointers.
+ */
+typedef	db_size_t	roff_t;
+
+/*
+ * Forward structure declarations, so we can declare pointers and
+ * applications can get type checking.
+ */
+struct __channel;	typedef struct __channel CHANNEL;
+struct __db;		typedef struct __db DB;
+struct __db_bt_stat;	typedef struct __db_bt_stat DB_BTREE_STAT;
+struct __db_channel;	typedef struct __db_channel DB_CHANNEL;
+struct __db_cipher;	typedef struct __db_cipher DB_CIPHER;
+struct __db_compact;	typedef struct __db_compact DB_COMPACT;
+struct __db_dbt;	typedef struct __db_dbt DBT;
+struct __db_distab;	typedef struct __db_distab DB_DISTAB;
+struct __db_env;	typedef struct __db_env DB_ENV;
+struct __db_h_stat;	typedef struct __db_h_stat DB_HASH_STAT;
+struct __db_heap_rid;	typedef struct __db_heap_rid DB_HEAP_RID;
+struct __db_heap_stat;	typedef struct __db_heap_stat DB_HEAP_STAT;
+struct __db_ilock;	typedef struct __db_ilock DB_LOCK_ILOCK;
+struct __db_lock_hstat;	typedef struct __db_lock_hstat DB_LOCK_HSTAT;
+struct __db_lock_pstat;	typedef struct __db_lock_pstat DB_LOCK_PSTAT;
+struct __db_lock_stat;	typedef struct __db_lock_stat DB_LOCK_STAT;
+struct __db_lock_u;	typedef struct __db_lock_u DB_LOCK;
+struct __db_locker;	typedef struct __db_locker DB_LOCKER;
+struct __db_lockreq;	typedef struct __db_lockreq DB_LOCKREQ;
+struct __db_locktab;	typedef struct __db_locktab DB_LOCKTAB;
+struct __db_log;	typedef struct __db_log DB_LOG;
+struct __db_log_cursor;	typedef struct __db_log_cursor DB_LOGC;
+struct __db_log_stat;	typedef struct __db_log_stat DB_LOG_STAT;
+struct __db_lsn;	typedef struct __db_lsn DB_LSN;
+struct __db_mpool;	typedef struct __db_mpool DB_MPOOL;
+struct __db_mpool_fstat;typedef struct __db_mpool_fstat DB_MPOOL_FSTAT;
+struct __db_mpool_stat;	typedef struct __db_mpool_stat DB_MPOOL_STAT;
+struct __db_mpoolfile;	typedef struct __db_mpoolfile DB_MPOOLFILE;
+struct __db_mutex_stat;	typedef struct __db_mutex_stat DB_MUTEX_STAT;
+struct __db_mutex_t;	typedef struct __db_mutex_t DB_MUTEX;
+struct __db_mutexmgr;	typedef struct __db_mutexmgr DB_MUTEXMGR;
+struct __db_preplist;	typedef struct __db_preplist DB_PREPLIST;
+struct __db_qam_stat;	typedef struct __db_qam_stat DB_QUEUE_STAT;
+struct __db_rep;	typedef struct __db_rep DB_REP;
+struct __db_rep_stat;	typedef struct __db_rep_stat DB_REP_STAT;
+struct __db_repmgr_conn_err;
+	typedef struct __db_repmgr_conn_err DB_REPMGR_CONN_ERR;
+struct __db_repmgr_site;typedef struct __db_repmgr_site DB_REPMGR_SITE;
+struct __db_repmgr_stat;typedef struct __db_repmgr_stat DB_REPMGR_STAT;
+struct __db_seq_record; typedef struct __db_seq_record DB_SEQ_RECORD;
+struct __db_seq_stat;	typedef struct __db_seq_stat DB_SEQUENCE_STAT;
+struct __db_site;	typedef struct __db_site DB_SITE;
+struct __db_sequence;	typedef struct __db_sequence DB_SEQUENCE;
+struct __db_thread_info;typedef struct __db_thread_info DB_THREAD_INFO;
+struct __db_txn;	typedef struct __db_txn DB_TXN;
+struct __db_txn_active;	typedef struct __db_txn_active DB_TXN_ACTIVE;
+struct __db_txn_stat;	typedef struct __db_txn_stat DB_TXN_STAT;
+struct __db_txn_token;	typedef struct __db_txn_token DB_TXN_TOKEN;
+struct __db_txnmgr;	typedef struct __db_txnmgr DB_TXNMGR;
+struct __dbc;		typedef struct __dbc DBC;
+struct __dbc_internal;	typedef struct __dbc_internal DBC_INTERNAL;
+struct __env;		typedef struct __env ENV;
+struct __fh_t;		typedef struct __fh_t DB_FH;
+struct __fname;		typedef struct __fname FNAME;
+struct __key_range;	typedef struct __key_range DB_KEY_RANGE;
+struct __mpoolfile;	typedef struct __mpoolfile MPOOLFILE;
+struct __db_logvrfy_config;
+typedef struct __db_logvrfy_config DB_LOG_VERIFY_CONFIG;
+
+/*
+ * The Berkeley DB API flags are automatically-generated -- the following flag
+ * names are no longer used, but remain for compatibility reasons.
+ */
+#define	DB_DEGREE_2	      DB_READ_COMMITTED
+#define	DB_DIRTY_READ	      DB_READ_UNCOMMITTED
+#define	DB_JOINENV	      0x0
+
+/* Key/data structure -- a Data-Base Thang. */
+struct __db_dbt {
+	void	 *data;			/* Key/data */
+	u_int32_t size;			/* key/data length */
+
+	u_int32_t ulen;			/* RO: length of user buffer. */
+	u_int32_t dlen;			/* RO: get/put record length. */
+	u_int32_t doff;			/* RO: get/put record offset. */
+
+	void *app_data;
+
+#define	DB_DBT_APPMALLOC	0x001	/* Callback allocated memory. */
+#define	DB_DBT_BULK		0x002	/* Internal: Insert if duplicate. */
+#define	DB_DBT_DUPOK		0x004	/* Internal: Insert if duplicate. */
+#define	DB_DBT_ISSET		0x008	/* Lower level calls set value. */
+#define	DB_DBT_MALLOC		0x010	/* Return in malloc'd memory. */
+#define	DB_DBT_MULTIPLE		0x020	/* References multiple records. */
+#define	DB_DBT_PARTIAL		0x040	/* Partial put/get. */
+#define	DB_DBT_REALLOC		0x080	/* Return in realloc'd memory. */
+#define	DB_DBT_READONLY		0x100	/* Readonly, don't update. */
+#define	DB_DBT_STREAMING	0x200	/* Internal: DBT is being streamed. */
+#define	DB_DBT_USERCOPY		0x400	/* Use the user-supplied callback. */
+#define	DB_DBT_USERMEM		0x800	/* Return in user's memory. */
+	u_int32_t flags;
+};
+
+/*******************************************************
+ * Mutexes.
+ *******************************************************/
+/* 
+ * When mixed size addressing is supported mutexes need to be the same size
+ * independent of the process address size is.
+ */
+#ifdef HAVE_MIXED_SIZE_ADDRESSING
+typedef db_size_t	db_mutex_t;
+#else
+typedef uintptr_t	db_mutex_t;
+#endif
+
+struct __db_mutex_stat { /* SHARED */
+	/* The following fields are maintained in the region's copy. */
+	u_int32_t st_mutex_align;	/* Mutex alignment */
+	u_int32_t st_mutex_tas_spins;	/* Mutex test-and-set spins */
+	u_int32_t st_mutex_init;	/* Initial mutex count */
+	u_int32_t st_mutex_cnt;		/* Mutex count */
+	u_int32_t st_mutex_max;		/* Mutex max */
+	u_int32_t st_mutex_free;	/* Available mutexes */
+	u_int32_t st_mutex_inuse;	/* Mutexes in use */
+	u_int32_t st_mutex_inuse_max;	/* Maximum mutexes ever in use */
+
+	/* The following fields are filled-in from other places. */
+#ifndef __TEST_DB_NO_STATISTICS
+	uintmax_t st_region_wait;	/* Region lock granted after wait. */
+	uintmax_t st_region_nowait;	/* Region lock granted without wait. */
+	roff_t	  st_regsize;		/* Region size. */
+	roff_t	  st_regmax;		/* Region max. */
+#endif
+};
+
+/* This is the length of the buffer passed to DB_ENV->thread_id_string() */
+#define	DB_THREADID_STRLEN	128
+
+/*******************************************************
+ * Locking.
+ *******************************************************/
+#define	DB_LOCKVERSION	1
+
+#define	DB_FILE_ID_LEN		20	/* Unique file ID length. */
+
+/*
+ * Deadlock detector modes; used in the DB_ENV structure to configure the
+ * locking subsystem.
+ */
+#define	DB_LOCK_NORUN		0
+#define	DB_LOCK_DEFAULT		1	/* Default policy. */
+#define	DB_LOCK_EXPIRE		2	/* Only expire locks, no detection. */
+#define	DB_LOCK_MAXLOCKS	3	/* Select locker with max locks. */
+#define	DB_LOCK_MAXWRITE	4	/* Select locker with max writelocks. */
+#define	DB_LOCK_MINLOCKS	5	/* Select locker with min locks. */
+#define	DB_LOCK_MINWRITE	6	/* Select locker with min writelocks. */
+#define	DB_LOCK_OLDEST		7	/* Select oldest locker. */
+#define	DB_LOCK_RANDOM		8	/* Select random locker. */
+#define	DB_LOCK_YOUNGEST	9	/* Select youngest locker. */
+
+/*
+ * Simple R/W lock modes and for multi-granularity intention locking.
+ *
+ * !!!
+ * These values are NOT random, as they are used as an index into the lock
+ * conflicts arrays, i.e., DB_LOCK_IWRITE must be == 3, and DB_LOCK_IREAD
+ * must be == 4.
+ */
+typedef enum {
+	DB_LOCK_NG=0,			/* Not granted. */
+	DB_LOCK_READ=1,			/* Shared/read. */
+	DB_LOCK_WRITE=2,		/* Exclusive/write. */
+	DB_LOCK_WAIT=3,			/* Wait for event */
+	DB_LOCK_IWRITE=4,		/* Intent exclusive/write. */
+	DB_LOCK_IREAD=5,		/* Intent to share/read. */
+	DB_LOCK_IWR=6,			/* Intent to read and write. */
+	DB_LOCK_READ_UNCOMMITTED=7,	/* Degree 1 isolation. */
+	DB_LOCK_WWRITE=8		/* Was Written. */
+} db_lockmode_t;
+
+/*
+ * Request types.
+ */
+typedef enum {
+	DB_LOCK_DUMP=0,			/* Display held locks. */
+	DB_LOCK_GET=1,			/* Get the lock. */
+	DB_LOCK_GET_TIMEOUT=2,		/* Get lock with a timeout. */
+	DB_LOCK_INHERIT=3,		/* Pass locks to parent. */
+	DB_LOCK_PUT=4,			/* Release the lock. */
+	DB_LOCK_PUT_ALL=5,		/* Release locker's locks. */
+	DB_LOCK_PUT_OBJ=6,		/* Release locker's locks on obj. */
+	DB_LOCK_PUT_READ=7,		/* Release locker's read locks. */
+	DB_LOCK_TIMEOUT=8,		/* Force a txn to timeout. */
+	DB_LOCK_TRADE=9,		/* Trade locker ids on a lock. */
+	DB_LOCK_UPGRADE_WRITE=10	/* Upgrade writes for dirty reads. */
+} db_lockop_t;
+
+/*
+ * Status of a lock.
+ */
+typedef enum  {
+	DB_LSTAT_ABORTED=1,		/* Lock belongs to an aborted txn. */
+	DB_LSTAT_EXPIRED=2,		/* Lock has expired. */
+	DB_LSTAT_FREE=3,		/* Lock is unallocated. */
+	DB_LSTAT_HELD=4,		/* Lock is currently held. */
+	DB_LSTAT_PENDING=5,		/* Lock was waiting and has been
+					 * promoted; waiting for the owner
+					 * to run and upgrade it to held. */
+	DB_LSTAT_WAITING=6		/* Lock is on the wait queue. */
+}db_status_t;
+
+/* Lock statistics structure. */
+struct __db_lock_stat { /* SHARED */
+	u_int32_t st_id;		/* Last allocated locker ID. */
+	u_int32_t st_cur_maxid;		/* Current maximum unused ID. */
+	u_int32_t st_initlocks;		/* Initial number of locks in table. */
+	u_int32_t st_initlockers;	/* Initial num of lockers in table. */
+	u_int32_t st_initobjects;	/* Initial num of objects in table. */
+	u_int32_t st_locks;		/* Current number of locks in table. */
+	u_int32_t st_lockers;		/* Current num of lockers in table. */
+	u_int32_t st_objects;		/* Current num of objects in table. */
+	u_int32_t st_maxlocks;		/* Maximum number of locks in table. */
+	u_int32_t st_maxlockers;	/* Maximum num of lockers in table. */
+	u_int32_t st_maxobjects;	/* Maximum num of objects in table. */
+	u_int32_t st_partitions;	/* number of partitions. */
+	u_int32_t st_tablesize;		/* Size of object hash table. */
+	int32_t   st_nmodes;		/* Number of lock modes. */
+	u_int32_t st_nlockers;		/* Current number of lockers. */
+#ifndef __TEST_DB_NO_STATISTICS
+	u_int32_t st_nlocks;		/* Current number of locks. */
+	u_int32_t st_maxnlocks;		/* Maximum number of locks so far. */
+	u_int32_t st_maxhlocks;		/* Maximum number of locks in any bucket. */
+	uintmax_t st_locksteals;	/* Number of lock steals so far. */
+	uintmax_t st_maxlsteals;	/* Maximum number steals in any partition. */
+	u_int32_t st_maxnlockers;	/* Maximum number of lockers so far. */
+	u_int32_t st_nobjects;		/* Current number of objects. */
+	u_int32_t st_maxnobjects;	/* Maximum number of objects so far. */
+	u_int32_t st_maxhobjects;	/* Maximum number of objectsin any bucket. */
+	uintmax_t st_objectsteals;	/* Number of objects steals so far. */
+	uintmax_t st_maxosteals;	/* Maximum number of steals in any partition. */
+	uintmax_t st_nrequests;		/* Number of lock gets. */
+	uintmax_t st_nreleases;		/* Number of lock puts. */
+	uintmax_t st_nupgrade;		/* Number of lock upgrades. */
+	uintmax_t st_ndowngrade;	/* Number of lock downgrades. */
+	uintmax_t st_lock_wait;		/* Lock conflicts w/ subsequent wait */
+	uintmax_t st_lock_nowait;	/* Lock conflicts w/o subsequent wait */
+	uintmax_t st_ndeadlocks;	/* Number of lock deadlocks. */
+	db_timeout_t st_locktimeout;	/* Lock timeout. */
+	uintmax_t st_nlocktimeouts;	/* Number of lock timeouts. */
+	db_timeout_t st_txntimeout;	/* Transaction timeout. */
+	uintmax_t st_ntxntimeouts;	/* Number of transaction timeouts. */
+	uintmax_t st_part_wait;		/* Partition lock granted after wait. */
+	uintmax_t st_part_nowait;	/* Partition lock granted without wait. */
+	uintmax_t st_part_max_wait;	/* Max partition lock granted after wait. */
+	uintmax_t st_part_max_nowait;	/* Max partition lock granted without wait. */
+	uintmax_t st_objs_wait;	/* 	Object lock granted after wait. */
+	uintmax_t st_objs_nowait;	/* Object lock granted without wait. */
+	uintmax_t st_lockers_wait;	/* Locker lock granted after wait. */
+	uintmax_t st_lockers_nowait;	/* Locker lock granted without wait. */
+	uintmax_t st_region_wait;	/* Region lock granted after wait. */
+	uintmax_t st_region_nowait;	/* Region lock granted without wait. */
+	u_int32_t st_hash_len;		/* Max length of bucket. */
+	roff_t	  st_regsize;		/* Region size. */
+#endif
+};
+
+struct __db_lock_hstat { /* SHARED */
+	uintmax_t st_nrequests;		/* Number of lock gets. */
+	uintmax_t st_nreleases;		/* Number of lock puts. */
+	uintmax_t st_nupgrade;		/* Number of lock upgrades. */
+	uintmax_t st_ndowngrade;	/* Number of lock downgrades. */
+	u_int32_t st_nlocks;		/* Current number of locks. */
+	u_int32_t st_maxnlocks;		/* Maximum number of locks so far. */
+	u_int32_t st_nobjects;		/* Current number of objects. */
+	u_int32_t st_maxnobjects;	/* Maximum number of objects so far. */
+	uintmax_t st_lock_wait;		/* Lock conflicts w/ subsequent wait */
+	uintmax_t st_lock_nowait;	/* Lock conflicts w/o subsequent wait */
+	uintmax_t st_nlocktimeouts;	/* Number of lock timeouts. */
+	uintmax_t st_ntxntimeouts;	/* Number of transaction timeouts. */
+	u_int32_t st_hash_len;		/* Max length of bucket. */
+};
+
+struct __db_lock_pstat { /* SHARED */
+	u_int32_t st_nlocks;		/* Current number of locks. */
+	u_int32_t st_maxnlocks;		/* Maximum number of locks so far. */
+	u_int32_t st_nobjects;		/* Current number of objects. */
+	u_int32_t st_maxnobjects;	/* Maximum number of objects so far. */
+	uintmax_t st_locksteals;	/* Number of lock steals so far. */
+	uintmax_t st_objectsteals;	/* Number of objects steals so far. */
+};
+
+/*
+ * DB_LOCK_ILOCK --
+ *	Internal DB access method lock.
+ */
+struct __db_ilock { /* SHARED */
+	db_pgno_t pgno;			/* Page being locked. */
+	u_int8_t fileid[DB_FILE_ID_LEN];/* File id. */
+#define	DB_HANDLE_LOCK		1
+#define	DB_RECORD_LOCK		2
+#define	DB_PAGE_LOCK		3
+#define	DB_DATABASE_LOCK	4
+	u_int32_t type;			/* Type of lock. */
+};
+
+/*
+ * DB_LOCK --
+ *	The structure is allocated by the caller and filled in during a
+ *	lock_get request (or a lock_vec/DB_LOCK_GET).
+ */
+struct __db_lock_u { /* SHARED */
+	roff_t		off;		/* Offset of the lock in the region */
+	u_int32_t	ndx;		/* Index of the object referenced by
+					 * this lock; used for locking. */
+	u_int32_t	gen;		/* Generation number of this lock. */
+	db_lockmode_t	mode;		/* mode of this lock. */
+};
+
+/* Lock request structure. */
+struct __db_lockreq {
+	db_lockop_t	 op;		/* Operation. */
+	db_lockmode_t	 mode;		/* Requested mode. */
+	db_timeout_t	 timeout;	/* Time to expire lock. */
+	DBT		*obj;		/* Object being locked. */
+	DB_LOCK		 lock;		/* Lock returned. */
+};
+
+/*******************************************************
+ * Logging.
+ *******************************************************/
+#define	DB_LOGVERSION	20		/* Current log version. */
+#define	DB_LOGVERSION_LATCHING 15	/* Log version using latching: db-4.8 */
+#define	DB_LOGCHKSUM	12		/* Check sum headers: db-4.5 */
+#define	DB_LOGOLDVER	8		/* Oldest version supported: db-4.2 */
+#define	DB_LOGMAGIC	0x040988
+
+/*
+ * A DB_LSN has two parts, a fileid which identifies a specific file, and an
+ * offset within that file.  The fileid is an unsigned 4-byte quantity that
+ * uniquely identifies a file within the log directory -- currently a simple
+ * counter inside the log.  The offset is also an unsigned 4-byte value.  The
+ * log manager guarantees the offset is never more than 4 bytes by switching
+ * to a new log file before the maximum length imposed by an unsigned 4-byte
+ * offset is reached.
+ */
+struct __db_lsn { /* SHARED */
+	u_int32_t	file;		/* File ID. */
+	u_int32_t	offset;		/* File offset. */
+};
+
+/*
+ * Application-specified log record types start at DB_user_BEGIN, and must not
+ * equal or exceed DB_debug_FLAG.
+ *
+ * DB_debug_FLAG is the high-bit of the u_int32_t that specifies a log record
+ * type.  If the flag is set, it's a log record that was logged for debugging
+ * purposes only, even if it reflects a database change -- the change was part
+ * of a non-durable transaction.
+ */
+#define	DB_user_BEGIN		10000
+#define	DB_debug_FLAG		0x80000000
+
+/*
+ * DB_LOGC --
+ *	Log cursor.
+ */
+struct __db_log_cursor {
+	ENV	 *env;			/* Environment */
+
+	DB_FH	 *fhp;			/* File handle. */
+	DB_LSN	  lsn;			/* Cursor: LSN */
+	u_int32_t len;			/* Cursor: record length */
+	u_int32_t prev;			/* Cursor: previous record's offset */
+
+	DBT	  dbt;			/* Return DBT. */
+	DB_LSN    p_lsn;		/* Persist LSN. */
+	u_int32_t p_version;		/* Persist version. */
+
+	u_int8_t *bp;			/* Allocated read buffer. */
+	u_int32_t bp_size;		/* Read buffer length in bytes. */
+	u_int32_t bp_rlen;		/* Read buffer valid data length. */
+	DB_LSN	  bp_lsn;		/* Read buffer first byte LSN. */
+
+	u_int32_t bp_maxrec;		/* Max record length in the log file. */
+
+	/* DB_LOGC PUBLIC HANDLE LIST BEGIN */
+	int (*close) __P((DB_LOGC *, u_int32_t));
+	int (*get) __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t));
+	int (*version) __P((DB_LOGC *, u_int32_t *, u_int32_t));
+	/* DB_LOGC PUBLIC HANDLE LIST END */
+
+#define	DB_LOG_DISK		0x01	/* Log record came from disk. */
+#define	DB_LOG_LOCKED		0x02	/* Log region already locked */
+#define	DB_LOG_SILENT_ERR	0x04	/* Turn-off error messages. */
+	u_int32_t flags;
+};
+
+/* Log statistics structure. */
+struct __db_log_stat { /* SHARED */
+	u_int32_t st_magic;		/* Log file magic number. */
+	u_int32_t st_version;		/* Log file version number. */
+	int32_t   st_mode;		/* Log file permissions mode. */
+	u_int32_t st_lg_bsize;		/* Log buffer size. */
+	u_int32_t st_lg_size;		/* Log file size. */
+	u_int32_t st_wc_bytes;		/* Bytes to log since checkpoint. */
+	u_int32_t st_wc_mbytes;		/* Megabytes to log since checkpoint. */
+	u_int32_t st_fileid_init;	/* Initial allocation for fileids. */
+#ifndef __TEST_DB_NO_STATISTICS
+	u_int32_t st_nfileid;		/* Current number of fileids. */
+	u_int32_t st_maxnfileid;	/* Maximum number of fileids used. */
+	uintmax_t st_record;		/* Records entered into the log. */
+	u_int32_t st_w_bytes;		/* Bytes to log. */
+	u_int32_t st_w_mbytes;		/* Megabytes to log. */
+	uintmax_t st_wcount;		/* Total I/O writes to the log. */
+	uintmax_t st_wcount_fill;	/* Overflow writes to the log. */
+	uintmax_t st_rcount;		/* Total I/O reads from the log. */
+	uintmax_t st_scount;		/* Total syncs to the log. */
+	uintmax_t st_region_wait;	/* Region lock granted after wait. */
+	uintmax_t st_region_nowait;	/* Region lock granted without wait. */
+	u_int32_t st_cur_file;		/* Current log file number. */
+	u_int32_t st_cur_offset;	/* Current log file offset. */
+	u_int32_t st_disk_file;		/* Known on disk log file number. */
+	u_int32_t st_disk_offset;	/* Known on disk log file offset. */
+	u_int32_t st_maxcommitperflush;	/* Max number of commits in a flush. */
+	u_int32_t st_mincommitperflush;	/* Min number of commits in a flush. */
+	roff_t	  st_regsize;		/* Region size. */
+#endif
+};
+
+/*
+ * We need to record the first log record of a transaction.  For user
+ * defined logging this macro returns the place to put that information,
+ * if it is need in rlsnp, otherwise it leaves it unchanged.  We also
+ * need to track the last record of the transaction, this returns the
+ * place to put that info.
+ */
+#define	DB_SET_TXN_LSNP(txn, blsnp, llsnp)		\
+	((txn)->set_txn_lsnp(txn, blsnp, llsnp))
+
+/*
+ * Definition of the structure which specifies marshalling of log records.
+ */
+typedef enum {
+	LOGREC_Done,
+	LOGREC_ARG,
+	LOGREC_HDR,
+	LOGREC_DATA,
+	LOGREC_DB,
+	LOGREC_DBOP,
+	LOGREC_DBT,
+	LOGREC_LOCKS,
+	LOGREC_OP,
+	LOGREC_PGDBT,
+	LOGREC_PGDDBT,
+	LOGREC_PGLIST,
+	LOGREC_POINTER,
+	LOGREC_TIME
+} log_rec_type_t;
+
+typedef const struct __log_rec_spec {
+	log_rec_type_t	type;
+	u_int32_t	offset;
+	const char 	*name;
+	const char	fmt[4];
+} DB_LOG_RECSPEC;
+
+/*
+ * Size of a DBT in a log record.
+ */
+#define	LOG_DBT_SIZE(dbt)						\
+    (sizeof(u_int32_t) + ((dbt) == NULL ? 0 : (dbt)->size))
+
+/*******************************************************
+ * Shared buffer cache (mpool).
+ *******************************************************/
+/* Priority values for DB_MPOOLFILE->{put,set_priority}. */
+typedef enum {
+	DB_PRIORITY_UNCHANGED=0,
+	DB_PRIORITY_VERY_LOW=1,
+	DB_PRIORITY_LOW=2,
+	DB_PRIORITY_DEFAULT=3,
+	DB_PRIORITY_HIGH=4,
+	DB_PRIORITY_VERY_HIGH=5
+} DB_CACHE_PRIORITY;
+
+/* Per-process DB_MPOOLFILE information. */
+struct __db_mpoolfile {
+	DB_FH	  *fhp;			/* Underlying file handle. */
+
+	/*
+	 * !!!
+	 * The ref, pinref and q fields are protected by the region lock.
+	 */
+	u_int32_t  ref;			/* Reference count. */
+
+	u_int32_t pinref;		/* Pinned block reference count. */
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__db_mpoolfile) q;
+	 */
+	struct {
+		struct __db_mpoolfile *tqe_next;
+		struct __db_mpoolfile **tqe_prev;
+	} q;				/* Linked list of DB_MPOOLFILE's. */
+
+	/*
+	 * !!!
+	 * The rest of the fields (with the exception of the MP_FLUSH flag)
+	 * are not thread-protected, even when they may be modified at any
+	 * time by the application.  The reason is the DB_MPOOLFILE handle
+	 * is single-threaded from the viewpoint of the application, and so
+	 * the only fields needing to be thread-protected are those accessed
+	 * by checkpoint or sync threads when using DB_MPOOLFILE structures
+	 * to flush buffers from the cache.
+	 */
+	ENV	       *env;		/* Environment */
+	MPOOLFILE      *mfp;		/* Underlying MPOOLFILE. */
+
+	u_int32_t	clear_len;	/* Cleared length on created pages. */
+	u_int8_t			/* Unique file ID. */
+			fileid[DB_FILE_ID_LEN];
+	int		ftype;		/* File type. */
+	int32_t		lsn_offset;	/* LSN offset in page. */
+	u_int32_t	gbytes, bytes;	/* Maximum file size. */
+	DBT	       *pgcookie;	/* Byte-string passed to pgin/pgout. */
+	int32_t		priority;	/* Cache priority. */
+
+	void	       *addr;		/* Address of mmap'd region. */
+	size_t		len;		/* Length of mmap'd region. */
+
+	u_int32_t	config_flags;	/* Flags to DB_MPOOLFILE->set_flags. */
+
+	/* DB_MPOOLFILE PUBLIC HANDLE LIST BEGIN */
+	int (*close) __P((DB_MPOOLFILE *, u_int32_t));
+	int (*get)
+	    __P((DB_MPOOLFILE *, db_pgno_t *, DB_TXN *, u_int32_t, void *));
+	int (*get_clear_len) __P((DB_MPOOLFILE *, u_int32_t *));
+	int (*get_fileid) __P((DB_MPOOLFILE *, u_int8_t *));
+	int (*get_flags) __P((DB_MPOOLFILE *, u_int32_t *));
+	int (*get_ftype) __P((DB_MPOOLFILE *, int *));
+	int (*get_last_pgno) __P((DB_MPOOLFILE *, db_pgno_t *));
+	int (*get_lsn_offset) __P((DB_MPOOLFILE *, int32_t *));
+	int (*get_maxsize) __P((DB_MPOOLFILE *, u_int32_t *, u_int32_t *));
+	int (*get_pgcookie) __P((DB_MPOOLFILE *, DBT *));
+	int (*get_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY *));
+	int (*open) __P((DB_MPOOLFILE *, const char *, u_int32_t, int, size_t));
+	int (*put) __P((DB_MPOOLFILE *, void *, DB_CACHE_PRIORITY, u_int32_t));
+	int (*set_clear_len) __P((DB_MPOOLFILE *, u_int32_t));
+	int (*set_fileid) __P((DB_MPOOLFILE *, u_int8_t *));
+	int (*set_flags) __P((DB_MPOOLFILE *, u_int32_t, int));
+	int (*set_ftype) __P((DB_MPOOLFILE *, int));
+	int (*set_lsn_offset) __P((DB_MPOOLFILE *, int32_t));
+	int (*set_maxsize) __P((DB_MPOOLFILE *, u_int32_t, u_int32_t));
+	int (*set_pgcookie) __P((DB_MPOOLFILE *, DBT *));
+	int (*set_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY));
+	int (*sync) __P((DB_MPOOLFILE *));
+	/* DB_MPOOLFILE PUBLIC HANDLE LIST END */
+
+	/*
+	 * MP_FILEID_SET, MP_OPEN_CALLED and MP_READONLY do not need to be
+	 * thread protected because they are initialized before the file is
+	 * linked onto the per-process lists, and never modified.
+	 *
+	 * MP_FLUSH is thread protected because it is potentially read/set by
+	 * multiple threads of control.
+	 */
+#define	MP_FILEID_SET	0x001		/* Application supplied a file ID. */
+#define	MP_FLUSH	0x002		/* Was used to flush a buffer. */
+#define	MP_FOR_FLUSH	0x004		/* Was opened to flush a buffer. */
+#define	MP_MULTIVERSION	0x008		/* Opened for multiversion access. */
+#define	MP_OPEN_CALLED	0x010		/* File opened. */
+#define	MP_READONLY	0x020		/* File is readonly. */
+#define	MP_DUMMY	0x040		/* File is dummy for __memp_fput. */
+	u_int32_t  flags;
+};
+
+/* Mpool statistics structure. */
+struct __db_mpool_stat { /* SHARED */
+	u_int32_t st_gbytes;		/* Total cache size: GB. */
+	u_int32_t st_bytes;		/* Total cache size: B. */
+	u_int32_t st_ncache;		/* Number of cache regions. */
+	u_int32_t st_max_ncache;	/* Maximum number of regions. */
+	db_size_t st_mmapsize;		/* Maximum file size for mmap. */
+	int32_t st_maxopenfd;		/* Maximum number of open fd's. */
+	int32_t st_maxwrite;		/* Maximum buffers to write. */
+	db_timeout_t st_maxwrite_sleep;	/* Sleep after writing max buffers. */
+	u_int32_t st_pages;		/* Total number of pages. */
+#ifndef __TEST_DB_NO_STATISTICS
+	u_int32_t st_map;		/* Pages from mapped files. */
+	uintmax_t st_cache_hit;	/* Pages found in the cache. */
+	uintmax_t st_cache_miss;	/* Pages not found in the cache. */
+	uintmax_t st_page_create;	/* Pages created in the cache. */
+	uintmax_t st_page_in;		/* Pages read in. */
+	uintmax_t st_page_out;		/* Pages written out. */
+	uintmax_t st_ro_evict;		/* Clean pages forced from the cache. */
+	uintmax_t st_rw_evict;		/* Dirty pages forced from the cache. */
+	uintmax_t st_page_trickle;	/* Pages written by memp_trickle. */
+	u_int32_t st_page_clean;	/* Clean pages. */
+	u_int32_t st_page_dirty;	/* Dirty pages. */
+	u_int32_t st_hash_buckets;	/* Number of hash buckets. */
+	u_int32_t st_hash_mutexes;	/* Number of hash bucket mutexes. */
+	u_int32_t st_pagesize;		/* Assumed page size. */
+	u_int32_t st_hash_searches;	/* Total hash chain searches. */
+	u_int32_t st_hash_longest;	/* Longest hash chain searched. */
+	uintmax_t st_hash_examined;	/* Total hash entries searched. */
+	uintmax_t st_hash_nowait;	/* Hash lock granted with nowait. */
+	uintmax_t st_hash_wait;		/* Hash lock granted after wait. */
+	uintmax_t st_hash_max_nowait;	/* Max hash lock granted with nowait. */
+	uintmax_t st_hash_max_wait;	/* Max hash lock granted after wait. */
+	uintmax_t st_region_nowait;	/* Region lock granted with nowait. */
+	uintmax_t st_region_wait;	/* Region lock granted after wait. */
+	uintmax_t st_mvcc_frozen;	/* Buffers frozen. */
+	uintmax_t st_mvcc_thawed;	/* Buffers thawed. */
+	uintmax_t st_mvcc_freed;	/* Frozen buffers freed. */
+	uintmax_t st_alloc;		/* Number of page allocations. */
+	uintmax_t st_alloc_buckets;	/* Buckets checked during allocation. */
+	uintmax_t st_alloc_max_buckets;/* Max checked during allocation. */
+	uintmax_t st_alloc_pages;	/* Pages checked during allocation. */
+	uintmax_t st_alloc_max_pages;	/* Max checked during allocation. */
+	uintmax_t st_io_wait;		/* Thread waited on buffer I/O. */
+	uintmax_t st_sync_interrupted;	/* Number of times sync interrupted. */
+	uintmax_t st_oddfsize_detect;	/* Odd file size detected. */
+	uintmax_t st_oddfsize_resolve;	/* Odd file size resolved. */
+	roff_t	  st_regsize;		/* Region size. */
+	roff_t	  st_regmax;		/* Region max. */
+#endif
+};
+
+/*
+ * Mpool file statistics structure.
+ * The first fields in this structure must mirror the __db_mpool_fstat_int
+ * structure, since content is mem copied between the two.
+ */
+struct __db_mpool_fstat {
+	u_int32_t st_pagesize;		/* Page size. */
+#ifndef __TEST_DB_NO_STATISTICS
+	u_int32_t st_map;		/* Pages from mapped files. */
+	uintmax_t st_cache_hit;	/* Pages found in the cache. */
+	uintmax_t st_cache_miss;	/* Pages not found in the cache. */
+	uintmax_t st_page_create;	/* Pages created in the cache. */
+	uintmax_t st_page_in;		/* Pages read in. */
+	uintmax_t st_page_out;		/* Pages written out. */
+	uintmax_t st_backup_spins;	/* Number of spins during a copy. */
+#endif
+	char *file_name;	/* File name. */
+};
+
+/*******************************************************
+ * Transactions and recovery.
+ *******************************************************/
+#define	DB_TXNVERSION	1
+
+typedef enum {
+	DB_TXN_ABORT=0,			/* Public. */
+	DB_TXN_APPLY=1,			/* Public. */
+	DB_TXN_BACKWARD_ROLL=3,		/* Public. */
+	DB_TXN_FORWARD_ROLL=4,		/* Public. */
+	DB_TXN_OPENFILES=5,		/* Internal. */
+	DB_TXN_POPENFILES=6,		/* Internal. */
+	DB_TXN_PRINT=7,			/* Public. */
+	DB_TXN_LOG_VERIFY=8		/* Internal. */
+} db_recops;
+
+/*
+ * BACKWARD_ALLOC is used during the forward pass to pick up any aborted
+ * allocations for files that were created during the forward pass.
+ * The main difference between _ALLOC and _ROLL is that the entry for
+ * the file not exist during the rollforward pass.
+ */
+#define	DB_UNDO(op)	((op) == DB_TXN_ABORT || (op) == DB_TXN_BACKWARD_ROLL)
+#define	DB_REDO(op)	((op) == DB_TXN_FORWARD_ROLL || (op) == DB_TXN_APPLY)
+
+struct __db_txn {
+	DB_TXNMGR	*mgrp;		/* Pointer to transaction manager. */
+	DB_TXN		*parent;	/* Pointer to transaction's parent. */
+	DB_LOCKER	*locker;	/* Locker for this txn. */
+	DB_THREAD_INFO	*thread_info;	/* Pointer to thread information. */
+
+	void		*td;		/* Detail structure within region. */
+	db_timeout_t	lock_timeout;	/* Timeout for locks for this txn. */
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_HEAD(__kids, __db_txn) kids;
+	 */
+	struct __kids {
+		struct __db_txn *tqh_first;
+		struct __db_txn **tqh_last;
+	} kids;
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_HEAD(__my_cursors, __dbc) my_cursors;
+	 */
+	struct __my_cursors {
+		struct __dbc *tqh_first;
+		struct __dbc **tqh_last;
+	} my_cursors;
+	u_int32_t	cursors;	/* Number of cursors open for txn */
+	u_int32_t	txnid;		/* Unique transaction id. */
+
+	void	*api_internal;		/* C++ API private. */
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_HEAD(__femfs, MPOOLFILE) femfs;
+	 *
+	 * These are DBs involved in file extension in this transaction.
+	 */
+	struct __femfs {
+		DB *tqh_first;
+		DB **tqh_last;
+	} femfs;
+
+	DB_TXN_TOKEN	*token_buffer;	/* User's commit token buffer. */
+	void	*xml_internal;		/* XML API private. */
+
+#define	TXN_XA_THREAD_NOTA		0
+#define	TXN_XA_THREAD_ASSOCIATED	1
+#define	TXN_XA_THREAD_SUSPENDED		2
+#define	TXN_XA_THREAD_UNASSOCIATED 	3
+	u_int32_t	xa_thr_status;
+
+#define	TXN_CHILDCOMMIT		0x00001	/* Txn has committed. */
+#define	TXN_COMPENSATE		0x00002	/* Compensating transaction. */
+#define	TXN_DEADLOCK		0x00004	/* Txn has deadlocked. */
+#define	TXN_FAMILY		0x00008	/* Cursors/children are independent. */
+#define	TXN_IGNORE_LEASE	0x00010	/* Skip lease check at commit time. */
+#define	TXN_INFAMILY		0x00020	/* Part of a transaction family. */
+#define	TXN_LOCKTIMEOUT		0x00040	/* Txn has a lock timeout. */
+#define	TXN_MALLOC		0x00080	/* Structure allocated by TXN system. */
+#define	TXN_NOSYNC		0x00100	/* Do not sync on prepare and commit. */
+#define	TXN_NOWAIT		0x00200	/* Do not wait on locks. */
+#define	TXN_PRIVATE		0x00400	/* Txn owned by cursor. */
+#define	TXN_READONLY		0x00800	/* CDS group handle. */
+#define	TXN_READ_COMMITTED	0x01000	/* Txn has degree 2 isolation. */
+#define	TXN_READ_UNCOMMITTED	0x02000	/* Txn has degree 1 isolation. */
+#define	TXN_RESTORED		0x04000	/* Txn has been restored. */
+#define	TXN_SNAPSHOT		0x08000	/* Snapshot Isolation. */
+#define	TXN_SYNC		0x10000	/* Write and sync on prepare/commit. */
+#define	TXN_WRITE_NOSYNC	0x20000	/* Write only on prepare/commit. */
+#define TXN_BULK		0x40000 /* Enable bulk loading optimization. */
+	u_int32_t	flags;
+};
+
+#define	TXN_SYNC_FLAGS (TXN_SYNC | TXN_NOSYNC | TXN_WRITE_NOSYNC)
+
+/*
+ * Structure used for two phase commit interface.
+ * We set the size of our global transaction id (gid) to be 128 in order
+ * to match that defined by the XA X/Open standard.
+ */
+#define	DB_GID_SIZE	128
+struct __db_preplist {
+	DB_TXN	*txn;
+	u_int8_t gid[DB_GID_SIZE];
+};
+
+/* Transaction statistics structure. */
+struct __db_txn_active {
+	u_int32_t txnid;		/* Transaction ID */
+	u_int32_t parentid;		/* Transaction ID of parent */
+	pid_t     pid;			/* Process owning txn ID */
+	db_threadid_t tid;		/* Thread owning txn ID */
+
+	DB_LSN	  lsn;			/* LSN when transaction began */
+
+	DB_LSN	  read_lsn;		/* Read LSN for MVCC */
+	u_int32_t mvcc_ref;		/* MVCC reference count */
+
+	u_int32_t priority;		/* Deadlock resolution priority */
+
+#define	TXN_ABORTED		1
+#define	TXN_COMMITTED		2
+#define	TXN_NEED_ABORT		3
+#define	TXN_PREPARED		4
+#define	TXN_RUNNING		5
+	u_int32_t status;		/* Status of the transaction */
+
+#define	TXN_XA_ACTIVE		1
+#define	TXN_XA_DEADLOCKED	2
+#define	TXN_XA_IDLE		3
+#define	TXN_XA_PREPARED		4
+#define	TXN_XA_ROLLEDBACK	5
+	u_int32_t xa_status;		/* XA status */
+
+	u_int8_t  gid[DB_GID_SIZE];	/* Global transaction ID */
+	char	  name[51];		/* 50 bytes of name, nul termination */
+};
+
+struct __db_txn_stat {
+	u_int32_t st_nrestores;		/* number of restored transactions
+					   after recovery. */
+#ifndef __TEST_DB_NO_STATISTICS
+	DB_LSN	  st_last_ckp;		/* lsn of the last checkpoint */
+	time_t	  st_time_ckp;		/* time of last checkpoint */
+	u_int32_t st_last_txnid;	/* last transaction id given out */
+	u_int32_t st_inittxns;		/* inital txns allocated */
+	u_int32_t st_maxtxns;		/* maximum txns possible */
+	uintmax_t st_naborts;		/* number of aborted transactions */
+	uintmax_t st_nbegins;		/* number of begun transactions */
+	uintmax_t st_ncommits;		/* number of committed transactions */
+	u_int32_t st_nactive;		/* number of active transactions */
+	u_int32_t st_nsnapshot;		/* number of snapshot transactions */
+	u_int32_t st_maxnactive;	/* maximum active transactions */
+	u_int32_t st_maxnsnapshot;	/* maximum snapshot transactions */
+	uintmax_t st_region_wait;	/* Region lock granted after wait. */
+	uintmax_t st_region_nowait;	/* Region lock granted without wait. */
+	roff_t	  st_regsize;		/* Region size. */
+	DB_TXN_ACTIVE *st_txnarray;	/* array of active transactions */
+#endif
+};
+
+#define	DB_TXN_TOKEN_SIZE		20
+struct __db_txn_token {
+	u_int8_t buf[DB_TXN_TOKEN_SIZE];
+};
+
+/*******************************************************
+ * Replication.
+ *******************************************************/
+/* Special, out-of-band environment IDs. */
+#define	DB_EID_BROADCAST	-1
+#define	DB_EID_INVALID		-2
+#define	DB_EID_MASTER		-3
+
+#define	DB_REP_DEFAULT_PRIORITY		100
+
+/* Acknowledgement policies; 0 reserved as OOB. */
+#define	DB_REPMGR_ACKS_ALL		1
+#define	DB_REPMGR_ACKS_ALL_AVAILABLE	2
+#define	DB_REPMGR_ACKS_ALL_PEERS	3
+#define	DB_REPMGR_ACKS_NONE		4
+#define	DB_REPMGR_ACKS_ONE		5
+#define	DB_REPMGR_ACKS_ONE_PEER		6
+#define	DB_REPMGR_ACKS_QUORUM		7
+
+/* Replication timeout configuration values. */
+#define	DB_REP_ACK_TIMEOUT		1	/* RepMgr acknowledgements. */
+#define	DB_REP_CHECKPOINT_DELAY		2	/* Master checkpoint delay. */
+#define	DB_REP_CONNECTION_RETRY		3	/* RepMgr connections. */
+#define	DB_REP_ELECTION_RETRY		4	/* RepMgr elect retries. */
+#define	DB_REP_ELECTION_TIMEOUT		5	/* Rep normal elections. */
+#define	DB_REP_FULL_ELECTION_TIMEOUT	6	/* Rep full elections. */
+#define	DB_REP_HEARTBEAT_MONITOR	7	/* RepMgr client HB monitor. */
+#define	DB_REP_HEARTBEAT_SEND		8	/* RepMgr master send freq. */
+#define	DB_REP_LEASE_TIMEOUT		9	/* Master leases. */
+
+/*
+ * Event notification types.  (Tcl testing interface currently assumes there are
+ * no more than 32 of these.)
+ */
+#define	DB_EVENT_PANIC			 0
+#define	DB_EVENT_REG_ALIVE		 1
+#define	DB_EVENT_REG_PANIC		 2
+#define	DB_EVENT_REP_CLIENT		 3
+#define	DB_EVENT_REP_CONNECT_BROKEN	 4
+#define	DB_EVENT_REP_CONNECT_ESTD	 5
+#define	DB_EVENT_REP_CONNECT_TRY_FAILED	 6
+#define	DB_EVENT_REP_DUPMASTER		 7
+#define	DB_EVENT_REP_ELECTED		 8
+#define	DB_EVENT_REP_ELECTION_FAILED	 9
+#define	DB_EVENT_REP_INIT_DONE		10
+#define	DB_EVENT_REP_JOIN_FAILURE	11
+#define	DB_EVENT_REP_LOCAL_SITE_REMOVED	12
+#define	DB_EVENT_REP_MASTER		13
+#define	DB_EVENT_REP_MASTER_FAILURE	14
+#define	DB_EVENT_REP_NEWMASTER		15
+#define	DB_EVENT_REP_PERM_FAILED	16
+#define	DB_EVENT_REP_SITE_ADDED		17
+#define	DB_EVENT_REP_SITE_REMOVED	18
+#define	DB_EVENT_REP_STARTUPDONE	19
+#define	DB_EVENT_REP_WOULD_ROLLBACK	20	/* Undocumented; C API only. */
+#define	DB_EVENT_WRITE_FAILED		21
+#define	DB_EVENT_NO_SUCH_EVENT		 0xffffffff /* OOB sentinel value */
+
+/* Replication Manager site status. */
+struct __db_repmgr_site {
+	int eid;
+	char *host;
+	u_int port;
+
+#define	DB_REPMGR_CONNECTED	1
+#define	DB_REPMGR_DISCONNECTED	2
+	u_int32_t status;
+
+#define	DB_REPMGR_ISPEER	0x01
+	u_int32_t flags;
+};
+
+/* Replication statistics. */
+struct __db_rep_stat { /* SHARED */
+	/* !!!
+	 * Many replication statistics fields cannot be protected by a mutex
+	 * without an unacceptable performance penalty, since most message
+	 * processing is done without the need to hold a region-wide lock.
+	 * Fields whose comments end with a '+' may be updated without holding
+	 * the replication or log mutexes (as appropriate), and thus may be
+	 * off somewhat (or, on unreasonable architectures under unlucky
+	 * circumstances, garbaged).
+	 */
+	u_int32_t st_startup_complete;	/* Site completed client sync-up. */
+#ifndef __TEST_DB_NO_STATISTICS
+	uintmax_t st_log_queued;	/* Log records currently queued.+ */
+	u_int32_t st_status;		/* Current replication status. */
+	DB_LSN st_next_lsn;		/* Next LSN to use or expect. */
+	DB_LSN st_waiting_lsn;		/* LSN we're awaiting, if any. */
+	DB_LSN st_max_perm_lsn;		/* Maximum permanent LSN. */
+	db_pgno_t st_next_pg;		/* Next pg we expect. */
+	db_pgno_t st_waiting_pg;	/* pg we're awaiting, if any. */
+
+	u_int32_t st_dupmasters;	/* # of times a duplicate master
+					   condition was detected.+ */
+	db_ssize_t st_env_id;		/* Current environment ID. */
+	u_int32_t st_env_priority;	/* Current environment priority. */
+	uintmax_t st_bulk_fills;	/* Bulk buffer fills. */
+	uintmax_t st_bulk_overflows;	/* Bulk buffer overflows. */
+	uintmax_t st_bulk_records;	/* Bulk records stored. */
+	uintmax_t st_bulk_transfers;	/* Transfers of bulk buffers. */
+	uintmax_t st_client_rerequests;/* Number of forced rerequests. */
+	uintmax_t st_client_svc_req;	/* Number of client service requests
+					   received by this client. */
+	uintmax_t st_client_svc_miss;	/* Number of client service requests
+					   missing on this client. */
+	u_int32_t st_gen;		/* Current generation number. */
+	u_int32_t st_egen;		/* Current election gen number. */
+	uintmax_t st_lease_chk;		/* Lease validity checks. */
+	uintmax_t st_lease_chk_misses;	/* Lease checks invalid. */
+	uintmax_t st_lease_chk_refresh;	/* Lease refresh attempts. */
+	uintmax_t st_lease_sends;	/* Lease messages sent live. */
+
+	uintmax_t st_log_duplicated;	/* Log records received multiply.+ */
+	uintmax_t st_log_queued_max;	/* Max. log records queued at once.+ */
+	uintmax_t st_log_queued_total;	/* Total # of log recs. ever queued.+ */
+	uintmax_t st_log_records;	/* Log records received and put.+ */
+	uintmax_t st_log_requested;	/* Log recs. missed and requested.+ */
+	db_ssize_t st_master;		/* Env. ID of the current master. */
+	uintmax_t st_master_changes;	/* # of times we've switched masters. */
+	uintmax_t st_msgs_badgen;	/* Messages with a bad generation #.+ */
+	uintmax_t st_msgs_processed;	/* Messages received and processed.+ */
+	uintmax_t st_msgs_recover;	/* Messages ignored because this site
+					   was a client in recovery.+ */
+	uintmax_t st_msgs_send_failures;/* # of failed message sends.+ */
+	uintmax_t st_msgs_sent;	/* # of successful message sends.+ */
+	uintmax_t st_newsites;		/* # of NEWSITE msgs. received.+ */
+	u_int32_t st_nsites;		/* Current number of sites we will
+					   assume during elections. */
+	uintmax_t st_nthrottles;	/* # of times we were throttled. */
+	uintmax_t st_outdated;		/* # of times we detected and returned
+					   an OUTDATED condition.+ */
+	uintmax_t st_pg_duplicated;	/* Pages received multiply.+ */
+	uintmax_t st_pg_records;	/* Pages received and stored.+ */
+	uintmax_t st_pg_requested;	/* Pages missed and requested.+ */
+	uintmax_t st_txns_applied;	/* # of transactions applied.+ */
+	uintmax_t st_startsync_delayed;/* # of STARTSYNC msgs delayed.+ */
+
+	/* Elections generally. */
+	uintmax_t st_elections;	/* # of elections held.+ */
+	uintmax_t st_elections_won;	/* # of elections won by this site.+ */
+
+	/* Statistics about an in-progress election. */
+	db_ssize_t st_election_cur_winner;	/* Current front-runner. */
+	u_int32_t st_election_gen;	/* Election generation number. */
+	u_int32_t st_election_datagen;	/* Election data generation number. */
+	DB_LSN st_election_lsn;		/* Max. LSN of current winner. */
+	u_int32_t st_election_nsites;	/* # of "registered voters". */
+	u_int32_t st_election_nvotes;	/* # of "registered voters" needed. */
+	u_int32_t st_election_priority;	/* Current election priority. */
+	int32_t   st_election_status;	/* Current election status. */
+	u_int32_t st_election_tiebreaker;/* Election tiebreaker value. */
+	u_int32_t st_election_votes;	/* Votes received in this round. */
+	u_int32_t st_election_sec;	/* Last election time seconds. */
+	u_int32_t st_election_usec;	/* Last election time useconds. */
+	u_int32_t st_max_lease_sec;	/* Maximum lease timestamp seconds. */
+	u_int32_t st_max_lease_usec;	/* Maximum lease timestamp useconds. */
+
+	/* Undocumented statistics only used by the test system. */
+#ifdef	CONFIG_TEST
+	u_int32_t st_filefail_cleanups;	/* # of FILE_FAIL cleanups done. */
+#endif
+#endif
+};
+
+/* Replication Manager statistics. */
+struct __db_repmgr_stat { /* SHARED */
+	uintmax_t st_perm_failed;	/* # of insufficiently ack'ed msgs. */
+	uintmax_t st_msgs_queued;	/* # msgs queued for network delay. */
+	uintmax_t st_msgs_dropped;	/* # msgs discarded due to excessive
+					   queue length. */
+	uintmax_t st_connection_drop;	/* Existing connections dropped. */
+	uintmax_t st_connect_fail;	/* Failed new connection attempts. */
+	uintmax_t st_elect_threads;	/* # of active election threads. */
+	uintmax_t st_max_elect_threads;	/* Max concurrent e-threads ever. */
+};
+
+/* Replication Manager connection error. */
+struct __db_repmgr_conn_err {
+	int		eid;		/* Replication Environment ID. */
+	int		error;		/* System networking error code. */
+};
+
+/*******************************************************
+ * Sequences.
+ *******************************************************/
+/*
+ * The storage record for a sequence.
+ */
+struct __db_seq_record {
+	u_int32_t	seq_version;	/* Version size/number. */
+	u_int32_t	flags;		/* DB_SEQ_XXX Flags. */
+	db_seq_t	seq_value;	/* Current value. */
+	db_seq_t	seq_max;	/* Max permitted. */
+	db_seq_t	seq_min;	/* Min permitted. */
+};
+
+/*
+ * Handle for a sequence object.
+ */
+struct __db_sequence {
+	DB		*seq_dbp;	/* DB handle for this sequence. */
+	db_mutex_t	mtx_seq;	/* Mutex if sequence is threaded. */
+	DB_SEQ_RECORD	*seq_rp;	/* Pointer to current data. */
+	DB_SEQ_RECORD	seq_record;	/* Data from DB_SEQUENCE. */
+	int32_t		seq_cache_size; /* Number of values cached. */
+	db_seq_t	seq_last_value;	/* Last value cached. */
+	db_seq_t	seq_prev_value;	/* Last value returned. */
+	DBT		seq_key;	/* DBT pointing to sequence key. */
+	DBT		seq_data;	/* DBT pointing to seq_record. */
+
+	/* API-private structure: used by C++ and Java. */
+	void		*api_internal;
+
+	/* DB_SEQUENCE PUBLIC HANDLE LIST BEGIN */
+	int		(*close) __P((DB_SEQUENCE *, u_int32_t));
+	int		(*get) __P((DB_SEQUENCE *,
+			      DB_TXN *, int32_t, db_seq_t *, u_int32_t));
+	int		(*get_cachesize) __P((DB_SEQUENCE *, int32_t *));
+	int		(*get_db) __P((DB_SEQUENCE *, DB **));
+	int		(*get_flags) __P((DB_SEQUENCE *, u_int32_t *));
+	int		(*get_key) __P((DB_SEQUENCE *, DBT *));
+	int		(*get_range) __P((DB_SEQUENCE *,
+			     db_seq_t *, db_seq_t *));
+	int		(*initial_value) __P((DB_SEQUENCE *, db_seq_t));
+	int		(*open) __P((DB_SEQUENCE *,
+			    DB_TXN *, DBT *, u_int32_t));
+	int		(*remove) __P((DB_SEQUENCE *, DB_TXN *, u_int32_t));
+	int		(*set_cachesize) __P((DB_SEQUENCE *, int32_t));
+	int		(*set_flags) __P((DB_SEQUENCE *, u_int32_t));
+	int		(*set_range) __P((DB_SEQUENCE *, db_seq_t, db_seq_t));
+	int		(*stat) __P((DB_SEQUENCE *,
+			    DB_SEQUENCE_STAT **, u_int32_t));
+	int		(*stat_print) __P((DB_SEQUENCE *, u_int32_t));
+	/* DB_SEQUENCE PUBLIC HANDLE LIST END */
+};
+
+struct __db_seq_stat { /* SHARED */
+	uintmax_t st_wait;		/* Sequence lock granted w/o wait. */
+	uintmax_t st_nowait;		/* Sequence lock granted after wait. */
+	db_seq_t  st_current;		/* Current value in db. */
+	db_seq_t  st_value;		/* Current cached value. */
+	db_seq_t  st_last_value;	/* Last cached value. */
+	db_seq_t  st_min;		/* Minimum value. */
+	db_seq_t  st_max;		/* Maximum value. */
+	int32_t   st_cache_size;	/* Cache size. */
+	u_int32_t st_flags;		/* Flag value. */
+};
+
+/*******************************************************
+ * Access methods.
+ *******************************************************/
+/*
+ * Any new methods need to retain the original numbering.  The type
+ * is written in a log record so must be maintained.
+ */
+typedef enum {
+	DB_BTREE=1,
+	DB_HASH=2,
+	DB_HEAP=6,
+	DB_RECNO=3,
+	DB_QUEUE=4,
+	DB_UNKNOWN=5			/* Figure it out on open. */
+} DBTYPE;
+
+#define	DB_RENAMEMAGIC	0x030800	/* File has been renamed. */
+
+#define	DB_BTREEVERSION	9		/* Current btree version. */
+#define	DB_BTREEOLDVER	8		/* Oldest btree version supported. */
+#define	DB_BTREEMAGIC	0x053162
+
+#define	DB_HASHVERSION	9		/* Current hash version. */
+#define	DB_HASHOLDVER	7		/* Oldest hash version supported. */
+#define	DB_HASHMAGIC	0x061561
+
+#define	DB_HEAPVERSION	1		/* Current heap version. */
+#define	DB_HEAPOLDVER	1		/* Oldest heap version supported. */
+#define	DB_HEAPMAGIC	0x074582
+
+#define	DB_QAMVERSION	4		/* Current queue version. */
+#define	DB_QAMOLDVER	3		/* Oldest queue version supported. */
+#define	DB_QAMMAGIC	0x042253
+
+#define	DB_SEQUENCE_VERSION 2		/* Current sequence version. */
+#define	DB_SEQUENCE_OLDVER  1		/* Oldest sequence version supported. */
+
+/*
+ * DB access method and cursor operation values.  Each value is an operation
+ * code to which additional bit flags are added.
+ */
+#define	DB_AFTER		 1	/* Dbc.put */
+#define	DB_APPEND		 2	/* Db.put */
+#define	DB_BEFORE		 3	/* Dbc.put */
+#define	DB_CONSUME		 4	/* Db.get */
+#define	DB_CONSUME_WAIT		 5	/* Db.get */
+#define	DB_CURRENT		 6	/* Dbc.get, Dbc.put, DbLogc.get */
+#define	DB_FIRST		 7	/* Dbc.get, DbLogc->get */
+#define	DB_GET_BOTH		 8	/* Db.get, Dbc.get */
+#define	DB_GET_BOTHC		 9	/* Dbc.get (internal) */
+#define	DB_GET_BOTH_RANGE	10	/* Db.get, Dbc.get */
+#define	DB_GET_RECNO		11	/* Dbc.get */
+#define	DB_JOIN_ITEM		12	/* Dbc.get; don't do primary lookup */
+#define	DB_KEYFIRST		13	/* Dbc.put */
+#define	DB_KEYLAST		14	/* Dbc.put */
+#define	DB_LAST			15	/* Dbc.get, DbLogc->get */
+#define	DB_NEXT			16	/* Dbc.get, DbLogc->get */
+#define	DB_NEXT_DUP		17	/* Dbc.get */
+#define	DB_NEXT_NODUP		18	/* Dbc.get */
+#define	DB_NODUPDATA		19	/* Db.put, Dbc.put */
+#define	DB_NOOVERWRITE		20	/* Db.put */
+#define	DB_OVERWRITE_DUP	21	/* Dbc.put, Db.put; no DB_KEYEXIST */
+#define	DB_POSITION		22	/* Dbc.dup */
+#define	DB_PREV			23	/* Dbc.get, DbLogc->get */
+#define	DB_PREV_DUP		24	/* Dbc.get */
+#define	DB_PREV_NODUP		25	/* Dbc.get */
+#define	DB_SET			26	/* Dbc.get, DbLogc->get */
+#define	DB_SET_RANGE		27	/* Dbc.get */
+#define	DB_SET_RECNO		28	/* Db.get, Dbc.get */
+#define	DB_UPDATE_SECONDARY	29	/* Dbc.get, Dbc.del (internal) */
+#define	DB_SET_LTE		30	/* Dbc.get (internal) */
+#define	DB_GET_BOTH_LTE		31	/* Dbc.get (internal) */
+
+/* This has to change when the max opcode hits 255. */
+#define	DB_OPFLAGS_MASK	0x000000ff	/* Mask for operations flags. */
+
+/*
+ * DB (user visible) error return codes.
+ *
+ * !!!
+ * We don't want our error returns to conflict with other packages where
+ * possible, so pick a base error value that's hopefully not common.  We
+ * document that we own the error name space from -30,800 to -30,999.
+ */
+/* DB (public) error return codes. */
+#define	DB_BUFFER_SMALL		(-30999)/* User memory too small for return. */
+#define	DB_DONOTINDEX		(-30998)/* "Null" return from 2ndary callbk. */
+#define	DB_FOREIGN_CONFLICT	(-30997)/* A foreign db constraint triggered. */
+#define	DB_HEAP_FULL		(-30996)/* No free space in a heap file. */
+#define	DB_KEYEMPTY		(-30995)/* Key/data deleted or never created. */
+#define	DB_KEYEXIST		(-30994)/* The key/data pair already exists. */
+#define	DB_LOCK_DEADLOCK	(-30993)/* Deadlock. */
+#define	DB_LOCK_NOTGRANTED	(-30992)/* Lock unavailable. */
+#define	DB_LOG_BUFFER_FULL	(-30991)/* In-memory log buffer full. */
+#define	DB_LOG_VERIFY_BAD	(-30990)/* Log verification failed. */
+#define	DB_NOSERVER		(-30989)/* Server panic return. */
+#define	DB_NOTFOUND		(-30988)/* Key/data pair not found (EOF). */
+#define	DB_OLD_VERSION		(-30987)/* Out-of-date version. */
+#define	DB_PAGE_NOTFOUND	(-30986)/* Requested page not found. */
+#define	DB_REP_DUPMASTER	(-30985)/* There are two masters. */
+#define	DB_REP_HANDLE_DEAD	(-30984)/* Rolled back a commit. */
+#define	DB_REP_HOLDELECTION	(-30983)/* Time to hold an election. */
+#define	DB_REP_IGNORE		(-30982)/* This msg should be ignored.*/
+#define	DB_REP_ISPERM		(-30981)/* Cached not written perm written.*/
+#define	DB_REP_JOIN_FAILURE	(-30980)/* Unable to join replication group. */
+#define	DB_REP_LEASE_EXPIRED	(-30979)/* Master lease has expired. */
+#define	DB_REP_LOCKOUT		(-30978)/* API/Replication lockout now. */
+#define	DB_REP_NEWSITE		(-30977)/* New site entered system. */
+#define	DB_REP_NOTPERM		(-30976)/* Permanent log record not written. */
+#define	DB_REP_UNAVAIL		(-30975)/* Site cannot currently be reached. */
+#define	DB_REP_WOULDROLLBACK	(-30974)/* UNDOC: rollback inhibited by app. */
+#define	DB_RUNRECOVERY		(-30973)/* Panic return. */
+#define	DB_SECONDARY_BAD	(-30972)/* Secondary index corrupt. */
+#define	DB_TIMEOUT		(-30971)/* Timed out on read consistency. */
+#define	DB_VERIFY_BAD		(-30970)/* Verify failed; bad format. */
+#define	DB_VERSION_MISMATCH	(-30969)/* Environment version mismatch. */
+
+/* DB (private) error return codes. */
+#define	DB_ALREADY_ABORTED	(-30899)
+#define	DB_CHKSUM_FAIL		(-30898)/* Checksum failed. */
+#define	DB_DELETED		(-30897)/* Recovery file marked deleted. */
+#define	DB_EVENT_NOT_HANDLED	(-30896)/* Forward event to application. */
+#define	DB_NEEDSPLIT		(-30895)/* Page needs to be split. */
+#define	DB_REP_BULKOVF		(-30894)/* Rep bulk buffer overflow. */
+#define	DB_REP_LOGREADY		(-30893)/* Rep log ready for recovery. */
+#define	DB_REP_NEWMASTER	(-30892)/* We have learned of a new master. */
+#define	DB_REP_PAGEDONE		(-30891)/* This page was already done. */
+#define	DB_SURPRISE_KID		(-30890)/* Child commit where parent
+					   didn't know it was a parent. */
+#define	DB_SWAPBYTES		(-30889)/* Database needs byte swapping. */
+#define	DB_TXN_CKP		(-30888)/* Encountered ckp record in log. */
+#define	DB_VERIFY_FATAL		(-30887)/* DB->verify cannot proceed. */
+
+/* Database handle. */
+struct __db {
+	/*******************************************************
+	 * Public: owned by the application.
+	 *******************************************************/
+	u_int32_t pgsize;		/* Database logical page size. */
+	DB_CACHE_PRIORITY priority;	/* Database priority in cache. */
+
+					/* Callbacks. */
+	int (*db_append_recno) __P((DB *, DBT *, db_recno_t));
+	void (*db_feedback) __P((DB *, int, int));
+	int (*dup_compare) __P((DB *, const DBT *, const DBT *));
+
+	void	*app_private;		/* Application-private handle. */
+
+	/*******************************************************
+	 * Private: owned by DB.
+	 *******************************************************/
+	DB_ENV	*dbenv;			/* Backing public environment. */
+	ENV	*env;			/* Backing private environment. */
+
+	DBTYPE	 type;			/* DB access method type. */
+
+	DB_MPOOLFILE *mpf;		/* Backing buffer pool. */
+
+	db_mutex_t mutex;		/* Synchronization for free threading */
+
+	char *fname, *dname;		/* File/database passed to DB->open. */
+	const char *dirname;		/* Directory of DB file. */
+	u_int32_t open_flags;		/* Flags passed to DB->open. */
+
+	u_int8_t fileid[DB_FILE_ID_LEN];/* File's unique ID for locking. */
+
+	u_int32_t adj_fileid;		/* File's unique ID for curs. adj. */
+
+#define	DB_LOGFILEID_INVALID	-1
+	FNAME *log_filename;		/* File's naming info for logging. */
+
+	db_pgno_t meta_pgno;		/* Meta page number */
+	DB_LOCKER *locker;		/* Locker for handle locking. */
+	DB_LOCKER *cur_locker;		/* Current handle lock holder. */
+	DB_TXN *cur_txn;		/* Opening transaction. */
+	DB_LOCKER *associate_locker;	/* Locker for DB->associate call. */
+	DB_LOCK	 handle_lock;		/* Lock held on this handle. */
+
+	time_t	 timestamp;		/* Handle timestamp for replication. */
+	u_int32_t fid_gen;		/* Rep generation number for fids. */
+
+	/*
+	 * Returned data memory for DB->get() and friends.
+	 */
+	DBT	 my_rskey;		/* Secondary key. */
+	DBT	 my_rkey;		/* [Primary] key. */
+	DBT	 my_rdata;		/* Data. */
+
+	/*
+	 * !!!
+	 * Some applications use DB but implement their own locking outside of
+	 * DB.  If they're using fcntl(2) locking on the underlying database
+	 * file, and we open and close a file descriptor for that file, we will
+	 * discard their locks.  The DB_FCNTL_LOCKING flag to DB->open is an
+	 * undocumented interface to support this usage which leaves any file
+	 * descriptors we open until DB->close.  This will only work with the
+	 * DB->open interface and simple caches, e.g., creating a transaction
+	 * thread may open/close file descriptors this flag doesn't protect.
+	 * Locking with fcntl(2) on a file that you don't own is a very, very
+	 * unsafe thing to do.  'Nuff said.
+	 */
+	DB_FH	*saved_open_fhp;	/* Saved file handle. */
+
+	/*
+	 * Linked list of DBP's, linked from the ENV, used to keep track
+	 * of all open db handles for cursor adjustment.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__db) dblistlinks;
+	 */
+	struct {
+		struct __db *tqe_next;
+		struct __db **tqe_prev;
+	} dblistlinks;
+
+	/*
+	 * Cursor queues.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_HEAD(__cq_fq, __dbc) free_queue;
+	 * TAILQ_HEAD(__cq_aq, __dbc) active_queue;
+	 * TAILQ_HEAD(__cq_jq, __dbc) join_queue;
+	 */
+	struct __cq_fq {
+		struct __dbc *tqh_first;
+		struct __dbc **tqh_last;
+	} free_queue;
+	struct __cq_aq {
+		struct __dbc *tqh_first;
+		struct __dbc **tqh_last;
+	} active_queue;
+	struct __cq_jq {
+		struct __dbc *tqh_first;
+		struct __dbc **tqh_last;
+	} join_queue;
+
+	/*
+	 * Secondary index support.
+	 *
+	 * Linked list of secondary indices -- set in the primary.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * LIST_HEAD(s_secondaries, __db);
+	 */
+	struct {
+		struct __db *lh_first;
+	} s_secondaries;
+
+	/*
+	 * List entries for secondaries, and reference count of how many
+	 * threads are updating this secondary (see Dbc.put).
+	 *
+	 * !!!
+	 * Note that these are synchronized by the primary's mutex, but
+	 * filled in in the secondaries.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * LIST_ENTRY(__db) s_links;
+	 */
+	struct {
+		struct __db *le_next;
+		struct __db **le_prev;
+	} s_links;
+	u_int32_t s_refcnt;
+
+	/* Secondary callback and free functions -- set in the secondary. */
+	int	(*s_callback) __P((DB *, const DBT *, const DBT *, DBT *));
+
+	/* Reference to primary -- set in the secondary. */
+	DB	*s_primary;
+
+#define	DB_ASSOC_IMMUTABLE_KEY    0x00000001 /* Secondary key is immutable. */
+#define	DB_ASSOC_CREATE    0x00000002 /* Secondary db populated on open. */
+
+	/* Flags passed to associate -- set in the secondary. */
+	u_int32_t s_assoc_flags;
+
+	/*
+	 * Foreign key support.
+	 *
+	 * Linked list of primary dbs -- set in the foreign db
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * LIST_HEAD(f_primaries, __db);
+	 */
+	struct {
+		struct __db_foreign_info *lh_first;
+	} f_primaries;
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__db) felink;
+	 *
+	 * Links in a list of DBs involved in file extension
+	 * during a transaction.  These are to be used only while the
+	 * metadata is locked.
+	 */
+	struct {
+		struct __db *tqe_next;
+		struct __db **tqe_prev;
+	} felink;
+
+	/* Reference to foreign -- set in the secondary. */
+	DB      *s_foreign;
+
+	/* API-private structure: used by DB 1.85, C++, Java, Perl and Tcl */
+	void	*api_internal;
+
+	/* Subsystem-private structure. */
+	void	*bt_internal;		/* Btree/Recno access method. */
+	void	*h_internal;		/* Hash access method. */
+	void	*heap_internal;		/* Heap access method. */
+	void	*p_internal;		/* Partition informaiton. */
+	void	*q_internal;		/* Queue access method. */
+
+	/* DB PUBLIC HANDLE LIST BEGIN */
+	int  (*associate) __P((DB *, DB_TXN *, DB *,
+		int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t));
+	int  (*associate_foreign) __P((DB *, DB *,
+		int (*)(DB *, const DBT *, DBT *, const DBT *, int *),
+		u_int32_t));
+	int  (*close) __P((DB *, u_int32_t));
+	int  (*cursor) __P((DB *, DB_TXN *, DBC **, u_int32_t));
+	int  (*del) __P((DB *, DB_TXN *, DBT *, u_int32_t));
+	void (*err) __P((DB *, int, const char *, ...));
+	void (*errx) __P((DB *, const char *, ...));
+	int  (*exists) __P((DB *, DB_TXN *, DBT *, u_int32_t));
+	int  (*fd) __P((DB *, int *));
+	int  (*get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
+	int  (*get_alloc) __P((DB *, void *(**)(size_t),
+		void *(**)(void *, size_t), void (**)(void *)));
+	int  (*get_append_recno) __P((DB *, int (**)(DB *, DBT *, db_recno_t)));
+	int  (*get_assoc_flags) __P((DB *, u_int32_t *));
+	int  (*get_bt_compare)
+		__P((DB *, int (**)(DB *, const DBT *, const DBT *)));
+	int  (*get_bt_minkey) __P((DB *, u_int32_t *));
+	int  (*get_bt_prefix)
+		__P((DB *, size_t (**)(DB *, const DBT *, const DBT *)));
+	int  (*get_byteswapped) __P((DB *, int *));
+	int  (*get_cachesize) __P((DB *, u_int32_t *, u_int32_t *, int *));
+	int  (*get_create_dir) __P((DB *, const char **));
+	int  (*get_dbname) __P((DB *, const char **, const char **));
+	int  (*get_dup_compare)
+		__P((DB *, int (**)(DB *, const DBT *, const DBT *)));
+	DB_ENV *(*get_env) __P((DB *));
+	void (*get_errcall) __P((DB *,
+		void (**)(const DB_ENV *, const char *, const char *)));
+	void (*get_errfile) __P((DB *, FILE **));
+	void (*get_errpfx) __P((DB *, const char **));
+	int  (*get_feedback) __P((DB *, void (**)(DB *, int, int)));
+	int  (*get_flags) __P((DB *, u_int32_t *));
+	int  (*get_lorder) __P((DB *, int *));
+	DB_MPOOLFILE *(*get_mpf) __P((DB *));
+	void (*get_msgcall) __P((DB *,
+	    void (**)(const DB_ENV *, const char *)));
+	void (*get_msgfile) __P((DB *, FILE **));
+	int  (*get_multiple) __P((DB *));
+	int  (*get_open_flags) __P((DB *, u_int32_t *));
+	int  (*get_pagesize) __P((DB *, u_int32_t *));
+	int  (*get_priority) __P((DB *, DB_CACHE_PRIORITY *));
+	int  (*get_re_delim) __P((DB *, int *));
+	int  (*get_re_len) __P((DB *, u_int32_t *));
+	int  (*get_re_pad) __P((DB *, int *));
+	int  (*get_re_source) __P((DB *, const char **));
+	int  (*get_transactional) __P((DB *));
+	int  (*get_type) __P((DB *, DBTYPE *));
+	int  (*key_range)
+		__P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t));
+	int  (*open) __P((DB *,
+		DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int));
+	int  (*pget) __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t));
+	int  (*put) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
+	int  (*remove) __P((DB *, const char *, const char *, u_int32_t));
+	int  (*rename) __P((DB *,
+		const char *, const char *, const char *, u_int32_t));
+	int  (*set_alloc) __P((DB *, void *(*)(size_t),
+		void *(*)(void *, size_t), void (*)(void *)));
+	int  (*set_append_recno) __P((DB *, int (*)(DB *, DBT *, db_recno_t)));
+	int  (*set_bt_compare)
+		__P((DB *, int (*)(DB *, const DBT *, const DBT *)));
+	int  (*set_bt_minkey) __P((DB *, u_int32_t));
+	int  (*set_bt_prefix)
+		__P((DB *, size_t (*)(DB *, const DBT *, const DBT *)));
+	int  (*set_cachesize) __P((DB *, u_int32_t, u_int32_t, int));
+	int  (*set_create_dir) __P((DB *, const char *));
+	int  (*set_dup_compare)
+		__P((DB *, int (*)(DB *, const DBT *, const DBT *)));
+	int  (*set_encrypt) __P((DB *, const char *, u_int32_t));
+	void (*set_errcall) __P((DB *,
+		void (*)(const DB_ENV *, const char *, const char *)));
+	void (*set_errfile) __P((DB *, FILE *));
+	void (*set_errpfx) __P((DB *, const char *));
+	int  (*set_feedback) __P((DB *, void (*)(DB *, int, int)));
+	int  (*set_flags) __P((DB *, u_int32_t));
+	int  (*set_lorder) __P((DB *, int));
+	void (*set_msgcall) __P((DB *, void (*)(const DB_ENV *, const char *)));
+	void (*set_msgfile) __P((DB *, FILE *));
+	int  (*set_pagesize) __P((DB *, u_int32_t));
+	int  (*set_paniccall) __P((DB *, void (*)(DB_ENV *, int)));
+	int  (*set_partition) __P((DB *,
+		u_int32_t, DBT *, u_int32_t (*)(DB *, DBT *key)));
+	int  (*set_partition_dirs) __P((DB *, const char **));
+	int  (*set_priority) __P((DB *, DB_CACHE_PRIORITY));
+	int  (*set_re_delim) __P((DB *, int));
+	int  (*set_re_len) __P((DB *, u_int32_t));
+	int  (*set_re_pad) __P((DB *, int));
+	int  (*set_re_source) __P((DB *, const char *));
+	int  (*sort_multiple) __P((DB *, DBT *, DBT *, u_int32_t));
+	int  (*stat) __P((DB *, DB_TXN *, void *, u_int32_t));
+	int  (*stat_print) __P((DB *, u_int32_t));
+	int  (*sync) __P((DB *, u_int32_t));
+	int  (*truncate) __P((DB *, DB_TXN *, u_int32_t *, u_int32_t));
+	int  (*verify)
+		__P((DB *, const char *, const char *, FILE *, u_int32_t));
+	/* DB PUBLIC HANDLE LIST END */
+
+	/* DB PRIVATE HANDLE LIST BEGIN */
+	int  (*dump) __P((DB *, const char *,
+		int (*)(void *, const void *), void *, int, int));
+	int  (*db_am_remove) __P((DB *, DB_THREAD_INFO *,
+		DB_TXN *, const char *, const char *, u_int32_t));
+	int  (*db_am_rename) __P((DB *, DB_THREAD_INFO *,
+		DB_TXN *, const char *, const char *, const char *));
+	/* DB PRIVATE HANDLE LIST END */
+
+	/*
+	 * Never called; these are a place to save function pointers
+	 * so that we can undo an associate.
+	 */
+	int  (*stored_get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
+	int  (*stored_close) __P((DB *, u_int32_t));
+
+	/* Alternative handle close function, used by C++ API. */
+	int  (*alt_close) __P((DB *, u_int32_t));
+
+#define	DB_OK_BTREE	0x01
+#define	DB_OK_HASH	0x02
+#define	DB_OK_HEAP	0x04
+#define	DB_OK_QUEUE	0x08
+#define	DB_OK_RECNO	0x10
+	u_int32_t	am_ok;		/* Legal AM choices. */
+
+	/*
+	 * This field really ought to be an AM_FLAG, but we have
+	 * have run out of bits.  If/when we decide to split up
+	 * the flags, we can incorporate it.
+	 */
+	int	 preserve_fid;		/* Do not free fileid on close. */
+
+#define	DB_AM_CHKSUM		0x00000001 /* Checksumming */
+#define	DB_AM_COMPENSATE	0x00000002 /* Created by compensating txn */
+#define	DB_AM_COMPRESS		0x00000004 /* Compressed BTree */
+#define	DB_AM_CREATED		0x00000008 /* Database was created upon open */
+#define	DB_AM_CREATED_MSTR	0x00000010 /* Encompassing file was created */
+#define	DB_AM_DBM_ERROR		0x00000020 /* Error in DBM/NDBM database */
+#define	DB_AM_DELIMITER		0x00000040 /* Variable length delimiter set */
+#define	DB_AM_DISCARD		0x00000080 /* Discard any cached pages */
+#define	DB_AM_DUP		0x00000100 /* DB_DUP */
+#define	DB_AM_DUPSORT		0x00000200 /* DB_DUPSORT */
+#define	DB_AM_ENCRYPT		0x00000400 /* Encryption */
+#define	DB_AM_FIXEDLEN		0x00000800 /* Fixed-length records */
+#define	DB_AM_INMEM		0x00001000 /* In-memory; no sync on close */
+#define	DB_AM_INORDER		0x00002000 /* DB_INORDER */
+#define	DB_AM_IN_RENAME		0x00004000 /* File is being renamed */
+#define	DB_AM_NOT_DURABLE	0x00008000 /* Do not log changes */
+#define	DB_AM_OPEN_CALLED	0x00010000 /* DB->open called */
+#define	DB_AM_PAD		0x00020000 /* Fixed-length record pad */
+#define	DB_AM_PARTDB		0x00040000 /* Handle for a database partition */
+#define	DB_AM_PGDEF		0x00080000 /* Page size was defaulted */
+#define	DB_AM_RDONLY		0x00100000 /* Database is readonly */
+#define	DB_AM_READ_UNCOMMITTED	0x00200000 /* Support degree 1 isolation */
+#define	DB_AM_RECNUM		0x00400000 /* DB_RECNUM */
+#define	DB_AM_RECOVER		0x00800000 /* DB opened by recovery routine */
+#define	DB_AM_RENUMBER		0x01000000 /* DB_RENUMBER */
+#define	DB_AM_REVSPLITOFF	0x02000000 /* DB_REVSPLITOFF */
+#define	DB_AM_SECONDARY		0x04000000 /* Database is a secondary index */
+#define	DB_AM_SNAPSHOT		0x08000000 /* DB_SNAPSHOT */
+#define	DB_AM_SUBDB		0x10000000 /* Subdatabases supported */
+#define	DB_AM_SWAP		0x20000000 /* Pages need to be byte-swapped */
+#define	DB_AM_TXN		0x40000000 /* Opened in a transaction */
+#define	DB_AM_VERIFYING		0x80000000 /* DB handle is in the verifier */
+	u_int32_t orig_flags;		   /* Flags at  open, for refresh */
+	u_int32_t flags;
+
+#define DB2_AM_EXCL		0x00000001 /* Exclusively lock the handle */ 
+#define DB2_AM_INTEXCL		0x00000002 /* Internal exclusive lock. */
+#define DB2_AM_NOWAIT		0x00000004 /* Do not wait for handle lock */ 
+	u_int32_t orig_flags2;		   /* Second flags word; for refresh */ 
+	u_int32_t flags2;		   /* Second flags word */
+};
+
+/*
+ * Macros for bulk operations.  These are only intended for the C API.
+ * For C++, use DbMultiple*Iterator or DbMultiple*Builder.
+ *
+ * Bulk operations store multiple entries into a single DBT structure. The
+ * following macros assist with creating and reading these Multiple DBTs.
+ *
+ * The basic layout for single data items is:
+ *
+ * -------------------------------------------------------------------------
+ * | data1 | ... | dataN | ..... |-1 | dNLen | dNOff | ... | d1Len | d1Off |
+ * -------------------------------------------------------------------------
+ *
+ * For the DB_MULTIPLE_KEY* macros, the items are in key/data pairs, so data1
+ * would be a key, and data2 its corresponding value (N is always even).
+ *
+ * For the DB_MULTIPLE_RECNO* macros, the record number is stored along with
+ * the len/off pair in the "header" section, and the list is zero terminated
+ * (since -1 is a valid record number):
+ *
+ * --------------------------------------------------------------------------
+ * | d1 |..| dN |..| 0 | dNLen | dNOff | recnoN |..| d1Len | d1Off | recno1 |
+ * --------------------------------------------------------------------------
+ */
+#define	DB_MULTIPLE_INIT(pointer, dbt)					\
+	(pointer = (u_int8_t *)(dbt)->data +				\
+	    (dbt)->ulen - sizeof(u_int32_t))
+
+#define	DB_MULTIPLE_NEXT(pointer, dbt, retdata, retdlen)		\
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		if (*__p == (u_int32_t)-1) {				\
+			retdata = NULL;					\
+			pointer = NULL;					\
+			break;						\
+		}							\
+		retdata = (u_int8_t *)(dbt)->data + *__p--;		\
+		retdlen = *__p--;					\
+		pointer = __p;						\
+		if (retdlen == 0 && retdata == (u_int8_t *)(dbt)->data)	\
+			retdata = NULL;					\
+	} while (0)
+
+#define	DB_MULTIPLE_KEY_NEXT(pointer, dbt, retkey, retklen, retdata, retdlen) \
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		if (*__p == (u_int32_t)-1) {				\
+			retdata = NULL;					\
+			retkey = NULL;					\
+			pointer = NULL;					\
+			break;						\
+		}							\
+		retkey = (u_int8_t *)(dbt)->data + *__p--;		\
+		retklen = *__p--;					\
+		retdata = (u_int8_t *)(dbt)->data + *__p--;		\
+		retdlen = *__p--;					\
+		pointer = __p;						\
+	} while (0)
+
+#define	DB_MULTIPLE_RECNO_NEXT(pointer, dbt, recno, retdata, retdlen)   \
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		if (*__p == (u_int32_t)0) {				\
+			recno = 0;					\
+			retdata = NULL;					\
+			pointer = NULL;					\
+			break;						\
+		}							\
+		recno = *__p--;						\
+		retdata = (u_int8_t *)(dbt)->data + *__p--;		\
+		retdlen = *__p--;					\
+		pointer = __p;						\
+	} while (0)
+
+#define DB_MULTIPLE_WRITE_INIT(pointer, dbt)				\
+	do {								\
+		(dbt)->flags |= DB_DBT_BULK;				\
+		pointer = (u_int8_t *)(dbt)->data +			\
+		    (dbt)->ulen - sizeof(u_int32_t);			\
+		*(u_int32_t *)(pointer) = (u_int32_t)-1;		\
+	} while (0)
+
+#define DB_MULTIPLE_RESERVE_NEXT(pointer, dbt, writedata, writedlen)	\
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		u_int32_t __off = ((pointer) ==	(u_int8_t *)(dbt)->data +\
+		    (dbt)->ulen - sizeof(u_int32_t)) ?  0 : __p[1] + __p[2];\
+		if ((u_int8_t *)(dbt)->data + __off + (writedlen) >	\
+		    (u_int8_t *)(__p - 2))				\
+			writedata = NULL;				\
+		else {							\
+			writedata = (u_int8_t *)(dbt)->data + __off;	\
+			__p[0] = __off;					\
+			__p[-1] = (u_int32_t)(writedlen);		\
+			__p[-2] = (u_int32_t)-1;			\
+			pointer = __p - 2;				\
+		}							\
+	} while (0)
+
+#define DB_MULTIPLE_WRITE_NEXT(pointer, dbt, writedata, writedlen)	\
+	do {								\
+		void *__destd;						\
+		DB_MULTIPLE_RESERVE_NEXT((pointer), (dbt),		\
+		    __destd, (writedlen));				\
+		if (__destd == NULL)					\
+			pointer = NULL;					\
+		else							\
+			memcpy(__destd, (writedata), (writedlen));	\
+	} while (0)
+
+#define DB_MULTIPLE_KEY_RESERVE_NEXT(pointer, dbt, writekey, writeklen, writedata, writedlen) \
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		u_int32_t __off = ((pointer) == (u_int8_t *)(dbt)->data +\
+		    (dbt)->ulen - sizeof(u_int32_t)) ?  0 : __p[1] + __p[2];\
+		if ((u_int8_t *)(dbt)->data + __off + (writeklen) +	\
+		    (writedlen) > (u_int8_t *)(__p - 4)) {		\
+			writekey = NULL;				\
+			writedata = NULL;				\
+		} else {						\
+			writekey = (u_int8_t *)(dbt)->data + __off;	\
+			__p[0] = __off;					\
+			__p[-1] = (u_int32_t)(writeklen);		\
+			__p -= 2;					\
+			__off += (u_int32_t)(writeklen);		\
+			writedata = (u_int8_t *)(dbt)->data + __off;	\
+			__p[0] = __off;					\
+			__p[-1] = (u_int32_t)(writedlen);		\
+			__p[-2] = (u_int32_t)-1;			\
+			pointer = __p - 2;				\
+		}							\
+	} while (0)
+
+#define DB_MULTIPLE_KEY_WRITE_NEXT(pointer, dbt, writekey, writeklen, writedata, writedlen) \
+	do {								\
+		void *__destk, *__destd;				\
+		DB_MULTIPLE_KEY_RESERVE_NEXT((pointer), (dbt),		\
+		    __destk, (writeklen), __destd, (writedlen));	\
+		if (__destk == NULL)					\
+			pointer = NULL;					\
+		else {							\
+			memcpy(__destk, (writekey), (writeklen));	\
+			if (__destd != NULL)				\
+				memcpy(__destd, (writedata), (writedlen));\
+		}							\
+	} while (0)
+
+#define DB_MULTIPLE_RECNO_WRITE_INIT(pointer, dbt)			\
+	do {								\
+		(dbt)->flags |= DB_DBT_BULK;				\
+		pointer = (u_int8_t *)(dbt)->data +			\
+		    (dbt)->ulen - sizeof(u_int32_t);			\
+		*(u_int32_t *)(pointer) = 0;				\
+	} while (0)
+
+#define DB_MULTIPLE_RECNO_RESERVE_NEXT(pointer, dbt, recno, writedata, writedlen) \
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		u_int32_t __off = ((pointer) == (u_int8_t *)(dbt)->data +\
+		    (dbt)->ulen - sizeof(u_int32_t)) ? 0 : __p[1] + __p[2]; \
+		if (((u_int8_t *)(dbt)->data + __off) + (writedlen) >	\
+		    (u_int8_t *)(__p - 3))				\
+			writedata = NULL;				\
+		else {							\
+			writedata = (u_int8_t *)(dbt)->data + __off;	\
+			__p[0] = (u_int32_t)(recno);			\
+			__p[-1] = __off;				\
+			__p[-2] = (u_int32_t)(writedlen);		\
+			__p[-3] = 0;					\
+			pointer = __p - 3;				\
+		}							\
+	} while (0)
+
+#define DB_MULTIPLE_RECNO_WRITE_NEXT(pointer, dbt, recno, writedata, writedlen)\
+	do {								\
+		void *__destd;						\
+		DB_MULTIPLE_RECNO_RESERVE_NEXT((pointer), (dbt),	\
+		    (recno), __destd, (writedlen));			\
+		if (__destd == NULL)					\
+			pointer = NULL;					\
+		else if ((writedlen) != 0)				\
+			memcpy(__destd, (writedata), (writedlen));	\
+	} while (0)
+
+struct __db_heap_rid {
+	db_pgno_t pgno;			/* Page number. */
+	db_indx_t indx;			/* Index in the offset table. */
+};
+#define DB_HEAP_RID_SZ	(sizeof(db_pgno_t) + sizeof(db_indx_t))
+
+/*******************************************************
+ * Access method cursors.
+ *******************************************************/
+struct __dbc {
+	DB *dbp;			/* Backing database */
+	DB_ENV *dbenv;			/* Backing environment */
+	ENV *env;			/* Backing environment */
+
+	DB_THREAD_INFO *thread_info;	/* Thread that owns this cursor. */
+	DB_TXN	 *txn;			/* Associated transaction. */
+	DB_CACHE_PRIORITY priority;	/* Priority in cache. */
+
+	/*
+	 * Active/free cursor queues.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__dbc) links;
+	 */
+	struct {
+		DBC *tqe_next;
+		DBC **tqe_prev;
+	} links;
+
+	/*
+	 * Cursor queue of the owning transaction.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__dbc) txn_cursors;
+	 */
+	struct {
+		DBC *tqe_next;	/* next element */
+		DBC **tqe_prev;	/* address of previous next element */
+	} txn_cursors;
+
+	/*
+	 * The DBT *'s below are used by the cursor routines to return
+	 * data to the user when DBT flags indicate that DB should manage
+	 * the returned memory.  They point at a DBT containing the buffer
+	 * and length that will be used, and "belonging" to the handle that
+	 * should "own" this memory.  This may be a "my_*" field of this
+	 * cursor--the default--or it may be the corresponding field of
+	 * another cursor, a DB handle, a join cursor, etc.  In general, it
+	 * will be whatever handle the user originally used for the current
+	 * DB interface call.
+	 */
+	DBT	 *rskey;		/* Returned secondary key. */
+	DBT	 *rkey;			/* Returned [primary] key. */
+	DBT	 *rdata;		/* Returned data. */
+
+	DBT	  my_rskey;		/* Space for returned secondary key. */
+	DBT	  my_rkey;		/* Space for returned [primary] key. */
+	DBT	  my_rdata;		/* Space for returned data. */
+
+	DB_LOCKER *lref;		/* Reference to default locker. */
+	DB_LOCKER *locker;		/* Locker for this operation. */
+	DBT	  lock_dbt;		/* DBT referencing lock. */
+	DB_LOCK_ILOCK lock;		/* Object to be locked. */
+	DB_LOCK	  mylock;		/* CDB lock held on this cursor. */
+
+	DBTYPE	  dbtype;		/* Cursor type. */
+
+	DBC_INTERNAL *internal;		/* Access method private. */
+
+	/* DBC PUBLIC HANDLE LIST BEGIN */
+	int (*close) __P((DBC *));
+	int (*cmp) __P((DBC *, DBC *, int *, u_int32_t));
+	int (*count) __P((DBC *, db_recno_t *, u_int32_t));
+	int (*del) __P((DBC *, u_int32_t));
+	int (*dup) __P((DBC *, DBC **, u_int32_t));
+	int (*get) __P((DBC *, DBT *, DBT *, u_int32_t));
+	int (*get_priority) __P((DBC *, DB_CACHE_PRIORITY *));
+	int (*pget) __P((DBC *, DBT *, DBT *, DBT *, u_int32_t));
+	int (*put) __P((DBC *, DBT *, DBT *, u_int32_t));
+	int (*set_priority) __P((DBC *, DB_CACHE_PRIORITY));
+	/* DBC PUBLIC HANDLE LIST END */
+
+	/* The following are the method names deprecated in the 4.6 release. */
+	int (*c_close) __P((DBC *));
+	int (*c_count) __P((DBC *, db_recno_t *, u_int32_t));
+	int (*c_del) __P((DBC *, u_int32_t));
+	int (*c_dup) __P((DBC *, DBC **, u_int32_t));
+	int (*c_get) __P((DBC *, DBT *, DBT *, u_int32_t));
+	int (*c_pget) __P((DBC *, DBT *, DBT *, DBT *, u_int32_t));
+	int (*c_put) __P((DBC *, DBT *, DBT *, u_int32_t));
+
+	/* DBC PRIVATE HANDLE LIST BEGIN */
+	int (*am_bulk) __P((DBC *, DBT *, u_int32_t));
+	int (*am_close) __P((DBC *, db_pgno_t, int *));
+	int (*am_del) __P((DBC *, u_int32_t));
+	int (*am_destroy) __P((DBC *));
+	int (*am_get) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
+	int (*am_put) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
+	int (*am_writelock) __P((DBC *));
+	/* DBC PRIVATE HANDLE LIST END */
+
+/*
+ * DBC_DONTLOCK and DBC_RECOVER are used during recovery and transaction
+ * abort.  If a transaction is being aborted or recovered then DBC_RECOVER
+ * will be set and locking and logging will be disabled on this cursor.  If
+ * we are performing a compensating transaction (e.g. free page processing)
+ * then DB_DONTLOCK will be set to inhibit locking, but logging will still
+ * be required. DB_DONTLOCK is also used if the whole database is locked.
+ */
+#define	DBC_ACTIVE		0x00001	/* Cursor in use. */
+#define	DBC_BULK		0x00002	/* Bulk update cursor. */
+#define	DBC_DONTLOCK		0x00004	/* Don't lock on this cursor. */
+#define	DBC_DOWNREV		0x00008	/* Down rev replication master. */
+#define	DBC_DUPLICATE		0x00010	/* Create a duplicate cursor. */
+#define	DBC_ERROR		0x00020	/* Error in this request. */
+#define	DBC_FAMILY		0x00040 /* Part of a locker family. */
+#define	DBC_FROM_DB_GET		0x00080 /* Called from the DB->get() method. */
+#define	DBC_MULTIPLE		0x00100	/* Return Multiple data. */
+#define	DBC_MULTIPLE_KEY	0x00200	/* Return Multiple keys and data. */
+#define	DBC_OPD			0x00400	/* Cursor references off-page dups. */
+#define	DBC_OWN_LID		0x00800	/* Free lock id on destroy. */
+#define	DBC_PARTITIONED		0x01000	/* Cursor for a partitioned db. */
+#define	DBC_READ_COMMITTED	0x02000	/* Cursor has degree 2 isolation. */
+#define	DBC_READ_UNCOMMITTED	0x04000	/* Cursor has degree 1 isolation. */
+#define	DBC_RECOVER		0x08000	/* Recovery cursor; don't log/lock. */
+#define	DBC_RMW			0x10000	/* Acquire write flag in read op. */
+#define	DBC_TRANSIENT		0x20000	/* Cursor is transient. */
+#define	DBC_WAS_READ_COMMITTED	0x40000	/* Cursor holds a read commited lock. */
+#define	DBC_WRITECURSOR		0x80000	/* Cursor may be used to write (CDB). */
+#define	DBC_WRITER	       0x100000	/* Cursor immediately writing (CDB). */
+	u_int32_t flags;
+};
+
+/* Key range statistics structure */
+struct __key_range {
+	double less;
+	double equal;
+	double greater;
+};
+
+/* Btree/Recno statistics structure. */
+struct __db_bt_stat { /* SHARED */
+	u_int32_t bt_magic;		/* Magic number. */
+	u_int32_t bt_version;		/* Version number. */
+	u_int32_t bt_metaflags;		/* Metadata flags. */
+	u_int32_t bt_nkeys;		/* Number of unique keys. */
+	u_int32_t bt_ndata;		/* Number of data items. */
+	u_int32_t bt_pagecnt;		/* Page count. */
+	u_int32_t bt_pagesize;		/* Page size. */
+	u_int32_t bt_minkey;		/* Minkey value. */
+	u_int32_t bt_re_len;		/* Fixed-length record length. */
+	u_int32_t bt_re_pad;		/* Fixed-length record pad. */
+	u_int32_t bt_levels;		/* Tree levels. */
+	u_int32_t bt_int_pg;		/* Internal pages. */
+	u_int32_t bt_leaf_pg;		/* Leaf pages. */
+	u_int32_t bt_dup_pg;		/* Duplicate pages. */
+	u_int32_t bt_over_pg;		/* Overflow pages. */
+	u_int32_t bt_empty_pg;		/* Empty pages. */
+	u_int32_t bt_free;		/* Pages on the free list. */
+	uintmax_t bt_int_pgfree;	/* Bytes free in internal pages. */
+	uintmax_t bt_leaf_pgfree;	/* Bytes free in leaf pages. */
+	uintmax_t bt_dup_pgfree;	/* Bytes free in duplicate pages. */
+	uintmax_t bt_over_pgfree;	/* Bytes free in overflow pages. */
+};
+
+struct __db_compact {
+	/* Input Parameters. */
+	u_int32_t	compact_fillpercent;	/* Desired fillfactor: 1-100 */
+	db_timeout_t	compact_timeout;	/* Lock timeout. */
+	u_int32_t	compact_pages;		/* Max pages to process. */
+	/* Output Stats. */
+	u_int32_t	compact_empty_buckets;	/* Empty hash buckets found. */
+	u_int32_t	compact_pages_free;	/* Number of pages freed. */
+	u_int32_t	compact_pages_examine;	/* Number of pages examine. */
+	u_int32_t	compact_levels;		/* Number of levels removed. */
+	u_int32_t	compact_deadlock;	/* Number of deadlocks. */
+	db_pgno_t	compact_pages_truncated; /* Pages truncated to OS. */
+	/* Internal. */
+	db_pgno_t	compact_truncate;	/* Page number for truncation */
+};
+
+/* Hash statistics structure. */
+struct __db_h_stat { /* SHARED */
+	u_int32_t hash_magic;		/* Magic number. */
+	u_int32_t hash_version;		/* Version number. */
+	u_int32_t hash_metaflags;	/* Metadata flags. */
+	u_int32_t hash_nkeys;		/* Number of unique keys. */
+	u_int32_t hash_ndata;		/* Number of data items. */
+	u_int32_t hash_pagecnt;		/* Page count. */
+	u_int32_t hash_pagesize;	/* Page size. */
+	u_int32_t hash_ffactor;		/* Fill factor specified at create. */
+	u_int32_t hash_buckets;		/* Number of hash buckets. */
+	u_int32_t hash_free;		/* Pages on the free list. */
+	uintmax_t hash_bfree;		/* Bytes free on bucket pages. */
+	u_int32_t hash_bigpages;	/* Number of big key/data pages. */
+	uintmax_t hash_big_bfree;	/* Bytes free on big item pages. */
+	u_int32_t hash_overflows;	/* Number of overflow pages. */
+	uintmax_t hash_ovfl_free;	/* Bytes free on ovfl pages. */
+	u_int32_t hash_dup;		/* Number of dup pages. */
+	uintmax_t hash_dup_free;	/* Bytes free on duplicate pages. */
+};
+
+/* Heap statistics structure. */
+struct __db_heap_stat { /* SHARED */
+	u_int32_t heap_magic;		/* Magic number. */
+	u_int32_t heap_version;		/* Version number. */
+	u_int32_t heap_metaflags;	/* Metadata flags. */
+	u_int32_t heap_nrecs;		/* Number of records. */
+	u_int32_t heap_pagecnt;		/* Page count. */
+	u_int32_t heap_pagesize;	/* Page size. */
+	u_int32_t heap_nregions;	/* Number of regions. */
+	u_int32_t heap_regionsize;	/* Number of pages in a region. */
+};
+
+/* Queue statistics structure. */
+struct __db_qam_stat { /* SHARED */
+	u_int32_t qs_magic;		/* Magic number. */
+	u_int32_t qs_version;		/* Version number. */
+	u_int32_t qs_metaflags;		/* Metadata flags. */
+	u_int32_t qs_nkeys;		/* Number of unique keys. */
+	u_int32_t qs_ndata;		/* Number of data items. */
+	u_int32_t qs_pagesize;		/* Page size. */
+	u_int32_t qs_extentsize;	/* Pages per extent. */
+	u_int32_t qs_pages;		/* Data pages. */
+	u_int32_t qs_re_len;		/* Fixed-length record length. */
+	u_int32_t qs_re_pad;		/* Fixed-length record pad. */
+	u_int32_t qs_pgfree;		/* Bytes free in data pages. */
+	u_int32_t qs_first_recno;	/* First not deleted record. */
+	u_int32_t qs_cur_recno;		/* Next available record number. */
+};
+
+/*******************************************************
+ * Environment.
+ *******************************************************/
+#define	DB_REGION_MAGIC	0x120897	/* Environment magic number. */
+
+/*
+ * Database environment structure.
+ *
+ * This is the public database environment handle.  The private environment
+ * handle is the ENV structure.   The user owns this structure, the library
+ * owns the ENV structure.  The reason there are two structures is because
+ * the user's configuration outlives any particular DB_ENV->open call, and
+ * separate structures allows us to easily discard internal information without
+ * discarding the user's configuration.
+ *
+ * Fields in the DB_ENV structure should normally be set only by application
+ * DB_ENV handle methods.
+ */
+
+/*
+ * Memory configuration types.
+ */
+typedef enum {
+	DB_MEM_LOCK=1,
+	DB_MEM_LOCKOBJECT=2,
+	DB_MEM_LOCKER=3,
+	DB_MEM_LOGID=4,
+	DB_MEM_TRANSACTION=5,
+	DB_MEM_THREAD=6
+} DB_MEM_CONFIG;
+
+/*
+ * Backup configuration types.
+ */
+typedef enum {
+	DB_BACKUP_READ_COUNT = 1,
+	DB_BACKUP_READ_SLEEP = 2,
+	DB_BACKUP_SIZE = 3,
+	DB_BACKUP_WRITE_DIRECT = 4
+} DB_BACKUP_CONFIG;
+
+struct __db_env {
+	ENV *env;			/* Linked ENV structure */
+
+	/*
+	 * The DB_ENV structure can be used concurrently, so field access is
+	 * protected.
+	 */
+	db_mutex_t mtx_db_env;		/* DB_ENV structure mutex */
+
+					/* Error message callback */
+	void (*db_errcall) __P((const DB_ENV *, const char *, const char *));
+	FILE		*db_errfile;	/* Error message file stream */
+	const char	*db_errpfx;	/* Error message prefix */
+
+					/* Other message callback */
+	void (*db_msgcall) __P((const DB_ENV *, const char *));
+	FILE		*db_msgfile;	/* Other message file stream */
+
+	/* Other application callback functions */
+	int   (*app_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops));
+	void  (*db_event_func) __P((DB_ENV *, u_int32_t, void *));
+	void  (*db_feedback) __P((DB_ENV *, int, int));
+	void  (*db_free) __P((void *));
+	void  (*db_paniccall) __P((DB_ENV *, int));
+	void *(*db_malloc) __P((size_t));
+	void *(*db_realloc) __P((void *, size_t));
+	int   (*is_alive) __P((DB_ENV *, pid_t, db_threadid_t, u_int32_t));
+	void  (*thread_id) __P((DB_ENV *, pid_t *, db_threadid_t *));
+	char *(*thread_id_string) __P((DB_ENV *, pid_t, db_threadid_t, char *));
+
+	/* Application specified paths */
+	char	*db_log_dir;		/* Database log file directory */
+	char	*db_md_dir;		/* Persistent metadata directory */
+	char	*db_tmp_dir;		/* Database tmp file directory */
+
+	char    *db_create_dir;		/* Create directory for data files */
+	char   **db_data_dir;		/* Database data file directories */
+	int	 data_cnt;		/* Database data file slots */
+	int	 data_next;		/* Next database data file slot */
+
+	char	*intermediate_dir_mode;	/* Intermediate directory perms */
+
+	long	 shm_key;		/* shmget key */
+
+	char	*passwd;		/* Cryptography support */
+	size_t	 passwd_len;
+
+	/* Private handle references */
+	void	*app_private;		/* Application-private handle */
+	void	*api1_internal;		/* C++, Perl API private */
+	void	*api2_internal;		/* Java API private */
+
+	u_int32_t	verbose;	/* DB_VERB_XXX flags */
+
+	/* Mutex configuration */
+	u_int32_t	mutex_align;	/* Mutex alignment */
+	u_int32_t	mutex_cnt;	/* Number of mutexes to configure */
+	u_int32_t	mutex_inc;	/* Number of mutexes to add */
+	u_int32_t	mutex_max;	/* Max number of mutexes */
+	u_int32_t	mutex_tas_spins;/* Test-and-set spin count */
+
+	/* Locking configuration */
+	u_int8_t       *lk_conflicts;	/* Two dimensional conflict matrix */
+	int		lk_modes;	/* Number of lock modes in table */
+	u_int32_t	lk_detect;	/* Deadlock detect on all conflicts */
+	u_int32_t	lk_max;	/* Maximum number of locks */
+	u_int32_t	lk_max_lockers;/* Maximum number of lockers */
+	u_int32_t	lk_max_objects;/* Maximum number of locked objects */
+	u_int32_t	lk_init;	/* Initial number of locks */
+	u_int32_t	lk_init_lockers;/* Initial number of lockers */
+	u_int32_t	lk_init_objects;/* Initial number of locked objects */
+	u_int32_t	lk_partitions ;/* Number of object partitions */
+	db_timeout_t	lk_timeout;	/* Lock timeout period */
+	/* Used during initialization */
+	u_int32_t	locker_t_size;	/* Locker hash table size. */
+	u_int32_t	object_t_size;	/* Object hash table size. */
+
+	/* Logging configuration */
+	u_int32_t	lg_bsize;	/* Buffer size */
+	u_int32_t	lg_fileid_init;	/* Initial allocation for fname structs */
+	int		lg_filemode;	/* Log file permission mode */
+	u_int32_t	lg_regionmax;	/* Region size */
+	u_int32_t	lg_size;	/* Log file size */
+	u_int32_t	lg_flags;	/* Log configuration */
+
+	/* Memory pool configuration */
+	u_int32_t	mp_gbytes;	/* Cache size: GB */
+	u_int32_t	mp_bytes;	/* Cache size: bytes */
+	u_int32_t	mp_max_gbytes;	/* Maximum cache size: GB */
+	u_int32_t	mp_max_bytes;	/* Maximum cache size: bytes */
+	size_t		mp_mmapsize;	/* Maximum file size for mmap */
+	int		mp_maxopenfd;	/* Maximum open file descriptors */
+	int		mp_maxwrite;	/* Maximum buffers to write */
+	u_int		mp_ncache;	/* Initial number of cache regions */
+	u_int32_t	mp_pagesize;	/* Average page size */
+	u_int32_t	mp_tablesize;	/* Approximate hash table size */
+	u_int32_t	mp_mtxcount;	/* Number of mutexs */
+					/* Sleep after writing max buffers */
+	db_timeout_t	mp_maxwrite_sleep;
+
+	/* Transaction configuration */
+	u_int32_t	tx_init;	/* Initial number of transactions */
+	u_int32_t	tx_max;		/* Maximum number of transactions */
+	time_t		tx_timestamp;	/* Recover to specific timestamp */
+	db_timeout_t	tx_timeout;	/* Timeout for transactions */
+
+	/* Thread tracking configuration */
+	u_int32_t	thr_init;	/* Thread count */
+	u_int32_t	thr_max;	/* Thread max */
+	roff_t		memory_max;	/* Maximum region memory */
+
+	/*
+	 * The following fields are not strictly user-owned, but they outlive
+	 * the ENV structure, and so are stored here.
+	 */
+	DB_FH		*registry;	/* DB_REGISTER file handle */
+	u_int32_t	registry_off;	/*
+					 * Offset of our slot.  We can't use
+					 * off_t because its size depends on
+					 * build settings.
+					 */
+        db_timeout_t	envreg_timeout; /* DB_REGISTER wait timeout */
+
+#define	DB_ENV_AUTO_COMMIT	0x00000001 /* DB_AUTO_COMMIT */
+#define	DB_ENV_CDB_ALLDB	0x00000002 /* CDB environment wide locking */
+#define	DB_ENV_FAILCHK		0x00000004 /* Failchk is running */
+#define	DB_ENV_DIRECT_DB	0x00000008 /* DB_DIRECT_DB set */
+#define	DB_ENV_DSYNC_DB		0x00000010 /* DB_DSYNC_DB set */
+#define	DB_ENV_DATABASE_LOCKING	0x00000020 /* Try database-level locking */
+#define	DB_ENV_MULTIVERSION	0x00000040 /* DB_MULTIVERSION set */
+#define	DB_ENV_NOLOCKING	0x00000080 /* DB_NOLOCKING set */
+#define	DB_ENV_NOMMAP		0x00000100 /* DB_NOMMAP set */
+#define	DB_ENV_NOPANIC		0x00000200 /* Okay if panic set */
+#define	DB_ENV_OVERWRITE	0x00000400 /* DB_OVERWRITE set */
+#define	DB_ENV_REGION_INIT	0x00000800 /* DB_REGION_INIT set */
+#define	DB_ENV_TIME_NOTGRANTED	0x00001000 /* DB_TIME_NOTGRANTED set */
+#define	DB_ENV_TXN_NOSYNC	0x00002000 /* DB_TXN_NOSYNC set */
+#define	DB_ENV_TXN_NOWAIT	0x00004000 /* DB_TXN_NOWAIT set */
+#define	DB_ENV_TXN_SNAPSHOT	0x00008000 /* DB_TXN_SNAPSHOT set */
+#define	DB_ENV_TXN_WRITE_NOSYNC	0x00010000 /* DB_TXN_WRITE_NOSYNC set */
+#define	DB_ENV_YIELDCPU		0x00020000 /* DB_YIELDCPU set */
+#define DB_ENV_HOTBACKUP	0x00040000 /* DB_HOTBACKUP_IN_PROGRESS set */
+#define DB_ENV_NOFLUSH		0x00080000 /* DB_NOFLUSH set */
+	u_int32_t flags;
+
+	/* DB_ENV PUBLIC HANDLE LIST BEGIN */
+	int  (*add_data_dir) __P((DB_ENV *, const char *));
+	int  (*close) __P((DB_ENV *, u_int32_t));
+	void (*err) __P((const DB_ENV *, int, const char *, ...));
+	void (*errx) __P((const DB_ENV *, const char *, ...));
+	int  (*get_alloc) __P((DB_ENV *, void *(**)(size_t),
+		void *(**)(void *, size_t), void (**)(void *)));
+	int  (*get_cache_max) __P((DB_ENV *, u_int32_t *, u_int32_t *));
+	int  (*get_cachesize) __P((DB_ENV *, u_int32_t *, u_int32_t *, int *));
+	int  (*get_create_dir) __P((DB_ENV *, const char **));
+	int  (*get_data_dirs) __P((DB_ENV *, const char ***));
+	int  (*get_data_len) __P((DB_ENV *, u_int32_t *));
+	void (*get_errcall) __P((DB_ENV *,
+		void (**)(const DB_ENV *, const char *, const char *)));
+	void (*get_errfile) __P((DB_ENV *, FILE **));
+	void (*get_errpfx) __P((DB_ENV *, const char **));
+	int  (*get_flags) __P((DB_ENV *, u_int32_t *));
+	int  (*get_feedback) __P((DB_ENV *, void (**)(DB_ENV *, int, int)));
+	int  (*get_home) __P((DB_ENV *, const char **));
+	int  (*get_intermediate_dir_mode) __P((DB_ENV *, const char **));
+	int  (*get_memory_init) __P((DB_ENV *, DB_MEM_CONFIG, u_int32_t *));
+	int  (*get_memory_max) __P((DB_ENV *, u_int32_t *, u_int32_t *));
+	int  (*get_metadata_dir) __P((DB_ENV *, const char **));
+	int  (*get_mp_max_openfd) __P((DB_ENV *, int *));
+	int  (*get_mp_max_write) __P((DB_ENV *, int *, db_timeout_t *));
+	int  (*get_mp_mmapsize) __P((DB_ENV *, size_t *));
+	int  (*get_mp_mtxcount) __P((DB_ENV *, u_int32_t *));
+	int  (*get_mp_pagesize) __P((DB_ENV *, u_int32_t *));
+	int  (*get_mp_tablesize) __P((DB_ENV *, u_int32_t *));
+	void (*get_msgcall)
+		__P((DB_ENV *, void (**)(const DB_ENV *, const char *)));
+	void (*get_msgfile) __P((DB_ENV *, FILE **));
+	int  (*get_open_flags) __P((DB_ENV *, u_int32_t *));
+	int  (*get_shm_key) __P((DB_ENV *, long *));
+	int  (*get_thread_count) __P((DB_ENV *, u_int32_t *));
+	int  (*get_thread_id_fn)
+		__P((DB_ENV *, void (**)(DB_ENV *, pid_t *, db_threadid_t *)));
+	int  (*get_thread_id_string_fn) __P((DB_ENV *,
+		char *(**)(DB_ENV *, pid_t, db_threadid_t, char *)));
+	int  (*get_timeout) __P((DB_ENV *, db_timeout_t *, u_int32_t));
+	int  (*get_tmp_dir) __P((DB_ENV *, const char **));
+	int  (*get_verbose) __P((DB_ENV *, u_int32_t, int *));
+	int  (*is_bigendian) __P((void));
+	int  (*memp_fcreate) __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t));
+	int  (*memp_register) __P((DB_ENV *, int, int (*)(DB_ENV *, db_pgno_t,
+		void *, DBT *), int (*)(DB_ENV *, db_pgno_t, void *, DBT *)));
+	int  (*memp_stat) __P((DB_ENV *,
+		DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t));
+	int  (*memp_stat_print) __P((DB_ENV *, u_int32_t));
+	int  (*memp_sync) __P((DB_ENV *, DB_LSN *));
+	int  (*memp_trickle) __P((DB_ENV *, int, int *));
+	int  (*mutex_alloc) __P((DB_ENV *, u_int32_t, db_mutex_t *));
+	int  (*mutex_free) __P((DB_ENV *, db_mutex_t));
+	int  (*mutex_get_align) __P((DB_ENV *, u_int32_t *));
+	int  (*mutex_get_increment) __P((DB_ENV *, u_int32_t *));
+	int  (*mutex_get_init) __P((DB_ENV *, u_int32_t *));
+	int  (*mutex_get_max) __P((DB_ENV *, u_int32_t *));
+	int  (*mutex_get_tas_spins) __P((DB_ENV *, u_int32_t *));
+	int  (*mutex_lock) __P((DB_ENV *, db_mutex_t));
+	int  (*mutex_set_align) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_set_increment) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_set_init) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_set_max) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_set_tas_spins) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_stat) __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t));
+	int  (*mutex_stat_print) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_unlock) __P((DB_ENV *, db_mutex_t));
+	int  (*open) __P((DB_ENV *, const char *, u_int32_t, int));
+	int  (*remove) __P((DB_ENV *, const char *, u_int32_t));
+	int  (*set_alloc) __P((DB_ENV *, void *(*)(size_t),
+		void *(*)(void *, size_t), void (*)(void *)));
+	int  (*set_cache_max) __P((DB_ENV *, u_int32_t, u_int32_t));
+	int  (*set_cachesize) __P((DB_ENV *, u_int32_t, u_int32_t, int));
+	int  (*set_create_dir) __P((DB_ENV *, const char *));
+	int  (*set_data_dir) __P((DB_ENV *, const char *));
+	int  (*set_data_len) __P((DB_ENV *, u_int32_t));
+	int  (*set_encrypt) __P((DB_ENV *, const char *, u_int32_t));
+	void (*set_errcall) __P((DB_ENV *,
+		void (*)(const DB_ENV *, const char *, const char *)));
+	void (*set_errfile) __P((DB_ENV *, FILE *));
+	void (*set_errpfx) __P((DB_ENV *, const char *));
+	int  (*set_event_notify)
+		__P((DB_ENV *, void (*)(DB_ENV *, u_int32_t, void *)));
+	int  (*set_feedback) __P((DB_ENV *, void (*)(DB_ENV *, int, int)));
+	int  (*set_flags) __P((DB_ENV *, u_int32_t, int));
+	int  (*set_intermediate_dir_mode) __P((DB_ENV *, const char *));
+	int  (*set_isalive) __P((DB_ENV *,
+		int (*)(DB_ENV *, pid_t, db_threadid_t, u_int32_t)));
+	int  (*set_memory_init) __P((DB_ENV *, DB_MEM_CONFIG, u_int32_t));
+	int  (*set_memory_max) __P((DB_ENV *, u_int32_t, u_int32_t));
+	int  (*set_metadata_dir) __P((DB_ENV *, const char *));
+	int  (*set_mp_max_openfd) __P((DB_ENV *, int));
+	int  (*set_mp_max_write) __P((DB_ENV *, int, db_timeout_t));
+	int  (*set_mp_mmapsize) __P((DB_ENV *, size_t));
+	int  (*set_mp_mtxcount) __P((DB_ENV *, u_int32_t));
+	int  (*set_mp_pagesize) __P((DB_ENV *, u_int32_t));
+	int  (*set_mp_tablesize) __P((DB_ENV *, u_int32_t));
+	void (*set_msgcall)
+		__P((DB_ENV *, void (*)(const DB_ENV *, const char *)));
+	void (*set_msgfile) __P((DB_ENV *, FILE *));
+	int  (*set_paniccall) __P((DB_ENV *, void (*)(DB_ENV *, int)));
+	int  (*set_shm_key) __P((DB_ENV *, long));
+	int  (*set_thread_count) __P((DB_ENV *, u_int32_t));
+	int  (*set_thread_id)
+		__P((DB_ENV *, void (*)(DB_ENV *, pid_t *, db_threadid_t *)));
+	int  (*set_thread_id_string) __P((DB_ENV *,
+		char *(*)(DB_ENV *, pid_t, db_threadid_t, char *)));
+	int  (*set_timeout) __P((DB_ENV *, db_timeout_t, u_int32_t));
+	int  (*set_tmp_dir) __P((DB_ENV *, const char *));
+	int  (*set_verbose) __P((DB_ENV *, u_int32_t, int));
+	int  (*stat_print) __P((DB_ENV *, u_int32_t));
+	/* DB_ENV PUBLIC HANDLE LIST END */
+
+	/* DB_ENV PRIVATE HANDLE LIST BEGIN */
+	int  (*prdbt) __P((DBT *, int,
+		const char *, void *, int (*)(void *, const void *), int, int));
+	/* DB_ENV PRIVATE HANDLE LIST END */
+};
+
+/*
+ * Dispatch structure for recovery, log verification and print routines. Since
+ * internal and external routines take different arguments (ENV versus DB_ENV),
+ * we need something more elaborate than a single pointer and size.
+ */
+struct __db_distab {
+	int   (**int_dispatch) __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+	size_t	int_size;
+	int   (**ext_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops));
+	size_t	ext_size;
+};
+
+/*
+ * Log verification configuration structure.
+ */
+struct __db_logvrfy_config {
+	int continue_after_fail, verbose;
+	u_int32_t cachesize;
+	const char *temp_envhome;
+	const char *dbfile, *dbname;
+	DB_LSN start_lsn, end_lsn;
+	time_t start_time, end_time;
+};
+
+struct __db_channel {
+	CHANNEL *channel;	/* Pointer to internal state details. */
+	int eid;		/* Env. ID passed in constructor. */
+	db_timeout_t timeout;
+
+	/* DB_CHANNEL PUBLIC HANDLE LIST BEGIN */
+	int (*close) __P((DB_CHANNEL *, u_int32_t));
+	int (*send_msg) __P((DB_CHANNEL *, DBT *, u_int32_t, u_int32_t));
+	int (*send_request) __P((DB_CHANNEL *,
+		DBT *, u_int32_t, DBT *, db_timeout_t, u_int32_t));
+	int  (*set_timeout) __P((DB_CHANNEL *, db_timeout_t));
+	/* DB_CHANNEL PUBLIC HANDLE LIST END */
+};
+
+struct __db_site {
+	ENV *env;
+	int eid;
+	const char *host;
+	u_int port;
+	u_int32_t flags;
+
+	/* DB_SITE PUBLIC HANDLE LIST BEGIN */
+	int (*get_address) __P((DB_SITE *, const char **, u_int *));
+	int (*get_config) __P((DB_SITE *, u_int32_t, u_int32_t *));
+	int (*get_eid) __P((DB_SITE *, int *));
+	int (*set_config) __P((DB_SITE *, u_int32_t, u_int32_t));
+	int (*remove) __P((DB_SITE *));
+	int (*close) __P((DB_SITE *));
+	/* DB_SITE PUBLIC HANDLE LIST END */
+};
+
+#if DB_DBM_HSEARCH != 0
+/*******************************************************
+ * Dbm/Ndbm historic interfaces.
+ *******************************************************/
+typedef struct __db DBM;
+
+#define	DBM_INSERT	0		/* Flags to dbm_store(). */
+#define	DBM_REPLACE	1
+
+/*
+ * The DB support for ndbm(3) always appends this suffix to the
+ * file name to avoid overwriting the user's original database.
+ */
+#define	DBM_SUFFIX	".db"
+
+#if defined(_XPG4_2)
+typedef struct {
+	char *dptr;
+	size_t dsize;
+} datum;
+#else
+typedef struct {
+	char *dptr;
+	int dsize;
+} datum;
+#endif
+
+/*
+ * Translate NDBM calls into DB calls so that DB doesn't step on the
+ * application's name space.
+ */
+#define	dbm_clearerr(a)		__db_ndbm_clearerr@DB_VERSION_UNIQUE_NAME@(a)
+#define	dbm_close(a)		__db_ndbm_close@DB_VERSION_UNIQUE_NAME@(a)
+#define	dbm_delete(a, b)	__db_ndbm_delete@DB_VERSION_UNIQUE_NAME@(a, b)
+#define	dbm_dirfno(a)		__db_ndbm_dirfno@DB_VERSION_UNIQUE_NAME@(a)
+#define	dbm_error(a)		__db_ndbm_error@DB_VERSION_UNIQUE_NAME@(a)
+#define	dbm_fetch(a, b)		__db_ndbm_fetch@DB_VERSION_UNIQUE_NAME@(a, b)
+#define	dbm_firstkey(a)		__db_ndbm_firstkey@DB_VERSION_UNIQUE_NAME@(a)
+#define	dbm_nextkey(a)		__db_ndbm_nextkey@DB_VERSION_UNIQUE_NAME@(a)
+#define	dbm_open(a, b, c)	__db_ndbm_open@DB_VERSION_UNIQUE_NAME@(a, b, c)
+#define	dbm_pagfno(a)		__db_ndbm_pagfno@DB_VERSION_UNIQUE_NAME@(a)
+#define	dbm_rdonly(a)		__db_ndbm_rdonly@DB_VERSION_UNIQUE_NAME@(a)
+#define	dbm_store(a, b, c, d) \
+	__db_ndbm_store@DB_VERSION_UNIQUE_NAME@(a, b, c, d)
+
+/*
+ * Translate DBM calls into DB calls so that DB doesn't step on the
+ * application's name space.
+ *
+ * The global variables dbrdonly, dirf and pagf were not retained when 4BSD
+ * replaced the dbm interface with ndbm, and are not supported here.
+ */
+#define	dbminit(a)	__db_dbm_init@DB_VERSION_UNIQUE_NAME@(a)
+#define	dbmclose	__db_dbm_close@DB_VERSION_UNIQUE_NAME@
+#if !defined(__cplusplus)
+#define	delete(a)	__db_dbm_delete@DB_VERSION_UNIQUE_NAME@(a)
+#endif
+#define	fetch(a)	__db_dbm_fetch@DB_VERSION_UNIQUE_NAME@(a)
+#define	firstkey	__db_dbm_firstkey@DB_VERSION_UNIQUE_NAME@
+#define	nextkey(a)	__db_dbm_nextkey@DB_VERSION_UNIQUE_NAME@(a)
+#define	store(a, b)	__db_dbm_store@DB_VERSION_UNIQUE_NAME@(a, b)
+
+/*******************************************************
+ * Hsearch historic interface.
+ *******************************************************/
+typedef enum {
+	FIND, ENTER
+} ACTION;
+
+typedef struct entry {
+	char *key;
+	char *data;
+} ENTRY;
+
+#define	hcreate(a)	__db_hcreate@DB_VERSION_UNIQUE_NAME@(a)
+#define	hdestroy	__db_hdestroy@DB_VERSION_UNIQUE_NAME@
+#define	hsearch(a, b)	__db_hsearch@DB_VERSION_UNIQUE_NAME@(a, b)
+
+#endif /* DB_DBM_HSEARCH */
+
+#if defined(__cplusplus)
+}
+#endif
+
+@platform_footer@
+#endif /* !_DB_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/db_185.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,198 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_185_H_
+#define	_DB_185_H_
+
+#include <sys/types.h>
+
+#include <limits.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * XXX
+ * Handle function prototypes and the keyword "const".  This steps on name
+ * space that DB doesn't control, but all of the other solutions are worse.
+ */
+#undef	__P
+#if defined(__STDC__) || defined(__cplusplus)
+#define	__P(protos)	protos		/* ANSI C prototypes */
+#else
+#define	const
+#define	__P(protos)	()		/* K&R C preprocessor */
+#endif
+
+#define	RET_ERROR	-1		/* Return values. */
+#define	RET_SUCCESS	 0
+#define	RET_SPECIAL	 1
+
+#ifndef	__BIT_TYPES_DEFINED__
+#define	__BIT_TYPES_DEFINED__
+@u_int8_decl@
+@int16_decl@
+@u_int16_decl@
+@int32_decl@
+@u_int32_decl@
+#endif
+
+/*
+ * XXX
+ * SGI/IRIX already has a pgno_t.
+ */
+#ifdef	__sgi
+#define	pgno_t	db_pgno_t
+#endif
+
+#define	MAX_PAGE_NUMBER	0xffffffff	/* >= # of pages in a file */
+typedef u_int32_t	pgno_t;
+#define	MAX_PAGE_OFFSET	65535		/* >= # of bytes in a page */
+typedef u_int16_t	indx_t;
+#define	MAX_REC_NUMBER	0xffffffff	/* >= # of records in a tree */
+typedef u_int32_t	recno_t;
+
+/* Key/data structure -- a Data-Base Thang. */
+typedef struct {
+	void	*data;			/* data */
+	size_t	 size;			/* data length */
+} DBT;
+
+/* Routine flags. */
+#define	R_CURSOR	1		/* del, put, seq */
+#define	__R_UNUSED	2		/* UNUSED */
+#define	R_FIRST		3		/* seq */
+#define	R_IAFTER	4		/* put (RECNO) */
+#define	R_IBEFORE	5		/* put (RECNO) */
+#define	R_LAST		6		/* seq (BTREE, RECNO) */
+#define	R_NEXT		7		/* seq */
+#define	R_NOOVERWRITE	8		/* put */
+#define	R_PREV		9		/* seq (BTREE, RECNO) */
+#define	R_SETCURSOR	10		/* put (RECNO) */
+#define	R_RECNOSYNC	11		/* sync (RECNO) */
+
+typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
+
+/* Access method description structure. */
+typedef struct __db {
+	DBTYPE type;			/* Underlying db type. */
+	int (*close)	__P((struct __db *));
+	int (*del)	__P((const struct __db *, const DBT *, u_int));
+	int (*get)	__P((const struct __db *, const DBT *, DBT *, u_int));
+	int (*put)	__P((const struct __db *, DBT *, const DBT *, u_int));
+	int (*seq)	__P((const struct __db *, DBT *, DBT *, u_int));
+	int (*sync)	__P((const struct __db *, u_int));
+	void *internal;			/* Access method private. */
+	int (*fd)	__P((const struct __db *));
+} DB;
+
+#define	BTREEMAGIC	0x053162
+#define	BTREEVERSION	3
+
+/* Structure used to pass parameters to the btree routines. */
+typedef struct {
+#define	R_DUP		0x01	/* duplicate keys */
+	u_int32_t flags;
+	u_int32_t cachesize;	/* bytes to cache */
+	u_int32_t maxkeypage;	/* maximum keys per page */
+	u_int32_t minkeypage;	/* minimum keys per page */
+	u_int32_t psize;	/* page size */
+	int	(*compare)	/* comparison function */
+	    __P((const DBT *, const DBT *));
+	size_t	(*prefix)	/* prefix function */
+	    __P((const DBT *, const DBT *));
+	int	lorder;		/* byte order */
+} BTREEINFO;
+
+#define	HASHMAGIC	0x061561
+#define	HASHVERSION	2
+
+/* Structure used to pass parameters to the hashing routines. */
+typedef struct {
+	u_int32_t bsize;	/* bucket size */
+	u_int32_t ffactor;	/* fill factor */
+	u_int32_t nelem;	/* number of elements */
+	u_int32_t cachesize;	/* bytes to cache */
+	u_int32_t		/* hash function */
+		(*hash) __P((const void *, size_t));
+	int	lorder;		/* byte order */
+} HASHINFO;
+
+/* Structure used to pass parameters to the record routines. */
+typedef struct {
+#define	R_FIXEDLEN	0x01	/* fixed-length records */
+#define	R_NOKEY		0x02	/* key not required */
+#define	R_SNAPSHOT	0x04	/* snapshot the input */
+	u_int32_t flags;
+	u_int32_t cachesize;	/* bytes to cache */
+	u_int32_t psize;	/* page size */
+	int	lorder;		/* byte order */
+	size_t	reclen;		/* record length (fixed-length records) */
+	u_char	bval;		/* delimiting byte (variable-length records */
+	char	*bfname;	/* btree file name */
+} RECNOINFO;
+
+/* Re-define the user's dbopen calls. */
+#define	dbopen __db185_open@DB_VERSION_UNIQUE_NAME@
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_DB_185_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/db_am.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,349 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+#ifndef _DB_AM_H_
+#define	_DB_AM_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+struct __db_foreign_info; \
+			typedef struct __db_foreign_info DB_FOREIGN_INFO;
+
+/*
+ * Keep track of information for foreign keys.  Used to maintain a linked list
+ * of 'primary' DBs which reference this 'foreign' DB.
+ */
+struct __db_foreign_info {
+	DB *dbp;
+	u_int32_t flags;
+	int (*callback) __P((DB *, const DBT *, DBT *, const DBT *, int *));
+
+	/*
+	 * List entries for foreign key.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * LIST_ENTRY(__db) s_links;
+	 */
+	struct {
+		struct __db_foreign_info *le_next;
+		struct __db_foreign_info **le_prev;
+	} f_links;
+};
+
+/*
+ * IS_ENV_AUTO_COMMIT --
+ *	Auto-commit test for enviroment operations: DbEnv::{open,remove,rename}
+ */
+#define	IS_ENV_AUTO_COMMIT(env, txn, flags)				\
+	(LF_ISSET(DB_AUTO_COMMIT) ||					\
+	    (((txn) == NULL || F_ISSET((txn), TXN_FAMILY)) &&		\
+	    F_ISSET((env)->dbenv, DB_ENV_AUTO_COMMIT) &&		\
+	    !LF_ISSET(DB_NO_AUTO_COMMIT)))
+
+/*
+ * IS_DB_AUTO_COMMIT --
+ *	Auto-commit test for database operations.
+ */
+#define	IS_DB_AUTO_COMMIT(dbp, txn)					\
+	(((txn) == NULL || F_ISSET((txn), TXN_FAMILY)) &&		\
+	    F_ISSET((dbp), DB_AM_TXN))
+
+/*
+ * STRIP_AUTO_COMMIT --
+ *	Releases after 4.3 no longer requires DB operations to specify the
+ *	AUTO_COMMIT flag, but the API continues to allow it to be specified.
+ */
+#define	STRIP_AUTO_COMMIT(f)	FLD_CLR((f), DB_AUTO_COMMIT)
+
+/* DB recovery operation codes. */
+#define	DB_ADD_DUP	1
+#define	DB_REM_DUP	2
+#define	DB_ADD_BIG	3
+#define	DB_REM_BIG	4
+#define	DB_ADD_PAGE_COMPAT	5	/* Compatibility for 4.2 db_relink */
+#define	DB_REM_PAGE_COMPAT	6	/* Compatibility for 4.2 db_relink */
+#define	DB_APPEND_BIG	7
+#define	DB_ADD_HEAP	8
+#define	DB_REM_HEAP	9
+
+#define OP_MODE_SHIFT   8
+#define OP_PAGE_MASK    0xff
+
+#define OP_SET(mode, page)	(((mode) << OP_MODE_SHIFT) | (TYPE(page)))
+#define OP_MODE_GET(mode)	((mode) >> OP_MODE_SHIFT)
+#define OP_PAGE_GET(mode)	((mode) & OP_PAGE_MASK)
+
+
+/*
+ * Standard initialization and shutdown macros for all recovery functions.
+ */
+#define	REC_INTRO(func, ip, do_cursor) do {				\
+	argp = NULL;							\
+	dbc = NULL;							\
+	file_dbp = NULL;						\
+	COMPQUIET(mpf, NULL);	/* Not all recovery routines use mpf. */\
+	if ((ret = func(env, &file_dbp,					\
+	    (info != NULL) ? ((DB_TXNHEAD *)info)->td : NULL,		\
+	    dbtp->data, &argp)) != 0) {					\
+		if (ret	== DB_DELETED) {				\
+			ret = 0;					\
+			goto done;					\
+		}							\
+		goto out;						\
+	}								\
+	if (do_cursor) {						\
+		if ((ret = __db_cursor(file_dbp,			\
+		    ip, NULL, &dbc, DB_RECOVER)) != 0)			\
+			goto out;					\
+	}								\
+	mpf = file_dbp->mpf;						\
+} while (0)
+
+#define	REC_CLOSE {							\
+	int __t_ret;							\
+	if (argp != NULL)						\
+		__os_free(env, argp);					\
+	if (dbc != NULL &&						\
+	    (__t_ret = __dbc_close(dbc)) != 0 && ret == 0)		\
+		ret = __t_ret;						\
+	}								\
+	return (ret)
+
+/*
+ * No-op versions of the same macros.
+ */
+#define	REC_NOOP_INTRO(func) do {					\
+	argp = NULL;							\
+	if ((ret = func(env, dbtp->data, &argp)) != 0)		\
+		return (ret);						\
+} while (0)
+#define	REC_NOOP_CLOSE							\
+	if (argp != NULL)						\
+		__os_free(env, argp);					\
+	return (ret)
+
+/*
+ * Macro for reading pages during recovery.  In most cases we
+ * want to avoid an error if the page is not found during rollback.
+ */
+#define	REC_FGET(mpf, ip, pgno, pagep, cont)				\
+	if ((ret = __memp_fget(mpf,					\
+	     &(pgno), ip, NULL, 0, pagep)) != 0) {			\
+		if (ret != DB_PAGE_NOTFOUND) {				\
+			ret = __db_pgerr(file_dbp, pgno, ret);		\
+			goto out;					\
+		} else							\
+			goto cont;					\
+	}
+#define	REC_DIRTY(mpf, ip, priority, pagep)				\
+	if ((ret = __memp_dirty(mpf,					\
+	    pagep, ip, NULL, priority, DB_MPOOL_EDIT)) != 0) {		\
+		ret = __db_pgerr(file_dbp, PGNO(*(pagep)), ret);	\
+		goto out;						\
+	}
+
+/*
+ * Standard debugging macro for all recovery functions.
+ */
+#ifdef DEBUG_RECOVER
+#define	REC_PRINT(func)							\
+	(void)func(env, dbtp, lsnp, op, info);
+#else
+#define	REC_PRINT(func)
+#endif
+
+/*
+ * Actions to __db_lget
+ */
+#define	LCK_ALWAYS		1	/* Lock even for off page dup cursors */
+#define	LCK_COUPLE		2	/* Lock Couple */
+#define	LCK_COUPLE_ALWAYS	3	/* Lock Couple even in txn. */
+#define	LCK_DOWNGRADE		4	/* Downgrade the lock. (internal) */
+#define	LCK_ROLLBACK		5	/* Lock even if in rollback */
+
+/*
+ * If doing transactions we have to hold the locks associated with a data item
+ * from a page for the entire transaction.  However, we don't have to hold the
+ * locks associated with walking the tree.  Distinguish between the two so that
+ * we don't tie up the internal pages of the tree longer than necessary.
+ */
+#define	__LPUT(dbc, lock)						\
+	__ENV_LPUT((dbc)->env, lock)
+
+#define	__ENV_LPUT(env, lock)						\
+	(LOCK_ISSET(lock) ? __lock_put(env, &(lock)) : 0)
+
+/*
+ * __TLPUT -- transactional lock put
+ *	If the lock is valid then
+ *	   If we are not in a transaction put the lock.
+ *	   Else if the cursor is doing dirty reads and this was a read then
+ *		put the lock.
+ *	   Else if the db is supporting dirty reads and this is a write then
+ *		downgrade it.
+ *	Else do nothing.
+ */
+#define	__TLPUT(dbc, lock)						\
+	(LOCK_ISSET(lock) ? __db_lput(dbc, &(lock)) : 0)
+
+/*
+ * Check whether a database is a primary (that is, has associated secondaries).
+ */
+#define	DB_IS_PRIMARY(dbp) (LIST_FIRST(&dbp->s_secondaries) != NULL)
+/*
+ * A database should be required to be readonly if it's been explicitly
+ * specified as such or if we're a client in a replicated environment
+ * and the user did not specify DB_TXN_NOT_DURABLE.
+ */
+#define	DB_IS_READONLY(dbp)						\
+    (F_ISSET(dbp, DB_AM_RDONLY) ||					\
+    (IS_REP_CLIENT((dbp)->env) && !F_ISSET((dbp), DB_AM_NOT_DURABLE)))
+
+#ifdef HAVE_COMPRESSION
+/*
+ * Check whether a database is compressed (btree only)
+ */
+#define	DB_IS_COMPRESSED(dbp)						\
+    (((BTREE *)(dbp)->bt_internal)->bt_compress != NULL)
+#endif
+
+/*
+ * We copy the key out if there's any chance the key in the database is not
+ * the same as the user-specified key.  If there is a custom comparator we
+ * return a key, as the user-specified key might be a partial key, containing
+ * only the unique identifier.  [#13572] [#15770]
+ *
+ * The test for (flags != 0) is necessary for Db.{get,pget}, but it's not
+ * legal to pass a non-zero flags value to Dbc.{get,pget}.
+ *
+ * We need to split out the hash component, since it is possible to build
+ * without hash support enabled. Which would result in a null pointer access.
+ */
+#ifdef HAVE_HASH
+#define	DB_RETURNS_A_KEY_HASH(dbp)					\
+	((HASH *)(dbp)->h_internal)->h_compare != NULL
+#else
+#define	DB_RETURNS_A_KEY_HASH(dbp)	0
+#endif
+#define	DB_RETURNS_A_KEY(dbp, flags)					\
+	(((flags) != 0 && (flags) != DB_GET_BOTH &&			\
+	    (flags) != DB_GET_BOTH_RANGE && (flags) != DB_SET) ||	\
+	    ((BTREE *)(dbp)->bt_internal)->bt_compare != __bam_defcmp ||\
+	    DB_RETURNS_A_KEY_HASH(dbp))
+
+/*
+ * For portability, primary keys that are record numbers are stored in
+ * secondaries in the same byte order as the secondary database.  As a
+ * consequence, we need to swap the byte order of these keys before attempting
+ * to use them for lookups in the primary.  We also need to swap user-supplied
+ * primary keys that are used in secondary lookups (for example, with the
+ * DB_GET_BOTH flag on a secondary get).
+ */
+#include "dbinc/db_swap.h"
+
+#define	SWAP_IF_NEEDED(sdbp, pkey)					\
+	do {								\
+		if (((sdbp)->s_primary->type == DB_QUEUE ||		\
+		    (sdbp)->s_primary->type == DB_RECNO) &&		\
+		    F_ISSET((sdbp), DB_AM_SWAP))			\
+			P_32_SWAP((pkey)->data);			\
+	} while (0)
+
+/*
+ * Cursor adjustment:
+ *	Return the first DB handle in the sorted ENV list of DB
+ *	handles that has a matching file ID.
+ */
+#define	FIND_FIRST_DB_MATCH(env, dbp, tdbp) do {			\
+	for ((tdbp) = (dbp);						\
+	    TAILQ_PREV((tdbp), __dblist, dblistlinks) != NULL &&	\
+	    TAILQ_PREV((tdbp),						\
+		__dblist, dblistlinks)->adj_fileid == (dbp)->adj_fileid;\
+	    (tdbp) = TAILQ_PREV((tdbp), __dblist, dblistlinks))		\
+		;							\
+} while (0)
+
+/*
+ * Macros used to implement a binary search algorithm. Shared between the
+ * btree and hash implementations.
+ */
+#define	DB_BINARY_SEARCH_FOR(base, limit, nument, adjust)		\
+	for (base = 0, limit = (nument) / (db_indx_t)(adjust);		\
+	    (limit) != 0; (limit) >>= 1)
+
+#define	DB_BINARY_SEARCH_INCR(index, base, limit, adjust)		\
+	index = (base) + (((limit) >> 1) * (adjust))
+
+#define	DB_BINARY_SEARCH_SHIFT_BASE(index, base, limit, adjust)	do {	\
+	base = (index) + (adjust);					\
+	--(limit);							\
+} while (0)
+
+/*
+ * Sequence macros, shared between sequence.c and seq_stat.c
+ */
+#define	SEQ_IS_OPEN(seq)	((seq)->seq_key.data != NULL)
+
+#define	SEQ_ILLEGAL_AFTER_OPEN(seq, name)				\
+	if (SEQ_IS_OPEN(seq))						\
+		return (__db_mi_open((seq)->seq_dbp->env, name, 1));
+
+#define	SEQ_ILLEGAL_BEFORE_OPEN(seq, name)				\
+	if (!SEQ_IS_OPEN(seq))						\
+		return (__db_mi_open((seq)->seq_dbp->env, name, 0));
+
+/*
+ * Flags to __db_chk_meta.
+ */
+#define	DB_CHK_META	0x01	/* Checksum the meta page. */
+#define	DB_CHK_NOLSN	0x02	/* Don't check the LSN. */
+#define	DB_CHK_ONLY	0x04	/* Only do the checksum. */
+#define	DB_SKIP_CHK	0x08	/* Don't checksum or decrypt the meta page. */
+
+/*
+ * Flags to __db_truncate_page.
+ */
+#define DB_EXCH_FREE		0x01	/* Free the old page. */
+#define DB_EXCH_PARENT		0x02	/* There is a parent to update. */
+
+/* We usually want to do these operations. */
+#define DB_EXCH_DEFAULT		(DB_EXCH_FREE | DB_EXCH_PARENT)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc/db_dispatch.h"
+#include "dbinc_auto/db_auto.h"
+#include "dbinc_auto/crdel_auto.h"
+#include "dbinc_auto/db_ext.h"
+#endif /* !_DB_AM_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/db_cxx.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1545 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_CXX_H_
+#define	_DB_CXX_H_
+//
+// C++ assumptions:
+//
+// To ensure portability to many platforms, both new and old, we make
+// few assumptions about the C++ compiler and library.  For example,
+// we do not expect STL, templates or namespaces to be available.  The
+// "newest" C++ feature used is exceptions, which are used liberally
+// to transmit error information.  Even the use of exceptions can be
+// disabled at runtime, to do so, use the DB_CXX_NO_EXCEPTIONS flags
+// with the DbEnv or Db constructor.
+//
+// C++ naming conventions:
+//
+//  - All top level class names start with Db.
+//  - All class members start with lower case letter.
+//  - All private data members are suffixed with underscore.
+//  - Use underscores to divide names into multiple words.
+//  - Simple data accessors are named with get_ or set_ prefix.
+//  - All method names are taken from names of functions in the C
+//    layer of db (usually by dropping a prefix like "db_").
+//    These methods have the same argument types and order,
+//    other than dropping the explicit arg that acts as "this".
+//
+// As a rule, each DbFoo object has exactly one underlying DB_FOO struct
+// (defined in db.h) associated with it.  In some cases, we inherit directly
+// from the DB_FOO structure to make this relationship explicit.  Often,
+// the underlying C layer allocates and deallocates these structures, so
+// there is no easy way to add any data to the DbFoo class.  When you see
+// a comment about whether data is permitted to be added, this is what
+// is going on.  Of course, if we need to add data to such C++ classes
+// in the future, we will arrange to have an indirect pointer to the
+// DB_FOO struct (as some of the classes already have).
+//
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// Forward declarations
+//
+
+#include <stdarg.h>
+
+@cxx_have_stdheaders@
+#ifdef HAVE_CXX_STDHEADERS
+#include <iostream>
+#include <exception>
+#define	__DB_STD(x)	std::x
+#else
+#include <iostream.h>
+#include <exception.h>
+#define	__DB_STD(x)	x
+#endif
+
+#include "db.h"
+
+class Db;                                        // forward
+class Dbc;                                       // forward
+class DbChannel;                                 // forward
+class DbEnv;                                     // forward
+class DbHeapRecordId;                            // forward
+class DbInfo;                                    // forward
+class DbLock;                                    // forward
+class DbLogc;                                    // forward
+class DbLsn;                                     // forward
+class DbMpoolFile;                               // forward
+class DbPreplist;                                // forward
+class DbSequence;                                // forward
+class DbSite;                                    // forward
+class Dbt;                                       // forward
+class DbTxn;                                     // forward
+
+class DbMultipleIterator;                        // forward
+class DbMultipleKeyDataIterator;                 // forward
+class DbMultipleRecnoDataIterator;               // forward
+class DbMultipleDataIterator;                    // forward
+
+class DbException;                               // forward
+class DbDeadlockException;                       // forward
+class DbLockNotGrantedException;                 // forward
+class DbMemoryException;                         // forward
+class DbRepHandleDeadException;                  // forward
+class DbRunRecoveryException;                    // forward
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// Turn off inappropriate compiler warnings
+//
+
+#ifdef _MSC_VER
+
+// These are level 4 warnings that are explicitly disabled.
+// With Visual C++, by default you do not see above level 3 unless
+// you use /W4.  But we like to compile with the highest level
+// warnings to catch other errors.
+//
+// 4201: nameless struct/union
+//       triggered by standard include file <winnt.h>
+//
+// 4514: unreferenced inline function has been removed
+//       certain include files in MSVC define methods that are not called
+//
+#pragma warning(push)
+#pragma warning(disable: 4201 4514)
+
+#endif
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// Mechanisms for declaring classes
+//
+
+//
+// Every class defined in this file has an _exported next to the class name.
+// This is needed for WinTel machines so that the class methods can
+// be exported or imported in a DLL as appropriate.  Users of the DLL
+// use the define DB_USE_DLL.  When the DLL is built, DB_CREATE_DLL
+// must be defined.
+//
+#if defined(_MSC_VER)
+
+#  if defined(DB_CREATE_DLL)
+#    define _exported __declspec(dllexport)      // creator of dll
+#  elif defined(DB_USE_DLL)
+#    define _exported __declspec(dllimport)      // user of dll
+#  else
+#    define _exported                            // static lib creator or user
+#  endif
+
+#else /* _MSC_VER */
+
+#  define _exported
+
+#endif /* _MSC_VER */
+
+// Some interfaces can be customized by allowing users to define
+// callback functions.  For performance and logistical reasons, some
+// callback functions must be declared in extern "C" blocks.  For others,
+// we allow you to declare the callbacks in C++ or C (or an extern "C"
+// block) as you wish.  See the set methods for the callbacks for
+// the choices.
+//
+extern "C" {
+	typedef void * (*db_malloc_fcn_type)
+		(size_t);
+	typedef void * (*db_realloc_fcn_type)
+		(void *, size_t);
+	typedef void (*db_free_fcn_type)
+		(void *);
+	typedef int (*bt_compare_fcn_type)          /*C++ version available*/
+		(DB *, const DBT *, const DBT *);
+	typedef size_t (*bt_prefix_fcn_type)        /*C++ version available*/
+		(DB *, const DBT *, const DBT *);
+	typedef int (*dup_compare_fcn_type)         /*C++ version available*/
+		(DB *, const DBT *, const DBT *);
+	typedef int (*h_compare_fcn_type)          /*C++ version available*/
+		(DB *, const DBT *, const DBT *);
+	typedef u_int32_t (*h_hash_fcn_type)        /*C++ version available*/
+		(DB *, const void *, u_int32_t);
+	typedef int (*pgin_fcn_type)
+		(DB_ENV *dbenv, db_pgno_t pgno, void *pgaddr, DBT *pgcookie);
+	typedef int (*pgout_fcn_type)
+		(DB_ENV *dbenv, db_pgno_t pgno, void *pgaddr, DBT *pgcookie);
+}
+
+//
+// Represents a database table = a set of keys with associated values.
+//
+class _exported Db
+{
+	friend class DbEnv;
+
+public:
+	Db(DbEnv*, u_int32_t);      // Create a Db object.
+	virtual ~Db();              // Calls close() if the user hasn't.
+
+	// These methods exactly match those in the C interface.
+	//
+	virtual int associate(DbTxn *txn, Db *secondary, int (*callback)
+	    (Db *, const Dbt *, const Dbt *, Dbt *), u_int32_t flags);
+	virtual int associate_foreign(Db *foreign, int (*callback)
+	    (Db *, const Dbt *, Dbt *, const Dbt *, int *), u_int32_t flags);
+	virtual int close(u_int32_t flags);
+	virtual int compact(DbTxn *txnid, Dbt *start,
+	    Dbt *stop, DB_COMPACT *c_data, u_int32_t flags, Dbt *end);
+	virtual int cursor(DbTxn *txnid, Dbc **cursorp, u_int32_t flags);
+	virtual int del(DbTxn *txnid, Dbt *key, u_int32_t flags);
+	virtual void err(int, const char *, ...);
+	virtual void errx(const char *, ...);
+	virtual int exists(DbTxn *txnid, Dbt *key, u_int32_t flags);
+	virtual int fd(int *fdp);
+	virtual int get(DbTxn *txnid, Dbt *key, Dbt *data, u_int32_t flags);
+	virtual int get_alloc(
+	    db_malloc_fcn_type *, db_realloc_fcn_type *, db_free_fcn_type *);
+	virtual int get_append_recno(int (**)(Db *, Dbt *, db_recno_t));
+	virtual int get_bt_compare(int (**)(Db *, const Dbt *, const Dbt *));
+	virtual int get_bt_compress(
+	    int (**)(
+	    Db *, const Dbt *, const Dbt *, const Dbt *, const Dbt *, Dbt *),
+	    int (**)(Db *, const Dbt *, const Dbt *, Dbt *, Dbt *, Dbt *));
+	virtual int get_bt_minkey(u_int32_t *);
+	virtual int get_bt_prefix(size_t (**)(Db *, const Dbt *, const Dbt *));
+	virtual int get_byteswapped(int *);
+	virtual int get_cachesize(u_int32_t *, u_int32_t *, int *);
+	virtual int get_create_dir(const char **);
+	virtual int get_dbname(const char **, const char **);
+	virtual int get_dup_compare(int (**)(Db *, const Dbt *, const Dbt *));
+	virtual int get_encrypt_flags(u_int32_t *);
+	virtual void get_errcall(
+	    void (**)(const DbEnv *, const char *, const char *));
+	virtual void get_errfile(FILE **);
+	virtual void get_errpfx(const char **);
+	virtual int get_feedback(void (**)(Db *, int, int));
+	virtual int get_flags(u_int32_t *);
+	virtual int get_heapsize(u_int32_t *, u_int32_t *);
+	virtual int get_heap_regionsize(u_int32_t *);
+	virtual int get_h_compare(int (**)(Db *, const Dbt *, const Dbt *));
+	virtual int get_h_ffactor(u_int32_t *);
+	virtual int get_h_hash(u_int32_t (**)(Db *, const void *, u_int32_t));
+	virtual int get_h_nelem(u_int32_t *);
+	virtual int get_lk_exclusive(bool *, bool *);
+	virtual int get_lorder(int *);
+	virtual void get_msgcall(void (**)(const DbEnv *, const char *));
+	virtual void get_msgfile(FILE **);
+	virtual int get_multiple();
+	virtual int get_open_flags(u_int32_t *);
+	virtual int get_pagesize(u_int32_t *);
+	virtual int get_partition_callback(
+	    u_int32_t *, u_int32_t (**)(Db *, Dbt *key));
+	virtual int get_partition_dirs(const char ***);
+	virtual int get_partition_keys(u_int32_t *, Dbt **);
+	virtual int get_priority(DB_CACHE_PRIORITY *);
+	virtual int get_q_extentsize(u_int32_t *);
+	virtual int get_re_delim(int *);
+	virtual int get_re_len(u_int32_t *);
+	virtual int get_re_pad(int *);
+	virtual int get_re_source(const char **);
+	virtual int get_transactional();
+	virtual int get_type(DBTYPE *);
+	virtual int join(Dbc **curslist, Dbc **dbcp, u_int32_t flags);
+	virtual int key_range(DbTxn *, Dbt *, DB_KEY_RANGE *, u_int32_t);
+	virtual int open(DbTxn *txnid,
+	    const char *, const char *subname, DBTYPE, u_int32_t, int);
+	virtual int pget(DbTxn *txnid,
+	    Dbt *key, Dbt *pkey, Dbt *data, u_int32_t flags);
+	virtual int put(DbTxn *, Dbt *, Dbt *, u_int32_t);
+	virtual int remove(const char *, const char *, u_int32_t);
+	virtual int rename(const char *, const char *, const char *, u_int32_t);
+	virtual int set_alloc(
+	    db_malloc_fcn_type, db_realloc_fcn_type, db_free_fcn_type);
+	virtual void set_app_private(void *);
+	virtual int set_append_recno(int (*)(Db *, Dbt *, db_recno_t));
+	virtual int set_bt_compare(bt_compare_fcn_type); /*deprecated*/
+	virtual int set_bt_compare(int (*)(Db *, const Dbt *, const Dbt *));
+	virtual int set_bt_compress(
+	    int (*)
+	    (Db *, const Dbt *, const Dbt *, const Dbt *, const Dbt *, Dbt *),
+	    int (*)(Db *, const Dbt *, const Dbt *, Dbt *, Dbt *, Dbt *));
+	virtual int set_bt_minkey(u_int32_t);
+	virtual int set_bt_prefix(bt_prefix_fcn_type); /*deprecated*/
+	virtual int set_bt_prefix(size_t (*)(Db *, const Dbt *, const Dbt *));
+	virtual int set_cachesize(u_int32_t, u_int32_t, int);
+	virtual int set_create_dir(const char *);
+	virtual int set_dup_compare(dup_compare_fcn_type); /*deprecated*/
+	virtual int set_dup_compare(int (*)(Db *, const Dbt *, const Dbt *));
+	virtual int set_encrypt(const char *, u_int32_t);
+	virtual void set_errcall(
+	    void (*)(const DbEnv *, const char *, const char *));
+	virtual void set_errfile(FILE *);
+	virtual void set_errpfx(const char *);
+	virtual int set_feedback(void (*)(Db *, int, int));
+	virtual int set_flags(u_int32_t);
+	virtual int set_heapsize(u_int32_t, u_int32_t);
+	virtual int set_heap_regionsize(u_int32_t);
+	virtual int set_h_compare(h_compare_fcn_type); /*deprecated*/
+	virtual int set_h_compare(int (*)(Db *, const Dbt *, const Dbt *));
+	virtual int set_h_ffactor(u_int32_t);
+	virtual int set_h_hash(h_hash_fcn_type); /*deprecated*/
+	virtual int set_h_hash(u_int32_t (*)(Db *, const void *, u_int32_t));
+	virtual int set_h_nelem(u_int32_t);
+	virtual int set_lk_exclusive(bool);
+	virtual int set_lorder(int);
+	virtual void set_msgcall(void (*)(const DbEnv *, const char *));
+	virtual void set_msgfile(FILE *);
+	virtual int set_pagesize(u_int32_t);
+	virtual int set_paniccall(void (*)(DbEnv *, int));
+	virtual int set_partition(
+	    u_int32_t, Dbt *, u_int32_t (*)(Db *, Dbt *));
+	virtual int set_partition_dirs(const char **);
+	virtual int set_priority(DB_CACHE_PRIORITY);
+	virtual int set_q_extentsize(u_int32_t);
+	virtual int set_re_delim(int);
+	virtual int set_re_len(u_int32_t);
+	virtual int set_re_pad(int);
+	virtual int set_re_source(const char *);
+	virtual int sort_multiple(Dbt *, Dbt *, u_int32_t);
+	virtual int stat(DbTxn *, void *sp, u_int32_t flags);
+	virtual int stat_print(u_int32_t flags);
+	virtual int sync(u_int32_t flags);
+	virtual int truncate(DbTxn *, u_int32_t *, u_int32_t);
+	virtual int upgrade(const char *name, u_int32_t flags);
+	virtual int verify(
+	    const char *, const char *, __DB_STD(ostream) *, u_int32_t);
+
+	// These additional methods are not in the C interface, and
+	// are only available for C++.
+	//
+	virtual void *get_app_private() const;
+	virtual __DB_STD(ostream) *get_error_stream();
+	virtual void set_error_stream(__DB_STD(ostream) *);
+	virtual __DB_STD(ostream) *get_message_stream();
+	virtual void set_message_stream(__DB_STD(ostream) *);
+
+	virtual DbEnv *get_env();
+	virtual DbMpoolFile *get_mpf();
+
+	virtual ENV *get_ENV()
+	{
+		return imp_->env;
+	}
+
+	virtual DB *get_DB()
+	{
+		return imp_;
+	}
+
+	virtual const DB *get_const_DB() const
+	{
+		return imp_;
+	}
+
+	static Db* get_Db(DB *db)
+	{
+		return (Db *)db->api_internal;
+	}
+
+	static const Db* get_const_Db(const DB *db)
+	{
+		return (const Db *)db->api_internal;
+	}
+	
+	u_int32_t get_create_flags() const
+	{
+		return construct_flags_;
+	}
+
+private:
+	// no copying
+	Db(const Db &);
+	Db &operator = (const Db &);
+
+	void cleanup();
+	int initialize();
+	int error_policy();
+
+	// instance data
+	DB *imp_;
+	DbEnv *dbenv_;
+	DbMpoolFile *mpf_;
+	int construct_error_;
+	u_int32_t flags_;
+	u_int32_t construct_flags_;
+
+	static int alt_close(DB *, u_int32_t);
+
+public:
+	// These are public only because they need to be called
+	// via C callback functions.  They should never be used by
+	// external users of this class.
+	//
+	int (*append_recno_callback_)(Db *, Dbt *, db_recno_t);
+	int (*associate_callback_)(Db *, const Dbt *, const Dbt *, Dbt *);
+	int (*associate_foreign_callback_)
+	    (Db *, const Dbt *, Dbt *, const Dbt *, int *);
+	int (*bt_compare_callback_)(Db *, const Dbt *, const Dbt *);
+	int (*bt_compress_callback_)(
+	    Db *, const Dbt *, const Dbt *, const Dbt *, const Dbt *, Dbt *);
+	int (*bt_decompress_callback_)(
+	    Db *, const Dbt *, const Dbt *, Dbt *, Dbt *, Dbt *);
+	size_t (*bt_prefix_callback_)(Db *, const Dbt *, const Dbt *);
+	u_int32_t (*db_partition_callback_)(Db *, Dbt *);
+	int (*dup_compare_callback_)(Db *, const Dbt *, const Dbt *);
+	void (*feedback_callback_)(Db *, int, int);
+	int (*h_compare_callback_)(Db *, const Dbt *, const Dbt *);
+	u_int32_t (*h_hash_callback_)(Db *, const void *, u_int32_t);
+};
+
+//
+// Cursor
+//
+class _exported Dbc : protected DBC
+{
+	friend class Db;
+
+public:
+	int close();
+	int cmp(Dbc *other_csr, int *result, u_int32_t flags);
+	int count(db_recno_t *countp, u_int32_t flags);
+	int del(u_int32_t flags);
+	int dup(Dbc** cursorp, u_int32_t flags);
+	int get(Dbt* key, Dbt *data, u_int32_t flags);
+	int get_priority(DB_CACHE_PRIORITY *priorityp);
+	int pget(Dbt* key, Dbt* pkey, Dbt *data, u_int32_t flags);
+	int put(Dbt* key, Dbt *data, u_int32_t flags);
+	int set_priority(DB_CACHE_PRIORITY priority);
+
+private:
+	// No data is permitted in this class (see comment at top)
+
+	// Note: use Db::cursor() to get pointers to a Dbc,
+	// and call Dbc::close() rather than delete to release them.
+	//
+	Dbc();
+	~Dbc();
+
+	// no copying
+	Dbc(const Dbc &);
+	Dbc &operator = (const Dbc &);
+};
+
+//
+// A channel in replication group
+//
+class _exported DbChannel
+{
+	friend class DbEnv;
+
+public:
+	int close();
+	int send_msg(Dbt *msg, u_int32_t nmsg, u_int32_t flags);
+	int send_request(Dbt *request, u_int32_t nrequest, Dbt *response,
+	    db_timeout_t timeout, u_int32_t flags); 
+	int set_timeout(db_timeout_t timeout);
+
+	virtual DB_CHANNEL *get_DB_CHANNEL()
+	{
+		return imp_;
+	}
+
+	virtual const DB_CHANNEL *get_const_DB_CHANNEL() const
+	{
+		return imp_;
+	}
+
+private:
+	DbChannel();
+	virtual ~DbChannel();
+
+	// no copying
+	DbChannel(const DbChannel &);
+	DbChannel &operator = (const DbChannel &);
+	DB_CHANNEL *imp_;
+	DbEnv *dbenv_;
+};
+
+//
+// Berkeley DB environment class.  Provides functions for opening databases.
+// User of this library can use this class as a starting point for
+// developing a DB application - derive their application class from
+// this one, add application control logic.
+//
+// Note that if you use the default constructor, you must explicitly
+// call appinit() before any other db activity (e.g. opening files)
+//
+class _exported DbEnv
+{
+	friend class Db;
+	friend class DbLock;
+	friend class DbMpoolFile;
+
+public:
+	// After using this constructor, you can set any needed
+	// parameters for the environment using the set_* methods.
+	// Then call open() to finish initializing the environment
+	// and attaching it to underlying files.
+	//
+	DbEnv(u_int32_t flags);
+
+	virtual ~DbEnv();
+
+	// These methods match those in the C interface.
+	//
+	virtual int add_data_dir(const char *);
+	virtual int backup(const char *target, u_int32_t flags);
+	virtual int cdsgroup_begin(DbTxn **tid);
+	virtual int close(u_int32_t);
+	virtual int dbbackup(
+	    const char *dbfile, const char *target, u_int32_t flags);
+	virtual int dbremove(DbTxn *txn, const char *name, const char *subdb,
+	    u_int32_t flags);
+	virtual int dbrename(DbTxn *txn, const char *name, const char *subdb,
+	    const char *newname, u_int32_t flags);
+	virtual void err(int, const char *, ...);
+	virtual void errx(const char *, ...);
+	virtual int failchk(u_int32_t);
+	virtual int fileid_reset(const char *, u_int32_t);
+	virtual int get_alloc(db_malloc_fcn_type *, db_realloc_fcn_type *,
+	    db_free_fcn_type *);
+	virtual void *get_app_private() const;
+	virtual int get_home(const char **);
+	virtual int get_open_flags(u_int32_t *);
+	virtual int open(const char *, u_int32_t, int);
+	virtual int remove(const char *, u_int32_t);
+	virtual int stat_print(u_int32_t flags);
+
+	virtual int set_alloc(db_malloc_fcn_type, db_realloc_fcn_type,
+	    db_free_fcn_type);
+	virtual void set_app_private(void *);
+	virtual int get_backup_callbacks(
+	    int (**)(DbEnv *, const char *, const char *, void **),
+	    int (**)(DbEnv *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *),
+	    int (**)(DbEnv *, const char *, void *));
+	virtual int set_backup_callbacks(
+	    int (*)(DbEnv *, const char *, const char *, void **),
+	    int (*)(DbEnv *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *),
+	    int (*)(DbEnv *, const char *, void *));
+	virtual int get_backup_config(DB_BACKUP_CONFIG, u_int32_t *);
+	virtual int set_backup_config(DB_BACKUP_CONFIG, u_int32_t);
+	virtual int get_cachesize(u_int32_t *, u_int32_t *, int *);
+	virtual int set_cachesize(u_int32_t, u_int32_t, int);
+	virtual int get_cache_max(u_int32_t *, u_int32_t *);
+	virtual int set_cache_max(u_int32_t, u_int32_t);
+	virtual int get_create_dir(const char **);
+	virtual int set_create_dir(const char *);
+	virtual int get_data_dirs(const char ***);
+	virtual int set_data_dir(const char *);
+	virtual int get_encrypt_flags(u_int32_t *);
+	virtual int get_intermediate_dir_mode(const char **);
+	virtual int set_intermediate_dir_mode(const char *);
+	virtual int get_isalive(
+	    int (**)(DbEnv *, pid_t, db_threadid_t, u_int32_t));
+	virtual int set_isalive(
+	    int (*)(DbEnv *, pid_t, db_threadid_t, u_int32_t));
+	virtual int set_encrypt(const char *, u_int32_t);
+	virtual void get_errcall(
+	    void (**)(const DbEnv *, const char *, const char *));
+	virtual void set_errcall(
+	    void (*)(const DbEnv *, const char *, const char *));
+	virtual void get_errfile(FILE **);
+	virtual void set_errfile(FILE *);
+	virtual void get_errpfx(const char **);
+	virtual void set_errpfx(const char *);
+	virtual int set_event_notify(void (*)(DbEnv *, u_int32_t, void *));
+	virtual int get_flags(u_int32_t *);
+	virtual int set_flags(u_int32_t, int);
+	virtual bool is_bigendian();
+	virtual int lsn_reset(const char *, u_int32_t);
+	virtual int get_feedback(void (**)(DbEnv *, int, int));
+	virtual int set_feedback(void (*)(DbEnv *, int, int));
+	virtual int get_lg_bsize(u_int32_t *);
+	virtual int set_lg_bsize(u_int32_t);
+	virtual int get_lg_dir(const char **);
+	virtual int set_lg_dir(const char *);
+	virtual int get_lg_filemode(int *);
+	virtual int set_lg_filemode(int);
+	virtual int get_lg_max(u_int32_t *);
+	virtual int set_lg_max(u_int32_t);
+	virtual int get_lg_regionmax(u_int32_t *);
+	virtual int set_lg_regionmax(u_int32_t);
+	virtual int get_lk_conflicts(const u_int8_t **, int *);
+	virtual int set_lk_conflicts(u_int8_t *, int);
+	virtual int get_lk_detect(u_int32_t *);
+	virtual int set_lk_detect(u_int32_t);
+	virtual int get_lk_max_lockers(u_int32_t *);
+	virtual int set_lk_max_lockers(u_int32_t);
+	virtual int get_lk_max_locks(u_int32_t *);
+	virtual int set_lk_max_locks(u_int32_t);
+	virtual int get_lk_max_objects(u_int32_t *);
+	virtual int set_lk_max_objects(u_int32_t);
+	virtual int get_lk_partitions(u_int32_t *);
+	virtual int set_lk_partitions(u_int32_t);
+	virtual int get_lk_priority(u_int32_t, u_int32_t *);
+	virtual int set_lk_priority(u_int32_t, u_int32_t);
+	virtual int get_lk_tablesize(u_int32_t *);
+	virtual int set_lk_tablesize(u_int32_t);
+	virtual int get_memory_init(DB_MEM_CONFIG, u_int32_t *);
+	virtual int set_memory_init(DB_MEM_CONFIG, u_int32_t);
+	virtual int get_memory_max(u_int32_t *, u_int32_t *);
+	virtual int set_memory_max(u_int32_t, u_int32_t);
+	virtual int get_metadata_dir(const char **);
+	virtual int set_metadata_dir(const char *);
+	virtual int get_mp_mmapsize(size_t *);
+	virtual int set_mp_mmapsize(size_t);
+	virtual int get_mp_max_openfd(int *);
+	virtual int set_mp_max_openfd(int);
+	virtual int get_mp_max_write(int *, db_timeout_t *);
+	virtual int set_mp_max_write(int, db_timeout_t);
+	virtual int get_mp_pagesize(u_int32_t *);
+	virtual int set_mp_pagesize(u_int32_t);
+	virtual int get_mp_tablesize(u_int32_t *);
+	virtual int set_mp_tablesize(u_int32_t);
+	virtual void get_msgcall(void (**)(const DbEnv *, const char *));
+	virtual void set_msgcall(void (*)(const DbEnv *, const char *));
+	virtual void get_msgfile(FILE **);
+	virtual void set_msgfile(FILE *);
+	virtual int set_paniccall(void (*)(DbEnv *, int));
+	virtual int get_shm_key(long *);
+	virtual int set_shm_key(long);
+	virtual int get_timeout(db_timeout_t *, u_int32_t);
+	virtual int set_timeout(db_timeout_t, u_int32_t);
+	virtual int get_tmp_dir(const char **);
+	virtual int set_tmp_dir(const char *);
+	virtual int get_tx_max(u_int32_t *);
+	virtual int set_tx_max(u_int32_t);
+	virtual int get_app_dispatch(
+	    int (**)(DbEnv *, Dbt *, DbLsn *, db_recops));
+	virtual int set_app_dispatch(int (*)(DbEnv *,
+	    Dbt *, DbLsn *, db_recops));
+	virtual int get_tx_timestamp(time_t *);
+	virtual int set_tx_timestamp(time_t *);
+	virtual int get_verbose(u_int32_t which, int *);
+	virtual int set_verbose(u_int32_t which, int);
+
+	// Version information.  Static methods, can be called at any time.
+	//
+	static char *version(int *major, int *minor, int *patch);
+	static char *full_version(int *family, int *release,
+	    int *major, int *minor, int *patch);
+
+	// Convert DB errors to strings
+	static char *strerror(int);
+
+	// If an error is detected and the error call function
+	// or stream is set, a message is dispatched or printed.
+	// If a prefix is set, each message is prefixed.
+	//
+	// You can use set_errcall() or set_errfile() above to control
+	// error functionality.  Alternatively, you can call
+	// set_error_stream() to force all errors to a C++ stream.
+	// It is unwise to mix these approaches.
+	//
+	virtual __DB_STD(ostream) *get_error_stream();
+	virtual void set_error_stream(__DB_STD(ostream) *);
+	virtual __DB_STD(ostream) *get_message_stream();
+	virtual void set_message_stream(__DB_STD(ostream) *);
+
+	// used internally
+	static void runtime_error(DbEnv *dbenv, const char *caller, int err,
+				  int error_policy);
+	static void runtime_error_dbt(DbEnv *dbenv, const char *caller, Dbt *dbt,
+				  int error_policy);
+	static void runtime_error_lock_get(DbEnv *dbenv, const char *caller,
+				  int err, db_lockop_t op, db_lockmode_t mode,
+				  Dbt *obj, DbLock lock, int index,
+				  int error_policy);
+
+	// Lock functions
+	//
+	virtual int lock_detect(u_int32_t flags, u_int32_t atype, int *aborted);
+	virtual int lock_get(u_int32_t locker, u_int32_t flags, Dbt *obj,
+		     db_lockmode_t lock_mode, DbLock *lock);
+	virtual int lock_id(u_int32_t *idp);
+	virtual int lock_id_free(u_int32_t id);
+	virtual int lock_put(DbLock *lock);
+	virtual int lock_stat(DB_LOCK_STAT **statp, u_int32_t flags);
+	virtual int lock_stat_print(u_int32_t flags);
+	virtual int lock_vec(u_int32_t locker, u_int32_t flags,
+		     DB_LOCKREQ list[], int nlist, DB_LOCKREQ **elistp);
+
+	// Log functions
+	//
+	virtual int log_archive(char **list[], u_int32_t flags);
+	static int log_compare(const DbLsn *lsn0, const DbLsn *lsn1);
+	virtual int log_cursor(DbLogc **cursorp, u_int32_t flags);
+	virtual int log_file(DbLsn *lsn, char *namep, size_t len);
+	virtual int log_flush(const DbLsn *lsn);
+	virtual int log_get_config(u_int32_t, int *);
+	virtual int log_put(DbLsn *lsn, const Dbt *data, u_int32_t flags);
+	virtual int log_printf(DbTxn *, const char *, ...);
+	virtual int log_set_config(u_int32_t, int);
+	virtual int log_stat(DB_LOG_STAT **spp, u_int32_t flags);
+	virtual int log_stat_print(u_int32_t flags);
+	virtual int log_verify(DB_LOG_VERIFY_CONFIG *);
+
+	// Mpool functions
+	//
+	virtual int memp_fcreate(DbMpoolFile **dbmfp, u_int32_t flags);
+	virtual int memp_register(int ftype,
+			  pgin_fcn_type pgin_fcn,
+			  pgout_fcn_type pgout_fcn);
+	virtual int memp_stat(DB_MPOOL_STAT
+		      **gsp, DB_MPOOL_FSTAT ***fsp, u_int32_t flags);
+	virtual int memp_stat_print(u_int32_t flags);
+	virtual int memp_sync(DbLsn *lsn);
+	virtual int memp_trickle(int pct, int *nwrotep);
+
+	// Mpool functions
+	//
+	virtual int mutex_alloc(u_int32_t, db_mutex_t *);
+	virtual int mutex_free(db_mutex_t);
+	virtual int mutex_get_align(u_int32_t *);
+	virtual int mutex_get_increment(u_int32_t *);
+	virtual int mutex_get_init(u_int32_t *);
+	virtual int mutex_get_max(u_int32_t *);
+	virtual int mutex_get_tas_spins(u_int32_t *);
+	virtual int mutex_lock(db_mutex_t);
+	virtual int mutex_set_align(u_int32_t);
+	virtual int mutex_set_increment(u_int32_t);
+	virtual int mutex_set_init(u_int32_t);
+	virtual int mutex_set_max(u_int32_t);
+	virtual int mutex_set_tas_spins(u_int32_t);
+	virtual int mutex_stat(DB_MUTEX_STAT **, u_int32_t);
+	virtual int mutex_stat_print(u_int32_t);
+	virtual int mutex_unlock(db_mutex_t);
+
+	// Transaction functions
+	//
+	virtual int txn_begin(DbTxn *pid, DbTxn **tid, u_int32_t flags);
+	virtual int txn_checkpoint(u_int32_t kbyte, u_int32_t min,
+			u_int32_t flags);
+	virtual int txn_recover(DbPreplist *preplist, long count,
+			long *retp, u_int32_t flags);
+	virtual int txn_stat(DB_TXN_STAT **statp, u_int32_t flags);
+	virtual int txn_stat_print(u_int32_t flags);
+
+	// Replication functions
+	//
+	virtual int rep_elect(u_int32_t, u_int32_t, u_int32_t);
+	virtual int rep_flush();
+	virtual int rep_process_message(Dbt *, Dbt *, int, DbLsn *);
+	virtual int rep_start(Dbt *, u_int32_t);
+	virtual int rep_stat(DB_REP_STAT **statp, u_int32_t flags);
+	virtual int rep_stat_print(u_int32_t flags);
+	virtual int rep_get_clockskew(u_int32_t *, u_int32_t *);
+	virtual int rep_set_clockskew(u_int32_t, u_int32_t);
+	virtual int rep_get_limit(u_int32_t *, u_int32_t *);
+	virtual int rep_set_limit(u_int32_t, u_int32_t);
+	virtual int rep_set_transport(int, int (*)(DbEnv *,
+	    const Dbt *, const Dbt *, const DbLsn *, int, u_int32_t));
+	virtual int rep_set_request(u_int32_t, u_int32_t);
+	virtual int rep_get_request(u_int32_t *, u_int32_t *);
+	virtual int get_thread_count(u_int32_t *);
+	virtual int set_thread_count(u_int32_t);
+	virtual int get_thread_id_fn(
+	    void (**)(DbEnv *, pid_t *, db_threadid_t *));
+	virtual int set_thread_id(void (*)(DbEnv *, pid_t *, db_threadid_t *));
+	virtual int get_thread_id_string_fn(
+	    char *(**)(DbEnv *, pid_t, db_threadid_t, char *));
+	virtual int set_thread_id_string(char *(*)(DbEnv *,
+	    pid_t, db_threadid_t, char *));
+	virtual int rep_set_config(u_int32_t, int);
+	virtual int rep_get_config(u_int32_t, int *);
+	virtual int rep_sync(u_int32_t flags);
+
+	// Advanced replication functions
+	//
+	virtual int rep_get_nsites(u_int32_t *n);
+	virtual int rep_set_nsites(u_int32_t n);
+	virtual int rep_get_priority(u_int32_t *priorityp);
+	virtual int rep_set_priority(u_int32_t priority);
+	virtual int rep_get_timeout(int which, db_timeout_t *timeout);
+	virtual int rep_set_timeout(int which, db_timeout_t timeout);
+	virtual int repmgr_channel(int eid, DbChannel **channel,
+	    u_int32_t flags);
+	virtual int repmgr_get_ack_policy(int *policy);
+	virtual int repmgr_set_ack_policy(int policy);
+	virtual int repmgr_local_site(DbSite **site);
+	virtual int repmgr_msg_dispatch(void (*) (DbEnv *,
+	    DbChannel *, Dbt *, u_int32_t, u_int32_t), u_int32_t flags);
+	virtual int repmgr_site(const char *host, u_int port, DbSite **site,
+	    u_int32_t flags);
+	virtual int repmgr_site_by_eid(int eid, DbSite **site);
+	virtual int repmgr_site_list(u_int *countp, DB_REPMGR_SITE **listp);
+	virtual int repmgr_start(int nthreads, u_int32_t flags);
+	virtual int repmgr_stat(DB_REPMGR_STAT **statp, u_int32_t flags);
+	virtual int repmgr_stat_print(u_int32_t flags);
+
+	// Conversion functions
+	//
+	virtual ENV *get_ENV()
+	{
+		return imp_->env;
+	}
+
+	virtual DB_ENV *get_DB_ENV()
+	{
+		return imp_;
+	}
+
+	virtual const DB_ENV *get_const_DB_ENV() const
+	{
+		return imp_;
+	}
+
+	static DbEnv* get_DbEnv(DB_ENV *dbenv)
+	{
+		return dbenv ? (DbEnv *)dbenv->api1_internal : 0;
+	}
+
+	static const DbEnv* get_const_DbEnv(const DB_ENV *dbenv)
+	{
+		return dbenv ? (const DbEnv *)dbenv->api1_internal : 0;
+	}
+
+	u_int32_t get_create_flags() const
+	{
+		return construct_flags_;
+	}
+
+	// For internal use only.
+	static DbEnv* wrap_DB_ENV(DB_ENV *dbenv);
+
+	// These are public only because they need to be called
+	// via C functions.  They should never be called by users
+	// of this class.
+	//
+	static int _app_dispatch_intercept(DB_ENV *dbenv, DBT *dbt, DB_LSN *lsn,
+				       db_recops op);
+	static int _backup_close_intercept(DB_ENV *dbenv,
+	    const char *dbname, void *handle);
+	static int _backup_open_intercept(DB_ENV *dbenv,
+	    const char *dbname, const char *target, void **handle);
+	static int _backup_write_intercept(DB_ENV *dbenv, u_int32_t off_gbytes,
+	    u_int32_t off_bytes, u_int32_t size, u_int8_t *buf, void *handle);
+	static void _paniccall_intercept(DB_ENV *dbenv, int errval);
+	static void _feedback_intercept(DB_ENV *dbenv, int opcode, int pct);
+	static void  _event_func_intercept(DB_ENV *dbenv, u_int32_t, void *);
+	static int _isalive_intercept(DB_ENV *dbenv, pid_t pid,
+	    db_threadid_t thrid, u_int32_t flags);
+	static int _rep_send_intercept(DB_ENV *dbenv, const DBT *cntrl,
+	    const DBT *data, const DB_LSN *lsn, int id, u_int32_t flags);
+	static void _stream_error_function(const DB_ENV *dbenv,
+	    const char *prefix, const char *message);
+	static void _stream_message_function(const DB_ENV *dbenv,
+	    const char *message);
+	static void _thread_id_intercept(DB_ENV *dbenv, pid_t *pidp,
+	    db_threadid_t *thridp);
+	static char *_thread_id_string_intercept(DB_ENV *dbenv, pid_t pid,
+	    db_threadid_t thrid, char *buf);
+	static void _message_dispatch_intercept(DB_ENV *dbenv,
+	    DB_CHANNEL *dbchannel, DBT *request, u_int32_t nrequest,
+	    u_int32_t cb_flags);
+
+private:
+	void cleanup();
+	int initialize(DB_ENV *dbenv);
+	int error_policy();
+
+	// For internal use only.
+	DbEnv(DB_ENV *, u_int32_t flags);
+
+	// no copying
+	DbEnv(const DbEnv &);
+	void operator = (const DbEnv &);
+
+	// instance data
+	DB_ENV *imp_;
+	int construct_error_;
+	u_int32_t construct_flags_;
+	__DB_STD(ostream) *error_stream_;
+	__DB_STD(ostream) *message_stream_;
+
+	int (*app_dispatch_callback_)(DbEnv *, Dbt *, DbLsn *, db_recops);
+	int (*backup_close_callback_)(DbEnv *, const char *, void *);
+	int (*backup_open_callback_)(
+	    DbEnv *, const char *, const char *, void **);
+	int (*backup_write_callback_)(
+	    DbEnv *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *);
+	int (*isalive_callback_)(DbEnv *, pid_t, db_threadid_t, u_int32_t);
+	void (*error_callback_)(const DbEnv *, const char *, const char *);
+	void (*feedback_callback_)(DbEnv *, int, int);
+	void (*message_callback_)(const DbEnv *, const char *);
+	void (*paniccall_callback_)(DbEnv *, int);
+	void (*event_func_callback_)(DbEnv *, u_int32_t, void *);
+	int (*rep_send_callback_)(DbEnv *, const Dbt *, const Dbt *,
+	    const DbLsn *, int, u_int32_t);
+	void (*thread_id_callback_)(DbEnv *, pid_t *, db_threadid_t *);
+	char *(*thread_id_string_callback_)(DbEnv *, pid_t, db_threadid_t,
+	    char *);
+	void (*message_dispatch_callback_)(DbEnv *, DbChannel *, Dbt *,
+	    u_int32_t, u_int32_t);
+};
+
+//
+// Heap record id
+//
+class _exported DbHeapRecordId : private DB_HEAP_RID
+{
+public:
+	db_pgno_t get_pgno() const		{ return pgno; }
+	void set_pgno(db_pgno_t value)		{ pgno = value; }
+
+	db_indx_t get_indx() const		{ return indx; }
+	void set_indx(db_indx_t value)		{ indx = value; }
+
+	DB_HEAP_RID *get_DB_HEAP_RID()		{ return (DB_HEAP_RID *)this; }
+	const DB_HEAP_RID *get_const_DB_HEAP_RID() const 
+					{ return (const DB_HEAP_RID *)this; }
+
+	static DbHeapRecordId* get_DbHeapRecordId(DB_HEAP_RID *rid) 
+					{ return (DbHeapRecordId *)rid; }
+	static const DbHeapRecordId* get_const_DbHeapRecordId(DB_HEAP_RID *rid)
+					{ return (const DbHeapRecordId *)rid; }
+
+	DbHeapRecordId(db_pgno_t pgno, db_indx_t indx);
+	DbHeapRecordId();
+	~DbHeapRecordId();
+	DbHeapRecordId(const DbHeapRecordId &);
+	DbHeapRecordId &operator = (const DbHeapRecordId &);
+};
+
+//
+// Lock
+//
+class _exported DbLock
+{
+	friend class DbEnv;
+
+public:
+	DbLock();
+	DbLock(const DbLock &);
+	DbLock &operator = (const DbLock &);
+
+protected:
+	// We can add data to this class if needed
+	// since its contained class is not allocated by db.
+	// (see comment at top)
+
+	DbLock(DB_LOCK);
+	DB_LOCK lock_;
+};
+
+//
+// Log cursor
+//
+class _exported DbLogc : protected DB_LOGC
+{
+	friend class DbEnv;
+
+public:
+	int close(u_int32_t _flags);
+	int get(DbLsn *lsn, Dbt *data, u_int32_t _flags);
+	int version(u_int32_t *versionp, u_int32_t _flags);
+
+private:
+	// No data is permitted in this class (see comment at top)
+
+	// Note: use Db::cursor() to get pointers to a Dbc,
+	// and call Dbc::close() rather than delete to release them.
+	//
+	DbLogc();
+	~DbLogc();
+
+	// no copying
+	DbLogc(const Dbc &);
+	DbLogc &operator = (const Dbc &);
+};
+
+//
+// Log sequence number
+//
+class _exported DbLsn : public DB_LSN
+{
+	friend class DbEnv;          // friendship needed to cast to base class
+	friend class DbLogc;         // friendship needed to cast to base class
+};
+
+//
+// Memory pool file
+//
+class _exported DbMpoolFile
+{
+	friend class DbEnv;
+	friend class Db;
+
+public:
+	int close(u_int32_t flags);
+	int get(db_pgno_t *pgnoaddr, DbTxn *txn, u_int32_t flags, void *pagep);
+	int get_clear_len(u_int32_t *len);
+	int get_fileid(u_int8_t *fileid);
+	int get_flags(u_int32_t *flagsp);
+	int get_ftype(int *ftype);
+	int get_last_pgno(db_pgno_t *pgnop);
+	int get_lsn_offset(int32_t *offsetp);
+	int get_maxsize(u_int32_t *gbytes, u_int32_t *bytes);
+	int get_pgcookie(DBT *dbt);
+	int get_priority(DB_CACHE_PRIORITY *priorityp);
+	int get_transactional(void);
+	int open(const char *file, u_int32_t flags, int mode, size_t pagesize);
+	int put(void *pgaddr, DB_CACHE_PRIORITY priority, u_int32_t flags);
+	int set_clear_len(u_int32_t len);
+	int set_fileid(u_int8_t *fileid);
+	int set_flags(u_int32_t flags, int onoff);
+	int set_ftype(int ftype);
+	int set_lsn_offset(int32_t offset);
+	int set_maxsize(u_int32_t gbytes, u_int32_t bytes);
+	int set_pgcookie(DBT *dbt);
+	int set_priority(DB_CACHE_PRIORITY priority);
+	int sync();
+
+	virtual DB_MPOOLFILE *get_DB_MPOOLFILE()
+	{
+		return imp_;
+	}
+
+	virtual const DB_MPOOLFILE *get_const_DB_MPOOLFILE() const
+	{
+		return imp_;
+	}
+
+private:
+	DB_MPOOLFILE *imp_;
+
+	// We can add data to this class if needed
+	// since it is implemented via a pointer.
+	// (see comment at top)
+
+	// Note: use DbEnv::memp_fcreate() to get pointers to a DbMpoolFile,
+	// and call DbMpoolFile::close() rather than delete to release them.
+	//
+	DbMpoolFile();
+
+	// Shut g++ up.
+protected:
+	virtual ~DbMpoolFile();
+
+private:
+	// no copying
+	DbMpoolFile(const DbMpoolFile &);
+	void operator = (const DbMpoolFile &);
+};
+
+//
+// This is filled in and returned by the DbEnv::txn_recover() method.
+//
+class _exported DbPreplist
+{
+public:
+	DbTxn *txn;
+	u_int8_t gid[DB_GID_SIZE];
+};
+
+//
+// A sequence record in a database
+//
+class _exported DbSequence
+{
+public:
+	DbSequence(Db *db, u_int32_t flags);
+	virtual ~DbSequence();
+
+	int open(DbTxn *txnid, Dbt *key, u_int32_t flags);
+	int initial_value(db_seq_t value);
+	int close(u_int32_t flags);
+	int remove(DbTxn *txnid, u_int32_t flags);
+	int stat(DB_SEQUENCE_STAT **sp, u_int32_t flags);
+	int stat_print(u_int32_t flags);
+
+	int get(DbTxn *txnid, int32_t delta, db_seq_t *retp, u_int32_t flags);
+	int get_cachesize(int32_t *sizep);
+	int set_cachesize(int32_t size);
+	int get_flags(u_int32_t *flagsp);
+	int set_flags(u_int32_t flags);
+	int get_range(db_seq_t *minp, db_seq_t *maxp);
+	int set_range(db_seq_t min, db_seq_t max);
+
+	Db *get_db();
+	Dbt *get_key();
+
+	virtual DB_SEQUENCE *get_DB_SEQUENCE()
+	{
+		return imp_;
+	}
+
+	virtual const DB_SEQUENCE *get_const_DB_SEQUENCE() const
+	{
+		return imp_;
+	}
+
+	static DbSequence* get_DbSequence(DB_SEQUENCE *seq)
+	{
+		return (DbSequence *)seq->api_internal;
+	}
+
+	static const DbSequence* get_const_DbSequence(const DB_SEQUENCE *seq)
+	{
+		return (const DbSequence *)seq->api_internal;
+	}
+
+	// For internal use only.
+	static DbSequence* wrap_DB_SEQUENCE(DB_SEQUENCE *seq);
+
+private:
+	DbSequence(DB_SEQUENCE *seq);
+	// no copying
+	DbSequence(const DbSequence &);
+	DbSequence &operator = (const DbSequence &);
+
+	DB_SEQUENCE *imp_;
+	DBT key_;
+};
+
+//
+// A site in replication group 
+//
+class _exported DbSite
+{
+	friend class DbEnv;
+
+public:
+	int close();
+	int get_address(const char **hostp, u_int *port);
+	int get_config(u_int32_t which, u_int32_t *value);
+	int get_eid(int *eidp);
+	int remove();
+	int set_config(u_int32_t which, u_int32_t value);
+
+	virtual DB_SITE *get_DB_SITE()
+	{
+		return imp_;
+	}
+
+	virtual const DB_SITE *get_const_DB_SITE() const
+	{
+		return imp_;
+	}
+
+private:
+        DbSite();
+        virtual ~DbSite();
+
+	// no copying
+	DbSite(const DbSite &);
+	DbSite &operator = (const DbSite &);
+	DB_SITE *imp_;
+};
+
+//
+// Transaction
+//
+class _exported DbTxn
+{
+	friend class DbEnv;
+
+public:
+	int abort();
+	int commit(u_int32_t flags);
+	int discard(u_int32_t flags);
+	u_int32_t id();
+	int get_name(const char **namep);
+	int get_priority(u_int32_t *priorityp);
+	int prepare(u_int8_t *gid);
+	int set_name(const char *name);
+	int set_priority(u_int32_t priority);
+	int set_timeout(db_timeout_t timeout, u_int32_t flags);
+
+	virtual DB_TXN *get_DB_TXN()
+	{
+		return imp_;
+	}
+
+	virtual const DB_TXN *get_const_DB_TXN() const
+	{
+		return imp_;
+	}
+
+	static DbTxn* get_DbTxn(DB_TXN *txn)
+	{
+		return (DbTxn *)txn->api_internal;
+	}
+
+	static const DbTxn* get_const_DbTxn(const DB_TXN *txn)
+	{
+		return (const DbTxn *)txn->api_internal;
+	}
+
+	// For internal use only.
+	static DbTxn* wrap_DB_TXN(DB_TXN *txn);
+	void remove_child_txn(DbTxn *kid);
+	void add_child_txn(DbTxn *kid);
+
+	void set_parent(DbTxn *ptxn)
+	{
+		parent_txn_ = ptxn;
+	}
+
+private:
+	DB_TXN *imp_;
+
+	// We use a TAILQ to store this object's kids of DbTxn objects, and
+	// each kid has a "parent_txn_" to point to this DbTxn object.
+	//
+	// If imp_ has a parent transaction which is not wrapped by DbTxn 
+	// class, parent_txn_ will be NULL since we don't need to maintain 
+	// this parent-kid relationship. This relationship only helps to 
+	// delete unresolved kids when the parent is resolved.
+	DbTxn *parent_txn_;
+
+	// We can add data to this class if needed
+	// since it is implemented via a pointer.
+	// (see comment at top)
+
+	// Note: use DbEnv::txn_begin() to get pointers to a DbTxn,
+	// and call DbTxn::abort() or DbTxn::commit rather than
+	// delete to release them.
+	//
+	DbTxn(DbTxn *ptxn);
+	// For internal use only.
+	DbTxn(DB_TXN *txn, DbTxn *ptxn);
+	virtual ~DbTxn();
+
+	// no copying
+	DbTxn(const DbTxn &);
+	void operator = (const DbTxn &);
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_HEAD(__children, DbTxn) children;
+	 */
+	struct __children {
+		DbTxn *tqh_first;
+		DbTxn **tqh_last;
+	} children;
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(DbTxn) child_entry;
+	 */
+	struct {
+		DbTxn *tqe_next;
+		DbTxn **tqe_prev;
+	} child_entry;
+};
+
+//
+// A chunk of data, maybe a key or value.
+//
+class _exported Dbt : private DBT
+{
+	friend class Db;
+	friend class Dbc;
+	friend class DbEnv;
+	friend class DbLogc;
+	friend class DbSequence;
+
+public:
+	// key/data
+	void *get_data() const                 { return data; }
+	void set_data(void *value)             { data = value; }
+
+	// key/data length
+	u_int32_t get_size() const             { return size; }
+	void set_size(u_int32_t value)         { size = value; }
+
+	// RO: length of user buffer.
+	u_int32_t get_ulen() const             { return ulen; }
+	void set_ulen(u_int32_t value)         { ulen = value; }
+
+	// RO: get/put record length.
+	u_int32_t get_dlen() const             { return dlen; }
+	void set_dlen(u_int32_t value)         { dlen = value; }
+
+	// RO: get/put record offset.
+	u_int32_t get_doff() const             { return doff; }
+	void set_doff(u_int32_t value)         { doff = value; }
+
+	// flags
+	u_int32_t get_flags() const            { return flags; }
+	void set_flags(u_int32_t value)        { flags = value; }
+
+	// Conversion functions
+	DBT *get_DBT()                         { return (DBT *)this; }
+	const DBT *get_const_DBT() const       { return (const DBT *)this; }
+
+	static Dbt* get_Dbt(DBT *dbt)          { return (Dbt *)dbt; }
+	static const Dbt* get_const_Dbt(const DBT *dbt)
+					       { return (const Dbt *)dbt; }
+
+	Dbt(void *data, u_int32_t size);
+	Dbt();
+	~Dbt();
+	Dbt(const Dbt &);
+	Dbt &operator = (const Dbt &);
+
+private:
+	// Note: no extra data appears in this class (other than
+	// inherited from DBT) since we need DBT and Dbt objects
+	// to have interchangable pointers.
+	//
+	// When subclassing this class, remember that callback
+	// methods like bt_compare, bt_prefix, dup_compare may
+	// internally manufacture DBT objects (which later are
+	// cast to Dbt), so such callbacks might receive objects
+	// not of your subclassed type.
+};
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// multiple key/data/recno iterator classes
+//
+
+// DbMultipleIterator is a shared private base class for the three types
+// of bulk-return Iterator;  it should never be instantiated directly,
+// but it handles the functionality shared by its subclasses.
+class _exported DbMultipleIterator
+{
+public:
+	DbMultipleIterator(const Dbt &dbt);
+protected:
+	u_int8_t *data_;
+	u_int32_t *p_;
+};
+
+class _exported DbMultipleKeyDataIterator : private DbMultipleIterator
+{
+public:
+	DbMultipleKeyDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {}
+	bool next(Dbt &key, Dbt &data);
+};
+
+class _exported DbMultipleRecnoDataIterator : private DbMultipleIterator
+{
+public:
+	DbMultipleRecnoDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {}
+	bool next(db_recno_t &recno, Dbt &data);
+};
+
+class _exported DbMultipleDataIterator : private DbMultipleIterator
+{
+public:
+	DbMultipleDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {}
+	bool next(Dbt &data);
+};
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// multiple key/data/recno builder classes
+//
+
+// DbMultipleBuilder is a shared private base class for the three types
+// of bulk buffer builders;  it should never be instantiated directly,
+// but it handles the functionality shared by its subclasses.
+class _exported DbMultipleBuilder
+{
+public:
+	DbMultipleBuilder(Dbt &dbt);
+protected:
+	Dbt &dbt_;
+	void *p_;
+};
+
+class _exported DbMultipleDataBuilder : DbMultipleBuilder
+{
+public:
+	DbMultipleDataBuilder(Dbt &dbt) : DbMultipleBuilder(dbt) {}
+	bool append(void *dbuf, size_t dlen);
+	bool reserve(void *&ddest, size_t dlen);
+};
+
+class _exported DbMultipleKeyDataBuilder : DbMultipleBuilder
+{
+public:
+	DbMultipleKeyDataBuilder(Dbt &dbt) : DbMultipleBuilder(dbt) {}
+	bool append(void *kbuf, size_t klen, void *dbuf, size_t dlen);
+	bool reserve(void *&kdest, size_t klen, void *&ddest, size_t dlen);
+};
+
+class _exported DbMultipleRecnoDataBuilder
+{
+public:
+	DbMultipleRecnoDataBuilder(Dbt &dbt);
+	bool append(db_recno_t recno, void *dbuf, size_t dlen);
+	bool reserve(db_recno_t recno, void *&ddest, size_t dlen);
+protected:
+	Dbt &dbt_;
+	void *p_;
+};
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// Exception classes
+//
+
+// Almost any error in the DB library throws a DbException.
+// Every exception should be considered an abnormality
+// (e.g. bug, misuse of DB, file system error).
+//
+class _exported DbException : public __DB_STD(exception)
+{
+public:
+	virtual ~DbException() throw();
+	DbException(int err);
+	DbException(const char *description);
+	DbException(const char *description, int err);
+	DbException(const char *prefix, const char *description, int err);
+	int get_errno() const;
+	virtual const char *what() const throw();
+	DbEnv *get_env() const;
+	void set_env(DbEnv *dbenv);
+
+	DbException(const DbException &);
+	DbException &operator = (const DbException &);
+
+private:
+	void describe(const char *prefix, const char *description);
+
+	char *what_;
+	int err_;                   // errno
+	DbEnv *dbenv_;
+};
+
+//
+// A specific sort of exception that occurs when
+// an operation is aborted to resolve a deadlock.
+//
+class _exported DbDeadlockException : public DbException
+{
+public:
+	virtual ~DbDeadlockException() throw();
+	DbDeadlockException(const char *description);
+
+	DbDeadlockException(const DbDeadlockException &);
+	DbDeadlockException &operator = (const DbDeadlockException &);
+};
+
+//
+// A specific sort of exception that occurs when
+// a lock is not granted, e.g. by lock_get or lock_vec.
+// Note that the Dbt is only live as long as the Dbt used
+// in the offending call.
+//
+class _exported DbLockNotGrantedException : public DbException
+{
+public:
+	virtual ~DbLockNotGrantedException() throw();
+	DbLockNotGrantedException(const char *prefix, db_lockop_t op,
+	    db_lockmode_t mode, const Dbt *obj, const DbLock lock, int index);
+	DbLockNotGrantedException(const char *description);
+
+	DbLockNotGrantedException(const DbLockNotGrantedException &);
+	DbLockNotGrantedException &operator =
+	    (const DbLockNotGrantedException &);
+
+	db_lockop_t get_op() const;
+	db_lockmode_t get_mode() const;
+	const Dbt* get_obj() const;
+	DbLock *get_lock() const;
+	int get_index() const;
+
+private:
+	db_lockop_t op_;
+	db_lockmode_t mode_;
+	const Dbt *obj_;
+	DbLock *lock_;
+	int index_;
+};
+
+//
+// A specific sort of exception that occurs when
+// user declared memory is insufficient in a Dbt.
+//
+class _exported DbMemoryException : public DbException
+{
+public:
+	virtual ~DbMemoryException() throw();
+	DbMemoryException(Dbt *dbt);
+	DbMemoryException(const char *prefix, Dbt *dbt);
+
+	DbMemoryException(const DbMemoryException &);
+	DbMemoryException &operator = (const DbMemoryException &);
+
+	Dbt *get_dbt() const;
+private:
+	Dbt *dbt_;
+};
+
+//
+// A specific sort of exception that occurs when a change of replication
+// master requires that all handles be re-opened.
+//
+class _exported DbRepHandleDeadException : public DbException
+{
+public:
+	virtual ~DbRepHandleDeadException() throw();
+	DbRepHandleDeadException(const char *description);
+
+	DbRepHandleDeadException(const DbRepHandleDeadException &);
+	DbRepHandleDeadException &operator = (const DbRepHandleDeadException &);
+};
+
+//
+// A specific sort of exception that occurs when
+// recovery is required before continuing DB activity.
+//
+class _exported DbRunRecoveryException : public DbException
+{
+public:
+	virtual ~DbRunRecoveryException() throw();
+	DbRunRecoveryException(const char *description);
+
+	DbRunRecoveryException(const DbRunRecoveryException &);
+	DbRunRecoveryException &operator = (const DbRunRecoveryException &);
+};
+
+//
+// A specific sort of exception that occurs when
+
+////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////
+//
+// Restore default compiler warnings
+//
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif /* !_DB_CXX_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/db_int.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1184 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_INT_H_
+#define	_DB_INT_H_
+
+/*******************************************************
+ * Berkeley DB ANSI/POSIX include files.
+ *******************************************************/
+#ifdef HAVE_SYSTEM_INCLUDE_FILES
+#include <sys/types.h>
+#ifdef DIAG_MVCC
+#include <sys/mman.h>
+#endif
+#include <sys/stat.h>
+
+#if defined(HAVE_REPLICATION_THREADS)
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_VXWORKS
+#include <selectLib.h>
+#endif
+#endif
+
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+
+#ifdef HAVE_VXWORKS
+#include <net/uio.h>
+#else
+#include <sys/uio.h>
+#endif
+
+#if defined(HAVE_REPLICATION_THREADS)
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#endif
+
+#if defined(STDC_HEADERS) || defined(__cplusplus)
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#endif /* !HAVE_SYSTEM_INCLUDE_FILES */
+
+#ifdef DB_WIN32
+#include "dbinc/win_db.h"
+#endif
+
+#ifdef HAVE_DBM
+#undef	DB_DBM_HSEARCH
+#define	DB_DBM_HSEARCH 1
+#endif
+
+#include "db.h"
+#include "clib_port.h"
+
+#include "dbinc/queue.h"
+#include "dbinc/shqueue.h"
+#include "dbinc/perfmon.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * The Windows compiler needs to be told about structures that are available
+ * outside a dll.
+ */
+#if defined(DB_WIN32) && defined(_MSC_VER) && \
+    !defined(DB_CREATE_DLL) && !defined(_LIB)
+#define	__DB_IMPORT __declspec(dllimport)
+#else
+#define	__DB_IMPORT
+#endif
+
+/*******************************************************
+ * Forward structure declarations.
+ *******************************************************/
+struct __db_commit_info; typedef struct __db_commit_info DB_COMMIT_INFO;
+struct __db_reginfo_t;	typedef struct __db_reginfo_t REGINFO;
+struct __db_txnhead;	typedef struct __db_txnhead DB_TXNHEAD;
+struct __db_txnlist;	typedef struct __db_txnlist DB_TXNLIST;
+struct __vrfy_childinfo;typedef struct __vrfy_childinfo VRFY_CHILDINFO;
+struct __vrfy_dbinfo;   typedef struct __vrfy_dbinfo VRFY_DBINFO;
+struct __vrfy_pageinfo; typedef struct __vrfy_pageinfo VRFY_PAGEINFO;
+
+struct __db_log_verify_info;
+struct __txn_verify_info;
+struct __lv_filereg_info;
+struct __lv_ckp_info;
+struct __lv_timestamp_info;
+typedef struct __db_log_verify_info DB_LOG_VRFY_INFO;
+typedef struct __txn_verify_info VRFY_TXN_INFO;
+typedef struct __lv_filereg_info VRFY_FILEREG_INFO;
+typedef struct __lv_filelife VRFY_FILELIFE;
+typedef struct __lv_ckp_info VRFY_CKP_INFO;
+typedef struct __lv_timestamp_info VRFY_TIMESTAMP_INFO;
+
+/*
+ * TXNINFO_HANDLER --
+ *	Callback function pointer type for __iterate_txninfo.
+ */
+typedef int (*TXNINFO_HANDLER) __P((DB_LOG_VRFY_INFO *, VRFY_TXN_INFO *, void *));
+
+typedef SH_TAILQ_HEAD(__hash_head) DB_HASHTAB;
+
+/*******************************************************
+ * General purpose constants and macros.
+ *******************************************************/
+#undef	FALSE
+#define	FALSE		0
+#undef	TRUE
+#define	TRUE		(!FALSE)
+
+#define	MEGABYTE	1048576
+#define	GIGABYTE	1073741824
+
+#define	NS_PER_MS	1000000		/* Nanoseconds in a millisecond */
+#define	NS_PER_US	1000		/* Nanoseconds in a microsecond */
+#define	NS_PER_SEC	1000000000	/* Nanoseconds in a second */
+#define	US_PER_MS	1000		/* Microseconds in a millisecond */
+#define	US_PER_SEC	1000000		/* Microseconds in a second */
+#define	MS_PER_SEC	1000		/* Milliseconds in a second */
+
+#define	RECNO_OOB	0		/* Illegal record number. */
+
+/*
+ * Define a macro which has no runtime effect, yet avoids triggering empty
+ * statement compiler warnings. Use it as the text of conditionally-null macros.
+ */
+#define	NOP_STATEMENT	do { } while (0)
+
+/* Test for a power-of-two (tests true for zero, which doesn't matter here). */
+#define	POWER_OF_TWO(x)	(((x) & ((x) - 1)) == 0)
+
+/* Test for valid page sizes. */
+#define	DB_MIN_PGSIZE	0x000200	/* Minimum page size (512). */
+#define	DB_MAX_PGSIZE	0x010000	/* Maximum page size (65536). */
+#define	IS_VALID_PAGESIZE(x)						\
+	(POWER_OF_TWO(x) && (x) >= DB_MIN_PGSIZE && ((x) <= DB_MAX_PGSIZE))
+
+/* Minimum number of pages cached, by default. */
+#define	DB_MINPAGECACHE	16
+
+/*
+ * If we are unable to determine the underlying filesystem block size, use
+ * 8K on the grounds that most OS's use less than 8K for a VM page size.
+ */
+#define	DB_DEF_IOSIZE	(8 * 1024)
+
+/* Align an integer to a specific boundary. */
+#undef	DB_ALIGN
+#define	DB_ALIGN(v, bound)						\
+	(((v) + (bound) - 1) & ~(((uintmax_t)(bound)) - 1))
+
+/* Increment a pointer to a specific boundary. */
+#undef	ALIGNP_INC
+#define	ALIGNP_INC(p, bound)						\
+	(void *)(((uintptr_t)(p) + (bound) - 1) & ~(((uintptr_t)(bound)) - 1))
+
+/*
+ * DB_ALIGN8 adjusts structure alignments to make sure shared structures have
+ * fixed size and filed offset on both 32bit and 64bit platforms when
+ * HAVE_MIXED_SIZE_ADDRESSING is defined.
+ */
+#ifdef HAVE_MIXED_SIZE_ADDRESSING
+#define DB_ALIGN8 @DB_STRUCT_ALIGN8@
+#else
+#define DB_ALIGN8
+#endif
+
+/*
+ * Berkeley DB uses the va_copy macro from C99, not all compilers include
+ * it, so add a dumb implementation compatible with pre C99 implementations.
+ */
+#ifndef	va_copy
+#define	va_copy(d, s)	((d) = (s))
+#endif
+
+/*
+ * Print an address as a u_long (a u_long is the largest type we can print
+ * portably).  Most 64-bit systems have made longs 64-bits, so this should
+ * work.
+ */
+#define	P_TO_ULONG(p)	((u_long)(uintptr_t)(p))
+
+/*
+ * Convert a pointer to an integral value.
+ *
+ * The (u_int16_t)(uintptr_t) cast avoids warnings: the (uintptr_t) cast
+ * converts the value to an integral type, and the (u_int16_t) cast converts
+ * it to a small integral type so we don't get complaints when we assign the
+ * final result to an integral type smaller than uintptr_t.
+ */
+#define	P_TO_UINT32(p)	((u_int32_t)(uintptr_t)(p))
+#define	P_TO_UINT16(p)	((u_int16_t)(uintptr_t)(p))
+#define	P_TO_ROFF(p)	((roff_t)(uintptr_t)(p))
+
+/* The converse of P_TO_ROFF() above. */
+#define	ROFF_TO_P(roff)	((void *)(uintptr_t)(roff))
+
+/*
+ * There are several on-page structures that are declared to have a number of
+ * fields followed by a variable length array of items.  The structure size
+ * without including the variable length array or the address of the first of
+ * those elements can be found using SSZ.
+ *
+ * This macro can also be used to find the offset of a structure element in a
+ * structure.  This is used in various places to copy structure elements from
+ * unaligned memory references, e.g., pointers into a packed page.
+ *
+ * There are two versions because compilers object if you take the address of
+ * an array.
+ */
+#undef	SSZ
+#define	SSZ(name, field)  P_TO_UINT16(&(((name *)0)->field))
+
+#undef	SSZA
+#define	SSZA(name, field) P_TO_UINT16(&(((name *)0)->field[0]))
+
+/* Structure used to print flag values. */
+typedef struct __fn {
+	u_int32_t mask;			/* Flag value. */
+	const char *name;		/* Flag name. */
+} FN;
+
+/* Set, clear and test flags. */
+#define	FLD_CLR(fld, f)		(fld) &= ~(f)
+#define	FLD_ISSET(fld, f)	((fld) & (f))
+#define	FLD_SET(fld, f)		(fld) |= (f)
+#define	F_CLR(p, f)		(p)->flags &= ~(f)
+#define	F_ISSET(p, f)		((p)->flags & (f))
+#define	F_SET(p, f)		(p)->flags |= (f)
+#define	F2_CLR(p, f)		((p)->flags2 &= ~(f))
+#define	F2_ISSET(p, f)		((p)->flags2 & (f))
+#define	F2_SET(p, f)		((p)->flags2 |= (f))
+#define	LF_CLR(f)		((flags) &= ~(f))
+#define	LF_ISSET(f)		((flags) & (f))
+#define	LF_SET(f)		((flags) |= (f))
+
+/*
+ * Calculate a percentage.  The values can overflow 32-bit integer arithmetic
+ * so we use floating point.
+ *
+ * When calculating a bytes-vs-page size percentage, we're getting the inverse
+ * of the percentage in all cases, that is, we want 100 minus the percentage we
+ * calculate.
+ */
+#define	DB_PCT(v, total)						\
+	((int)((total) == 0 ? 0 : ((double)(v) * 100) / (total)))
+#define	DB_PCT_PG(v, total, pgsize)					\
+	((int)((total) == 0 ? 0 :					\
+	    100 - ((double)(v) * 100) / (((double)total) * (pgsize))))
+
+/*
+ * Statistics update shared memory and so are expensive -- don't update the
+ * values unless we're going to display the results.
+ * When performance monitoring is enabled, the changed value can be published
+ * (via DTrace or SystemTap) along with another associated value or two.
+ */
+#undef	STAT
+#ifdef	HAVE_STATISTICS
+#define	STAT(x)	x
+#define	STAT_ADJUST(env, cat, subcat, val, amount, id)			\
+	do {								\
+		(val) += (amount);					\
+		STAT_PERFMON2((env), cat, subcat, (val), (id));		\
+	} while (0)
+#define	STAT_ADJUST_VERB(env, cat, subcat, val, amount, id1, id2)	\
+	do {								\
+		(val) += (amount);					\
+		STAT_PERFMON3((env), cat, subcat, (val), (id1), (id2));	\
+	} while (0)
+#define	STAT_INC(env, cat, subcat, val, id) 				\
+	STAT_ADJUST(env, cat, subcat, (val), 1, (id))
+#define	STAT_INC_VERB(env, cat, subcat, val, id1, id2) 			\
+	STAT_ADJUST_VERB((env), cat, subcat, (val), 1, (id1), (id2))
+/*
+ * STAT_DEC() subtracts one rather than adding (-1) with STAT_ADJUST(); the
+ * latter might generate a compilation warning for an unsigned value.
+ */
+#define	STAT_DEC(env, cat, subcat, val, id) 				\
+	do {								\
+		(val)--;						\
+		STAT_PERFMON2((env), cat, subcat, (val), (id));		\
+	} while (0)
+/* N.B.: Add a verbose version of STAT_DEC() when needed. */
+
+#define	STAT_SET(env, cat, subcat, val, newval, id) 			\
+	do {								\
+		(val) = (newval);					\
+		STAT_PERFMON2((env), cat, subcat, (val), (id));		\
+	} while (0)
+#define	STAT_SET_VERB(env, cat, subcat, val, newval, id1, id2) 		\
+	do {								\
+		(val) = (newval);					\
+		STAT_PERFMON3((env), cat, subcat, (val), (id1), (id2));	\
+	} while (0)
+#else
+#define	STAT(x)							NOP_STATEMENT
+#define	STAT_ADJUST(env, cat, subcat, val, amt, id)		NOP_STATEMENT
+#define	STAT_ADJUST_VERB(env, cat, subcat, val, amt, id1, id2)	NOP_STATEMENT
+#define	STAT_INC(env, cat, subcat, val, id)			NOP_STATEMENT
+#define	STAT_INC_VERB(env, cat, subcat, val, id1, id2)		NOP_STATEMENT
+#define	STAT_DEC(env, cat, subcat, val, id)			NOP_STATEMENT
+#define	STAT_SET(env, cat, subcat, val, newval, id)		NOP_STATEMENT
+#define	STAT_SET_VERB(env, cat, subcat, val, newval, id1, id2)	NOP_STATEMENT
+#endif
+
+#if defined HAVE_SIMPLE_THREAD_TYPE
+#define DB_THREADID_INIT(t)	COMPQUIET((t), 0)
+#else
+#define DB_THREADID_INIT(t)	memset(&(t), 0, sizeof(t))
+#endif
+
+/*
+ * These macros are used when an error condition is first noticed. They allow
+ * one to be notified (via e.g. DTrace, SystemTap, ...) when an error occurs
+ * deep inside DB, rather than when it is returned back through the API.
+ *
+ * The second actual argument to these is the second part of the error or
+ * warning event name. They work when 'errcode' is a symbolic name e.g.
+ * EINVAL or DB_LOCK_DEALOCK, not a variable.  Noticing system call failures
+ * would be handled by tracing on syscall exit; when e.g., it returns < 0.
+ */
+#define	ERR_ORIGIN(env, errcode)        				\
+	(PERFMON0(env, error, errcode), errcode)
+
+#define	ERR_ORIGIN_MSG(env, errcode, msg)				\
+	(PERFMON1(env, error, errcode, msg), errcode)
+
+#define	WARNING_ORIGIN(env, errcode)					\
+	(PERFMON0(env, warning, errcode), errcode)
+
+/*
+ * Structure used for callback message aggregation.
+ *
+ * Display values in XXX_stat_print calls.
+ */
+typedef struct __db_msgbuf {
+	char *buf;			/* Heap allocated buffer. */
+	char *cur;			/* Current end of message. */
+	size_t len;			/* Allocated length of buffer. */
+} DB_MSGBUF;
+#define	DB_MSGBUF_INIT(a) do {						\
+	(a)->buf = (a)->cur = NULL;					\
+	(a)->len = 0;							\
+} while (0)
+#define	DB_MSGBUF_FLUSH(env, a) do {					\
+	if ((a)->buf != NULL) {						\
+		if ((a)->cur != (a)->buf)				\
+			__db_msg(env, "%s", (a)->buf);			\
+		__os_free(env, (a)->buf);				\
+		DB_MSGBUF_INIT(a);					\
+	}								\
+} while (0)
+#define	DB_MSGBUF_REP_FLUSH(env, a, diag_msg, regular_msg) do {		\
+	if ((a)->buf != NULL) {						\
+		if ((a)->cur != (a)->buf && diag_msg)			\
+			__db_repmsg(env, "%s", (a)->buf);		\
+		if (regular_msg)					\
+			DB_MSGBUF_FLUSH(env, a);			\
+		else {							\
+			__os_free(env, (a)->buf);			\
+			DB_MSGBUF_INIT(a);				\
+		}							\
+	}								\
+} while (0)
+#define	STAT_FMT(msg, fmt, type, v) do {				\
+	DB_MSGBUF __mb;							\
+	DB_MSGBUF_INIT(&__mb);						\
+	__db_msgadd(env, &__mb, fmt, (type)(v));			\
+	__db_msgadd(env, &__mb, "\t%s", msg);				\
+	DB_MSGBUF_FLUSH(env, &__mb);					\
+} while (0)
+#define	STAT_HEX(msg, v)						\
+	__db_msg(env, "%#lx\t%s", (u_long)(v), msg)
+#define	STAT_ISSET(msg, p)						\
+	__db_msg(env, "%sSet\t%s", (p) == NULL ? "!" : " ", msg)
+#define	STAT_LONG(msg, v)						\
+	__db_msg(env, "%ld\t%s", (long)(v), msg)
+#define	STAT_LSN(msg, lsnp)						\
+	__db_msg(env, "%lu/%lu\t%s",					\
+	    (u_long)(lsnp)->file, (u_long)(lsnp)->offset, msg)
+#define	STAT_POINTER(msg, v)						\
+	__db_msg(env, "%#lx\t%s", P_TO_ULONG(v), msg)
+#define	STAT_STRING(msg, p) do {					\
+	const char *__p = p;	/* p may be a function call. */		\
+	__db_msg(env, "%s\t%s", __p == NULL ? "!Set" : __p, msg);	\
+} while (0)
+#define	STAT_ULONG(msg, v)						\
+	__db_msg(env, "%lu\t%s", (u_long)(v), msg)
+
+/*
+ * The following macros are used to control how error and message strings are
+ * output by Berkeley DB. There are essentially three different controls
+ * available:
+ *  - Default behavior is to output error strings with its unique identifier.
+ *  - If HAVE_STRIPPED_MESSAGES is enabled, a unique identifier along with any
+ *    parameters to the error string will be output.
+ *  - If HAVE_LOCALIZATION is defined, and the '_()' macro is implemented, a
+ *    gettext or ICU style translation will be done.
+ *
+ * Each new string that will be output should be wrapped in a DB_STR* macro.
+ * There are three versions of this macro for different scenarions:
+ *  - DB_STR for strings that need an identifier, and don't have any argument.
+ *  - DB_STR_A for strings that need an identifier, and have argument(s).
+ *  - DB_STR_P for strings that don't need an identifier, and don't have
+ *    arguments.
+ *
+ * Error message IDs are automatically assigned by dist/s_message_id script.
+ */
+#ifdef HAVE_LOCALIZATION
+#define _(msg)	msg	/* Replace with localization function. */
+#else
+#define _(msg)	msg
+#endif
+
+#ifdef HAVE_STRIPPED_MESSAGES
+#define DB_STR_C(msg, fmt)	fmt
+#else
+#define DB_STR_C(msg, fmt)	_(msg)
+#endif
+
+#define DB_MSGID(id)		"BDB" id
+
+#define DB_STR(id, msg)		DB_MSGID(id) " " DB_STR_C(msg, "")
+
+#define DB_STR_A(id, msg, fmt)	DB_MSGID(id) " " DB_STR_C(msg, fmt)
+
+#define DB_STR_P(msg)		_(msg)
+
+/*
+ * There are quite a few places in Berkeley DB where we want to initialize
+ * a DBT from a string or other random pointer type, using a length typed
+ * to size_t in most cases.  This macro avoids a lot of casting.  The macro
+ * comes in two flavors because we often want to clear the DBT first.
+ */
+#define	DB_SET_DBT(dbt, d, s)  do {					\
+	(dbt).data = (void *)(d);					\
+	(dbt).size = (u_int32_t)(s);					\
+} while (0)
+#define	DB_INIT_DBT(dbt, d, s)  do {					\
+	memset(&(dbt), 0, sizeof(dbt));					\
+	DB_SET_DBT(dbt, d, s);						\
+} while (0)
+
+/*******************************************************
+ * API return values
+ *******************************************************/
+/*
+ * Return values that are OK for each different call.  Most calls have a
+ * standard 'return of 0 is only OK value', but some, like db->get have
+ * DB_NOTFOUND as a return value, but it really isn't an error.
+ */
+#define	DB_RETOK_STD(ret)	((ret) == 0)
+#define	DB_RETOK_DBCDEL(ret)	((ret) == 0 || (ret) == DB_KEYEMPTY || \
+				    (ret) == DB_NOTFOUND)
+#define	DB_RETOK_DBCGET(ret)	((ret) == 0 || (ret) == DB_KEYEMPTY || \
+				    (ret) == DB_NOTFOUND)
+#define	DB_RETOK_DBCPUT(ret)	((ret) == 0 || (ret) == DB_KEYEXIST || \
+				    (ret) == DB_NOTFOUND)
+#define	DB_RETOK_DBDEL(ret)	DB_RETOK_DBCDEL(ret)
+#define	DB_RETOK_DBGET(ret)	DB_RETOK_DBCGET(ret)
+#define	DB_RETOK_DBPUT(ret)	((ret) == 0 || (ret) == DB_KEYEXIST)
+#define	DB_RETOK_EXISTS(ret)	DB_RETOK_DBCGET(ret)
+#define	DB_RETOK_LGGET(ret)	((ret) == 0 || (ret) == DB_NOTFOUND)
+#define	DB_RETOK_MPGET(ret)	((ret) == 0 || (ret) == DB_PAGE_NOTFOUND)
+#define	DB_RETOK_REPPMSG(ret)	((ret) == 0 || \
+				    (ret) == DB_REP_IGNORE || \
+				    (ret) == DB_REP_ISPERM || \
+				    (ret) == DB_REP_NEWMASTER || \
+				    (ret) == DB_REP_NEWSITE || \
+				    (ret) == DB_REP_NOTPERM || \
+				    (ret) == DB_REP_WOULDROLLBACK)
+#define	DB_RETOK_REPMGR_LOCALSITE(ret)	((ret) == 0 || (ret) == DB_NOTFOUND)
+#define	DB_RETOK_REPMGR_START(ret) ((ret) == 0 || (ret) == DB_REP_IGNORE)
+#define	DB_RETOK_TXNAPPLIED(ret) ((ret) == 0 || \
+				    (ret) == DB_NOTFOUND ||		\
+				    (ret) == DB_TIMEOUT ||		\
+				    (ret) == DB_KEYEMPTY)
+
+/* Find a reasonable operation-not-supported error. */
+#ifdef	EOPNOTSUPP
+#define	DB_OPNOTSUP	EOPNOTSUPP
+#else
+#ifdef	ENOTSUP
+#define	DB_OPNOTSUP	ENOTSUP
+#else
+#define	DB_OPNOTSUP	EINVAL
+#endif
+#endif
+
+/*******************************************************
+ * Files.
+ *******************************************************/
+/*
+ * We use 1024 as the maximum path length.  It's too hard to figure out what
+ * the real path length is, as it was traditionally stored in <sys/param.h>,
+ * and that file isn't always available.
+ */
+#define	DB_MAXPATHLEN	1024
+
+#define	PATH_DOT	"."	/* Current working directory. */
+				/* Path separator character(s). */
+#define	PATH_SEPARATOR	"@PATH_SEPARATOR@"
+
+/*******************************************************
+ * Environment.
+ *******************************************************/
+/* Type passed to __db_appname(). */
+typedef enum {
+	DB_APP_NONE=0,			/* No type (region). */
+	DB_APP_DATA,			/* Data file. */
+	DB_APP_LOG,			/* Log file. */
+	DB_APP_META,			/* Persistent metadata file. */
+	DB_APP_RECOVER,			/* We are in recovery. */
+	DB_APP_TMP			/* Temporary file. */
+} APPNAME;
+
+/*
+ * A set of macros to check if various functionality has been configured.
+ *
+ * ALIVE_ON	The is_alive function is configured.
+ * CDB_LOCKING	CDB product locking.
+ * CRYPTO_ON	Security has been configured.
+ * LOCKING_ON	Locking has been configured.
+ * LOGGING_ON	Logging has been configured.
+ * MUTEX_ON	Mutexes have been configured.
+ * MPOOL_ON	Memory pool has been configured.
+ * REP_ON	Replication has been configured.
+ * TXN_ON	Transactions have been configured.
+ *
+ * REP_ON is more complex than most: if the BDB library was compiled without
+ * replication support, ENV->rep_handle will be NULL; if the BDB library has
+ * replication support, but it was not configured, the region reference will
+ * be NULL.
+ */
+#define	ALIVE_ON(env)		((env)->dbenv->is_alive != NULL)
+#define	CDB_LOCKING(env)	F_ISSET(env, ENV_CDB)
+#define	CRYPTO_ON(env)		((env)->crypto_handle != NULL)
+#define	LOCKING_ON(env)		((env)->lk_handle != NULL)
+#define	LOGGING_ON(env)		((env)->lg_handle != NULL)
+#define	MPOOL_ON(env)		((env)->mp_handle != NULL)
+#define	MUTEX_ON(env)		((env)->mutex_handle != NULL)
+#define	REP_ON(env)							\
+	((env)->rep_handle != NULL && (env)->rep_handle->region != NULL)
+#define	TXN_ON(env)		((env)->tx_handle != NULL)
+
+/*
+ * STD_LOCKING	Standard locking, that is, locking was configured and CDB
+ *		was not.  We do not do locking in off-page duplicate trees,
+ *		so we check for that in the cursor first.
+ */
+#define	STD_LOCKING(dbc)						\
+	(!F_ISSET(dbc, DBC_OPD) &&					\
+	    !CDB_LOCKING((dbc)->env) && LOCKING_ON((dbc)->env))
+
+/*
+ * IS_RECOVERING: The system is running recovery.
+ */
+#define	IS_RECOVERING(env)						\
+	(LOGGING_ON(env) && F_ISSET((env)->lg_handle, DBLOG_RECOVER))
+
+/* Initialization methods are often illegal before/after open is called. */
+#define	ENV_ILLEGAL_AFTER_OPEN(env, name)				\
+	if (F_ISSET((env), ENV_OPEN_CALLED))				\
+		return (__db_mi_open(env, name, 1));
+#define	ENV_ILLEGAL_BEFORE_OPEN(env, name)				\
+	if (!F_ISSET((env), ENV_OPEN_CALLED))				\
+		return (__db_mi_open(env, name, 0));
+
+/* We're not actually user hostile, honest. */
+#define	ENV_REQUIRES_CONFIG(env, handle, i, flags)			\
+	if (handle == NULL)						\
+		return (__env_not_config(env, i, flags));
+#define	ENV_REQUIRES_CONFIG_XX(env, handle, i, flags)			\
+	if ((env)->handle->region == NULL)				\
+		return (__env_not_config(env, i, flags));
+#define	ENV_NOT_CONFIGURED(env, handle, i, flags)			\
+	if (F_ISSET((env), ENV_OPEN_CALLED))				\
+		ENV_REQUIRES_CONFIG(env, handle, i, flags)
+
+#define	ENV_ENTER_RET(env, ip, ret) do {				\
+	ret = 0;							\
+	PANIC_CHECK_RET(env, ret);					\
+ 	if (ret == 0) {							\
+		if ((env)->thr_hashtab == NULL)				\
+			ip = NULL;					\
+		else 							\
+			ret = __env_set_state(env, &(ip), THREAD_ACTIVE);\
+	}								\
+} while (0)
+
+#define	ENV_ENTER(env, ip) do {						\
+	int __ret;							\
+	ip = NULL;							\
+	ENV_ENTER_RET(env, ip, __ret);					\
+	if (__ret != 0)							\
+		return (__ret);						\
+} while (0)
+
+#define	FAILCHK_THREAD(env, ip) do {					\
+	if ((ip) != NULL)						\
+		(ip)->dbth_state = THREAD_FAILCHK;			\
+} while (0)
+
+#define	ENV_GET_THREAD_INFO(env, ip) ENV_ENTER(env, ip)
+
+#ifdef DIAGNOSTIC
+#define	ENV_LEAVE(env, ip) do {						\
+	if ((ip) != NULL) {						\
+		DB_ASSERT(env, ((ip)->dbth_state == THREAD_ACTIVE  ||	\
+		    (ip)->dbth_state == THREAD_FAILCHK));		\
+		(ip)->dbth_state = THREAD_OUT;				\
+	}								\
+} while (0)
+#else
+#define	ENV_LEAVE(env, ip) do {						\
+	if ((ip) != NULL)						\
+		(ip)->dbth_state = THREAD_OUT;				\
+} while (0)
+#endif
+#ifdef DIAGNOSTIC
+#define	CHECK_THREAD(env) do {						\
+	if ((env)->thr_hashtab != NULL)					\
+		(void)__env_set_state(env, NULL, THREAD_VERIFY);	\
+} while (0)
+#ifdef HAVE_STATISTICS
+#define	CHECK_MTX_THREAD(env, mtx) do {					\
+	if (mtx->alloc_id != MTX_MUTEX_REGION &&			\
+	    mtx->alloc_id != MTX_ENV_REGION &&				\
+	    mtx->alloc_id != MTX_APPLICATION)				\
+		CHECK_THREAD(env);					\
+} while (0)
+#else
+#define	CHECK_MTX_THREAD(env, mtx)	NOP_STATEMENT
+#endif
+#else
+#define	CHECK_THREAD(env)		NOP_STATEMENT
+#define	CHECK_MTX_THREAD(env, mtx)	NOP_STATEMENT
+#endif
+
+typedef enum {
+	THREAD_SLOT_NOT_IN_USE=0,
+	THREAD_OUT,
+	THREAD_ACTIVE,
+	THREAD_BLOCKED,
+	THREAD_BLOCKED_DEAD,
+	THREAD_FAILCHK,
+	THREAD_VERIFY
+} DB_THREAD_STATE;
+
+typedef struct __pin_list {
+	roff_t b_ref;		/* offset to buffer. */
+	int region;		/* region containing buffer. */
+} PIN_LIST;
+#define	PINMAX 4
+
+struct __db_thread_info { /* SHARED */
+	pid_t		dbth_pid;
+	db_threadid_t	dbth_tid;
+	DB_THREAD_STATE	dbth_state;
+	SH_TAILQ_ENTRY	dbth_links;
+	/*
+	 * The next field contains the (process local) reference to the XA
+	 * transaction currently associated with this thread of control.
+	 */
+	SH_TAILQ_HEAD(__dbth_xatxn) dbth_xatxn;
+	u_int32_t	dbth_xa_status;
+	/*
+	 * The following fields track which buffers this thread of
+	 * control has pinned in the mpool buffer cache.
+	 */
+	u_int16_t	dbth_pincount;	/* Number of pins for this thread. */
+	u_int16_t	dbth_pinmax;	/* Number of slots allocated. */
+	roff_t		dbth_pinlist;	/* List of pins. */
+	PIN_LIST	dbth_pinarray[PINMAX];	/* Initial array of slots. */
+#ifdef DIAGNOSTIC
+	roff_t		dbth_locker;	/* Current locker for this thread. */
+	u_int32_t	dbth_check_off;	/* Count of number of LOCK_OFF calls. */
+#endif
+};
+#ifdef DIAGNOSTIC
+#define LOCK_CHECK_OFF(ip) if ((ip) != NULL)				\
+	(ip)->dbth_check_off++
+
+#define LOCK_CHECK_ON(ip) if ((ip) != NULL)				\
+	(ip)->dbth_check_off--
+
+#define LOCK_CHECK(dbc, pgno, mode, type)				\
+	DB_ASSERT((dbc)->dbp->env, (dbc)->locker == NULL ||		\
+	     __db_haslock((dbc)->dbp->env,				\
+	    (dbc)->locker, (dbc)->dbp->mpf, pgno, mode, type) == 0)
+#else
+#define LOCK_CHECK_OFF(ip)	NOP_STATEMENT
+#define LOCK_CHECK_ON(ip)	NOP_STATEMENT
+#define LOCK_CHECK(dbc, pgno, mode)	NOP_STATEMENT
+#endif
+
+typedef struct __env_thread_info {
+	u_int32_t	thr_count;
+	u_int32_t	thr_init;
+	u_int32_t	thr_max;
+	u_int32_t	thr_nbucket;
+	roff_t		thr_hashoff;
+} THREAD_INFO;
+
+#define	DB_EVENT(env, e, einfo) do {					\
+	DB_ENV *__dbenv = (env)->dbenv;					\
+	if (__dbenv->db_event_func != NULL)				\
+		__dbenv->db_event_func(__dbenv, e, einfo);		\
+} while (0)
+
+typedef struct __flag_map {
+	u_int32_t inflag, outflag;
+} FLAG_MAP;
+
+typedef struct __db_backup_handle {
+	int	(*open) __P((DB_ENV *, const char *, const char *, void **));
+	int	(*write) __P((DB_ENV *,
+		    u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *));
+	int	(*close) __P((DB_ENV *, const char *, void *));
+	u_int32_t	size;
+	u_int32_t	read_count;
+	u_int32_t	read_sleep;
+#define	BACKUP_WRITE_DIRECT	0x0001
+	int	flags;
+} DB_BACKUP;
+
+/*
+ * Internal database environment structure.
+ *
+ * This is the private database environment handle.  The public environment
+ * handle is the DB_ENV structure.   The library owns this structure, the user
+ * owns the DB_ENV structure.  The reason there are two structures is because
+ * the user's configuration outlives any particular DB_ENV->open call, and
+ * separate structures allows us to easily discard internal information without
+ * discarding the user's configuration.
+ */
+struct __env {
+	DB_ENV *dbenv;			/* Linked DB_ENV structure */
+
+	/*
+	 * The ENV structure can be used concurrently, so field access is
+	 * protected.
+	 */
+	db_mutex_t mtx_env;		/* ENV structure mutex */
+
+	/*
+	 * Some fields are included in the ENV structure rather than in the
+	 * DB_ENV structure because they are only set as arguments to the
+	 * DB_ENV->open method.  In other words, because of the historic API,
+	 * not for any rational reason.
+	 *
+	 * Arguments to DB_ENV->open.
+	 */
+	char	 *db_home;		/* Database home */
+	u_int32_t open_flags;		/* Flags */
+	int	  db_mode;		/* Default open permissions */
+
+	pid_t	pid_cache;		/* Cached process ID */
+
+	DB_FH	*lockfhp;		/* fcntl(2) locking file handle */
+
+	DB_LOCKER *env_lref;		/* Locker in non-threaded handles */
+
+	DB_DISTAB   recover_dtab;	/* Dispatch table for recover funcs */
+
+	int dir_mode;			/* Intermediate directory perms. */
+
+#define ENV_DEF_DATA_LEN		100
+	u_int32_t data_len;		/* Data length in __db_prbytes. */
+
+	/* Thread tracking */
+	u_int32_t	 thr_nbucket;	/* Number of hash buckets */
+	DB_HASHTAB	*thr_hashtab;	/* Hash table of DB_THREAD_INFO */
+
+	/*
+	 * List of open DB handles for this ENV, used for cursor
+	 * adjustment.  Must be protected for multi-threaded support.
+	 */
+	db_mutex_t mtx_dblist;
+	int	   db_ref;		/* DB handle reference count */
+	TAILQ_HEAD(__dblist, __db) dblist;
+
+	/*
+	 * List of open file handles for this ENV.  Must be protected
+	 * for multi-threaded support.
+	 */
+	TAILQ_HEAD(__fdlist, __fh_t) fdlist;
+
+	db_mutex_t	 mtx_mt;	/* Mersenne Twister mutex */
+	int		 mti;		/* Mersenne Twister index */
+	u_long		*mt;		/* Mersenne Twister state vector */
+
+	DB_CIPHER	*crypto_handle;	/* Crypto handle */
+	DB_LOCKTAB	*lk_handle;	/* Lock handle */
+	DB_LOG		*lg_handle;	/* Log handle */
+	DB_MPOOL	*mp_handle;	/* Mpool handle */
+	DB_MUTEXMGR	*mutex_handle;	/* Mutex handle */
+	DB_REP		*rep_handle;	/* Replication handle */
+	DB_TXNMGR	*tx_handle;	/* Txn handle */
+
+	DB_BACKUP	*backup_handle;	/* database copy configuration. */
+
+	/*
+	 * XA support.
+	 */
+	int		 xa_rmid;	/* XA Resource Manager ID */
+	int		 xa_ref;	/* XA Reference count */
+	TAILQ_ENTRY(__env) links;	/* XA environments */
+
+	/* Application callback to copy data to/from a custom data source */
+#define	DB_USERCOPY_GETDATA	0x0001
+#define	DB_USERCOPY_SETDATA	0x0002
+	int (*dbt_usercopy)
+	    __P((DBT *, u_int32_t, void *, u_int32_t, u_int32_t));
+
+	int (*log_verify_wrap) __P((ENV *, const char *, u_int32_t,
+	    const char *, const char *, time_t, time_t, u_int32_t,  u_int32_t,
+	    u_int32_t, u_int32_t, int, int));
+
+	REGINFO	*reginfo;		/* REGINFO structure reference */
+
+#define	DB_TEST_ELECTINIT	 1	/* after __rep_elect_init */
+#define	DB_TEST_ELECTVOTE1	 2	/* after sending VOTE1 */
+#define	DB_TEST_NO_PAGES	 3	/* before sending PAGE */
+#define	DB_TEST_POSTDESTROY	 4	/* after destroy op */
+#define	DB_TEST_POSTLOG		 5	/* after logging all pages */
+#define	DB_TEST_POSTLOGMETA	 6	/* after logging meta in btree */
+#define	DB_TEST_POSTOPEN	 7	/* after __os_open */
+#define	DB_TEST_POSTSYNC	 8	/* after syncing the log */
+#define	DB_TEST_PREDESTROY	 9	/* before destroy op */
+#define	DB_TEST_PREOPEN		 10	/* before __os_open */
+#define	DB_TEST_REPMGR_PERM	 11	/* repmgr perm/archiving tests */
+#define	DB_TEST_SUBDB_LOCKS	 12	/* subdb locking tests */
+	int	test_abort;		/* Abort value for testing */
+	int	test_check;		/* Checkpoint value for testing */
+	int	test_copy;		/* Copy value for testing */
+
+#define	ENV_CDB			0x00000001 /* DB_INIT_CDB */
+#define	ENV_DBLOCAL		0x00000002 /* Environment for a private DB */
+#define	ENV_LITTLEENDIAN	0x00000004 /* Little endian system. */
+#define	ENV_LOCKDOWN		0x00000008 /* DB_LOCKDOWN set */
+#define	ENV_NO_OUTPUT_SET	0x00000010 /* No output channel set */
+#define	ENV_OPEN_CALLED		0x00000020 /* DB_ENV->open called */
+#define	ENV_PRIVATE		0x00000040 /* DB_PRIVATE set */
+#define	ENV_RECOVER_FATAL	0x00000080 /* Doing fatal recovery in env */
+#define	ENV_REF_COUNTED		0x00000100 /* Region references this handle */
+#define	ENV_SYSTEM_MEM		0x00000200 /* DB_SYSTEM_MEM set */
+#define	ENV_THREAD		0x00000400 /* DB_THREAD set */
+#define ENV_FORCE_TXN_BULK	0x00000800 /* Txns use bulk mode-for testing */
+	u_int32_t flags;
+};
+
+/*******************************************************
+ * Database Access Methods.
+ *******************************************************/
+/*
+ * DB_IS_THREADED --
+ *	The database handle is free-threaded (was opened with DB_THREAD).
+ */
+#define	DB_IS_THREADED(dbp)						\
+	((dbp)->mutex != MUTEX_INVALID)
+
+/* Initialization methods are often illegal before/after open is called. */
+#define	DB_ILLEGAL_AFTER_OPEN(dbp, name)				\
+	if (F_ISSET((dbp), DB_AM_OPEN_CALLED))				\
+		return (__db_mi_open((dbp)->env, name, 1));
+#define	DB_ILLEGAL_BEFORE_OPEN(dbp, name)				\
+	if (!F_ISSET((dbp), DB_AM_OPEN_CALLED))				\
+		return (__db_mi_open((dbp)->env, name, 0));
+/* Some initialization methods are illegal if environment isn't local. */
+#define	DB_ILLEGAL_IN_ENV(dbp, name)					\
+	if (!F_ISSET((dbp)->env, ENV_DBLOCAL))				\
+		return (__db_mi_env((dbp)->env, name));
+#define	DB_ILLEGAL_METHOD(dbp, flags) {					\
+	int __ret;							\
+	if ((__ret = __dbh_am_chk(dbp, flags)) != 0)			\
+		return (__ret);						\
+}
+
+/*
+ * Common DBC->internal fields.  Each access method adds additional fields
+ * to this list, but the initial fields are common.
+ */
+#define	__DBC_INTERNAL							\
+	DBC	 *opd;			/* Off-page duplicate cursor. */\
+	DBC	 *pdbc;			/* Pointer to parent cursor. */ \
+									\
+	void	 *page;			/* Referenced page. */		\
+	u_int32_t part;			/* Partition number. */		\
+	db_pgno_t root;			/* Tree root. */		\
+	db_pgno_t pgno;			/* Referenced page number. */	\
+	db_indx_t indx;			/* Referenced key item index. */\
+									\
+	/* Streaming -- cache last position. */				\
+	db_pgno_t stream_start_pgno;	/* Last start pgno. */		\
+	u_int32_t stream_off;		/* Current offset. */		\
+	db_pgno_t stream_curr_pgno;	/* Current overflow page. */	\
+									\
+	DB_LOCK		lock;		/* Cursor lock. */		\
+	db_lockmode_t	lock_mode;	/* Lock mode. */
+
+struct __dbc_internal {
+	__DBC_INTERNAL
+};
+
+/* Actions that __db_master_update can take. */
+typedef enum { MU_REMOVE, MU_RENAME, MU_OPEN, MU_MOVE } mu_action;
+
+/*
+ * Access-method-common macro for determining whether a cursor
+ * has been initialized.
+ */
+#ifdef HAVE_PARTITION
+#define	IS_INITIALIZED(dbc)	(DB_IS_PARTITIONED((dbc)->dbp) ?	\
+		((PART_CURSOR *)(dbc)->internal)->sub_cursor != NULL && \
+		((PART_CURSOR *)(dbc)->internal)->sub_cursor->		\
+		    internal->pgno != PGNO_INVALID :			\
+		(dbc)->internal->pgno != PGNO_INVALID)
+#else
+#define	IS_INITIALIZED(dbc)	((dbc)->internal->pgno != PGNO_INVALID)
+#endif
+
+/* Free the callback-allocated buffer, if necessary, hanging off of a DBT. */
+#define	FREE_IF_NEEDED(env, dbt)					\
+	if (F_ISSET((dbt), DB_DBT_APPMALLOC)) {				\
+		__os_ufree((env), (dbt)->data);				\
+		F_CLR((dbt), DB_DBT_APPMALLOC);				\
+	}
+
+/*
+ * Use memory belonging to object "owner" to return the results of
+ * any no-DBT-flag get ops on cursor "dbc".
+ */
+#define	SET_RET_MEM(dbc, owner)				\
+	do {						\
+		(dbc)->rskey = &(owner)->my_rskey;	\
+		(dbc)->rkey = &(owner)->my_rkey;	\
+		(dbc)->rdata = &(owner)->my_rdata;	\
+	} while (0)
+
+/* Use the return-data memory src is currently set to use in dest as well. */
+#define	COPY_RET_MEM(src, dest)				\
+	do {						\
+		(dest)->rskey = (src)->rskey;		\
+		(dest)->rkey = (src)->rkey;		\
+		(dest)->rdata = (src)->rdata;		\
+	} while (0)
+
+/* Reset the returned-memory pointers to their defaults. */
+#define	RESET_RET_MEM(dbc)				\
+	do {						\
+		(dbc)->rskey = &(dbc)->my_rskey;	\
+		(dbc)->rkey = &(dbc)->my_rkey;		\
+		(dbc)->rdata = &(dbc)->my_rdata;	\
+	} while (0)
+
+#define	COMPACT_TRUNCATE(c_data) do {			\
+	if (c_data->compact_truncate > 1)		\
+		c_data->compact_truncate--;		\
+} while (0)
+
+/*******************************************************
+ * Mpool.
+ *******************************************************/
+/*
+ * File types for DB access methods.  Negative numbers are reserved to DB.
+ */
+#define	DB_FTYPE_SET		-1		/* Call pgin/pgout functions. */
+#define	DB_FTYPE_NOTSET		 0		/* Don't call... */
+#define	DB_LSN_OFF_NOTSET	-1		/* Not yet set. */
+#define	DB_CLEARLEN_NOTSET	UINT32_MAX	/* Not yet set. */
+
+/* Structure used as the DB pgin/pgout pgcookie. */
+typedef struct __dbpginfo {
+	u_int32_t db_pagesize;		/* Underlying page size. */
+	u_int32_t flags;		/* Some DB_AM flags needed. */
+	DBTYPE  type;			/* DB type */
+} DB_PGINFO;
+
+/*******************************************************
+ * Log.
+ *******************************************************/
+/* Initialize an LSN to 'zero'. */
+#define	ZERO_LSN(LSN) do {						\
+	(LSN).file = 0;							\
+	(LSN).offset = 0;						\
+} while (0)
+#define	IS_ZERO_LSN(LSN)	((LSN).file == 0 && (LSN).offset == 0)
+
+#define	IS_INIT_LSN(LSN)	((LSN).file == 1 && (LSN).offset == 0)
+#define	INIT_LSN(LSN)		do {					\
+	(LSN).file = 1;							\
+	(LSN).offset = 0;						\
+} while (0)
+
+#define	MAX_LSN(LSN) do {						\
+	(LSN).file = UINT32_MAX;					\
+	(LSN).offset = UINT32_MAX;					\
+} while (0)
+#define	IS_MAX_LSN(LSN) \
+	((LSN).file == UINT32_MAX && (LSN).offset == UINT32_MAX)
+
+/* If logging is turned off, smash the lsn. */
+#define	LSN_NOT_LOGGED(LSN) do {					\
+	(LSN).file = 0;							\
+	(LSN).offset = 1;						\
+} while (0)
+#define	IS_NOT_LOGGED_LSN(LSN) \
+	((LSN).file == 0 && (LSN).offset == 1)
+
+/*
+ * LOG_COMPARE -- compare two LSNs.
+ */
+
+#define	LOG_COMPARE(lsn0, lsn1)						\
+	((lsn0)->file != (lsn1)->file ?					\
+	((lsn0)->file < (lsn1)->file ? -1 : 1) :			\
+	((lsn0)->offset != (lsn1)->offset ?				\
+	((lsn0)->offset < (lsn1)->offset ? -1 : 1) : 0))
+
+/*******************************************************
+ * Txn.
+ *******************************************************/
+#define	DB_NONBLOCK(C)	((C)->txn != NULL && F_ISSET((C)->txn, TXN_NOWAIT))
+#define	NOWAIT_FLAG(txn) \
+	((txn) != NULL && F_ISSET((txn), TXN_NOWAIT) ? DB_LOCK_NOWAIT : 0)
+#define	IS_REAL_TXN(txn)						\
+	((txn) != NULL && !F_ISSET(txn, TXN_FAMILY))
+#define	IS_SUBTRANSACTION(txn)						\
+	((txn) != NULL && (txn)->parent != NULL)
+
+/* Checks for existence of an XA transaction in access method interfaces. */
+#define	XA_CHECK_TXN(ip, txn) 						\
+	if ((ip) != NULL && (txn) == NULL) {				\
+		(txn) = SH_TAILQ_FIRST(&(ip)->dbth_xatxn, __db_txn);	\
+		DB_ASSERT(env, txn == NULL ||				\
+		    txn->xa_thr_status == TXN_XA_THREAD_ASSOCIATED);	\
+	}
+
+/* Ensure that there is no XA transaction active. */
+#define	XA_NO_TXN(ip, retval) {						\
+	DB_TXN *__txn;							\
+	retval = 0;							\
+	if ((ip) != NULL) {						\
+		__txn = SH_TAILQ_FIRST(&(ip)->dbth_xatxn, __db_txn);	\
+		if (__txn != NULL &&					\
+		    __txn->xa_thr_status == TXN_XA_THREAD_ASSOCIATED)	\
+		    	retval = EINVAL;				\
+	}								\
+}
+
+/*******************************************************
+ * Crypto.
+ *******************************************************/
+#define	DB_IV_BYTES     16		/* Bytes per IV */
+#define	DB_MAC_KEY	20		/* Bytes per MAC checksum */
+
+/*******************************************************
+ * Compression
+ *******************************************************/
+#define	CMP_INT_SPARE_VAL	0xFC	/* Smallest byte value that the integer
+					   compression algorithm doesn't use */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*******************************************************
+ * Remaining general DB includes.
+ *******************************************************/
+@db_int_def@
+
+#include "dbinc/globals.h"
+#include "dbinc/clock.h"
+#include "dbinc/debug.h"
+#include "dbinc/region.h"
+#include "dbinc_auto/env_ext.h"
+#include "dbinc/mutex.h"
+#ifdef HAVE_REPLICATION_THREADS
+#include "dbinc/repmgr.h"
+#endif
+#include "dbinc/rep.h"
+#include "dbinc/os.h"
+#include "dbinc_auto/clib_ext.h"
+#include "dbinc_auto/common_ext.h"
+
+/*******************************************************
+ * Remaining Log.
+ * These need to be defined after the general includes
+ * because they need rep.h from above.
+ *******************************************************/
+/*
+ * Test if the environment is currently logging changes.  If we're in recovery
+ * or we're a replication client, we don't need to log changes because they're
+ * already in the log, even though we have a fully functional log system.
+ */
+#define	DBENV_LOGGING(env)						\
+	(LOGGING_ON(env) && !IS_REP_CLIENT(env) && (!IS_RECOVERING(env)))
+
+/*
+ * Test if we need to log a change.  By default, we don't log operations without
+ * associated transactions, unless DIAGNOSTIC, DEBUG_ROP or DEBUG_WOP are on.
+ * This is because we want to get log records for read/write operations, and, if
+ * we are trying to debug something, more information is always better.
+ *
+ * The DBC_RECOVER flag is set when we're in abort, as well as during recovery;
+ * thus DBC_LOGGING may be false for a particular dbc even when DBENV_LOGGING
+ * is true.
+ *
+ * We explicitly use LOGGING_ON/IS_REP_CLIENT here because we don't want to pull
+ * in the log headers, which IS_RECOVERING (and thus DBENV_LOGGING) rely on, and
+ * because DBC_RECOVER should be set anytime IS_RECOVERING would be true.
+ *
+ * If we're not in recovery (master - doing an abort or a client applying
+ * a txn), then a client's only path through here is on an internal
+ * operation, and a master's only path through here is a transactional
+ * operation.  Detect if either is not the case.
+ */
+#if defined(DIAGNOSTIC) || defined(DEBUG_ROP)  || defined(DEBUG_WOP)
+#define	DBC_LOGGING(dbc)	__dbc_logging(dbc)
+#else
+#define	DBC_LOGGING(dbc)						\
+	((dbc)->txn != NULL && LOGGING_ON((dbc)->env) &&		\
+	    !F_ISSET((dbc), DBC_RECOVER) && !IS_REP_CLIENT((dbc)->env))
+#endif
+
+#endif /* !_DB_INT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/db_join.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,59 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_JOIN_H_
+#define	_DB_JOIN_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Joins use a join cursor that is similar to a regular DB cursor except
+ * that it only supports c_get and c_close functionality.  Also, it does
+ * not support the full range of flags for get.
+ */
+typedef struct __join_cursor {
+	u_int8_t *j_exhausted;	/* Array of flags; is cursor i exhausted? */
+	DBC	**j_curslist;	/* Array of cursors in the join: constant. */
+	DBC	**j_fdupcurs;	/* Cursors w/ first instances of current dup. */
+	DBC	**j_workcurs;	/* Scratch cursor copies to muck with. */
+	DB	 *j_primary;	/* Primary dbp. */
+	DBT	  j_key;	/* Used to do lookups. */
+	DBT	  j_rdata;	/* Memory used for data return. */
+	u_int32_t j_ncurs;	/* How many cursors do we have? */
+#define	JOIN_RETRY	0x01	/* Error on primary get; re-return same key. */
+	u_int32_t flags;
+} JOIN_CURSOR;
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_JOIN_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/db_page.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,863 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_PAGE_H_
+#define	_DB_PAGE_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * DB page formats.
+ *
+ * !!!
+ * This implementation requires that values within the following structures
+ * NOT be padded -- note, ANSI C permits random padding within structures.
+ * If your compiler pads randomly you can just forget ever making DB run on
+ * your system.  In addition, no data type can require larger alignment than
+ * its own size, e.g., a 4-byte data element may not require 8-byte alignment.
+ *
+ * Note that key/data lengths are often stored in db_indx_t's -- this is
+ * not accidental, nor does it limit the key/data size.  If the key/data
+ * item fits on a page, it's guaranteed to be small enough to fit into a
+ * db_indx_t, and storing it in one saves space.
+ */
+
+#define	PGNO_INVALID	0	/* Invalid page number in any database. */
+#define	PGNO_BASE_MD	0	/* Base database: metadata page number. */
+
+/* Page types. */
+#define	P_INVALID	0	/* Invalid page type. */
+#define	__P_DUPLICATE	1	/* Duplicate. DEPRECATED in 3.1 */
+#define	P_HASH_UNSORTED	2	/* Hash pages created pre 4.6. DEPRECATED */
+#define	P_IBTREE	3	/* Btree internal. */
+#define	P_IRECNO	4	/* Recno internal. */
+#define	P_LBTREE	5	/* Btree leaf. */
+#define	P_LRECNO	6	/* Recno leaf. */
+#define	P_OVERFLOW	7	/* Overflow. */
+#define	P_HASHMETA	8	/* Hash metadata page. */
+#define	P_BTREEMETA	9	/* Btree metadata page. */
+#define	P_QAMMETA	10	/* Queue metadata page. */
+#define	P_QAMDATA	11	/* Queue data page. */
+#define	P_LDUP		12	/* Off-page duplicate leaf. */
+#define	P_HASH		13	/* Sorted hash page. */
+#define	P_HEAPMETA	14	/* Heap metadata page. */
+#define	P_HEAP		15	/* Heap data page. */
+#define	P_IHEAP		16	/* Heap internal. */
+#define	P_PAGETYPE_MAX	17
+/* Flag to __db_new */
+#define	P_DONTEXTEND	0x8000	/* Don't allocate if there are no free pages. */
+
+/*
+ * When we create pages in mpool, we ask mpool to clear some number of bytes
+ * in the header.  This number must be at least as big as the regular page
+ * headers and cover enough of the btree and hash meta-data pages to obliterate
+ * the page type.
+ */
+#define	DB_PAGE_DB_LEN		32
+#define	DB_PAGE_QUEUE_LEN	0
+
+/************************************************************************
+ GENERIC METADATA PAGE HEADER
+ *
+ * !!!
+ * The magic and version numbers have to be in the same place in all versions
+ * of the metadata page as the application may not have upgraded the database.
+ ************************************************************************/
+typedef struct _dbmeta33 {
+	DB_LSN	  lsn;		/* 00-07: LSN. */
+	db_pgno_t pgno;		/* 08-11: Current page number. */
+	u_int32_t magic;	/* 12-15: Magic number. */
+	u_int32_t version;	/* 16-19: Version. */
+	u_int32_t pagesize;	/* 20-23: Pagesize. */
+	u_int8_t  encrypt_alg;	/*    24: Encryption algorithm. */
+	u_int8_t  type;		/*    25: Page type. */
+#define	DBMETA_CHKSUM		0x01
+#define	DBMETA_PART_RANGE	0x02
+#define	DBMETA_PART_CALLBACK	0x04
+	u_int8_t  metaflags;	/* 26: Meta-only flags */
+	u_int8_t  unused1;	/* 27: Unused. */
+	u_int32_t free;		/* 28-31: Free list page number. */
+	db_pgno_t last_pgno;	/* 32-35: Page number of last page in db. */
+	u_int32_t nparts;	/* 36-39: Number of partitions. */
+	u_int32_t key_count;	/* 40-43: Cached key count. */
+	u_int32_t record_count;	/* 44-47: Cached record count. */
+	u_int32_t flags;	/* 48-51: Flags: unique to each AM. */
+				/* 52-71: Unique file ID. */
+	u_int8_t  uid[DB_FILE_ID_LEN];
+} DBMETA33, DBMETA;
+
+/************************************************************************
+ BTREE METADATA PAGE LAYOUT
+ ************************************************************************/
+typedef struct _btmeta33 {
+#define	BTM_DUP		0x001	/*	  Duplicates. */
+#define	BTM_RECNO	0x002	/*	  Recno tree. */
+#define	BTM_RECNUM	0x004	/*	  Btree: maintain record count. */
+#define	BTM_FIXEDLEN	0x008	/*	  Recno: fixed length records. */
+#define	BTM_RENUMBER	0x010	/*	  Recno: renumber on insert/delete. */
+#define	BTM_SUBDB	0x020	/*	  Subdatabases. */
+#define	BTM_DUPSORT	0x040	/*	  Duplicates are sorted. */
+#define	BTM_COMPRESS	0x080	/*	  Compressed. */
+#define	BTM_MASK	0x0ff
+	DBMETA	dbmeta;		/* 00-71: Generic meta-data header. */
+
+	u_int32_t unused1;	/* 72-75: Unused space. */
+	u_int32_t minkey;	/* 76-79: Btree: Minkey. */
+	u_int32_t re_len;	/* 80-83: Recno: fixed-length record length. */
+	u_int32_t re_pad;	/* 84-87: Recno: fixed-length record pad. */
+	u_int32_t root;		/* 88-91: Root page. */
+	u_int32_t unused2[92];	/* 92-459: Unused space. */
+	u_int32_t crypto_magic;		/* 460-463: Crypto magic number */
+	u_int32_t trash[3];		/* 464-475: Trash space - Do not use */
+	u_int8_t iv[DB_IV_BYTES];	/* 476-495: Crypto IV */
+	u_int8_t chksum[DB_MAC_KEY];	/* 496-511: Page chksum */
+
+	/*
+	 * Minimum page size is 512.
+	 */
+} BTMETA33, BTMETA;
+
+/************************************************************************
+ HASH METADATA PAGE LAYOUT
+ ************************************************************************/
+typedef struct _hashmeta33 {
+#define	DB_HASH_DUP	0x01	/*	  Duplicates. */
+#define	DB_HASH_SUBDB	0x02	/*	  Subdatabases. */
+#define	DB_HASH_DUPSORT	0x04	/*	  Duplicates are sorted. */
+	DBMETA dbmeta;		/* 00-71: Generic meta-data page header. */
+
+	u_int32_t max_bucket;	/* 72-75: ID of Maximum bucket in use */
+	u_int32_t high_mask;	/* 76-79: Modulo mask into table */
+	u_int32_t low_mask;	/* 80-83: Modulo mask into table lower half */
+	u_int32_t ffactor;	/* 84-87: Fill factor */
+	u_int32_t nelem;	/* 88-91: Number of keys in hash table */
+	u_int32_t h_charkey;	/* 92-95: Value of hash(CHARKEY) */
+#define	NCACHED	32		/* number of spare points */
+				/* 96-223: Spare pages for overflow */
+	u_int32_t spares[NCACHED];
+	u_int32_t unused[59];	/* 224-459: Unused space */
+	u_int32_t crypto_magic;	/* 460-463: Crypto magic number */
+	u_int32_t trash[3];	/* 464-475: Trash space - Do not use */
+	u_int8_t iv[DB_IV_BYTES];	/* 476-495: Crypto IV */
+	u_int8_t chksum[DB_MAC_KEY];	/* 496-511: Page chksum */
+
+	/*
+	 * Minimum page size is 512.
+	 */
+} HMETA33, HMETA;
+
+/************************************************************************
+ HEAP METADATA PAGE LAYOUT
+*************************************************************************/
+/*
+ * Heap Meta data page structure
+ *
+ */
+typedef struct _heapmeta {
+	DBMETA    dbmeta;		/* 00-71: Generic meta-data header. */
+
+	db_pgno_t curregion;		/* 72-75: Current region pgno. */
+	u_int32_t nregions;		/* 76-79: Number of regions. */
+	u_int32_t gbytes;		/* 80-83: GBytes for fixed size heap. */
+	u_int32_t bytes;		/* 84-87: Bytes for fixed size heap. */
+	u_int32_t region_size;		/* 88-91: Max region size. */
+	u_int32_t unused2[92];		/* 92-459: Unused space.*/
+	u_int32_t crypto_magic;		/* 460-463: Crypto magic number */
+	u_int32_t trash[3];		/* 464-475: Trash space - Do not use */
+	u_int8_t  iv[DB_IV_BYTES];	/* 476-495: Crypto IV */
+	u_int8_t  chksum[DB_MAC_KEY];	/* 496-511: Page chksum */
+
+
+	/*
+	 * Minimum page size is 512.
+	 */
+} HEAPMETA;
+		
+/************************************************************************
+ QUEUE METADATA PAGE LAYOUT
+ ************************************************************************/
+/*
+ * QAM Meta data page structure
+ *
+ */
+typedef struct _qmeta33 {
+	DBMETA    dbmeta;	/* 00-71: Generic meta-data header. */
+
+	u_int32_t first_recno;	/* 72-75: First not deleted record. */
+	u_int32_t cur_recno;	/* 76-79: Next recno to be allocated. */
+	u_int32_t re_len;	/* 80-83: Fixed-length record length. */
+	u_int32_t re_pad;	/* 84-87: Fixed-length record pad. */
+	u_int32_t rec_page;	/* 88-91: Records Per Page. */
+	u_int32_t page_ext;	/* 92-95: Pages per extent */
+
+	u_int32_t unused[91];	/* 96-459: Unused space */
+	u_int32_t crypto_magic;	/* 460-463: Crypto magic number */
+	u_int32_t trash[3];	/* 464-475: Trash space - Do not use */
+	u_int8_t iv[DB_IV_BYTES];	/* 476-495: Crypto IV */
+	u_int8_t chksum[DB_MAC_KEY];	/* 496-511: Page chksum */
+	/*
+	 * Minimum page size is 512.
+	 */
+} QMETA33, QMETA;
+
+/*
+ * DBMETASIZE is a constant used by __db_file_setup and DB->verify
+ * as a buffer which is guaranteed to be larger than any possible
+ * metadata page size and smaller than any disk sector.
+ */
+#define	DBMETASIZE	512
+
+/************************************************************************
+ BTREE/HASH MAIN PAGE LAYOUT
+ ************************************************************************/
+/*
+ *	+-----------------------------------+
+ *	|    lsn    |   pgno    | prev pgno |
+ *	+-----------------------------------+
+ *	| next pgno |  entries  | hf offset |
+ *	+-----------------------------------+
+ *	|   level   |   type    |   chksum  |
+ *	+-----------------------------------+
+ *	|    iv     |   index   | free -->  |
+ *	+-----------+-----------------------+
+ *	|	 F R E E A R E A            |
+ *	+-----------------------------------+
+ *	|              <-- free |   item    |
+ *	+-----------------------------------+
+ *	|   item    |   item    |   item    |
+ *	+-----------------------------------+
+ *
+ * sizeof(PAGE) == 26 bytes + possibly 20 bytes of checksum and possibly
+ * 16 bytes of IV (+ 2 bytes for alignment), and the following indices
+ * are guaranteed to be two-byte aligned.  If we aren't doing crypto or
+ * checksumming the bytes are reclaimed for data storage.
+ *
+ * For hash and btree leaf pages, index items are paired, e.g., inp[0] is the
+ * key for inp[1]'s data.  All other types of pages only contain single items.
+ */
+typedef struct __pg_chksum {
+	u_int8_t	unused[2];		/* 26-27: For alignment */
+	u_int8_t	chksum[4];		/* 28-31: Checksum */
+} PG_CHKSUM;
+
+typedef struct __pg_crypto {
+	u_int8_t	unused[2];		/* 26-27: For alignment */
+	u_int8_t	chksum[DB_MAC_KEY];	/* 28-47: Checksum */
+	u_int8_t	iv[DB_IV_BYTES];	/* 48-63: IV */
+	/* !!!
+	 * Must be 16-byte aligned for crypto
+	 */
+} PG_CRYPTO;
+
+typedef struct _db_page {
+	DB_LSN	  lsn;		/* 00-07: Log sequence number. */
+	db_pgno_t pgno;		/* 08-11: Current page number. */
+	db_pgno_t prev_pgno;	/* 12-15: Previous page number. */
+	db_pgno_t next_pgno;	/* 16-19: Next page number. */
+	db_indx_t entries;	/* 20-21: Number of items on the page. */
+	db_indx_t hf_offset;	/* 22-23: High free byte page offset. */
+
+	/*
+	 * The btree levels are numbered from the leaf to the root, starting
+	 * with 1, so the leaf is level 1, its parent is level 2, and so on.
+	 * We maintain this level on all btree pages, but the only place that
+	 * we actually need it is on the root page.  It would not be difficult
+	 * to hide the byte on the root page once it becomes an internal page,
+	 * so we could get this byte back if we needed it for something else.
+	 */
+#define	LEAFLEVEL	  1
+#define	MAXBTREELEVEL	255
+	u_int8_t  level;	/*    24: Btree tree level. */
+	u_int8_t  type;		/*    25: Page type. */
+} PAGE;
+
+/*
+ * With many compilers sizeof(PAGE) == 28, while SIZEOF_PAGE == 26.
+ * We add in other things directly after the page header and need
+ * the SIZEOF_PAGE.  When giving the sizeof(), many compilers will
+ * pad it out to the next 4-byte boundary.
+ */
+#define	SIZEOF_PAGE	26
+/*
+ * !!!
+ * DB_AM_ENCRYPT always implies DB_AM_CHKSUM so that must come first.
+ */
+#define	P_INP(dbp, pg)							\
+	((db_indx_t *)((u_int8_t *)(pg) + SIZEOF_PAGE +			\
+	(F_ISSET((dbp), DB_AM_ENCRYPT) ? sizeof(PG_CRYPTO) :		\
+	(F_ISSET((dbp), DB_AM_CHKSUM) ? sizeof(PG_CHKSUM) : 0))))
+
+#define	P_IV(dbp, pg)							\
+	(F_ISSET((dbp), DB_AM_ENCRYPT) ? ((u_int8_t *)(pg) +		\
+	SIZEOF_PAGE + SSZA(PG_CRYPTO, iv))				\
+	: NULL)
+
+#define	P_CHKSUM(dbp, pg)						\
+	(F_ISSET((dbp), DB_AM_ENCRYPT) ? ((u_int8_t *)(pg) +		\
+	SIZEOF_PAGE + SSZA(PG_CRYPTO, chksum)) :			\
+	(F_ISSET((dbp), DB_AM_CHKSUM) ? ((u_int8_t *)(pg) +		\
+	SIZEOF_PAGE + SSZA(PG_CHKSUM, chksum))				\
+	: NULL))
+
+/* PAGE element macros. */
+#define	LSN(p)		(((PAGE *)p)->lsn)
+#define	PGNO(p)		(((PAGE *)p)->pgno)
+#define	PREV_PGNO(p)	(((PAGE *)p)->prev_pgno)
+#define	NEXT_PGNO(p)	(((PAGE *)p)->next_pgno)
+#define	NUM_ENT(p)	(((PAGE *)p)->entries)
+#define	HOFFSET(p)	(((PAGE *)p)->hf_offset)
+#define	LEVEL(p)	(((PAGE *)p)->level)
+#define	TYPE(p)		(((PAGE *)p)->type)
+
+/************************************************************************
+ HEAP PAGE LAYOUT
+ ************************************************************************/
+#define HEAPPG_NORMAL	26
+#define HEAPPG_CHKSUM	48
+#define HEAPPG_SEC	64
+
+/*
+ *	+0-----------2------------4-----------6-----------7+
+ *	|                        lsn                       |
+ *	+-------------------------+------------------------+
+ *	|           pgno          |         unused0        |
+ *      +-------------+-----------+-----------+------------+
+ *	|  high_indx  | free_indx |  entries  |  hf offset |
+ *	+-------+-----+-----------+-----------+------------+
+ *	|unused2|type |  unused3  |      ...chksum...      |
+ *	+-------+-----+-----------+------------------------+
+ *	|  ...iv...   |   offset table / free space map    |
+ *	+-------------+------------------------------------+
+ *	|free->	 	F R E E A R E A                    |
+ *	+--------------------------------------------------+
+ *	|                <-- free |          item          |
+ *	+-------------------------+------------------------+
+ *	|           item          |          item          |
+ *	+-------------------------+------------------------+
+ *
+ * The page layout of both heap internal and data pages.  If not using
+ * crypto, iv will be overwritten with data.  If not using checksumming,
+ * unused3 and chksum will also be overwritten with data and data will start at
+ * 26.  Note that this layout lets us re-use a lot of the PAGE element macros
+ * defined above.
+ */
+typedef struct _heappg {
+	DB_LSN lsn;		/* 00-07: Log sequence number. */
+	db_pgno_t pgno;		/* 08-11: Current page number. */
+	u_int32_t high_pgno;	/* 12-15: Highest page in region. */
+	u_int16_t high_indx;	/* 16-17: Highest index in the offset table. */
+	db_indx_t free_indx;	/* 18-19: First available index. */
+	db_indx_t entries;	/* 20-21: Number of items on the page. */
+	db_indx_t hf_offset;	/* 22-23: High free byte page offset. */
+	u_int8_t unused2[1];	/*    24: Unused. */
+	u_int8_t type;		/*    25: Page type. */
+	u_int8_t unused3[2];    /* 26-27: Never used, just checksum alignment. */
+	u_int8_t  chksum[DB_MAC_KEY]; /* 28-47: Checksum */
+	u_int8_t  iv[DB_IV_BYTES]; /* 48-63: IV */
+} HEAPPG;
+
+/* Define first possible data page for heap, 0 is metapage, 1 is region page */
+#define FIRST_HEAP_RPAGE 1 
+#define FIRST_HEAP_DPAGE 2
+
+typedef struct __heaphdr {
+#define HEAP_RECSPLIT 0x01 /* Heap data record is split */
+#define HEAP_RECFIRST 0x02 /* First piece of a split record */
+#define HEAP_RECLAST  0x04 /* Last piece of a split record */
+	u_int8_t flags;		/* 00: Flags describing record. */
+	u_int8_t unused;	/* 01: Padding. */
+	u_int16_t size;		/* 02-03: The size of the stored data piece. */
+} HEAPHDR;
+
+typedef struct __heaphdrsplt {
+	HEAPHDR std_hdr;	/* 00-03: The standard data header */
+	u_int32_t tsize;	/* 04-07: Total record size, 1st piece only */
+	db_pgno_t nextpg;	/* 08-11: RID.pgno of the next record piece */
+	db_indx_t nextindx;	/* 12-13: RID.indx of the next record piece */
+	u_int16_t unused;	/* 14-15: Padding. */
+} HEAPSPLITHDR;
+
+#define HEAP_HDRSIZE(hdr) 					\
+	(F_ISSET((hdr), HEAP_RECSPLIT) ? sizeof(HEAPSPLITHDR) : sizeof(HEAPHDR))
+
+#define HEAPPG_SZ(dbp)			       			\
+	(F_ISSET((dbp), DB_AM_ENCRYPT) ? HEAPPG_SEC :		\
+	F_ISSET((dbp), DB_AM_CHKSUM) ? HEAPPG_CHKSUM : HEAPPG_NORMAL)
+
+/* Each byte in the bitmap describes 4 pages (2 bits per page.) */
+#define HEAP_REGION_COUNT(dbp, size) (((size) - HEAPPG_SZ(dbp)) * 4)
+#define HEAP_DEFAULT_REGION_MAX(dbp)				\
+	(HEAP_REGION_COUNT(dbp, (u_int32_t)8 * 1024))
+#define	HEAP_REGION_SIZE(dbp)	(((HEAP*) (dbp)->heap_internal)->region_size)
+
+/* Figure out which region a given page belongs to. */
+#define HEAP_REGION_PGNO(dbp, p) 				\
+	((((p) - 1) / (HEAP_REGION_SIZE(dbp) + 1)) * 		\
+	(HEAP_REGION_SIZE(dbp) + 1) + 1)
+/* Translate a region pgno to region number */
+#define HEAP_REGION_NUM(dbp, pgno)				\
+	((((pgno) - 1) / (HEAP_REGION_SIZE((dbp)) + 1)) + 1)
+/* 
+ * Given an internal heap page and page number relative to that page, return the
+ * bits from map describing free space on the nth page.  Each byte in the map
+ * describes 4 pages. Point at the correct byte and mask the correct 2 bits.
+ */
+#define HEAP_SPACE(dbp, pg, n)					\
+	(HEAP_SPACEMAP((dbp), (pg))[(n) / 4] >> (2 * ((n) % 4)) & 3)
+      
+#define HEAP_SETSPACE(dbp, pg, n, b) do {				\
+	HEAP_SPACEMAP((dbp), (pg))[(n) / 4] &= ~(3 << (2 * ((n) % 4))); \
+	HEAP_SPACEMAP((dbp), (pg))[(n) / 4] |= ((b & 3) << (2 * ((n) % 4))); \
+} while (0)
+		
+/* Return the bitmap describing free space on heap data pages. */
+#define HEAP_SPACEMAP(dbp, pg) ((u_int8_t *)P_INP((dbp), (pg)))
+
+/* Return the offset table for a heap data page. */
+#define HEAP_OFFSETTBL(dbp, pg) P_INP((dbp), (pg))
+
+/* 
+ * Calculate the % of a page a given size occupies and translate that to the
+ * corresponding bitmap value. 
+ */
+#define HEAP_CALCSPACEBITS(dbp, sz, space) do {			\
+	(space) = 100 * (sz) / (dbp)->pgsize;			\
+	if ((space) <= HEAP_PG_FULL_PCT)			\
+		(space) = HEAP_PG_FULL;				\
+	else if ((space) <= HEAP_PG_GT66_PCT)			\
+		(space) = HEAP_PG_GT66;				\
+	else if ((space) <= HEAP_PG_GT33_PCT)			\
+		(space) = HEAP_PG_GT33;				\
+	else							\
+		(space) = HEAP_PG_LT33;				\
+} while (0)
+	
+/* Return the amount of free space on a heap data page. */
+#define HEAP_FREESPACE(dbp, p)                                  \
+	(HOFFSET(p) - HEAPPG_SZ(dbp) -				\
+	(NUM_ENT(p) == 0 ? 0 : ((HEAP_HIGHINDX(p) + 1) * sizeof(db_indx_t))))
+
+/* The maximum amount of data that can fit on an empty heap data page. */
+#define HEAP_MAXDATASIZE(dbp)					\
+	((dbp)->pgsize - HEAPPG_SZ(dbp) - sizeof(db_indx_t))
+
+#define HEAP_FREEINDX(p)	(((HEAPPG *)p)->free_indx)
+#define HEAP_HIGHINDX(p)	(((HEAPPG *)p)->high_indx)
+
+/* True if we have a page that deals with heap */
+#define HEAPTYPE(h)                                           \
+    (TYPE(h) == P_HEAPMETA || TYPE(h) == P_HEAP || TYPE(h) == P_IHEAP)
+
+/************************************************************************
+ QUEUE MAIN PAGE LAYOUT
+ ************************************************************************/
+/*
+ * Sizes of page below.  Used to reclaim space if not doing
+ * crypto or checksumming.  If you change the QPAGE below you
+ * MUST adjust this too.
+ */
+#define	QPAGE_NORMAL	28
+#define	QPAGE_CHKSUM	48
+#define	QPAGE_SEC	64
+
+typedef struct _qpage {
+	DB_LSN	  lsn;		/* 00-07: Log sequence number. */
+	db_pgno_t pgno;		/* 08-11: Current page number. */
+	u_int32_t unused0[3];	/* 12-23: Unused. */
+	u_int8_t  unused1[1];	/*    24: Unused. */
+	u_int8_t  type;		/*    25: Page type. */
+	u_int8_t  unused2[2];	/* 26-27: Unused. */
+	u_int8_t  chksum[DB_MAC_KEY]; /* 28-47: Checksum */
+	u_int8_t  iv[DB_IV_BYTES]; /* 48-63: IV */
+} QPAGE;
+
+#define	QPAGE_SZ(dbp)						\
+	(F_ISSET((dbp), DB_AM_ENCRYPT) ? QPAGE_SEC :		\
+	F_ISSET((dbp), DB_AM_CHKSUM) ? QPAGE_CHKSUM : QPAGE_NORMAL)
+/*
+ * !!!
+ * The next_pgno and prev_pgno fields are not maintained for btree and recno
+ * internal pages.  Doing so only provides a minor performance improvement,
+ * it's hard to do when deleting internal pages, and it increases the chance
+ * of deadlock during deletes and splits because we have to re-link pages at
+ * more than the leaf level.
+ *
+ * !!!
+ * The btree/recno access method needs db_recno_t bytes of space on the root
+ * page to specify how many records are stored in the tree.  (The alternative
+ * is to store the number of records in the meta-data page, which will create
+ * a second hot spot in trees being actively modified, or recalculate it from
+ * the BINTERNAL fields on each access.)  Overload the PREV_PGNO field.
+ */
+#define	RE_NREC(p)							\
+	((TYPE(p) == P_IBTREE || TYPE(p) == P_IRECNO) ?	PREV_PGNO(p) :	\
+	(db_pgno_t)(TYPE(p) == P_LBTREE ? NUM_ENT(p) / 2 : NUM_ENT(p)))
+#define	RE_NREC_ADJ(p, adj)						\
+	PREV_PGNO(p) += adj;
+#define	RE_NREC_SET(p, num)						\
+	PREV_PGNO(p) = (num);
+
+/*
+ * Initialize a page.
+ *
+ * !!!
+ * Don't modify the page's LSN, code depends on it being unchanged after a
+ * P_INIT call.
+ */
+#define	P_INIT(pg, pg_size, n, pg_prev, pg_next, btl, pg_type) do {	\
+	PGNO(pg) = (n);							\
+	PREV_PGNO(pg) = (pg_prev);					\
+	NEXT_PGNO(pg) = (pg_next);					\
+	NUM_ENT(pg) = (0);						\
+	HOFFSET(pg) = (db_indx_t)(pg_size);				\
+	LEVEL(pg) = (btl);						\
+	TYPE(pg) = (pg_type);						\
+} while (0)
+
+/* Page header length (offset to first index). */
+#define	P_OVERHEAD(dbp)	P_TO_UINT16(P_INP(dbp, 0))
+
+/* First free byte. */
+#define	LOFFSET(dbp, pg)						\
+    (P_OVERHEAD(dbp) + NUM_ENT(pg) * sizeof(db_indx_t))
+
+/* Free space on a regular page. */
+#define	P_FREESPACE(dbp, pg)	(HOFFSET(pg) - LOFFSET(dbp, pg))
+
+/* Get a pointer to the bytes at a specific index. */
+#define	P_ENTRY(dbp, pg, indx)	((u_int8_t *)pg + P_INP(dbp, pg)[indx])
+
+/************************************************************************
+ OVERFLOW PAGE LAYOUT
+ ************************************************************************/
+
+/*
+ * Overflow items are referenced by HOFFPAGE and BOVERFLOW structures, which
+ * store a page number (the first page of the overflow item) and a length
+ * (the total length of the overflow item).  The overflow item consists of
+ * some number of overflow pages, linked by the next_pgno field of the page.
+ * A next_pgno field of PGNO_INVALID flags the end of the overflow item.
+ *
+ * Overflow page overloads:
+ *	The amount of overflow data stored on each page is stored in the
+ *	hf_offset field.
+ *
+ *	The implementation reference counts overflow items as it's possible
+ *	for them to be promoted onto btree internal pages.  The reference
+ *	count is stored in the entries field.
+ */
+#define	OV_LEN(p)	(((PAGE *)p)->hf_offset)
+#define	OV_REF(p)	(((PAGE *)p)->entries)
+
+/* Maximum number of bytes that you can put on an overflow page. */
+#define	P_MAXSPACE(dbp, psize)	((psize) - P_OVERHEAD(dbp))
+
+/* Free space on an overflow page. */
+#define	P_OVFLSPACE(dbp, psize, pg)	(P_MAXSPACE(dbp, psize) - HOFFSET(pg))
+
+/************************************************************************
+ HASH PAGE LAYOUT
+ ************************************************************************/
+
+/* Each index references a group of bytes on the page. */
+#define	H_KEYDATA	1	/* Key/data item. */
+#define	H_DUPLICATE	2	/* Duplicate key/data item. */
+#define	H_OFFPAGE	3	/* Overflow key/data item. */
+#define	H_OFFDUP	4	/* Overflow page of duplicates. */
+
+/*
+ * !!!
+ * Items on hash pages are (potentially) unaligned, so we can never cast the
+ * (page + offset) pointer to an HKEYDATA, HOFFPAGE or HOFFDUP structure, as
+ * we do with B+tree on-page structures.  Because we frequently want the type
+ * field, it requires no alignment, and it's in the same location in all three
+ * structures, there's a pair of macros.
+ */
+#define	HPAGE_PTYPE(p)		(*(u_int8_t *)p)
+#define	HPAGE_TYPE(dbp, pg, indx)	(*P_ENTRY(dbp, pg, indx))
+
+/*
+ * The first and second types are H_KEYDATA and H_DUPLICATE, represented
+ * by the HKEYDATA structure:
+ *
+ *	+-----------------------------------+
+ *	|    type   | key/data ...          |
+ *	+-----------------------------------+
+ *
+ * For duplicates, the data field encodes duplicate elements in the data
+ * field:
+ *
+ *	+---------------------------------------------------------------+
+ *	|    type   | len1 | element1 | len1 | len2 | element2 | len2   |
+ *	+---------------------------------------------------------------+
+ *
+ * Thus, by keeping track of the offset in the element, we can do both
+ * backward and forward traversal.
+ */
+typedef struct _hkeydata {
+	u_int8_t  type;		/*    00: Page type. */
+	u_int8_t  data[1];	/* Variable length key/data item. */
+} HKEYDATA;
+#define	HKEYDATA_DATA(p)	(((u_int8_t *)p) + SSZA(HKEYDATA, data))
+
+/*
+ * The length of any HKEYDATA item. Note that indx is an element index,
+ * not a PAIR index.
+ */
+#define	LEN_HITEM(dbp, pg, pgsize, indx)				\
+	(((indx) == 0 ? (pgsize) :					\
+	(P_INP(dbp, pg)[(indx) - 1])) - (P_INP(dbp, pg)[indx]))
+
+#define	LEN_HKEYDATA(dbp, pg, psize, indx)				\
+	(db_indx_t)(LEN_HITEM(dbp, pg, psize, indx) - HKEYDATA_SIZE(0))
+
+/*
+ * Page space required to add a new HKEYDATA item to the page, with and
+ * without the index value.
+ */
+#define	HKEYDATA_SIZE(len)						\
+	((len) + SSZA(HKEYDATA, data))
+#define	HKEYDATA_PSIZE(len)						\
+	(HKEYDATA_SIZE(len) + sizeof(db_indx_t))
+
+/* Put a HKEYDATA item at the location referenced by a page entry. */
+#define	PUT_HKEYDATA(pe, kd, len, etype) {				\
+	((HKEYDATA *)(pe))->type = etype;				\
+	memcpy((u_int8_t *)(pe) + sizeof(u_int8_t), kd, len);		\
+}
+
+/*
+ * Macros the describe the page layout in terms of key-data pairs.
+ */
+#define	H_NUMPAIRS(pg)			(NUM_ENT(pg) / 2)
+#define	H_KEYINDEX(indx)		(indx)
+#define	H_DATAINDEX(indx)		((indx) + 1)
+#define	H_PAIRKEY(dbp, pg, indx)	P_ENTRY(dbp, pg, H_KEYINDEX(indx))
+#define	H_PAIRDATA(dbp, pg, indx)	P_ENTRY(dbp, pg, H_DATAINDEX(indx))
+#define	H_PAIRSIZE(dbp, pg, psize, indx)				\
+	(LEN_HITEM(dbp, pg, psize, H_KEYINDEX(indx)) +			\
+	LEN_HITEM(dbp, pg, psize, H_DATAINDEX(indx)))
+#define	LEN_HDATA(dbp, p, psize, indx)					\
+    LEN_HKEYDATA(dbp, p, psize, H_DATAINDEX(indx))
+#define	LEN_HKEY(dbp, p, psize, indx)					\
+    LEN_HKEYDATA(dbp, p, psize, H_KEYINDEX(indx))
+
+/*
+ * The third type is the H_OFFPAGE, represented by the HOFFPAGE structure:
+ */
+typedef struct _hoffpage {
+	u_int8_t  type;		/*    00: Page type and delete flag. */
+	u_int8_t  unused[3];	/* 01-03: Padding, unused. */
+	db_pgno_t pgno;		/* 04-07: Offpage page number. */
+	u_int32_t tlen;		/* 08-11: Total length of item. */
+} HOFFPAGE;
+
+#define	HOFFPAGE_PGNO(p)	(((u_int8_t *)p) + SSZ(HOFFPAGE, pgno))
+#define	HOFFPAGE_TLEN(p)	(((u_int8_t *)p) + SSZ(HOFFPAGE, tlen))
+
+/*
+ * Page space required to add a new HOFFPAGE item to the page, with and
+ * without the index value.
+ */
+#define	HOFFPAGE_SIZE		(sizeof(HOFFPAGE))
+#define	HOFFPAGE_PSIZE		(HOFFPAGE_SIZE + sizeof(db_indx_t))
+
+/*
+ * The fourth type is H_OFFDUP represented by the HOFFDUP structure:
+ */
+typedef struct _hoffdup {
+	u_int8_t  type;		/*    00: Page type and delete flag. */
+	u_int8_t  unused[3];	/* 01-03: Padding, unused. */
+	db_pgno_t pgno;		/* 04-07: Offpage page number. */
+} HOFFDUP;
+#define	HOFFDUP_PGNO(p)		(((u_int8_t *)p) + SSZ(HOFFDUP, pgno))
+
+/*
+ * Page space required to add a new HOFFDUP item to the page, with and
+ * without the index value.
+ */
+#define	HOFFDUP_SIZE		(sizeof(HOFFDUP))
+
+/************************************************************************
+ BTREE PAGE LAYOUT
+ ************************************************************************/
+
+/* Each index references a group of bytes on the page. */
+#define	B_KEYDATA	1	/* Key/data item. */
+#define	B_DUPLICATE	2	/* Duplicate key/data item. */
+#define	B_OVERFLOW	3	/* Overflow key/data item. */
+
+/*
+ * We have to store a deleted entry flag in the page.   The reason is complex,
+ * but the simple version is that we can't delete on-page items referenced by
+ * a cursor -- the return order of subsequent insertions might be wrong.  The
+ * delete flag is an overload of the top bit of the type byte.
+ */
+#define	B_DELETE	(0x80)
+#define	B_DCLR(t)	(t) &= ~B_DELETE
+#define	B_DSET(t)	(t) |= B_DELETE
+#define	B_DISSET(t)	((t) & B_DELETE)
+
+#define	B_TYPE(t)		((t) & ~B_DELETE)
+#define	B_TSET(t, type)	((t) = B_TYPE(type))
+#define	B_TSET_DELETED(t, type) ((t) = (type) | B_DELETE)
+
+/*
+ * The first type is B_KEYDATA, represented by the BKEYDATA structure:
+ */
+typedef struct _bkeydata {
+	db_indx_t len;		/* 00-01: Key/data item length. */
+	u_int8_t  type;		/*    02: Page type AND DELETE FLAG. */
+	u_int8_t  data[1];	/* Variable length key/data item. */
+} BKEYDATA;
+
+/* Get a BKEYDATA item for a specific index. */
+#define	GET_BKEYDATA(dbp, pg, indx)					\
+	((BKEYDATA *)P_ENTRY(dbp, pg, indx))
+
+/*
+ * Page space required to add a new BKEYDATA item to the page, with and
+ * without the index value.  The (u_int16_t) cast avoids warnings: DB_ALIGN
+ * casts to uintmax_t, the cast converts it to a small integral type so we
+ * don't get complaints when we assign the final result to an integral type
+ * smaller than uintmax_t.
+ */
+#define	BKEYDATA_SIZE(len)						\
+	(u_int16_t)DB_ALIGN((len) + SSZA(BKEYDATA, data), sizeof(u_int32_t))
+#define	BKEYDATA_PSIZE(len)						\
+	(BKEYDATA_SIZE(len) + sizeof(db_indx_t))
+
+/*
+ * The second and third types are B_DUPLICATE and B_OVERFLOW, represented
+ * by the BOVERFLOW structure.
+ */
+typedef struct _boverflow {
+	db_indx_t unused1;	/* 00-01: Padding, unused. */
+	u_int8_t  type;		/*    02: Page type AND DELETE FLAG. */
+	u_int8_t  unused2;	/*    03: Padding, unused. */
+	db_pgno_t pgno;		/* 04-07: Next page number. */
+	u_int32_t tlen;		/* 08-11: Total length of item. */
+} BOVERFLOW;
+
+/* Get a BOVERFLOW item for a specific index. */
+#define	GET_BOVERFLOW(dbp, pg, indx)					\
+	((BOVERFLOW *)P_ENTRY(dbp, pg, indx))
+
+/*
+ * Page space required to add a new BOVERFLOW item to the page, with and
+ * without the index value.
+ */
+#define	BOVERFLOW_SIZE							\
+	((u_int16_t)DB_ALIGN(sizeof(BOVERFLOW), sizeof(u_int32_t)))
+#define	BOVERFLOW_PSIZE							\
+	(BOVERFLOW_SIZE + sizeof(db_indx_t))
+
+#define	BITEM_SIZE(bk)							\
+	(B_TYPE((bk)->type) != B_KEYDATA ? BOVERFLOW_SIZE :		\
+	BKEYDATA_SIZE((bk)->len))
+
+#define	BITEM_PSIZE(bk)							\
+	(B_TYPE((bk)->type) != B_KEYDATA ? BOVERFLOW_PSIZE :		\
+	BKEYDATA_PSIZE((bk)->len))
+
+/*
+ * Btree leaf and hash page layouts group indices in sets of two, one for the
+ * key and one for the data.  Everything else does it in sets of one to save
+ * space.  Use the following macros so that it's real obvious what's going on.
+ */
+#define	O_INDX	1
+#define	P_INDX	2
+
+/************************************************************************
+ BTREE INTERNAL PAGE LAYOUT
+ ************************************************************************/
+
+/*
+ * Btree internal entry.
+ */
+typedef struct _binternal {
+	db_indx_t  len;		/* 00-01: Key/data item length. */
+	u_int8_t   type;	/*    02: Page type AND DELETE FLAG. */
+	u_int8_t   unused;	/*    03: Padding, unused. */
+	db_pgno_t  pgno;	/* 04-07: Page number of referenced page. */
+	db_recno_t nrecs;	/* 08-11: Subtree record count. */
+	u_int8_t   data[1];	/* Variable length key item. */
+} BINTERNAL;
+
+/* Get a BINTERNAL item for a specific index. */
+#define	GET_BINTERNAL(dbp, pg, indx)					\
+	((BINTERNAL *)P_ENTRY(dbp, pg, indx))
+
+/*
+ * Page space required to add a new BINTERNAL item to the page, with and
+ * without the index value.
+ */
+#define	BINTERNAL_SIZE(len)						\
+	(u_int16_t)DB_ALIGN((len) + SSZA(BINTERNAL, data), sizeof(u_int32_t))
+#define	BINTERNAL_PSIZE(len)						\
+	(BINTERNAL_SIZE(len) + sizeof(db_indx_t))
+
+/************************************************************************
+ RECNO INTERNAL PAGE LAYOUT
+ ************************************************************************/
+
+/*
+ * The recno internal entry.
+ */
+typedef struct _rinternal {
+	db_pgno_t  pgno;	/* 00-03: Page number of referenced page. */
+	db_recno_t nrecs;	/* 04-07: Subtree record count. */
+} RINTERNAL;
+
+/* Get a RINTERNAL item for a specific index. */
+#define	GET_RINTERNAL(dbp, pg, indx)					\
+	((RINTERNAL *)P_ENTRY(dbp, pg, indx))
+
+/*
+ * Page space required to add a new RINTERNAL item to the page, with and
+ * without the index value.
+ */
+#define	RINTERNAL_SIZE							\
+	(u_int16_t)DB_ALIGN(sizeof(RINTERNAL), sizeof(u_int32_t))
+#define	RINTERNAL_PSIZE							\
+	(RINTERNAL_SIZE + sizeof(db_indx_t))
+
+typedef struct __pglist {
+	db_pgno_t pgno, next_pgno;
+	DB_LSN lsn;
+} db_pglist_t;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_DB_PAGE_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/db_swap.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,284 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_SWAP_H_
+#define	_DB_SWAP_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Little endian <==> big endian 64-bit swap macros.
+ *	M_64_SWAP	swap a memory location
+ *	P_64_COPY	copy potentially unaligned 4 byte quantities
+ *	P_64_SWAP	swap a referenced memory location
+ */
+#undef	M_64_SWAP
+#define	M_64_SWAP(a) {							\
+	u_int64_t _tmp;							\
+	_tmp = (u_int64_t)a;						\
+	((u_int8_t *)&a)[0] = ((u_int8_t *)&_tmp)[7];			\
+	((u_int8_t *)&a)[1] = ((u_int8_t *)&_tmp)[6];			\
+	((u_int8_t *)&a)[2] = ((u_int8_t *)&_tmp)[5];			\
+	((u_int8_t *)&a)[3] = ((u_int8_t *)&_tmp)[4];			\
+	((u_int8_t *)&a)[4] = ((u_int8_t *)&_tmp)[3];			\
+	((u_int8_t *)&a)[5] = ((u_int8_t *)&_tmp)[2];			\
+	((u_int8_t *)&a)[6] = ((u_int8_t *)&_tmp)[1];			\
+	((u_int8_t *)&a)[7] = ((u_int8_t *)&_tmp)[0];			\
+}
+#undef	P_64_COPY
+#define	P_64_COPY(a, b) {						\
+	((u_int8_t *)b)[0] = ((u_int8_t *)a)[0];			\
+	((u_int8_t *)b)[1] = ((u_int8_t *)a)[1];			\
+	((u_int8_t *)b)[2] = ((u_int8_t *)a)[2];			\
+	((u_int8_t *)b)[3] = ((u_int8_t *)a)[3];			\
+	((u_int8_t *)b)[4] = ((u_int8_t *)a)[4];			\
+	((u_int8_t *)b)[5] = ((u_int8_t *)a)[5];			\
+	((u_int8_t *)b)[6] = ((u_int8_t *)a)[6];			\
+	((u_int8_t *)b)[7] = ((u_int8_t *)a)[7];			\
+}
+#undef	P_64_SWAP
+#define	P_64_SWAP(a) {							\
+	u_int64_t _tmp;							\
+	P_64_COPY(a, &_tmp);						\
+	((u_int8_t *)a)[0] = ((u_int8_t *)&_tmp)[7];			\
+	((u_int8_t *)a)[1] = ((u_int8_t *)&_tmp)[6];			\
+	((u_int8_t *)a)[2] = ((u_int8_t *)&_tmp)[5];			\
+	((u_int8_t *)a)[3] = ((u_int8_t *)&_tmp)[4];			\
+	((u_int8_t *)a)[4] = ((u_int8_t *)&_tmp)[3];			\
+	((u_int8_t *)a)[5] = ((u_int8_t *)&_tmp)[2];			\
+	((u_int8_t *)a)[6] = ((u_int8_t *)&_tmp)[1];			\
+	((u_int8_t *)a)[7] = ((u_int8_t *)&_tmp)[0];			\
+}
+
+/*
+ * Little endian <==> big endian 32-bit swap macros.
+ *	P_32_COPY	copy potentially unaligned 4 byte quantities
+ *	P_32_COPYSWAP	copy and swap potentially unaligned 4 byte quantities
+ *	P_32_SWAP	swap a referenced memory location
+ *	M_32_SWAP	swap a memory location
+ */
+#undef	P_32_COPY
+#define	P_32_COPY(a, b) do {						\
+	((u_int8_t *)b)[0] = ((u_int8_t *)a)[0];			\
+	((u_int8_t *)b)[1] = ((u_int8_t *)a)[1];			\
+	((u_int8_t *)b)[2] = ((u_int8_t *)a)[2];			\
+	((u_int8_t *)b)[3] = ((u_int8_t *)a)[3];			\
+} while (0)
+#undef	P_32_COPYSWAP
+#define	P_32_COPYSWAP(a, b) do {					\
+	((u_int8_t *)b)[0] = ((u_int8_t *)a)[3];			\
+	((u_int8_t *)b)[1] = ((u_int8_t *)a)[2];			\
+	((u_int8_t *)b)[2] = ((u_int8_t *)a)[1];			\
+	((u_int8_t *)b)[3] = ((u_int8_t *)a)[0];			\
+} while (0)
+#undef	P_32_SWAP
+#define	P_32_SWAP(a) do {						\
+	u_int32_t _tmp;							\
+	P_32_COPY(a, &_tmp);						\
+	P_32_COPYSWAP(&_tmp, a);					\
+} while (0)
+#undef	M_32_SWAP
+#define	M_32_SWAP(a) P_32_SWAP(&a)
+
+/*
+ * Little endian <==> big endian 16-bit swap macros.
+ *	P_16_COPY	copy potentially unaligned 2 byte quantities
+ *	P_16_COPYSWAP	copy and swap potentially unaligned 2 byte quantities
+ *	P_16_SWAP	swap a referenced memory location
+ *	M_16_SWAP	swap a memory location
+ */
+#undef	P_16_COPY
+#define	P_16_COPY(a, b) do {						\
+	((u_int8_t *)b)[0] = ((u_int8_t *)a)[0];			\
+	((u_int8_t *)b)[1] = ((u_int8_t *)a)[1];			\
+} while (0)
+#undef	P_16_COPYSWAP
+#define	P_16_COPYSWAP(a, b) do {					\
+	((u_int8_t *)b)[0] = ((u_int8_t *)a)[1];			\
+	((u_int8_t *)b)[1] = ((u_int8_t *)a)[0];			\
+} while (0)
+#undef	P_16_SWAP
+#define	P_16_SWAP(a) do {						\
+	u_int16_t _tmp;							\
+	P_16_COPY(a, &_tmp);						\
+	P_16_COPYSWAP(&_tmp, a);					\
+} while (0)
+#undef	M_16_SWAP
+#define	M_16_SWAP(a) P_16_SWAP(&a)
+
+#undef	SWAP32
+#define	SWAP32(p) {							\
+	P_32_SWAP(p);							\
+	(p) += sizeof(u_int32_t);					\
+}
+#undef	SWAP16
+#define	SWAP16(p) {							\
+	P_16_SWAP(p);							\
+	(p) += sizeof(u_int16_t);					\
+}
+
+/*
+ * Berkeley DB has local versions of htonl() and ntohl() that operate on
+ * pointers to the right size memory locations; the portability magic for
+ * finding the real system functions isn't worth the effort.
+ */
+#undef	DB_HTONL_SWAP
+#define	DB_HTONL_SWAP(env, p) do {					\
+	if (F_ISSET((env), ENV_LITTLEENDIAN))				\
+		P_32_SWAP(p);						\
+} while (0)
+#undef	DB_NTOHL_SWAP
+#define	DB_NTOHL_SWAP(env, p) do {					\
+	if (F_ISSET((env), ENV_LITTLEENDIAN))				\
+		P_32_SWAP(p);						\
+} while (0)
+
+#undef	DB_NTOHL_COPYIN
+#define	DB_NTOHL_COPYIN(env, i, p) do {					\
+	u_int8_t *tmp;							\
+	tmp = (u_int8_t *)&(i);						\
+	if (F_ISSET(env, ENV_LITTLEENDIAN)) {				\
+		tmp[3] = *p++;						\
+		tmp[2] = *p++;						\
+		tmp[1] = *p++;						\
+		tmp[0] = *p++;						\
+	} else {							\
+		memcpy(&i, p, sizeof(u_int32_t));			\
+		p = (u_int8_t *)p + sizeof(u_int32_t);			\
+	}								\
+} while (0)
+
+#undef	DB_NTOHS_COPYIN
+#define	DB_NTOHS_COPYIN(env, i, p) do {					\
+	u_int8_t *tmp;							\
+	tmp = (u_int8_t *)&(i);						\
+	if (F_ISSET(env, ENV_LITTLEENDIAN)) {				\
+		tmp[1] = *p++;						\
+		tmp[0] = *p++;						\
+	} else {							\
+		memcpy(&i, p, sizeof(u_int16_t));			\
+		p = (u_int8_t *)p + sizeof(u_int16_t);			\
+	}								\
+} while (0)
+
+#undef	DB_HTONL_COPYOUT
+#define	DB_HTONL_COPYOUT(env, p, i) do {				\
+	u_int8_t *tmp;							\
+	tmp = (u_int8_t *)p;						\
+	if (F_ISSET(env, ENV_LITTLEENDIAN)) {				\
+		*tmp++ = ((u_int8_t *)&(i))[3];				\
+		*tmp++ = ((u_int8_t *)&(i))[2];				\
+		*tmp++ = ((u_int8_t *)&(i))[1];				\
+		*tmp++ = ((u_int8_t *)&(i))[0];				\
+	} else								\
+		memcpy(p, &i, sizeof(u_int32_t));			\
+	p = (u_int8_t *)p + sizeof(u_int32_t);				\
+} while (0)
+
+#undef	DB_HTONS_COPYOUT
+#define	DB_HTONS_COPYOUT(env, p, i) do {				\
+	u_int8_t *tmp;							\
+	tmp = (u_int8_t *)p;						\
+	if (F_ISSET(env, ENV_LITTLEENDIAN)) {				\
+		*tmp++ = ((u_int8_t *)&(i))[1];				\
+		*tmp++ = ((u_int8_t *)&(i))[0];				\
+	} else								\
+		memcpy(p, &i, sizeof(u_int16_t));			\
+	p = (u_int8_t *)p + sizeof(u_int16_t);				\
+} while (0)
+
+/*
+ * Helper macros for swapped logs.  We write logs in little endian format to
+ * minimize disruption on x86 when upgrading from native byte order to
+ * platform-independent logs.
+ */
+#define	LOG_SWAPPED(env) !F_ISSET(env, ENV_LITTLEENDIAN)
+
+#define	LOGCOPY_32(env, x, p) do {					\
+	if (LOG_SWAPPED(env))						\
+		P_32_COPYSWAP((p), (x));				\
+	else								\
+		memcpy((x), (p), sizeof(u_int32_t));			\
+} while (0)
+
+#define	LOGCOPY_16(env, x, p) do {					\
+	if (LOG_SWAPPED(env))						\
+		P_16_COPYSWAP((p), (x));				\
+	else								\
+		memcpy((x), (p), sizeof(u_int16_t));			\
+} while (0)
+
+#define	LOGCOPY_TOLSN(env, lsnp, p) do {				\
+	LOGCOPY_32((env), &(lsnp)->file, (p));				\
+	LOGCOPY_32((env), &(lsnp)->offset,				\
+	    (u_int8_t *)(p) + sizeof(u_int32_t));			\
+} while (0)
+
+#define	LOGCOPY_FROMLSN(env, p, lsnp) do {				\
+	LOGCOPY_32((env), (p), &(lsnp)->file);				\
+	LOGCOPY_32((env),						\
+	    (u_int8_t *)(p) + sizeof(u_int32_t), &(lsnp)->offset);	\
+} while (0)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_DB_SWAP_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/db_upgrade.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,270 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_UPGRADE_H_
+#define	_DB_UPGRADE_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * This file defines the metadata pages from the previous release.
+ * These structures are only used to upgrade old versions of databases.
+ */
+
+/* Structures from the 3.1 release */
+typedef struct _dbmeta31 {
+	DB_LSN	  lsn;		/* 00-07: LSN. */
+	db_pgno_t pgno;		/* 08-11: Current page number. */
+	u_int32_t magic;	/* 12-15: Magic number. */
+	u_int32_t version;	/* 16-19: Version. */
+	u_int32_t pagesize;	/* 20-23: Pagesize. */
+	u_int8_t  unused1[1];	/*    24: Unused. */
+	u_int8_t  type;		/*    25: Page type. */
+	u_int8_t  unused2[2];	/* 26-27: Unused. */
+	u_int32_t free;		/* 28-31: Free list page number. */
+	DB_LSN    unused3;	/* 36-39: Unused. */
+	u_int32_t key_count;	/* 40-43: Cached key count. */
+	u_int32_t record_count;	/* 44-47: Cached record count. */
+	u_int32_t flags;	/* 48-51: Flags: unique to each AM. */
+				/* 52-71: Unique file ID. */
+	u_int8_t  uid[DB_FILE_ID_LEN];
+} DBMETA31;
+
+typedef struct _btmeta31 {
+	DBMETA31  dbmeta;		/* 00-71: Generic meta-data header. */
+
+	u_int32_t maxkey;	/* 72-75: Btree: Maxkey. */
+	u_int32_t minkey;	/* 76-79: Btree: Minkey. */
+	u_int32_t re_len;	/* 80-83: Recno: fixed-length record length. */
+	u_int32_t re_pad;	/* 84-87: Recno: fixed-length record pad. */
+	u_int32_t root;		/* 88-92: Root page. */
+
+	/*
+	 * Minimum page size is 128.
+	 */
+} BTMETA31;
+
+/************************************************************************
+ HASH METADATA PAGE LAYOUT
+ ************************************************************************/
+typedef struct _hashmeta31 {
+	DBMETA31 dbmeta;	/* 00-71: Generic meta-data page header. */
+
+	u_int32_t max_bucket;	/* 72-75: ID of Maximum bucket in use */
+	u_int32_t high_mask;	/* 76-79: Modulo mask into table */
+	u_int32_t low_mask;	/* 80-83: Modulo mask into table lower half */
+	u_int32_t ffactor;	/* 84-87: Fill factor */
+	u_int32_t nelem;	/* 88-91: Number of keys in hash table */
+	u_int32_t h_charkey;	/* 92-95: Value of hash(CHARKEY) */
+#define	NCACHED	32		/* number of spare points */
+				/* 96-223: Spare pages for overflow */
+	u_int32_t spares[NCACHED];
+
+	/*
+	 * Minimum page size is 256.
+	 */
+} HMETA31;
+
+/*
+ * QAM Meta data page structure
+ *
+ */
+typedef struct _qmeta31 {
+	DBMETA31 dbmeta;	/* 00-71: Generic meta-data header. */
+
+	u_int32_t start;	/* 72-75: Start offset. */
+	u_int32_t first_recno;	/* 76-79: First not deleted record. */
+	u_int32_t cur_recno;	/* 80-83: Last recno allocated. */
+	u_int32_t re_len;	/* 84-87: Fixed-length record length. */
+	u_int32_t re_pad;	/* 88-91: Fixed-length record pad. */
+	u_int32_t rec_page;	/* 92-95: Records Per Page. */
+
+	/*
+	 * Minimum page size is 128.
+	 */
+} QMETA31;
+/* Structures from the 3.2 release */
+typedef struct _qmeta32 {
+	DBMETA31 dbmeta;	/* 00-71: Generic meta-data header. */
+
+	u_int32_t first_recno;	/* 72-75: First not deleted record. */
+	u_int32_t cur_recno;	/* 76-79: Last recno allocated. */
+	u_int32_t re_len;	/* 80-83: Fixed-length record length. */
+	u_int32_t re_pad;	/* 84-87: Fixed-length record pad. */
+	u_int32_t rec_page;	/* 88-91: Records Per Page. */
+	u_int32_t page_ext;	/* 92-95: Pages per extent */
+
+	/*
+	 * Minimum page size is 128.
+	 */
+} QMETA32;
+
+/* Structures from the 3.0 release */
+
+typedef struct _dbmeta30 {
+	DB_LSN	  lsn;		/* 00-07: LSN. */
+	db_pgno_t pgno;		/* 08-11: Current page number. */
+	u_int32_t magic;	/* 12-15: Magic number. */
+	u_int32_t version;	/* 16-19: Version. */
+	u_int32_t pagesize;	/* 20-23: Pagesize. */
+	u_int8_t  unused1[1];	/*    24: Unused. */
+	u_int8_t  type;		/*    25: Page type. */
+	u_int8_t  unused2[2];	/* 26-27: Unused. */
+	u_int32_t free;		/* 28-31: Free list page number. */
+	u_int32_t flags;	/* 32-35: Flags: unique to each AM. */
+				/* 36-55: Unique file ID. */
+	u_int8_t  uid[DB_FILE_ID_LEN];
+} DBMETA30;
+
+/************************************************************************
+ BTREE METADATA PAGE LAYOUT
+ ************************************************************************/
+typedef struct _btmeta30 {
+	DBMETA30	dbmeta;	/* 00-55: Generic meta-data header. */
+
+	u_int32_t maxkey;	/* 56-59: Btree: Maxkey. */
+	u_int32_t minkey;	/* 60-63: Btree: Minkey. */
+	u_int32_t re_len;	/* 64-67: Recno: fixed-length record length. */
+	u_int32_t re_pad;	/* 68-71: Recno: fixed-length record pad. */
+	u_int32_t root;		/* 72-75: Root page. */
+
+	/*
+	 * Minimum page size is 128.
+	 */
+} BTMETA30;
+
+/************************************************************************
+ HASH METADATA PAGE LAYOUT
+ ************************************************************************/
+typedef struct _hashmeta30 {
+	DBMETA30 dbmeta;	/* 00-55: Generic meta-data page header. */
+
+	u_int32_t max_bucket;	/* 56-59: ID of Maximum bucket in use */
+	u_int32_t high_mask;	/* 60-63: Modulo mask into table */
+	u_int32_t low_mask;	/* 64-67: Modulo mask into table lower half */
+	u_int32_t ffactor;	/* 68-71: Fill factor */
+	u_int32_t nelem;	/* 72-75: Number of keys in hash table */
+	u_int32_t h_charkey;	/* 76-79: Value of hash(CHARKEY) */
+#define	NCACHED30	32		/* number of spare points */
+				/* 80-207: Spare pages for overflow */
+	u_int32_t spares[NCACHED30];
+
+	/*
+	 * Minimum page size is 256.
+	 */
+} HMETA30;
+
+/************************************************************************
+ QUEUE METADATA PAGE LAYOUT
+ ************************************************************************/
+/*
+ * QAM Meta data page structure
+ *
+ */
+typedef struct _qmeta30 {
+	DBMETA30    dbmeta;	/* 00-55: Generic meta-data header. */
+
+	u_int32_t start;	/* 56-59: Start offset. */
+	u_int32_t first_recno;	/* 60-63: First not deleted record. */
+	u_int32_t cur_recno;	/* 64-67: Last recno allocated. */
+	u_int32_t re_len;	/* 68-71: Fixed-length record length. */
+	u_int32_t re_pad;	/* 72-75: Fixed-length record pad. */
+	u_int32_t rec_page;	/* 76-79: Records Per Page. */
+
+	/*
+	 * Minimum page size is 128.
+	 */
+} QMETA30;
+
+/* Structures from Release 2.x */
+
+/************************************************************************
+ BTREE METADATA PAGE LAYOUT
+ ************************************************************************/
+
+/*
+ * Btree metadata page layout:
+ */
+typedef struct _btmeta2X {
+	DB_LSN	  lsn;		/* 00-07: LSN. */
+	db_pgno_t pgno;		/* 08-11: Current page number. */
+	u_int32_t magic;	/* 12-15: Magic number. */
+	u_int32_t version;	/* 16-19: Version. */
+	u_int32_t pagesize;	/* 20-23: Pagesize. */
+	u_int32_t maxkey;	/* 24-27: Btree: Maxkey. */
+	u_int32_t minkey;	/* 28-31: Btree: Minkey. */
+	u_int32_t free;		/* 32-35: Free list page number. */
+	u_int32_t flags;	/* 36-39: Flags. */
+	u_int32_t re_len;	/* 40-43: Recno: fixed-length record length. */
+	u_int32_t re_pad;	/* 44-47: Recno: fixed-length record pad. */
+				/* 48-67: Unique file ID. */
+	u_int8_t  uid[DB_FILE_ID_LEN];
+} BTMETA2X;
+
+/************************************************************************
+ HASH METADATA PAGE LAYOUT
+ ************************************************************************/
+
+/*
+ * Hash metadata page layout:
+ */
+/* Hash Table Information */
+typedef struct hashhdr {	/* Disk resident portion */
+	DB_LSN	lsn;		/* 00-07: LSN of the header page */
+	db_pgno_t pgno;		/* 08-11: Page number (btree compatibility). */
+	u_int32_t magic;	/* 12-15: Magic NO for hash tables */
+	u_int32_t version;	/* 16-19: Version ID */
+	u_int32_t pagesize;	/* 20-23: Bucket/Page Size */
+	u_int32_t ovfl_point;	/* 24-27: Overflow page allocation location */
+	u_int32_t last_freed;	/* 28-31: Last freed overflow page pgno */
+	u_int32_t max_bucket;	/* 32-35: ID of Maximum bucket in use */
+	u_int32_t high_mask;	/* 36-39: Modulo mask into table */
+	u_int32_t low_mask;	/* 40-43: Modulo mask into table lower half */
+	u_int32_t ffactor;	/* 44-47: Fill factor */
+	u_int32_t nelem;	/* 48-51: Number of keys in hash table */
+	u_int32_t h_charkey;	/* 52-55: Value of hash(CHARKEY) */
+	u_int32_t flags;	/* 56-59: Allow duplicates. */
+#define	NCACHED2X	32		/* number of spare points */
+				/* 60-187: Spare pages for overflow */
+	u_int32_t spares[NCACHED2X];
+				/* 188-207: Unique file ID. */
+	u_int8_t  uid[DB_FILE_ID_LEN];
+
+	/*
+	 * Minimum page size is 256.
+	 */
+} HASHHDR;
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_UPGRADE_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/db_verify.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,232 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_VERIFY_H_
+#define	_DB_VERIFY_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Structures and macros for the storage and retrieval of all information
+ * needed for inter-page verification of a database.
+ */
+
+/*
+ * EPRINT is the macro for error printing.  Takes as an arg the arg set
+ * for DB->err.
+ */
+#define	EPRINT(x) do {							\
+	if (!LF_ISSET(DB_SALVAGE))					\
+		__db_errx x;						\
+} while (0)
+
+/* Complain about a totally zeroed page where we don't expect one. */
+#define	ZEROPG_ERR_PRINT(dbenv, pgno, str) do {				\
+	EPRINT(((dbenv), DB_STR_A("0501", 				\
+	    "Page %lu: %s is of inappropriate type %lu", "%lu %s %lu"),	\
+	    (u_long)(pgno), str, (u_long)P_INVALID));			\
+	EPRINT(((dbenv), DB_STR_A("0502",				\
+	    "Page %lu: totally zeroed page",				\
+	    "%lu"), (u_long)(pgno)));					\
+} while (0)
+
+/*
+ * Note that 0 is, in general, a valid pgno, despite equaling PGNO_INVALID;
+ * we have to test it separately where it's not appropriate.
+ */
+#define	IS_VALID_PGNO(x)	((x) <= vdp->last_pgno)
+
+/*
+ * VRFY_DBINFO is the fundamental structure;  it either represents the database
+ * of subdatabases, or the sole database if there are no subdatabases.
+ */
+struct __vrfy_dbinfo {
+	DB_THREAD_INFO *thread_info;
+	/* Info about this database in particular. */
+	DBTYPE		type;
+
+	/* List of subdatabase meta pages, if any. */
+	LIST_HEAD(__subdbs, __vrfy_childinfo) subdbs;
+
+	/* Transaction handle for CDS group. */
+	DB_TXN *txn;
+
+	/* File-global info--stores VRFY_PAGEINFOs for each page. */
+	DB *pgdbp;
+
+	/* Child database--stores VRFY_CHILDINFOs of each page. */
+	DB *cdbp;
+
+	/* Page info structures currently in use. */
+	LIST_HEAD(__activepips, __vrfy_pageinfo) activepips;
+
+	/*
+	 * DB we use to keep track of which pages are linked somehow
+	 * during verification.  0 is the default, "unseen";  1 is seen.
+	 */
+	DB *pgset;
+
+	/*
+	 * This is a database we use during salvaging to keep track of which
+	 * overflow and dup pages we need to come back to at the end and print
+	 * with key "UNKNOWN".  Pages which print with a good key get set
+	 * to SALVAGE_IGNORE;  others get set, as appropriate, to SALVAGE_LDUP,
+	 * SALVAGE_LRECNODUP, SALVAGE_OVERFLOW for normal db overflow pages,
+	 * and SALVAGE_BTREE, SALVAGE_LRECNO, and SALVAGE_HASH for subdb
+	 * pages.
+	 */
+#define	SALVAGE_INVALID		0
+#define	SALVAGE_IGNORE		1
+#define	SALVAGE_LDUP		2
+#define	SALVAGE_IBTREE		3
+#define	SALVAGE_OVERFLOW	4
+#define	SALVAGE_LBTREE		5
+#define	SALVAGE_HASH		6
+#define	SALVAGE_LRECNO		7
+#define	SALVAGE_LRECNODUP	8
+	DB *salvage_pages;
+
+	db_pgno_t	last_pgno;
+	db_pgno_t	meta_last_pgno;
+	db_pgno_t	pgs_remaining;	/* For dbp->db_feedback(). */
+
+	/*
+	 * These are used during __bam_vrfy_subtree to keep track, while
+	 * walking up and down the Btree structure, of the prev- and next-page
+	 * chain of leaf pages and verify that it's intact.  Also, make sure
+	 * that this chain contains pages of only one type.
+	 */
+	db_pgno_t	prev_pgno;
+	db_pgno_t	next_pgno;
+	u_int8_t	leaf_type;
+
+	/* Queue needs these to verify data pages in the first pass. */
+	u_int32_t	re_pad;		/* Record pad character. */
+	u_int32_t	re_len;		/* Record length. */
+	u_int32_t	rec_page;
+	u_int32_t	page_ext;
+	u_int32_t       first_recno;
+	u_int32_t       last_recno;
+	int		nextents;
+	db_pgno_t	*extents;
+
+#define	SALVAGE_PRINTABLE	0x01	/* Output printable chars literally. */
+#define	SALVAGE_PRINTHEADER	0x02	/* Print the unknown-key header. */
+#define	SALVAGE_PRINTFOOTER	0x04	/* Print the unknown-key footer. */
+#define	SALVAGE_HASSUBDBS	0x08	/* There are subdatabases to salvage. */
+#define	VRFY_LEAFCHAIN_BROKEN	0x10	/* Lost one or more Btree leaf pgs. */
+#define	VRFY_QMETA_SET		0x20    /* We've seen a QUEUE meta page and
+					   set things up for it. */
+	u_int32_t	flags;
+}; /* VRFY_DBINFO */
+
+/*
+ * The amount of state information we need per-page is small enough that
+ * it's not worth the trouble to define separate structures for each
+ * possible type of page, and since we're doing verification with these we
+ * have to be open to the possibility that page N will be of a completely
+ * unexpected type anyway.  So we define one structure here with all the
+ * info we need for inter-page verification.
+ */
+struct __vrfy_pageinfo {
+	u_int8_t	type;
+	u_int8_t	bt_level;
+	u_int8_t	unused1;
+	u_int8_t	unused2;
+	db_pgno_t	pgno;
+	db_pgno_t	prev_pgno;
+	db_pgno_t	next_pgno;
+
+	/* meta pages */
+	db_pgno_t	root;
+	db_pgno_t	free;		/* Free list head. */
+
+	db_indx_t	entries;	/* Actual number of entries. */
+	u_int16_t	unused;
+	db_recno_t	rec_cnt;	/* Record count. */
+	u_int32_t	re_pad;		/* Record pad character. */
+	u_int32_t	re_len;		/* Record length. */
+	u_int32_t	bt_minkey;
+	u_int32_t	h_ffactor;
+	u_int32_t	h_nelem;
+
+	/* overflow pages */
+	/*
+	 * Note that refcount is the refcount for an overflow page; pi_refcount
+	 * is this structure's own refcount!
+	 */
+	u_int32_t	refcount;
+	u_int32_t	olen;
+
+#define	VRFY_DUPS_UNSORTED	0x0001	/* Have to flag the negative! */
+#define	VRFY_HAS_CHKSUM		0x0002
+#define	VRFY_HAS_DUPS		0x0004
+#define	VRFY_HAS_DUPSORT	0x0008	/* Has the flag set. */
+#define	VRFY_HAS_PART_RANGE	0x0010	/* Has the flag set. */
+#define	VRFY_HAS_PART_CALLBACK	0x0020	/* Has the flag set. */
+#define	VRFY_HAS_RECNUMS	0x0040
+#define	VRFY_HAS_SUBDBS		0x0080
+#define	VRFY_INCOMPLETE		0x0100	/* Meta or item order checks incomp. */
+#define	VRFY_IS_ALLZEROES	0x0200	/* Hash page we haven't touched? */
+#define	VRFY_IS_FIXEDLEN	0x0400
+#define	VRFY_IS_RECNO		0x0800
+#define	VRFY_IS_RRECNO		0x1000
+#define	VRFY_OVFL_LEAFSEEN	0x2000
+#define	VRFY_HAS_COMPRESS	0x4000
+#define	VRFY_NONEXISTENT	0x8000
+	u_int32_t	flags;
+
+	LIST_ENTRY(__vrfy_pageinfo) links;
+	u_int32_t	pi_refcount;
+}; /* VRFY_PAGEINFO */
+
+struct __vrfy_childinfo {
+	/* The following fields are set by the caller of __db_vrfy_childput. */
+	db_pgno_t	pgno;
+
+#define	V_DUPLICATE	1		/* off-page dup metadata */
+#define	V_OVERFLOW	2		/* overflow page */
+#define	V_RECNO		3		/* btree internal or leaf page */
+	u_int32_t	type;
+	db_recno_t	nrecs;		/* record count on a btree subtree */
+	u_int32_t	tlen;		/* ovfl. item total size */
+
+	/* The following field is maintained by __db_vrfy_childput. */
+	u_int32_t	refcnt;		/* # of times parent points to child. */
+
+	LIST_ENTRY(__vrfy_childinfo) links;
+}; /* VRFY_CHILDINFO */
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_VERIFY_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/debug.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,305 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_DEBUG_H_
+#define	_DB_DEBUG_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Turn on additional error checking in gcc 3.X.
+ */
+#if !defined(__GNUC__) || __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
+#define	__attribute__(s)
+#endif
+
+/*
+ * When running with #DIAGNOSTIC defined, we smash memory and do memory
+ * guarding with a special byte value.
+ */
+#define	CLEAR_BYTE	0xdb
+#define	GUARD_BYTE	0xdc
+
+/*
+ * DB assertions.
+ *
+ * Use __STDC__ rather than STDC_HEADERS, the #e construct is ANSI C specific.
+ */
+#if defined(DIAGNOSTIC) && defined(__STDC__)
+#define	DB_ASSERT(env, e)						\
+	((e) ? (void)0 : __db_assert(env, #e, __FILE__, __LINE__))
+#else
+#define	DB_ASSERT(env, e)	NOP_STATEMENT
+#endif
+
+/*
+ * "Shut that bloody compiler up!"
+ *
+ * Unused, or not-used-yet variable.  We need to write and then read the
+ * variable, some compilers are too bloody clever by half.
+ */
+#define	COMPQUIET(n, v)	do {					        \
+	(n) = (v);						        \
+	(n) = (n);						        \
+} while (0)
+
+/*
+ * Purify and other run-time tools complain about uninitialized reads/writes
+ * of structure fields whose only purpose is padding, as well as when heap
+ * memory that was never initialized is written to disk.
+ */
+#ifdef	UMRW
+#define	UMRW_SET(v)	(v) = 0
+#else
+#define	UMRW_SET(v)	NOP_STATEMENT
+#endif
+
+/*
+ * Errors are in one of two areas: a Berkeley DB error, or a system-level
+ * error.  We use db_strerror to translate the former and __os_strerror to
+ * translate the latter.
+ */
+typedef enum {
+	DB_ERROR_NOT_SET=0,
+	DB_ERROR_SET=1,
+	DB_ERROR_SYSTEM=2
+} db_error_set_t;
+
+/*
+ * Message handling.  Use a macro instead of a function because va_list
+ * references to variadic arguments cannot be reset to the beginning of the
+ * variadic argument list (and then rescanned), by functions other than the
+ * original routine that took the variadic list of arguments.
+ */
+#if defined(STDC_HEADERS) || defined(__cplusplus)
+#define	DB_REAL_ERR(dbenv, error, error_set, app_call, fmt) {		\
+	va_list __ap;							\
+									\
+	/* Call the application's callback function, if specified. */	\
+	va_start(__ap, fmt);						\
+	if ((dbenv) != NULL && (dbenv)->db_errcall != NULL)		\
+		__db_errcall(dbenv, error, error_set, fmt, __ap);	\
+	va_end(__ap);							\
+									\
+	/*								\
+	 * If the application specified a file descriptor, write to it.	\
+	 * If we wrote to neither the application's callback routine or	\
+	 * its file descriptor, and it's an application error message	\
+	 * using {DbEnv,Db}.{err,errx} or the application has never	\
+	 * configured an output channel, default by writing to stderr.	\
+	 */								\
+	va_start(__ap, fmt);						\
+	if ((dbenv) == NULL ||						\
+	    (dbenv)->db_errfile != NULL ||				\
+	    ((dbenv)->db_errcall == NULL &&				\
+	    ((app_call) || F_ISSET((dbenv)->env, ENV_NO_OUTPUT_SET))))	\
+		__db_errfile(dbenv, error, error_set, fmt, __ap);	\
+	va_end(__ap);							\
+}
+#else
+#define	DB_REAL_ERR(dbenv, error, error_set, app_call, fmt) {		\
+	va_list __ap;							\
+									\
+	/* Call the application's callback function, if specified. */	\
+	va_start(__ap);							\
+	if ((dbenv) != NULL && (dbenv)->db_errcall != NULL)		\
+		__db_errcall(dbenv, error, error_set, fmt, __ap);	\
+	va_end(__ap);							\
+									\
+	/*								\
+	 * If the application specified a file descriptor, write to it.	\
+	 * If we wrote to neither the application's callback routine or	\
+	 * its file descriptor, and it's an application error message	\
+	 * using {DbEnv,Db}.{err,errx} or the application has never	\
+	 * configured an output channel, default by writing to stderr.	\
+	 */								\
+	va_start(__ap);							\
+	if ((dbenv) == NULL ||						\
+	    (dbenv)->db_errfile != NULL ||				\
+	    ((dbenv)->db_errcall == NULL &&				\
+	    ((app_call) || F_ISSET((dbenv)->env, ENV_NO_OUTPUT_SET))))	\
+		 __db_errfile(env, error, error_set, fmt, __ap);	\
+	va_end(__ap);							\
+}
+#endif
+#if defined(STDC_HEADERS) || defined(__cplusplus)
+#define	DB_REAL_MSG(dbenv, fmt) {					\
+	va_list __ap;							\
+									\
+	/* Call the application's callback function, if specified. */	\
+	va_start(__ap, fmt);						\
+	if ((dbenv) != NULL && (dbenv)->db_msgcall != NULL)		\
+		__db_msgcall(dbenv, fmt, __ap);				\
+	va_end(__ap);							\
+									\
+	/*								\
+	 * If the application specified a file descriptor, write to it.	\
+	 * If we wrote to neither the application's callback routine or	\
+	 * its file descriptor, write to stdout.			\
+	 */								\
+	va_start(__ap, fmt);						\
+	if ((dbenv) == NULL ||						\
+	    (dbenv)->db_msgfile != NULL ||				\
+	    (dbenv)->db_msgcall == NULL) {				\
+		__db_msgfile(dbenv, fmt, __ap);				\
+	}								\
+	va_end(__ap);							\
+}
+#else
+#define	DB_REAL_MSG(dbenv, fmt) {					\
+	va_list __ap;							\
+									\
+	/* Call the application's callback function, if specified. */	\
+	va_start(__ap);							\
+	if ((dbenv) != NULL && (dbenv)->db_msgcall != NULL)		\
+		__db_msgcall(dbenv, fmt, __ap);				\
+	va_end(__ap);							\
+									\
+	/*								\
+	 * If the application specified a file descriptor, write to it.	\
+	 * If we wrote to neither the application's callback routine or	\
+	 * its file descriptor, write to stdout.			\
+	 */								\
+	va_start(__ap);							\
+	if ((dbenv) == NULL ||						\
+	    (dbenv)->db_msgfile != NULL ||				\
+	    (dbenv)->db_msgcall == NULL) {				\
+		__db_msgfile(dbenv, fmt, __ap);				\
+	}								\
+	va_end(__ap);							\
+}
+#endif
+
+/*
+ * Debugging macro to log operations.
+ *	If DEBUG_WOP is defined, log operations that modify the database.
+ *	If DEBUG_ROP is defined, log operations that read the database.
+ *
+ * D dbp
+ * T txn
+ * O operation (string)
+ * K key
+ * A data
+ * F flags
+ */
+#define	LOG_OP(C, T, O, K, A, F) {					\
+	DB_LSN __lsn;							\
+	DBT __op;							\
+	if (DBC_LOGGING((C))) {						\
+		memset(&__op, 0, sizeof(__op));				\
+		__op.data = O;						\
+		__op.size = (u_int32_t)strlen(O) + 1;			\
+		(void)__db_debug_log((C)->env, T, &__lsn, 0,		\
+		    &__op, (C)->dbp->log_filename->id, K, A, F);	\
+	}								\
+}
+#ifdef	DEBUG_ROP
+#define	DEBUG_LREAD(C, T, O, K, A, F)	LOG_OP(C, T, O, K, A, F)
+#else
+#define	DEBUG_LREAD(C, T, O, K, A, F)
+#endif
+#ifdef	DEBUG_WOP
+#define	DEBUG_LWRITE(C, T, O, K, A, F)	LOG_OP(C, T, O, K, A, F)
+#else
+#define	DEBUG_LWRITE(C, T, O, K, A, F)
+#endif
+
+/*
+ * Hook for testing recovery at various places in the create/delete paths.
+ * Hook for testing subdb locks.
+ */
+#if CONFIG_TEST
+#define	DB_TEST_SUBLOCKS(env, flags) do {				\
+	if ((env)->test_abort == DB_TEST_SUBDB_LOCKS)			\
+		(flags) |= DB_LOCK_NOWAIT;				\
+} while (0)
+
+#define	DB_ENV_TEST_RECOVERY(env, val, ret, name) do {			\
+	int __ret;							\
+	PANIC_CHECK((env));						\
+	if ((env)->test_copy == (val)) {				\
+		/* COPY the FILE */					\
+		if ((__ret = __db_testcopy((env), NULL, (name))) != 0)	\
+			(ret) = __env_panic((env), __ret);		\
+	}								\
+	if ((env)->test_abort == (val)) {				\
+		/* ABORT the TXN */					\
+		(env)->test_abort = 0;					\
+		(ret) = EINVAL;						\
+		goto db_tr_err;						\
+	}								\
+} while (0)
+
+#define	DB_TEST_RECOVERY(dbp, val, ret, name) do {			\
+	ENV *__env = (dbp)->env;					\
+	int __ret;							\
+	PANIC_CHECK(__env);						\
+	if (__env->test_copy == (val)) {				\
+		/* Copy the file. */					\
+		if (F_ISSET((dbp),					\
+		    DB_AM_OPEN_CALLED) && (dbp)->mpf != NULL)		\
+			(void)__db_sync(dbp);				\
+		if ((__ret =						\
+		    __db_testcopy(__env, (dbp), (name))) != 0)		\
+			(ret) = __env_panic(__env, __ret);		\
+	}								\
+	if (__env->test_abort == (val)) {				\
+		/* Abort the transaction. */				\
+		__env->test_abort = 0;					\
+		(ret) = EINVAL;						\
+		goto db_tr_err;						\
+	}								\
+} while (0)
+
+#define	DB_TEST_RECOVERY_LABEL	db_tr_err:
+
+#define	DB_TEST_SET(field, val) do {					\
+	if (field == (val))						\
+		goto db_tr_err;						\
+} while (0)
+
+#define	DB_TEST_WAIT(env, val)						\
+	if ((val) != 0)							\
+		__os_yield((env), (u_long)(val), 0)
+#else
+#define	DB_TEST_SUBLOCKS(env, flags)
+#define	DB_ENV_TEST_RECOVERY(env, val, ret, name)
+#define	DB_TEST_RECOVERY(dbp, val, ret, name)
+#define	DB_TEST_RECOVERY_LABEL
+#define	DB_TEST_SET(env, val)
+#define	DB_TEST_WAIT(env, val)
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_DEBUG_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/fop.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,54 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef	_DB_FOP_H_
+#define	_DB_FOP_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define	MAKE_INMEM(D) do {					\
+	F_SET((D), DB_AM_INMEM);				\
+	(void)__memp_set_flags((D)->mpf, DB_MPOOL_NOFILE, 1);	\
+} while (0)
+
+#define	CLR_INMEM(D) do {					\
+	F_CLR((D), DB_AM_INMEM);				\
+	(void)__memp_set_flags((D)->mpf, DB_MPOOL_NOFILE, 0);	\
+} while (0)
+
+#include "dbinc_auto/fileops_auto.h"
+#include "dbinc_auto/fileops_ext.h"
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_FOP_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/globals.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,127 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_GLOBALS_H_
+#define	_DB_GLOBALS_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*******************************************************
+ * Global variables.
+ *
+ * Held in a single structure to minimize the name-space pollution.
+ *******************************************************/
+#ifdef HAVE_VXWORKS
+#include "semLib.h"
+#endif
+
+typedef struct __db_globals {
+#ifdef HAVE_VXWORKS
+	u_int32_t db_global_init;	/* VxWorks: inited */
+	SEM_ID db_global_lock;		/* VxWorks: global semaphore */
+#endif
+#ifdef DB_WIN32
+#ifndef DB_WINCE
+	/*
+	 * These fields are used by the Windows implementation of mutexes.
+	 * Usually they are initialized by the first DB API call to lock a
+	 * mutex. If that would result in the mutexes being inaccessible by
+	 * other threads (e.g., ones which have lesser privileges) the
+	 * application may first call db_env_set_win_security().
+	 */
+	SECURITY_DESCRIPTOR win_default_sec_desc;
+	SECURITY_ATTRIBUTES win_default_sec_attr;
+#endif
+	SECURITY_ATTRIBUTES *win_sec_attr;
+#endif
+	
+	/* TAILQ_HEAD(__envq, __dbenv) envq; */
+	struct __envq {
+		struct __env *tqh_first;
+		struct __env **tqh_last;
+	} envq;
+
+	char *db_line;			/* DB display string. */
+
+	char error_buf[40];		/* Error string buffer. */
+
+	int uid_init;			/* srand set in UID generator */
+
+	u_long rand_next;		/* rand/srand value */
+
+	u_int32_t fid_serial;		/* file id counter */
+
+	int db_errno;			/* Errno value if not available */
+
+	size_t num_active_pids;		/* number of entries in active_pids */
+
+	size_t size_active_pids;	/* allocated size of active_pids */
+
+	pid_t *active_pids;		/* array active pids */
+
+	char *saved_errstr;		/* saved error string from backup */
+
+	/* Underlying OS interface jump table.*/
+	void	(*j_assert) __P((const char *, const char *, int));
+	int	(*j_close) __P((int));	
+	void	(*j_dirfree) __P((char **, int));
+	int	(*j_dirlist) __P((const char *, char ***, int *));
+	int	(*j_exists) __P((const char *, int *));
+	void	(*j_free) __P((void *));
+	int	(*j_fsync) __P((int));
+	int	(*j_ftruncate) __P((int, off_t));
+	int	(*j_ioinfo) __P((const char *,
+		    int, u_int32_t *, u_int32_t *, u_int32_t *));
+	void   *(*j_malloc) __P((size_t));
+	int	(*j_file_map) __P((DB_ENV *, char *, size_t, int, void **));
+	int	(*j_file_unmap) __P((DB_ENV *, void *));
+	int	(*j_open) __P((const char *, int, ...));
+	ssize_t	(*j_pread) __P((int, void *, size_t, off_t));
+	ssize_t	(*j_pwrite) __P((int, const void *, size_t, off_t));
+	ssize_t	(*j_read) __P((int, void *, size_t));
+	void   *(*j_realloc) __P((void *, size_t));
+	int	(*j_region_map) __P((DB_ENV *, char *, size_t, int *, void **));
+	int	(*j_region_unmap) __P((DB_ENV *, void *));
+	int	(*j_rename) __P((const char *, const char *));
+	int	(*j_seek) __P((int, off_t, int));
+	int	(*j_unlink) __P((const char *));
+	ssize_t	(*j_write) __P((int, const void *, size_t));
+	int	(*j_yield) __P((u_long, u_long));
+} DB_GLOBALS;
+
+extern	DB_GLOBALS	__db_global_values;
+#define	DB_GLOBAL(v)	__db_global_values.v
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_GLOBALS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/hash.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,195 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994
+ *	Margo Seltzer.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#ifndef	_DB_HASH_H_
+#define	_DB_HASH_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Hash internal structure. */
+typedef struct hash_t {
+	db_pgno_t meta_pgno;	/* Page number of the meta data page. */
+	u_int32_t revision;	/* Revision of subdb metadata. */
+	u_int32_t h_ffactor;	/* Fill factor. */
+	u_int32_t h_nelem;	/* Number of elements. */
+				/* Hash and compare functions. */
+	u_int32_t (*h_hash) __P((DB *, const void *, u_int32_t));
+	int (*h_compare) __P((DB *, const DBT *, const DBT *));
+} HASH;
+
+/* Cursor structure definitions. */
+typedef struct cursor_t {
+	/* struct __dbc_internal */
+	__DBC_INTERNAL
+
+	/* Hash private part */
+
+	/* Per-thread information */
+	DB_LOCK hlock;			/* Metadata page lock. */
+	HMETA *hdr;			/* Pointer to meta-data page. */
+	PAGE *split_buf;		/* Temporary buffer for splits. */
+
+	/* Hash cursor information */
+	db_pgno_t	bucket;		/* Bucket we are traversing. */
+	db_pgno_t	lbucket;	/* Bucket for which we are locked. */
+	db_indx_t	dup_off;	/* Offset within a duplicate set. */
+	db_indx_t	dup_len;	/* Length of current duplicate. */
+	db_indx_t	dup_tlen;	/* Total length of duplicate entry. */
+	u_int32_t	seek_size;	/* Number of bytes we need for add. */
+	db_pgno_t	seek_found_page;/* Page on which we can insert. */
+	db_indx_t	seek_found_indx;/* Insert position for item. */
+	u_int32_t	order;		/* Relative order among deleted curs. */
+
+#define	H_CONTINUE	0x0001		/* Join--search strictly fwd for data */
+#define	H_CONTRACT	0x0002		/* Table contracted.*/
+#define	H_DELETED	0x0004		/* Cursor item is deleted. */
+#define	H_DUPONLY	0x0008		/* Dups only; do not change key. */
+#define	H_EXPAND	0x0010		/* Table expanded. */
+#define	H_ISDUP		0x0020		/* Cursor is within duplicate set. */
+#define	H_NEXT_NODUP	0x0040		/* Get next non-dup entry. */
+#define	H_NOMORE	0x0080		/* No more entries in bucket. */
+#define	H_OK		0x0100		/* Request succeeded. */
+	u_int32_t	flags;
+} HASH_CURSOR;
+
+/* Test string. */
+#define	CHARKEY			"%$sniglet^&"
+
+/* Overflow management */
+/*
+ * The spares table indicates the page number at which each doubling begins.
+ * From this page number we subtract the number of buckets already allocated
+ * so that we can do a simple addition to calculate the page number here.
+ */
+#define	BS_TO_PAGE(bucket, spares)		\
+	((bucket) + (spares)[__db_log2((bucket) + 1)])
+#define	BUCKET_TO_PAGE(I, B)	(BS_TO_PAGE((B), (I)->hdr->spares))
+
+/* Constraints about much data goes on a page. */
+
+#define	MINFILL		4
+#define	ISBIG(I, N)	(((N) > ((I)->hdr->dbmeta.pagesize / MINFILL)) ? 1 : 0)
+
+/* Shorthands for accessing structure */
+#define	NDX_INVALID	0xFFFF
+#define	BUCKET_INVALID	0xFFFFFFFF
+
+/* On page duplicates are stored as a string of size-data-size triples. */
+#define	DUP_SIZE(len)	((len) + 2 * sizeof(db_indx_t))
+
+/* Log messages types (these are subtypes within a record type) */
+/* These bits are obsolete and are only needed for down rev logs. */
+#define	PAIR_KEYMASK		0x1
+#define	PAIR_DATAMASK		0x2
+#define	PAIR_DUPMASK		0x4
+#define	PAIR_MASK		0xf
+#define	PAIR_ISKEYBIG(N)	(N & PAIR_KEYMASK)
+#define	PAIR_ISDATABIG(N)	(N & PAIR_DATAMASK)
+#define	PAIR_ISDATADUP(N)	(N & PAIR_DUPMASK)
+#define	OPCODE_OF(N)	(N & ~PAIR_MASK)
+
+/* Operators for hash recover routines. */
+#define	PUTPAIR		0x20
+#define	DELPAIR		0x30
+#define	PUTOVFL		0x40
+#define	DELOVFL		0x50
+#define	HASH_UNUSED1	0x60
+#define	HASH_UNUSED2	0x70
+#define	SPLITOLD	0x80
+#define	SPLITNEW	0x90
+#define	SORTPAGE	0x100
+
+/* Flags to control behavior of __ham_del_pair */
+#define	HAM_DEL_NO_CURSOR	0x01 /* Don't do any cursor adjustment */
+#define	HAM_DEL_NO_RECLAIM	0x02 /* Don't reclaim empty pages */
+/* Just delete onpage items (even if they are references to off-page items). */
+#define	HAM_DEL_IGNORE_OFFPAGE	0x04
+
+typedef enum {
+	DB_HAM_CURADJ_DEL = 1,
+	DB_HAM_CURADJ_ADD = 2,
+	DB_HAM_CURADJ_ADDMOD = 3,
+	DB_HAM_CURADJ_DELMOD = 4
+} db_ham_curadj;
+
+typedef enum {
+	DB_HAM_CHGPG = 1,
+	DB_HAM_DELFIRSTPG = 2,
+	DB_HAM_DELMIDPG = 3,
+	DB_HAM_DELLASTPG = 4,
+	DB_HAM_DUP   = 5,
+	DB_HAM_SPLIT = 6
+} db_ham_mode;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/hash_auto.h"
+#include "dbinc_auto/hash_ext.h"
+#include "dbinc/db_am.h"
+#endif /* !_DB_HASH_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/heap.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,81 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2010, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef _DB_HEAP_H_
+#define _DB_HEAP_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Forward structure declarations. */
+struct __heap;		typedef struct __heap HEAP;
+struct __heap_cursor;	typedef struct __heap_cursor HEAP_CURSOR;
+
+/*
+ * The in-memory, per-heap data structure.
+ */
+struct __heap {		/* Heap access method. */
+	
+	u_int32_t gbytes;	/* Initial heap size. */
+	u_int32_t bytes;	/* Initial heap size. */
+	u_int32_t region_size;	/* Size of each region. */
+
+	db_pgno_t curregion;	/* The region of the next insert. */
+	db_pgno_t maxpgno;	/* Maximum page number of a fixed size heap. */
+	int curpgindx;	/* The last used offset in the region's space bitmap. */
+};
+
+struct __heap_cursor {
+	/* struct __dbc_internal */
+	__DBC_INTERNAL
+
+	/* Heap private part */
+
+	u_int32_t	flags;
+};
+
+#define HEAP_PG_FULL	3	/* No space on page. */
+#define HEAP_PG_GT66	2	/* Page greater than 66% full */
+#define HEAP_PG_GT33	1	/* Page greater than 33% full */
+#define HEAP_PG_LT33	0	/* Page less than 33% full */
+
+#define HEAP_PG_FULL_PCT	5	/* Less than 5% of page is free. */
+#define HEAP_PG_GT66_PCT	33	/* Less than 33% of page is free. */
+#define HEAP_PG_GT33_PCT	66	/* Less than 66% of page is free. */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/heap_auto.h"
+#include "dbinc_auto/heap_ext.h"
+#include "dbinc/db_am.h"
+#endif
+
+	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/hmac.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,61 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef	_DB_HMAC_H_
+#define	_DB_HMAC_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Algorithm specific information.
+ */
+/*
+ * SHA1 checksumming
+ */
+typedef struct {
+	u_int32_t	state[5];
+	u_int32_t	count[2];
+	unsigned char	buffer[64];
+} SHA1_CTX;
+
+/*
+ * AES assumes the SHA1 checksumming (also called MAC)
+ */
+#define	DB_MAC_MAGIC	"mac derivation key magic value"
+#define	DB_ENC_MAGIC	"encryption and decryption key value magic"
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/hmac_ext.h"
+#endif /* !_DB_HMAC_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/lock.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,348 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef	_DB_LOCK_H_
+#define	_DB_LOCK_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define	DB_LOCK_DEFAULT_N	1000	/* Default # of locks in region. */
+
+/*
+ * The locker id space is divided between the transaction manager and the lock
+ * manager.  Lock IDs start at 1 and go to DB_LOCK_MAXID.  Txn IDs start at
+ * DB_LOCK_MAXID + 1 and go up to TXN_MAXIMUM.
+ */
+#define	DB_LOCK_INVALIDID	0
+#define	DB_LOCK_MAXID		0x7fffffff
+
+/*
+ * A locker's deadlock resolution priority is stored as a 32 bit unsigned
+ * integer.  The maximum priority is DB_LOCK_MAXPRIORITY and the default
+ * priority is DB_LOCK_DEFPRIORITY.
+ */
+#define	DB_LOCK_DEFPRIORITY	100
+#define DB_LOCK_MAXPRIORITY	UINT32_MAX
+
+/*
+ * Out of band value for a lock.  Locks contain an offset into a lock region,
+ * so we use an invalid region offset to indicate an invalid or unset lock.
+ */
+#define	LOCK_INVALID		INVALID_ROFF
+#define	LOCK_ISSET(lock)	((lock).off != LOCK_INVALID)
+#define	LOCK_INIT(lock)		((lock).off = LOCK_INVALID)
+
+/*
+ * Macro to identify a write lock for the purpose of counting locks
+ * for the NUMWRITES option to deadlock detection.
+ */
+#define	IS_WRITELOCK(m) \
+	((m) == DB_LOCK_WRITE || (m) == DB_LOCK_WWRITE || \
+	    (m) == DB_LOCK_IWRITE || (m) == DB_LOCK_IWR)
+
+/*
+ * Macros to lock/unlock the lock region as a whole. Mostly used for
+ * initialization.
+ */
+#define	LOCK_REGION_LOCK(env)						\
+	MUTEX_LOCK(env, ((DB_LOCKREGION *)				\
+	    (env)->lk_handle->reginfo.primary)->mtx_region)
+#define	LOCK_REGION_UNLOCK(env)						\
+	MUTEX_UNLOCK(env, ((DB_LOCKREGION *)				\
+	    (env)->lk_handle->reginfo.primary)->mtx_region)
+
+/*
+ * DB_LOCKREGION --
+ *	The lock shared region.
+ */
+
+typedef struct __db_lockregion { /* SHARED */
+	db_mutex_t	mtx_region;	/* Region mutex. */
+
+	u_int32_t	need_dd;	/* flag for deadlock detector */
+	u_int32_t	detect;		/* run dd on every conflict */
+	db_timespec	next_timeout;	/* next time to expire a lock */
+	db_mutex_t	mtx_dd;		/* mutex for lock object dd list. */
+	db_mutex_t	mtx_lockers;	/* mutex for locker allocation. */
+	SH_TAILQ_HEAD(__dobj) dd_objs;	/* objects with waiters */
+					/* free locker header */
+        roff_t          locker_mem_off; /* block memory for lockers */
+	SH_TAILQ_HEAD(__flocker) free_lockers;
+	SH_TAILQ_HEAD(__lkrs) lockers;	/* list of lockers */
+
+	db_timeout_t	lk_timeout;	/* timeout for locks. */
+	db_timeout_t	tx_timeout;	/* timeout for txns. */
+
+	u_int32_t	locker_t_size;	/* size of locker hash table */
+	u_int32_t	object_t_size;	/* size of object hash table */
+	u_int32_t	part_t_size;	/* number of partitions */
+
+	roff_t		conf_off;	/* offset of conflicts array */
+	roff_t		obj_off;	/* offset of object hash table */
+	roff_t		part_off;	/* offset of partition array */
+	roff_t		stat_off;	/* offset to object hash stats */
+	roff_t		locker_off;	/* offset of locker hash table */
+
+	u_int32_t	lock_id;	/* Current lock(er) id to allocate. */
+	u_int32_t	cur_maxid;	/* Current max lock(er) id. */
+	u_int32_t	nlockers;	/* Current number of lockers. */
+	int32_t		nmodes;		/* Number of modes in conflict table. */
+	DB_LOCK_STAT	stat;		/* stats about locking. */
+} DB_LOCKREGION;
+
+/*
+ * Since we will store DBTs in shared memory, we need the equivalent of a
+ * DBT that will work in shared memory.
+ */
+typedef struct __sh_dbt { /* SHARED */
+	u_int32_t size;			/* Byte length. */
+	roff_t    off;			/* Region offset. */
+} SH_DBT;
+
+#define	SH_DBT_PTR(p)	((void *)(((u_int8_t *)(p)) + (p)->off))
+
+/*
+ * Object structures;  these live in the object hash table.
+ */
+typedef struct __db_lockobj { /* SHARED */
+	u_int32_t	indx;		/* Hash index of this object. */
+	u_int32_t	generation;	/* Generation of this object. */
+	SH_DBT	lockobj;		/* Identifies object locked. */
+	SH_TAILQ_ENTRY links;		/* Links for free list or hash list. */
+	SH_TAILQ_ENTRY dd_links;	/* Links for dd list. */
+	SH_TAILQ_HEAD(__waitl) waiters;	/* List of waiting locks. */
+	SH_TAILQ_HEAD(__holdl) holders;	/* List of held locks. */
+					/* Declare room in the object to hold
+					 * typical DB lock structures so that
+					 * we do not have to allocate them from
+					 * shalloc at run-time. */
+	u_int8_t objdata[sizeof(struct __db_ilock)];
+} DB_LOCKOBJ;
+
+/*
+ * Locker structures; these live in the locker hash table.
+ */
+struct __db_locker { /* SHARED */
+	u_int32_t id;			/* Locker id. */
+
+	pid_t pid;			/* Process owning locker ID */
+	db_threadid_t tid;		/* Thread owning locker ID */
+	db_mutex_t mtx_locker;		/* Mutex to block on. */
+
+	u_int32_t dd_id;		/* Deadlock detector id. */
+
+	u_int32_t nlocks;		/* Number of locks held. */
+	u_int32_t nwrites;		/* Number of write locks held. */
+	u_int32_t priority;		/* Deadlock resolution priority. */
+	u_int32_t nrequest;             /* number of requests. */
+	
+	roff_t  master_locker;		/* Locker of master transaction. */
+	roff_t  parent_locker;		/* Parent of this child. */
+	SH_LIST_HEAD(_child) child_locker;	/* List of descendant txns;
+						   only used in a "master"
+						   txn. */
+	SH_LIST_ENTRY child_link;	/* Links transactions in the family;
+					   elements of the child_locker
+					   list. */
+	SH_TAILQ_ENTRY links;		/* Links for free and hash list. */
+	SH_TAILQ_ENTRY ulinks;		/* Links in-use list. */
+	SH_LIST_HEAD(_held) heldby;	/* Locks held by this locker. */
+	db_timespec	lk_expire;	/* When current lock expires. */
+	db_timespec	tx_expire;	/* When this txn expires. */
+	db_timeout_t	lk_timeout;	/* How long do we let locks live. */
+
+#define	DB_LOCKER_DIRTY		0x0001	/* Has write locks. */
+#define	DB_LOCKER_INABORT	0x0002	/* Is aborting, don't abort again. */
+#define	DB_LOCKER_TIMEOUT	0x0004	/* Has timeout set. */
+#define	DB_LOCKER_FAMILY_LOCKER 0x0008	/* Part of a family of lockers. */
+#define	DB_LOCKER_HANDLE_LOCKER 0x0010	/* Not associated with a thread. */
+	u_int32_t flags;
+};
+
+/*
+ * Map a hash index into a partition.
+ */
+#define	LOCK_PART(reg, ndx)  (ndx % (reg)->part_t_size)
+
+/*
+ * Structure that contains information about a lock table partition.
+ */
+typedef struct __db_lockpart{ /* SHARED */
+	db_mutex_t	mtx_part;	/* mutex for partition*/
+					/* free lock header */
+	SH_TAILQ_HEAD(__flock) free_locks;
+					/* free obj header */
+	SH_TAILQ_HEAD(__fobj) free_objs;
+        roff_t          lock_mem_off;   /* block memory for locks */
+        roff_t          lockobj_mem_off;/* block memory for lockobjs */
+#ifdef HAVE_STATISTICS
+	DB_LOCK_PSTAT	part_stat;	/* Partition stats. */
+#endif
+} DB_LOCKPART;
+
+#define	FREE_LOCKS(lt, part)	((lt)->part_array[part].free_locks)
+#define	FREE_OBJS(lt, part)	((lt)->part_array[part].free_objs)
+
+/*
+ * DB_LOCKTAB --
+ *	The primary library lock data structure (i.e., the one referenced
+ * by the environment, as opposed to the internal one laid out in the region.)
+ */
+struct __db_locktab {
+	ENV		*env;		/* Environment. */
+	REGINFO		 reginfo;	/* Region information. */
+	u_int8_t	*conflicts;	/* Pointer to conflict matrix. */
+	DB_LOCKPART	*part_array;	/* Beginning of partition array. */
+#ifdef HAVE_STATISTICS
+	DB_LOCK_HSTAT	*obj_stat;	/* Object hash stats array. */
+#endif
+	DB_HASHTAB	*obj_tab;	/* Beginning of object hash table. */
+	DB_HASHTAB	*locker_tab;	/* Beginning of locker hash table. */
+};
+
+/*
+ * Test for conflicts.
+ *
+ * Cast HELD and WANTED to ints, they are usually db_lockmode_t enums.
+ */
+#define	CONFLICTS(T, R, HELD, WANTED) \
+	(T)->conflicts[((int)HELD) * (R)->nmodes + ((int)WANTED)]
+
+#define	OBJ_LINKS_VALID(L) ((L)->links.stqe_prev != -1)
+
+struct __db_lock { /* SHARED */
+	/*
+	 * Wait on mutex to wait on lock.  You reference your own mutex with
+	 * ID 0 and others reference your mutex with ID 1.
+	 */
+	db_mutex_t	mtx_lock;
+
+	roff_t		holder;		/* Who holds this lock. */
+	u_int32_t	gen;		/* Generation count. */
+	SH_TAILQ_ENTRY	links;		/* Free or holder/waiter list. */
+	SH_LIST_ENTRY	locker_links;	/* List of locks held by a locker. */
+	u_int32_t	refcount;	/* Reference count the lock. */
+	db_lockmode_t	mode;		/* What sort of lock. */
+	roff_t		obj;		/* Relative offset of object struct. */
+	u_int32_t	indx;		/* Hash index of this object. */
+	db_status_t	status;		/* Status of this lock. */
+};
+
+/*
+ * Flag values for __lock_put_internal:
+ * DB_LOCK_DOALL:     Unlock all references in this lock (instead of only 1).
+ * DB_LOCK_FREE:      Free the lock (used in checklocker).
+ * DB_LOCK_NOPROMOTE: Don't bother running promotion when releasing locks
+ *		      (used by __lock_put_internal).
+ * DB_LOCK_UNLINK:    Remove from the locker links (used in checklocker).
+ * Make sure that these do not conflict with the interface flags because
+ * we pass some of those around.
+ */
+#define	DB_LOCK_DOALL		0x010000
+#define	DB_LOCK_FREE		0x040000
+#define	DB_LOCK_NOPROMOTE	0x080000
+#define	DB_LOCK_UNLINK		0x100000
+#define	DB_LOCK_ONEWAITER	0x400000
+
+/*
+ * Macros to get/release different types of mutexes.
+ */
+/*
+ * Operations on lock objects must be protected by a mutex, either on their
+ * partition or on the lock region.  Lock structures associated with that
+ * object are protected as well.  Each partition has a free list of objects
+ * and lock structures protected by that mutex.  We want to avoid getting
+ * multiple mutexes, particularly in __lock_vec, when there is only a
+ * single partition.  If there is only one partition, then all the calls
+ * to LOCK_SYSTEM_LOCK(UNLOCK) actually acquire(release) a lock system
+ * wide mutex and MUTEX_LOCK(UNLOCK)_PARTITION are no-ops.  If the number
+ * of partitions is greater than one, then LOCK_SYSTEM_LOCK(UNLOCK) is a
+ * no-op, and MUTEX_LOCK(UNLOCK)_PARTITION acquire a mutex on a particular
+ * partition of the lock table.
+ */
+#define	LOCK_SYSTEM_LOCK(lt, reg) do {					\
+	if ((reg)->part_t_size == 1)					\
+		MUTEX_LOCK((lt)->env, (reg)->mtx_region);		\
+} while (0)
+#define	LOCK_SYSTEM_UNLOCK(lt, reg) do {				\
+	if ((reg)->part_t_size == 1)					\
+		MUTEX_UNLOCK((lt)->env, (reg)->mtx_region);		\
+} while (0)
+#define	MUTEX_LOCK_PARTITION(lt, reg, p) do {				\
+	if ((reg)->part_t_size != 1)					\
+		MUTEX_LOCK((lt)->env, (lt)->part_array[p].mtx_part);	\
+} while (0)
+#define	MUTEX_UNLOCK_PARTITION(lt, reg, p) do {				\
+	if ((reg)->part_t_size != 1)					\
+		MUTEX_UNLOCK((lt)->env, (lt)->part_array[p].mtx_part);	\
+} while (0)
+
+#define	OBJECT_LOCK(lt, reg, obj, ndx) do {				\
+	ndx = __lock_ohash(obj) % (reg)->object_t_size;			\
+	MUTEX_LOCK_PARTITION(lt, reg, LOCK_PART(reg, ndx));		\
+} while (0)
+
+#define	OBJECT_LOCK_NDX(lt, reg, ndx)					\
+	MUTEX_LOCK_PARTITION(lt, reg, LOCK_PART(reg, ndx));
+
+#define	OBJECT_UNLOCK(lt, reg, ndx)					\
+	MUTEX_UNLOCK_PARTITION(lt, reg, LOCK_PART(reg, ndx));
+
+/*
+ * Protect the object deadlock detector queue and the locker allocation
+ * and active queues
+ */
+#define	LOCK_DD(env, region)						\
+	MUTEX_LOCK(env, (region)->mtx_dd)
+#define	UNLOCK_DD(env, region)						\
+	MUTEX_UNLOCK(env, (region)->mtx_dd)
+#define	LOCK_LOCKERS(env, region)					\
+	MUTEX_LOCK(env, (region)->mtx_lockers)
+#define	UNLOCK_LOCKERS(env, region)					\
+	MUTEX_UNLOCK(env, (region)->mtx_lockers)
+
+/*
+ * __lock_locker_hash --
+ *	Hash function for entering lockers into the locker hash table.
+ *	Since these are simply 32-bit unsigned integers at the moment,
+ *	just return the locker value.
+ */
+#define	__lock_locker_hash(locker)	(locker)
+#define	LOCKER_HASH(lt, reg, locker, ndx)				\
+	ndx = __lock_locker_hash(locker) % (reg)->locker_t_size;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/lock_ext.h"
+#endif /* !_DB_LOCK_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/log.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,485 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_LOG_H_
+#define	_DB_LOG_H_
+
+#include "dbinc/db_swap.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*******************************************************
+ * DBREG:
+ *	The DB file register code keeps track of open files.  It's stored
+ *	in the log subsystem's shared region, and so appears in the log.h
+ *	header file, but is logically separate.
+ *	The dbp may not be open if we are recovering the abort of a create.
+ *******************************************************/
+/*
+ * The per-process table that maps log file-id's to DB structures.
+ */
+typedef	struct __db_entry {
+	DB	*dbp;			/* Open dbp for this file id. */
+	int	deleted;		/* File was not found during open. */
+} DB_ENTRY;
+
+/*
+ * FNAME --
+ *	File name and id.
+ */
+struct __fname {
+	SH_TAILQ_ENTRY q;		/* File name queue. */
+
+	pid_t	  pid;			/* Process that owns this. */
+	int32_t   id;			/* Logging file id. */
+	int32_t   old_id;		/* Saved logging file id. */
+	DBTYPE	  s_type;		/* Saved DB type. */
+
+	roff_t	  fname_off;		/* File name offset. */
+	roff_t	  dname_off;		/* Database name offset. */
+	db_pgno_t meta_pgno;		/* Page number of the meta page. */
+	u_int8_t  ufid[DB_FILE_ID_LEN];	/* Unique file id. */
+
+	u_int32_t create_txnid;		/*
+					 * Txn ID of the DB create, stored so
+					 * we can log it at register time.
+					 */
+	db_mutex_t mutex;		/* mutex from db handle. */
+			/* number of txn referencing + 1 for the db handle. */
+	u_int32_t txn_ref;
+
+#define	DB_FNAME_CLOSED		0x01	/* DBP was closed. */
+#define	DB_FNAME_DURABLE	0x02	/* File is durable. */
+#define	DB_FNAME_INMEM		0x04	/* File is in memory. */
+#define	DB_FNAME_NOTLOGGED	0x08	/* Log of close failed. */
+#define	DB_FNAME_RECOVER	0x10	/* File was opened by recovery code. */
+#define	DB_FNAME_RESTORED	0x20	/* File may be in restored txn. */
+#define	DB_FNAME_DBREG_MASK	0xf000	/* These bits come from DBREG below. */
+	u_int32_t flags;
+};
+
+/* File open/close register log record opcodes. */
+#define	DBREG_CHKPNT	1		/* Checkpoint: file name/id dump. */
+#define	DBREG_CLOSE	2		/* File close. */
+#define	DBREG_OPEN	3		/* File open. */
+#define	DBREG_PREOPEN	4		/* Open in mpool only. */
+#define	DBREG_RCLOSE	5		/* File close after recovery. */
+#define	DBREG_REOPEN	6		/* Open for in-memory database. */
+#define	DBREG_XCHKPNT	7		/* Checkpoint of exclusive file. */
+#define	DBREG_XOPEN	8		/* File exclusive open. */
+#define	DBREG_XREOPEN	9		/* File exclusive open in-memory. */
+
+/* These bits are logged so db_printlog can handle page data. */
+#define	DBREG_OP_MASK	0xf		/* Opcode mask */
+#define	DBREG_BIGEND	0x1000		/* Db Big endian. */
+#define	DBREG_CHKSUM	0x2000		/* Db is checksummed. */
+#define	DBREG_ENCRYPT	0x4000		/* Db is encrypted. */
+#define	DBREG_EXCL	0x8000		/* Db is exclusive. */
+
+/*******************************************************
+ * LOG:
+ *	The log subsystem information.
+ *******************************************************/
+struct __hdr;		typedef struct __hdr HDR;
+struct __log;		typedef struct __log LOG;
+struct __log_persist;	typedef struct __log_persist LOGP;
+
+#define	LFPREFIX	"log."		/* Log file name prefix. */
+#define	LFNAME		"log.%010d"	/* Log file name template. */
+#define	LFNAME_V1	"log.%05d"	/* Log file name template, rev 1. */
+#define IS_LOG_FILE(name)  (strncmp(name, LFPREFIX, sizeof(LFPREFIX) - 1) == 0)
+
+#define	LG_MAX_DEFAULT		(10 * MEGABYTE)	/* 10 MB. */
+#define	LG_MAX_INMEM		(256 * 1024)	/* 256 KB. */
+#define	LG_BSIZE_INMEM		(1 * MEGABYTE)	/* 1 MB. */
+
+/*
+ * Allocate a few bytes under a power-of-two value.  BDB doesn't care if it's
+ * a power-of-two or not, and requesting slightly under a power-of-two allows
+ * stupid allocators to avoid wasting space.
+ */
+#define	LG_BASE_REGION_SIZE	(130000)	/* 128KB - 1072B */
+#define	LG_BSIZE_DEFAULT	(32000)		/* 32 KB - 768B */
+#define	LG_CURSOR_BUF_SIZE	(32000)		/* 32 KB - 768B */
+
+/*
+ * DB_LOG
+ *	Per-process log structure.
+ */
+struct __db_log {
+	/*
+	 * These fields need to be protected for multi-threaded support.
+	 */
+	db_mutex_t mtx_dbreg;		/* Mutex for thread protection. */
+
+	DB_ENTRY *dbentry;		/* Recovery file-id mapping. */
+#define	DB_GROW_SIZE	64
+	int32_t	dbentry_cnt;		/* Entries.  Grows by DB_GROW_SIZE. */
+
+	/*
+	 * These fields are only accessed when the region lock is held, so
+	 * they do not have to be protected by the thread lock as well.
+	 */
+	u_int32_t lfname;		/* Log file "name". */
+	DB_FH	 *lfhp;			/* Log file handle. */
+	time_t	  lf_timestamp;		/* Log file timestamp. */
+
+	u_int8_t *bufp;			/* Region buffer. */
+
+	/* These fields are not thread protected. */
+	ENV	 *env;			/* Environment */
+	REGINFO	  reginfo;		/* Region information. */
+
+#define	DBLOG_AUTOREMOVE	0x01	/* Autoremove log files. */
+#define	DBLOG_DIRECT		0x02	/* Do direct I/O on the log. */
+#define	DBLOG_DSYNC		0x04	/* Set OS_DSYNC on the log. */
+#define	DBLOG_FORCE_OPEN	0x08	/* Force the DB open even if it appears
+					 * to be deleted. */
+#define	DBLOG_INMEMORY		0x10	/* Logging is in memory. */
+#define	DBLOG_OPENFILES		0x20	/* Prepared files need to be open. */
+#define	DBLOG_RECOVER		0x40	/* We are in recovery. */
+#define	DBLOG_ZERO		0x80	/* Zero fill the log. */
+#define	DBLOG_VERIFYING		0x100	/* The log is being verified. */
+	u_int32_t flags;
+};
+
+/*
+ * HDR --
+ *	Log record header.
+ */
+struct __hdr {
+	u_int32_t prev;			/* Previous offset. */
+	u_int32_t len;			/* Current length. */
+	u_int8_t  chksum[DB_MAC_KEY];	/* Current checksum. */
+	u_int8_t  iv[DB_IV_BYTES];	/* IV */
+	u_int32_t orig_size;		/* Original size of log record */
+	/* !!! - 'size' is not written to log, must be last in hdr */
+	size_t	  size;			/* Size of header to use */
+};
+
+/*
+ * LOG_HDR_SUM -- XOR in prev and len
+ *	This helps avoids the race misreading the log while it
+ * it is being updated.
+ */
+#define	LOG_HDR_SUM(crypto, hdr, sum) do {				\
+	if (crypto) {							\
+		((u_int32_t *)sum)[0] ^= ((HDR *)hdr)->prev;		\
+		((u_int32_t *)sum)[1] ^= ((HDR *)hdr)->len;		\
+	} else {							\
+		((u_int32_t *)sum)[0] ^=				\
+		     ((HDR *)hdr)->prev ^ ((HDR *)hdr)->len;		\
+	}								\
+} while (0)
+
+/*
+ * We use HDR internally, and then when we write out, we write out
+ * prev, len, and then a 4-byte checksum if normal operation or
+ * a crypto-checksum and IV and original size if running in crypto
+ * mode.  We must store the original size in case we pad.  Set the
+ * size when we set up the header.  We compute a DB_MAC_KEY size
+ * checksum regardless, but we can safely just use the first 4 bytes.
+ */
+#define	HDR_NORMAL_SZ	12
+#define	HDR_CRYPTO_SZ	12 + DB_MAC_KEY + DB_IV_BYTES
+
+struct __log_persist {
+	u_int32_t magic;		/* DB_LOGMAGIC */
+	u_int32_t version;		/* DB_LOGVERSION */
+
+	u_int32_t log_size;		/* Log file size. */
+	u_int32_t notused;		/* Historically the log file mode. */
+};
+
+/* Macros to lock/unlock the log region as a whole. */
+#define	LOG_SYSTEM_LOCK(env)						\
+	MUTEX_LOCK(env, ((LOG *)					\
+	    (env)->lg_handle->reginfo.primary)->mtx_region)
+#define	LOG_SYSTEM_UNLOCK(env)						\
+	MUTEX_UNLOCK(env, ((LOG *)					\
+	    (env)->lg_handle->reginfo.primary)->mtx_region)
+
+/*
+ * LOG --
+ *	Shared log region.  One of these is allocated in shared memory,
+ *	and describes the log.
+ */
+struct __log { /* SHARED */
+	db_mutex_t mtx_region;		/* Region mutex. */
+
+	db_mutex_t mtx_filelist;	/* Mutex guarding file name list. */
+
+	LOGP	persist;		/* Persistent information. */
+
+	SH_TAILQ_HEAD(__fq1) fq;	/* List of file names. */
+	int32_t	fid_max;		/* Max fid allocated. */
+	roff_t	free_fid_stack;		/* Stack of free file ids. */
+	u_int32_t  free_fids;		/* Height of free fid stack. */
+	u_int32_t  free_fids_alloced;	/* N free fid slots allocated. */
+
+	/*
+	 * The lsn LSN is the file offset that we're about to write and which
+	 * we will return to the user.
+	 */
+	DB_LSN	  lsn;			/* LSN at current file offset. */
+
+	/*
+	 * The f_lsn LSN is the LSN (returned to the user) that "owns" the
+	 * first byte of the buffer.  If the record associated with the LSN
+	 * spans buffers, it may not reflect the physical file location of
+	 * the first byte of the buffer.
+	 */
+	DB_LSN	  f_lsn;		/* LSN of first byte in the buffer. */
+	db_size_t b_off;		/* Current offset in the buffer. */
+	u_int32_t w_off;		/* Current write offset in the file. */
+	u_int32_t len;			/* Length of the last record. */
+
+	DB_LSN	  active_lsn;		/* Oldest active LSN in the buffer. */
+	db_size_t a_off;		/* Offset in the buffer of first active
+					   file. */
+
+	/*
+	 * The s_lsn LSN is the last LSN that we know is on disk, not just
+	 * written, but synced.  This field is protected by the flush mutex
+	 * rather than by the region mutex.
+	 */
+	db_mutex_t mtx_flush;		/* Mutex guarding flushing. */
+	int32_t	   in_flush;	/* Log flush in progress. */
+	DB_LSN	   s_lsn;		/* LSN of the last sync. */
+
+	DB_LOG_STAT stat;		/* Log statistics. */
+
+	/*
+	 * This timestamp is updated anytime someone unlinks log
+	 * files.  This can happen when calling __log_vtruncate
+	 * or replication internal init when it unlinks log files.
+	 *
+	 * The timestamp is used so that other processes that might
+	 * have file handles to log files know to close/reopen them
+	 * so they're not potentially writing to now-removed files.
+	 */
+	time_t	   timestamp;		/* Log trunc timestamp. */
+
+	/*
+	 * !!!
+	 * NOTE: the next group of fields are NOT protected by the log
+	 * region lock.  They are protected by REP->mtx_clientdb.  If you
+	 * need access to both, you must acquire REP->mtx_clientdb
+	 * before acquiring the log region lock.
+	 *
+	 * The waiting_lsn is used by the replication system.  It is the
+	 * first LSN that we are holding without putting in the log, because
+	 * we received one or more log records out of order.  Associated with
+	 * the waiting_lsn is the number of log records that we still have to
+	 * receive before we decide that we should request it again.
+	 *
+	 * The max_wait_lsn is used to control retransmission in the face
+	 * of dropped messages.  If we are requesting all records from the
+	 * current gap (i.e., chunk of the log that we are missing), then
+	 * the max_wait_lsn contains the first LSN that we are known to have
+	 * in the __db.rep.db.  If we requested only a single record, then
+	 * the max_wait_lsn has the LSN of that record we requested.
+	 */
+	/* BEGIN fields protected by rep->mtx_clientdb. */
+	DB_LSN	  waiting_lsn;		/* First log record after a gap. */
+	DB_LSN	  verify_lsn;		/* LSN we are waiting to verify. */
+	DB_LSN	  prev_ckp;		/* LSN of ckp preceding verify_lsn. */
+	DB_LSN	  max_wait_lsn;		/* Maximum LSN requested. */
+	DB_LSN	  max_perm_lsn;		/* Maximum PERMANENT LSN processed. */
+	db_timespec max_lease_ts;	/* Maximum Lease timestamp seen. */
+	db_timespec wait_ts;		/* Time to wait before requesting. */
+	db_timespec rcvd_ts;		/* Initial received time to wait. */
+	db_timespec last_ts;		/* Last time of insert in temp db. */
+	/*
+	 * The ready_lsn is also used by the replication system.  It is the
+	 * next LSN we expect to receive.  It's normally equal to "lsn",
+	 * except at the beginning of a log file, at which point it's set
+	 * to the LSN of the first record of the new file (after the
+	 * header), rather than to 0.
+	 */
+	DB_LSN	  ready_lsn;
+	/*
+	 * The bulk_buf is used by replication for bulk transfer.  While this
+	 * is protected by REP->mtx_clientdb, this doesn't contend with the
+	 * above fields because the above are used by clients and the bulk
+	 * fields below are used by a master.
+	 */
+	roff_t	  bulk_buf;		/* Bulk transfer buffer in region. */
+	roff_t	  bulk_off;		/* Current offset into bulk buffer. */
+	u_int32_t bulk_len;		/* Length of buffer. */
+	u_int32_t bulk_flags;		/* Bulk buffer flags. */
+	/* END fields protected by rep->mtx_clientdb. */
+
+	/*
+	 * During initialization, the log system walks forward through the
+	 * last log file to find its end.  If it runs into a checkpoint
+	 * while it's doing so, it caches it here so that the transaction
+	 * system doesn't need to walk through the file again on its
+	 * initialization.
+	 */
+	DB_LSN	cached_ckp_lsn;
+
+	u_int32_t regionmax;		/* Configured size of the region. */
+
+	roff_t	  buffer_off;		/* Log buffer offset in the region. */
+	u_int32_t buffer_size;		/* Log buffer size. */
+
+	u_int32_t log_size;		/* Log file's size. */
+	u_int32_t log_nsize;		/* Next log file's size. */
+
+	int	  filemode;		/* Log file permissions mode. */
+
+	/*
+	 * DB_LOG_AUTOREMOVE and DB_LOG_INMEMORY: not protected by a mutex,
+	 * all we care about is if they're zero or non-zero.
+	 */
+	int32_t	  db_log_autoremove;
+	int32_t	  db_log_inmemory;
+
+	u_int32_t ncommit;		/* Number of txns waiting to commit. */
+	DB_LSN	  t_lsn;		/* LSN of first commit */
+	SH_TAILQ_HEAD(__commit) commits;/* list of txns waiting to commit. */
+	SH_TAILQ_HEAD(__free) free_commits;/* free list of commit structs. */
+
+	/*
+	 * In-memory logs maintain a list of the start positions of all log
+	 * files currently active in the in-memory buffer.  This is to make the
+	 * lookup from LSN to log buffer offset efficient.
+	 */
+	SH_TAILQ_HEAD(__logfile) logfiles;
+	SH_TAILQ_HEAD(__free_logfile) free_logfiles;
+};
+
+/*
+ * __db_commit structure --
+ *	One of these is allocated for each transaction waiting to commit.
+ */
+struct __db_commit {
+	db_mutex_t	mtx_txnwait;	/* Mutex for txn to wait on. */
+	DB_LSN		lsn;		/* LSN of commit record. */
+	SH_TAILQ_ENTRY	links;		/* Either on free or waiting list. */
+
+#define	DB_COMMIT_FLUSH		0x0001	/* Flush the log when you wake up. */
+	u_int32_t	flags;
+};
+
+/*
+ * Check for the proper progression of Log Sequence Numbers.
+ * If we are rolling forward the LSN on the page must be greater
+ * than or equal to the previous LSN in log record.
+ * We ignore NOT LOGGED LSNs.  The user did an unlogged update.
+ * We should eventually see a log record that matches and continue
+ * forward.
+ * A ZERO LSN implies a page that was allocated prior to the recovery
+ * start point and then truncated later in the log.  An allocation of a
+ * page after this page will extend the file, leaving a hole.  We want to
+ * ignore this page until it is truncated again.
+ *
+ */
+
+#define	CHECK_LSN(e, redo, cmp, lsn, prev)				\
+	if (DB_REDO(redo) && (cmp) < 0 &&				\
+	    ((!IS_NOT_LOGGED_LSN(*(lsn)) && !IS_ZERO_LSN(*(lsn))) ||	\
+	    IS_REP_CLIENT(e))) {					\
+		ret = __db_check_lsn(e, lsn, prev);			\
+		goto out;						\
+	}
+#define	CHECK_ABORT(e, redo, cmp, lsn, prev)				\
+	if (redo == DB_TXN_ABORT && (cmp) != 0 &&			\
+	    ((!IS_NOT_LOGGED_LSN(*(lsn)) && !IS_ZERO_LSN(*(lsn))) ||	\
+	    IS_REP_CLIENT(e))) {					\
+		ret = __db_check_lsn(e, lsn, prev);			\
+		goto out;						\
+	}
+
+/*
+ * Helper for in-memory logs -- check whether an offset is in range
+ * in a ring buffer (inclusive of start, exclusive of end).
+ */
+struct __db_filestart {
+	u_int32_t	file;
+	size_t		b_off;
+
+	SH_TAILQ_ENTRY	links;		/* Either on free or waiting list. */
+};
+
+#define	RINGBUF_LEN(lp, start, end)					\
+	((start) < (end) ?						\
+	    (end) - (start) : (lp)->buffer_size - ((start) - (end)))
+
+/*
+ * Internal macro to set pointer to the begin_lsn for generated
+ * logging routines.  If begin_lsn is already set then do nothing.
+ * Return a pointer to the last lsn too.
+ */
+#undef DB_SET_TXN_LSNP
+#define	DB_SET_TXN_LSNP(txn, blsnp, llsnp) do {				\
+	DB_LSN *__lsnp;							\
+	TXN_DETAIL *__td;						\
+	__td = (txn)->td;						\
+	*(llsnp) = &__td->last_lsn;					\
+	while (__td->parent != INVALID_ROFF)				\
+		__td = R_ADDR(&(txn)->mgrp->reginfo, __td->parent);	\
+	__lsnp = &__td->begin_lsn;					\
+	if (IS_ZERO_LSN(*__lsnp))					\
+		*(blsnp) = __lsnp;					\
+} while (0)
+
+/*
+ * Status codes indicating the validity of a log file examined by
+ * __log_valid().
+ */
+typedef enum {
+	DB_LV_INCOMPLETE,
+	DB_LV_NONEXISTENT,
+	DB_LV_NORMAL,
+	DB_LV_OLD_READABLE,
+	DB_LV_OLD_UNREADABLE
+} logfile_validity;
+
+/*
+ * All log records have these fields.
+ */
+typedef struct __log_rec_hdr {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+} LOG_REC_HEADER;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/log_ext.h"
+#include "dbinc_auto/dbreg_auto.h"
+#include "dbinc_auto/dbreg_ext.h"
+#endif /* !_DB_LOG_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/log_verify.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,229 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+#ifndef _DB_LOG_VERIFY_H_
+#define _DB_LOG_VERIFY_H_
+
+#include "db_config.h"
+#include "db_int.h"
+
+/* 
+ * Log verification handle, such a handle is shared among all verification 
+ * functions during one verification process. 
+ */
+struct __db_log_verify_info {
+	DB_ENV *dbenv;		/* The database environment. */
+	DB *txninfo;		/* (txnid, __txn_verify_info) map. */
+	DB *ckps;		/* (ckp lrid, __ckpinfo) map. */
+	DB *fileregs; 		/* (file-uid, __file_reg_info) map. */
+	DB *fnameuid;		/* (fname, fuid), secondary db of fileregs. */
+	/* (dbreg-id, __file_reg_info) map, NOT the sec db for fileregs. */
+	DB *dbregids;
+	DB *pgtxn; 		/* (fileid-pageno, txnid) map. */
+	DB *txnpg; 		/* (txnid, fileid-pageno), sec db of pgtxn. */
+	/* lsn, (time-stamp, logtype(txn_regop or txn_ckp)) map. */
+	DB *lsntime; 
+	/* Secondary db of lsntime, use timestamp as secindex. */
+	DB *timelsn;
+
+	/* Time range database, (u_int32_t, __lv_txnrange) db. */
+	DB *txnrngs;
+	/* Store abort txn (lsn, txnid) map. */
+	DB *txnaborts;	
+	DB_LSN last_lsn;	/* Lsn of last log record we verified. */
+	/* The number of active, abort, commit and prepared txns. */
+	u_int32_t ntxn_active, ntxn_abort, ntxn_commit, ntxn_prep; 
+	u_int32_t nckp;		/* The number of checkpoint log records. */
+	/* 
+	 * Target database file unique id. Set if only verify log records 
+	 * of a database. 
+	 */
+	u_int8_t target_dbid[DB_FILE_ID_LEN];	
+	u_int32_t non_txnup_cnt;/* Number of non-txnal log records. */
+	u_int32_t unknown_logrec_cnt;/* Number of unknown log record. */
+	u_int32_t external_logrec_cnt;/* Number of external log record. */
+	/* 
+	 * (Log type, number of record) map. typeids are continuous 
+	 * integers, 256 is a big enough number. 
+	 */
+	u_int32_t lrtypes[256];	
+	u_int32_t aborted_txnid;/* The last aborted txnid. */
+	DB_LSN aborted_txnlsn; /* Last aborted txn's last log. */
+	DB_LSN valid_lsn; /* When reach this log,unset DB_LOG_VERIFY_PARTIAL. */
+	char *logtype_names[256];/* The type name string of each type of log.*/
+	const DB_LOG_VERIFY_CONFIG *lv_config;
+	DB_THREAD_INFO *ip;
+	u_int32_t flags;	/* The result of the verification. */
+};
+
+/* Transaction information. */
+struct __txn_verify_info {
+#define TXN_VERIFY_INFO_FIXSIZE (4 * sizeof(DB_LSN) + 9 * sizeof(u_int32_t))
+#define TXN_VERIFY_INFO_TOTSIZE(s)					\
+	(TXN_VERIFY_INFO_FIXSIZE + (s).num_recycle * sizeof(DB_LSN) + 	\
+	__lv_dbt_arrsz((s).fileups, (s).filenum) + 			\
+	sizeof(int32_t) * (s).filenum)
+
+	u_int32_t txnid; 	/* The key, also stored in data here. */
+	u_int32_t ptxnid; 	/* The parent txn id. */
+	
+	DB_LSN first_lsn;	/* Lsn of the first log record of this txn. */
+	DB_LSN last_lsn; 	/* Last lsn of the txn. */
+	DB_LSN prep_lsn; 	/* txn_prepare's lsn.*/
+	DB_LSN cur_lsn;		/* The lsn of the latest db op of this txn. */
+
+	u_int32_t num_recycle; 	/* The number of recycle lsns. */
+	u_int32_t filenum; 	/* The number of files updated. */
+
+#define TXN_STAT_ACTIVE 0
+#define TXN_STAT_ABORT 1
+#define TXN_STAT_COMMIT 2
+#define TXN_STAT_PREPARE 3
+	u_int32_t status;	/* Txn status */
+
+	/* The number of active, abort and commit children. */
+	u_int32_t nchild_active;
+	u_int32_t nchild_abort;
+	u_int32_t nchild_commit;
+
+	u_int32_t flags; /* Copied from the DB_TXN::flags member. */
+
+	DB_LSN *recycle_lsns; 	/* The array of txn_recycle records' lsns. */
+	/* The array of file unique ids of files updated by this txn. */
+	DBT *fileups; 	
+	int32_t *dbregid;/* The array of dbreg file ids updated by this txn. */
+};
+
+/* Database file information. */
+struct __lv_filereg_info {
+#define FILE_REG_INFO_FIXSIZE (sizeof(u_int32_t))
+#define FILE_REG_INFO_TOTSIZE(s) (FILE_REG_INFO_FIXSIZE + (s).fileid.size + \
+	sizeof((s).fileid.size) + sizeof(int32_t) * (s).regcnt 	+ \
+	strlen((s).fname) + 1)
+
+	u_int32_t regcnt;	/* The number of dbregids for this file-uid. */
+	int32_t *dbregids;
+	DBT fileid;		/* The file unique id. */
+	char *fname;		/* Database file name. */
+};
+
+/* Database file dbreg_register information. */
+struct __lv_filelife {
+	int32_t dbregid;	/* The primary key. */
+	DBTYPE dbtype;		/* The database type. */
+	u_int32_t lifetime;	/* DBREG_CHKPNT, DBREG_CLOSE, DBREG_OPEN, DBREG_XCHKPNT, DBREG_XOPEN */
+	db_pgno_t meta_pgno;	/* The meta_pgno; */
+	u_int8_t fileid[DB_FILE_ID_LEN];
+	DB_LSN lsn;		/* The lsn of log updating lifetime. */
+};
+
+/* Checkpoint information. */
+struct __lv_ckp_info {
+	int32_t timestamp;
+	DB_LSN lsn, ckplsn;	/* Lsn member is the primary key. */
+};
+
+/* 
+ * General information from log records which have timestamps. 
+ * We use it to do time range verifications. Such information is 
+ * acquired when backward-playing the logs before verification. 
+ */
+struct __lv_timestamp_info {
+	DB_LSN lsn;		/* The primary key. */
+	int32_t timestamp;	/* The secondary key. */
+
+	/* 
+	 * The log types containing a time stamp, so far only txn_ckp
+	 * and txn_regop types.
+	 */
+	u_int32_t logtype;
+};
+
+/* 
+ * Transaction ranges. Such information is acquired when backward-playing the
+ * logs before verification. Can be used to find aborted txns.
+ */
+struct __lv_txnrange {
+	/* 
+	 * Transaction ID, the primary key. The db storing records of this 
+	 * type should allow dup since txnids maybe reused. 
+	 */
+	u_int32_t txnid;
+
+	/* 
+	 * The parent txn id, ptxnid is the parent of txnid 
+	 * during [begin, end]. 
+	 */
+	u_int32_t ptxnid; 	
+
+	/* 
+	 * The first and last lsn, end is used to sort dup data because it's
+	 * seen prior to begin in a backward playback, and [begin, end] 
+	 * intervals won't overlap. 
+	 */
+	DB_LSN begin, end;
+
+	int32_t when_commit;/* The time of the commit, 0 if aborted. */
+};
+
+
+/* Parameter types for __iterate_txninfo function. */
+struct __add_recycle_params {
+	u_int32_t min, max;/* The recycled txnid range. */
+	/* The array of txn info to update into db. */
+	VRFY_TXN_INFO **ti2u;
+	u_int32_t ti2ui, ti2ul;/* The effective length and array length. */
+	DB_LSN recycle_lsn;
+}; 
+
+struct __ckp_verify_params {
+	DB_LSN lsn, ckp_lsn;
+	ENV *env;
+};
+
+/* Helper macros. */
+#define LOGTYPE_NAME(lvh, type) (lvh->logtype_names[type] == NULL ? \
+	NULL : lvh->logtype_names[type] + 3)
+#define NUMCMP(i1, i2) ((i1) > (i2) ? 1 : ((i1) < (i2) ? -1 : 0))
+
+#define INVAL_DBREGID -1
+
+/* 
+ * During recovery, DBREG_CHKPNT and DBREG_XCHKPNT can be seen as open,
+ * and it's followed by a DBREG_RCLOSE or DBREG_CLOSE. 
+ */
+#define IS_DBREG_OPEN(opcode) (opcode == DBREG_OPEN || opcode == \
+	DBREG_PREOPEN || opcode == DBREG_REOPEN || opcode == DBREG_CHKPNT \
+	|| opcode == DBREG_XCHKPNT || opcode == DBREG_XOPEN || \
+	opcode == DBREG_XREOPEN)
+#define IS_DBREG_CLOSE(opcode) (opcode == DBREG_CLOSE || opcode == DBREG_RCLOSE)
+
+#define IS_LOG_VRFY_SUPPORTED(version) ((version) == DB_LOGVERSION)
+
+#endif /* !_DB_LOG_VERIFY_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/mp.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,694 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef	_DB_MP_H_
+#define	_DB_MP_H_
+
+#include "dbinc/atomic.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+struct __bh;		typedef struct __bh BH;
+struct __bh_frozen_p;	typedef struct __bh_frozen_p BH_FROZEN_PAGE;
+struct __bh_frozen_a;	typedef struct __bh_frozen_a BH_FROZEN_ALLOC;
+struct __db_mpool_hash; typedef struct __db_mpool_hash DB_MPOOL_HASH;
+struct __db_mpool_fstat_int;
+typedef struct __db_mpool_fstat_int DB_MPOOL_FSTAT_INT;
+struct __db_mpreg;	typedef struct __db_mpreg DB_MPREG;
+struct __mpool;		typedef struct __mpool MPOOL;
+
+				/* We require at least 20KB of cache. */
+#define	DB_CACHESIZE_MIN	(20 * 1024)
+
+/*
+ * DB_MPOOLFILE initialization methods cannot be called after open is called,
+ * other methods cannot be called before open is called
+ */
+#define	MPF_ILLEGAL_AFTER_OPEN(dbmfp, name)				\
+	if (F_ISSET(dbmfp, MP_OPEN_CALLED))				\
+		return (__db_mi_open((dbmfp)->env, name, 1));
+#define	MPF_ILLEGAL_BEFORE_OPEN(dbmfp, name)				\
+	if (!F_ISSET(dbmfp, MP_OPEN_CALLED))				\
+		return (__db_mi_open((dbmfp)->env, name, 0));
+
+/*
+ * Cache flush operations, plus modifiers.
+ */
+#define	DB_SYNC_ALLOC		0x0001	/* Flush for allocation. */
+#define	DB_SYNC_CACHE		0x0002	/* Flush entire cache. */
+#define	DB_SYNC_CHECKPOINT	0x0004	/* Checkpoint. */
+#define	DB_SYNC_FILE		0x0008	/* Flush file. */
+#define	DB_SYNC_INTERRUPT_OK	0x0010	/* Allow interrupt and return OK. */
+#define	DB_SYNC_QUEUE_EXTENT	0x0020	/* Flush a queue file with extents. */
+#define	DB_SYNC_SUPPRESS_WRITE	0x0040	/* Ignore max-write configuration. */
+#define	DB_SYNC_TRICKLE		0x0080	/* Trickle sync. */
+
+/*
+ * DB_MPOOL --
+ *	Per-process memory pool structure.
+ */
+struct __db_mpool {
+	/* These fields need to be protected for multi-threaded support. */
+	db_mutex_t mutex;		/* Thread mutex. */
+
+	/*
+	 * DB_MPREG structure for the DB pgin/pgout routines.
+	 *
+	 * Linked list of application-specified pgin/pgout routines.
+	 */
+	DB_MPREG *pg_inout;
+	LIST_HEAD(__db_mpregh, __db_mpreg) dbregq;
+
+					/* List of DB_MPOOLFILE's. */
+	TAILQ_HEAD(__db_mpoolfileh, __db_mpoolfile) dbmfq;
+
+	/*
+	 * The env and reginfo fields are not thread protected, as they are
+	 * initialized during mpool creation, and not modified again.
+	 */
+	ENV	   *env;		/* Enclosing environment. */
+	REGINFO	   *reginfo;		/* Underlying cache regions. */
+};
+
+/*
+ * DB_MPREG --
+ *	DB_MPOOL registry of pgin/pgout functions.
+ */
+struct __db_mpreg {
+	LIST_ENTRY(__db_mpreg) q;	/* Linked list. */
+
+	int32_t ftype;			/* File type. */
+					/* Pgin, pgout routines. */
+	int (*pgin) __P((DB_ENV *, db_pgno_t, void *, DBT *));
+	int (*pgout) __P((DB_ENV *, db_pgno_t, void *, DBT *));
+};
+
+/*
+ * File hashing --
+ *	We hash each file to hash bucket based on its fileid
+ *	or, in the case of in memory files, its name.
+ */
+
+/* Number of file hash buckets, a small prime number */
+#define	MPOOL_FILE_BUCKETS	17
+
+#define	FHASH(id, len)	__ham_func5(NULL, id, (u_int32_t)(len))
+
+#define	FNBUCKET(id, len)						\
+	(FHASH(id, len) % MPOOL_FILE_BUCKETS)
+
+/* Macros to lock/unlock the mpool region as a whole. */
+#define	MPOOL_SYSTEM_LOCK(env)						\
+	MUTEX_LOCK(env, ((MPOOL *)					\
+	    (env)->mp_handle->reginfo[0].primary)->mtx_region)
+#define	MPOOL_SYSTEM_UNLOCK(env)					\
+	MUTEX_UNLOCK(env, ((MPOOL *)					\
+	    (env)->mp_handle->reginfo[0].primary)->mtx_region)
+
+/* Macros to lock/unlock a specific mpool region. */
+#define	MPOOL_REGION_LOCK(env, infop)					\
+	MUTEX_LOCK(env, ((MPOOL *)(infop)->primary)->mtx_region)
+#define	MPOOL_REGION_UNLOCK(env, infop)					\
+	MUTEX_UNLOCK(env, ((MPOOL *)(infop)->primary)->mtx_region)
+
+/*
+ * MPOOL --
+ *	Shared memory pool region.
+ */
+struct __mpool { /* SHARED */
+	/*
+	 * The memory pool can be broken up into individual pieces/files.
+	 * There are two reasons for this: firstly, on Solaris you can allocate
+	 * only a little more than 2GB of memory in a contiguous chunk,
+	 * and I expect to see more systems with similar issues.  Secondly,
+	 * applications can add / remove pieces to dynamically resize the
+	 * cache.
+	 *
+	 * While this structure is duplicated in each piece of the cache,
+	 * the first of these pieces/files describes the entire pool, the
+	 * second only describe a piece of the cache.
+	 */
+	db_mutex_t	mtx_region;	/* Region mutex. */
+	db_mutex_t	mtx_resize;	/* Resizing mutex. */
+
+	/*
+	 * The lsn field and list of underlying MPOOLFILEs are thread protected
+	 * by the region lock.
+	 */
+	DB_LSN	  lsn;			/* Maximum checkpoint LSN. */
+
+	/* Configuration information: protected by the region lock. */
+	u_int32_t max_nreg;		/* Maximum number of regions. */
+	u_int32_t gbytes;		/* Number of gigabytes in cache. */
+	u_int32_t bytes;		/* Number of bytes in cache. */
+	u_int32_t pagesize;		/* Default page size. */
+	db_size_t mp_mmapsize;		/* Maximum file size for mmap. */
+	int32_t mp_maxopenfd;		/* Maximum open file descriptors. */
+	int32_t mp_maxwrite;		/* Maximum buffers to write. */
+	db_timeout_t mp_maxwrite_sleep;	/* Sleep after writing max buffers. */
+
+	/*
+	 * The number of regions and the total number of hash buckets across
+	 * all regions.
+	 * These fields are not protected by a mutex because we assume that we
+	 * can read a 32-bit value atomically.  They are only modified by cache
+	 * resizing which holds the mpool resizing mutex to ensure that
+	 * resizing is single-threaded.  See the comment in mp_resize.c for
+	 * more information.
+	 */
+	u_int32_t nreg;			/* Number of underlying REGIONS. */
+	u_int32_t nbuckets;		/* Total number of hash buckets. */
+
+	/*
+	 * The regid field is protected by the resize mutex.
+	 */
+	roff_t	  regids;		/* Array of underlying REGION Ids. */
+
+	roff_t	  ftab;			/* Hash table of files. */
+
+	/*
+	 * The following fields describe the per-cache portion of the region.
+	 *
+	 * The htab and htab_buckets fields are not thread protected as they
+	 * are initialized during mpool creation, and not modified again.
+	 *
+	 * The last_checked, lru_priority, and lru_generation fields are thread
+	 * protected by the region lock.
+	 */
+	roff_t	  htab;			/* Hash table offset. */
+	u_int32_t htab_buckets;		/* Number of hash table entries. */
+	u_int32_t last_checked;		/* Last bucket checked for free. */
+	u_int32_t lru_priority;		/* Priority counter for buffer LRU. */
+	u_int32_t lru_generation;	/* Allocation race condition detector. */
+	u_int32_t htab_mutexes;		/* Number of hash mutexes per region. */
+
+	 /*
+	  * The pages field keeps track of the number of pages in the cache
+	  * and is protected by the region lock.  It is accessed for reading
+	  * without the lock to return statistics.
+	  */
+	u_int32_t pages;		/* Number of pages in the cache. */
+
+	/*
+	 * The stat fields are not thread protected, and cannot be trusted.
+	 */
+	DB_MPOOL_STAT stat;		/* Per-cache mpool statistics. */
+
+	/*
+	 * We track page puts so that we can decide when allocation is never
+	 * going to succeed.  We don't lock the field, all we care about is
+	 * if it changes.
+	 */
+	u_int32_t  put_counter;		/* Count of page put calls. */
+
+	/*
+	 * Cache flush operations take a long time...
+	 *
+	 * Some cache flush operations want to ignore the app's configured
+	 * max-write parameters (they are trying to quickly shut down an
+	 * environment, for example).  We can't specify that as an argument
+	 * to the cache region functions, because we may decide to ignore
+	 * the max-write configuration after the cache operation has begun.
+	 * If the variable suppress_maxwrite is set, ignore the application
+	 * max-write config.
+	 *
+	 * We may want to interrupt cache flush operations in high-availability
+	 * configurations.
+	 */
+#define	DB_MEMP_SUPPRESS_WRITE	0x01
+#define	DB_MEMP_SYNC_INTERRUPT	0x02
+	u_int32_t config_flags;
+
+	/* Free frozen buffer headers, protected by the region lock. */
+	SH_TAILQ_HEAD(__free_frozen) free_frozen;
+
+	/* Allocated blocks of frozen buffer headers. */
+	SH_TAILQ_HEAD(__alloc_frozen) alloc_frozen;
+};
+
+/*
+ * NREGION --
+ *	Select a cache region given the bucket number.
+ */
+#define	NREGION(mp, bucket)						\
+	((bucket) / (mp)->htab_buckets)
+
+/*
+ * MP_HASH --
+ *	 We make the assumption that early pages of the file are more likely
+ *	 to be retrieved than the later pages, which means the top bits will
+ *	 be more interesting for hashing as they're less likely to collide.
+ *	 That said, as 512 8K pages represents a 4MB file, so only reasonably
+ *	 large files will have page numbers with any other than the bottom 9
+ *	 bits set.  We XOR in the MPOOL offset of the MPOOLFILE that backs the
+ *	 page, since that should also be unique for the page.  We don't want
+ *	 to do anything very fancy -- speed is more important to us than using
+ *	 good hashing.
+ *
+ *	 Since moving to a dynamic hash, which boils down to using some of the
+ *	 least significant bits of the hash value, we no longer want to use a
+ *	 simple shift here, because it's likely with a bit shift that mf_offset
+ *	 will be ignored, and pages from different files end up in the same
+ *	 hash bucket.  Use a nearby prime instead.
+ */
+#define	MP_HASH(mf_offset, pgno)					\
+	((((pgno) << 8) ^ (pgno)) ^ (((u_int32_t) mf_offset) * 509))
+
+/*
+ * Inline the calculation of the mask, since we can't reliably store the mask
+ * with the number of buckets in the region.
+ *
+ * This is equivalent to:
+ *     mask = (1 << __db_log2(nbuckets)) - 1;
+ */
+#define	MP_MASK(nbuckets, mask) do {					\
+	for (mask = 1; mask < (nbuckets); mask = (mask << 1) | 1)	\
+		;							\
+} while (0)
+
+#define	MP_HASH_BUCKET(hash, nbuckets, mask, bucket) do {		\
+	(bucket) = (hash) & (mask);					\
+	if ((bucket) >= (nbuckets))					\
+		(bucket) &= ((mask) >> 1);				\
+} while (0)
+
+#define	MP_BUCKET(mf_offset, pgno, nbuckets, bucket) do {		\
+	u_int32_t __mask;						\
+	MP_MASK(nbuckets, __mask);					\
+	MP_HASH_BUCKET(MP_HASH(mf_offset, pgno), nbuckets,		\
+	    __mask, bucket);						\
+} while (0)
+
+/*
+ * MP_GET_REGION --
+ *	Select the region for a given page.
+ */
+#define	MP_GET_REGION(dbmfp, pgno, infopp, ret) do {			\
+	DB_MPOOL *__t_dbmp;						\
+	MPOOL *__t_mp;							\
+									\
+	__t_dbmp = dbmfp->env->mp_handle;				\
+	__t_mp = __t_dbmp->reginfo[0].primary;				\
+	if (__t_mp->max_nreg == 1) {					\
+		*(infopp) = &__t_dbmp->reginfo[0];			\
+	} else								\
+		ret = __memp_get_bucket((dbmfp)->env,			\
+		    (dbmfp)->mfp, (pgno), (infopp), NULL, NULL);	\
+} while (0)
+
+/*
+ * MP_GET_BUCKET --
+ *	Select and lock the bucket for a given page.
+ */
+#define	MP_GET_BUCKET(env, mfp, pgno, infopp, hp, bucket, ret) do {	\
+	DB_MPOOL *__t_dbmp;						\
+	MPOOL *__t_mp;							\
+	roff_t __t_mf_offset;						\
+									\
+	__t_dbmp = (env)->mp_handle;					\
+	__t_mp = __t_dbmp->reginfo[0].primary;				\
+	if (__t_mp->max_nreg == 1) {					\
+		*(infopp) = &__t_dbmp->reginfo[0];			\
+		__t_mf_offset = R_OFFSET(*(infopp), (mfp));		\
+		MP_BUCKET(__t_mf_offset,				\
+		    (pgno), __t_mp->nbuckets, bucket);		\
+		(hp) = R_ADDR(*(infopp), __t_mp->htab);			\
+		(hp) = &(hp)[bucket];				\
+		MUTEX_READLOCK(env, (hp)->mtx_hash);			\
+		ret = 0;						\
+	} else								\
+		ret = __memp_get_bucket((env),				\
+		    (mfp), (pgno), (infopp), &(hp), &(bucket));		\
+} while (0)
+
+struct __db_mpool_hash {
+	db_mutex_t	mtx_hash;	/* Per-bucket mutex. */
+
+	DB_HASHTAB	hash_bucket;	/* Head of bucket. */
+
+	db_atomic_t	hash_page_dirty;/* Count of dirty pages. */
+
+#ifndef __TEST_DB_NO_STATISTICS
+	u_int32_t	hash_io_wait;	/* Count of I/O waits. */
+	u_int32_t	hash_frozen;	/* Count of frozen buffers. */
+	u_int32_t	hash_thawed;	/* Count of thawed buffers. */
+	u_int32_t	hash_frozen_freed;/* Count of freed frozen buffers. */
+#endif
+
+	DB_LSN		old_reader;	/* Oldest snapshot reader (cached). */
+
+	u_int32_t	flags;
+};
+
+/*
+ * Mpool file statistics structure for use in shared memory.
+ * This structure must contain the same fields as the __db_mpool_fstat struct
+ * except for any pointer fields that are filled in only when the struct is
+ * being populated for output through the API.
+ */
+struct __db_mpool_fstat_int { /* SHARED */
+	u_int32_t st_pagesize;		/* Page size. */
+#ifndef __TEST_DB_NO_STATISTICS
+	u_int32_t st_map;		/* Pages from mapped files. */
+	uintmax_t st_cache_hit;	/* Pages found in the cache. */
+	uintmax_t st_cache_miss;	/* Pages not found in the cache. */
+	uintmax_t st_page_create;	/* Pages created in the cache. */
+	uintmax_t st_page_in;		/* Pages read in. */
+	uintmax_t st_page_out;		/* Pages written out. */
+	uintmax_t st_backup_spins;	/* Number of spins by a backup. */
+#endif
+};
+
+/*
+ * The base mpool priority is 1/4th of the name space, or just under 2^30. When
+ * the LRU priority counter is about to wrap (within a 128-entry 'red zone'
+ * area) we adjust everybody down so that no one is larger than the new LRU
+ * priority.
+ */
+#define	MPOOL_LRU_MAX		UINT32_MAX
+#define	MPOOL_LRU_REDZONE	(MPOOL_LRU_MAX - 128)
+#define	MPOOL_LRU_BASE		(MPOOL_LRU_MAX / 4)
+#define	MPOOL_LRU_DECREMENT	(MPOOL_LRU_MAX - MPOOL_LRU_BASE)
+
+/*
+ * Mpool priorities from low to high.  Defined in terms of fractions of the
+ * buffers in the pool.
+ */
+#define	MPOOL_PRI_VERY_LOW	-1	/* Dead duck.  Check and set to 0. */
+#define	MPOOL_PRI_LOW		-2	/* Low. */
+#define	MPOOL_PRI_DEFAULT	0	/* No adjustment -- special case.*/
+#define	MPOOL_PRI_HIGH		10	/* With the dirty buffers. */
+#define	MPOOL_PRI_DIRTY		10	/* Dirty gets a 10% boost. */
+#define	MPOOL_PRI_VERY_HIGH	1	/* Add number of buffers in pool. */
+
+/*
+ * MPOOLFILE --
+ *	Shared DB_MPOOLFILE information.
+ */
+struct __mpoolfile { /* SHARED */
+	db_mutex_t mutex;		/* MPOOLFILE mutex. */
+
+#ifndef HAVE_ATOMICFILEREAD
+	/* Information to synchronize backups. */
+	u_int32_t   backup_in_progress;	/* Backup running. */
+	pid_t       pid;		/* Process doing backup. */
+	db_threadid_t tid;		/* Thread doing backup. */
+	db_atomic_t writers;		/* Number of current writers. */
+	db_mutex_t  mtx_write;		/* block writers while updating.*/
+	db_pgno_t   low_pgno, high_pgno;/* Low and high backup range.*/
+#endif
+	
+	/* Protected by MPOOLFILE mutex. */
+	u_int32_t revision;		/* Bumped on any movement subdbs. */
+	u_int32_t mpf_cnt;		/* Ref count: DB_MPOOLFILEs. */
+	u_int32_t neutral_cnt;		/* Ref count: refs that don't care about
+					 * MVCC or DURABLE.  That is, read-only
+					 * or write behind references.
+					 */
+	u_int32_t block_cnt;		/* Ref count: blocks in cache. */
+	db_pgno_t last_pgno;		/* Last page in the file. */
+	db_pgno_t last_flushed_pgno;	/* Last page flushed to disk. */
+	db_pgno_t orig_last_pgno;	/* Original last page in the file. */
+	db_pgno_t maxpgno;		/* Maximum page number. */
+	u_int8_t excl_lockout;		/* Internal exclusive db lockout. */
+
+	roff_t	  path_off;		/* File name location. */
+
+	/* Protected by hash bucket mutex. */
+	SH_TAILQ_ENTRY q;		/* List of MPOOLFILEs */
+
+	/*
+	 * The following are used for file compaction processing.
+	 * They are only used when a thread is in the process
+	 * of trying to move free pages to the end of the file.
+	 * Other threads may look here when freeing a page.
+	 * Protected by a lock on the metapage.
+	 */
+	u_int32_t free_ref;		/* Refcount to freelist. */
+	u_int32_t free_cnt;		/* Count of free pages. */
+	db_size_t free_size;		/* Allocated size of free list. */
+	roff_t	  free_list;		/* Offset to free list. */
+
+	/*
+	 * We normally don't lock the deadfile field when we read it since we
+	 * only care if the field is zero or non-zero.  We do lock on read when
+	 * searching for a matching MPOOLFILE -- see that code for more detail.
+	 */
+	int32_t	  deadfile;		/* Dirty pages can be discarded. */
+
+	u_int32_t bucket;		/* hash bucket for this file. */
+
+	/*
+	 * None of the following fields are thread protected.
+	 *
+	 * There are potential races with the ftype field because it's read
+	 * without holding a lock.  However, it has to be set before adding
+	 * any buffers to the cache that depend on it being set, so there
+	 * would need to be incorrect operation ordering to have a problem.
+	 */
+	int32_t	  ftype;		/* File type. */
+
+	/*
+	 * There are potential races with the priority field because it's read
+	 * without holding a lock.  However, a collision is unlikely and if it
+	 * happens is of little consequence.
+	 */
+	int32_t   priority;		/* Priority when unpinning buffer. */
+
+	/*
+	 * There are potential races with the file_written field (many threads
+	 * may be writing blocks at the same time), and with no_backing_file
+	 * and unlink_on_close fields, as they may be set while other threads
+	 * are reading them.  However, we only care if the field value is zero
+	 * or non-zero, so don't lock the memory.
+	 *
+	 * !!!
+	 * Theoretically, a 64-bit architecture could put two of these fields
+	 * in a single memory operation and we could race.  I have never seen
+	 * an architecture where that's a problem, and I believe Java requires
+	 * that to never be the case.
+	 *
+	 * File_written is set whenever a buffer is marked dirty in the cache.
+	 * It can be cleared in some cases, after all dirty buffers have been
+	 * written AND the file has been flushed to disk.
+	 */
+	int32_t	  file_written;		/* File was written. */
+	int32_t	  no_backing_file;	/* Never open a backing file. */
+	int32_t	  unlink_on_close;	/* Unlink file on last close. */
+	db_atomic_t	  multiversion;	/* Number of DB_MULTIVERSION handles. */
+
+	/*
+	 * We do not protect the statistics in "stat" because of the cost of
+	 * the mutex in the get/put routines.  There is a chance that a count
+	 * will get lost.
+	 */
+	DB_MPOOL_FSTAT_INT stat;	/* Per-file mpool statistics. */
+
+	/*
+	 * The remaining fields are initialized at open and never subsequently
+	 * modified.
+	 */
+	int32_t	  lsn_off;		/* Page's LSN offset. */
+	u_int32_t clear_len;		/* Bytes to clear on page create. */
+
+	roff_t	  fileid_off;		/* File ID string location. */
+
+	u_int32_t pagesize;		/* Underlying pagesize. */
+	roff_t	  pgcookie_len;		/* Pgin/pgout cookie length. */
+	roff_t	  pgcookie_off;		/* Pgin/pgout cookie location. */
+
+	/*
+	 * The flags are initialized at open and never subsequently modified.
+	 */
+#define	MP_CAN_MMAP		0x001	/* If the file can be mmap'd. */
+#define	MP_DATABASE_LOCKING	0x002	/* Lock in exclusive mode. */
+#define	MP_DIRECT		0x004	/* No OS buffering. */
+#define	MP_DURABLE_UNKNOWN	0x008	/* We don't care about durability. */
+#define	MP_EXTENT		0x010	/* Extent file. */
+#define	MP_FAKE_DEADFILE	0x020	/* Deadfile field: fake flag. */
+#define	MP_FAKE_FILEWRITTEN	0x040	/* File_written field: fake flag. */
+#define	MP_FAKE_NB		0x080	/* No_backing_file field: fake flag. */
+#define	MP_FAKE_UOC		0x100	/* Unlink_on_close field: fake flag. */
+#define	MP_NOT_DURABLE		0x200	/* File is not durable. */
+#define	MP_TEMP			0x400	/* Backing file is a temporary. */
+	u_int32_t  flags;
+
+	db_pgno_t  fe_watermark;	/* File extension watermark. */
+	u_int32_t  fe_txnid;		/* Transaction that set watermark. */
+	u_int32_t  fe_nlws;		/* Number of log writes suppressed. */
+};
+
+/*
+ * Flags to __memp_bh_free.
+ */
+#define	BH_FREE_FREEMEM		0x01
+#define	BH_FREE_REUSE		0x02
+#define	BH_FREE_UNLOCKED	0x04
+
+/*
+ * BH --
+ *	Buffer header.
+ */
+struct __bh { /* SHARED */
+	db_mutex_t	mtx_buf;	/* Shared/Exclusive mutex */
+	db_atomic_t	ref;		/* Reference count. */
+#define	BH_REFCOUNT(bhp)	atomic_read(&(bhp)->ref)
+
+#define	BH_CALLPGIN	0x001		/* Convert the page before use. */
+#define	BH_DIRTY	0x002		/* Page is modified. */
+#define	BH_DIRTY_CREATE	0x004		/* Page is modified. */
+#define	BH_DISCARD	0x008		/* Page is useless. */
+#define	BH_EXCLUSIVE	0x010		/* Exclusive access acquired. */
+#define	BH_FREED	0x020		/* Page was freed. */
+#define	BH_FROZEN	0x040		/* Frozen buffer: allocate & re-read. */
+#define	BH_TRASH	0x080		/* Page is garbage. */
+#define	BH_THAWED	0x100		/* Page was thawed. */
+	u_int16_t	flags;
+
+	u_int32_t	priority;	/* Priority. */
+	SH_TAILQ_ENTRY	hq;		/* MPOOL hash bucket queue. */
+
+	db_pgno_t	pgno;		/* Underlying MPOOLFILE page number. */
+	roff_t		mf_offset;	/* Associated MPOOLFILE offset. */
+	u_int32_t	bucket;		/* Hash bucket containing header. */
+	int		region;		/* Region containing header. */
+
+	roff_t		td_off;		/* MVCC: creating TXN_DETAIL offset. */
+	SH_CHAIN_ENTRY	vc;		/* MVCC: version chain. */
+#ifdef DIAG_MVCC
+	u_int16_t	align_off;	/* Alignment offset for diagnostics.*/
+#endif
+
+	/*
+	 * !!!
+	 * This array must be at least size_t aligned -- the DB access methods
+	 * put PAGE and other structures into it, and then access them directly.
+	 * (We guarantee size_t alignment to applications in the documentation,
+	 * too.)
+	 */
+	DB_ALIGN8	u_int8_t buf[1];	/* Variable length data. */
+};
+
+/*
+ * BH_FROZEN_PAGE --
+ *	Data used to find a frozen buffer header.
+ */
+struct __bh_frozen_p {
+	BH header;
+	db_pgno_t	spgno;		/* Page number in freezer file. */
+};
+
+/*
+ * BH_FROZEN_ALLOC --
+ *	Frozen buffer headers are allocated a page at a time in general.  This
+ *	structure is allocated at the beginning of the page so that the
+ *	allocation chunks can be tracked and freed (for private environments).
+ */
+struct __bh_frozen_a {
+	SH_TAILQ_ENTRY links;
+};
+
+#define	MULTIVERSION(dbp)	atomic_read(&(dbp)->mpf->mfp->multiversion)
+
+#define	PAGE_TO_BH(p)	(BH *)((u_int8_t *)(p) - SSZA(BH, buf))
+#define	IS_DIRTY(p)							\
+    (F_ISSET(PAGE_TO_BH(p), BH_DIRTY|BH_EXCLUSIVE) == (BH_DIRTY|BH_EXCLUSIVE))
+
+#define	BH_OWNER(env, bhp)		((TXN_DETAIL *) NULL)
+
+#define	BH_OWNED_BY(env, bhp, txn)	FALSE
+
+#define	VISIBLE_LSN(env, bhp)						\
+    (&BH_OWNER(env, bhp)->visible_lsn)
+
+/*
+ * Make a copy of the buffer's visible LSN, one field at a time.  We rely on the
+ * 32-bit operations being atomic.  The visible_lsn starts at MAX_LSN and is
+ * set during commit or abort to the current LSN.
+ *
+ * If we race with a commit / abort, we may see either the file or the offset
+ * still at UINT32_MAX, so vlsn is guaranteed to be in the future.  That's OK,
+ * since we had to take the log region lock to allocate the read LSN so we were
+ * never going to see this buffer anyway.
+ */
+/* Without transactions -- and hence MVCC -- buffers are always visible. */
+#define	BH_VISIBLE(env, bhp, read_lsnp, vlsn)	TRUE
+
+#define	BH_OBSOLETE(bhp, old_lsn, vlsn)		FALSE
+
+#define	MVCC_SKIP_CURADJ(dbc, pgno) 		FALSE
+
+#if defined(DIAG_MVCC) && defined(HAVE_MPROTECT)
+#define	VM_PAGESIZE 4096
+#define	MVCC_BHSIZE(mfp, sz) do {					\
+	sz += VM_PAGESIZE + sizeof(BH);					\
+	if (mfp->pagesize < VM_PAGESIZE)				\
+		sz += VM_PAGESIZE - mfp->pagesize;			\
+} while (0)
+
+#define	MVCC_BHALIGN(p) 	NOP_STATEMENT
+
+#define	MVCC_BHUNALIGN(bhp) 	NOP_STATEMENT
+
+#ifdef linux
+#define	MVCC_MPROTECT(buf, sz, mode) do {				\
+	int __ret = mprotect((buf), (sz), (mode));			\
+	DB_ASSERT(env, __ret == 0);					\
+} while (0)
+#else
+#define	MVCC_MPROTECT(buf, sz, mode) do {				\
+	if (!F_ISSET(env, ENV_PRIVATE | ENV_SYSTEM_MEM)) {		\
+		int __ret = mprotect((buf), (sz), (mode));		\
+		DB_ASSERT(env, __ret == 0);				\
+	}								\
+} while (0)
+#endif /* linux */
+
+#else /* defined(DIAG_MVCC) && defined(HAVE_MPROTECT) */
+#define	MVCC_BHSIZE(mfp, sz) do {} while (0)
+#define	MVCC_BHALIGN(p) do {} while (0)
+#define	MVCC_BHUNALIGN(bhp) do {} while (0)
+#define	MVCC_MPROTECT(buf, size, mode) do {} while (0)
+#endif
+
+/*
+ * Flags to __memp_ftruncate.
+ */
+#define	MP_TRUNC_NOCACHE	0x01
+#define	MP_TRUNC_RECOVER	0x02
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/mp_ext.h"
+#endif /* !_DB_MP_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/mutex.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,341 @@
+/*
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_MUTEX_H_
+#define	_DB_MUTEX_H_
+
+#ifdef HAVE_MUTEX_SUPPORT
+/* The inlined trylock calls need access to the details of mutexes. */
+#define	LOAD_ACTUAL_MUTEX_CODE
+#include "dbinc/mutex_int.h"
+
+#ifndef HAVE_SHARED_LATCHES
+ #error "Shared latches are required in DB 4.8 and above"
+#endif
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * By default, spin 50 times per processor if fail to acquire a test-and-set
+ * mutex, we have anecdotal evidence it's a reasonable value.
+ */
+#define	MUTEX_SPINS_PER_PROCESSOR	50
+
+/*
+ * Mutexes are represented by unsigned, 32-bit integral values.  As the
+ * OOB value is 0, mutexes can be initialized by zero-ing out the memory
+ * in which they reside.
+ */
+#define	MUTEX_INVALID	0
+
+/*
+ * We track mutex allocations by ID.
+ */
+#define	MTX_APPLICATION		 1
+#define	MTX_ATOMIC_EMULATION	 2
+#define	MTX_DB_HANDLE		 3
+#define	MTX_ENV_DBLIST		 4
+#define	MTX_ENV_EXCLDBLIST	 5
+#define	MTX_ENV_HANDLE		 6
+#define	MTX_ENV_REGION		 7
+#define	MTX_LOCK_REGION		 8
+#define	MTX_LOGICAL_LOCK	 9
+#define	MTX_LOG_FILENAME	10
+#define	MTX_LOG_FLUSH		11
+#define	MTX_LOG_HANDLE		12
+#define	MTX_LOG_REGION		13
+#define	MTX_MPOOLFILE_HANDLE	14
+#define	MTX_MPOOL_BH		15
+#define	MTX_MPOOL_FH		16
+#define	MTX_MPOOL_FILE_BUCKET	17
+#define	MTX_MPOOL_HANDLE	18
+#define	MTX_MPOOL_HASH_BUCKET	19
+#define	MTX_MPOOL_REGION	20
+#define	MTX_MUTEX_REGION	21
+#define	MTX_MUTEX_TEST		22
+#define	MTX_REP_CHKPT		23
+#define	MTX_REP_DATABASE	24
+#define	MTX_REP_DIAG		25
+#define	MTX_REP_EVENT		26
+#define	MTX_REP_REGION		27
+#define	MTX_REP_START		28
+#define	MTX_REP_WAITER		29
+#define	MTX_REPMGR		30
+#define	MTX_SEQUENCE		31
+#define	MTX_TWISTER		32
+#define	MTX_TCL_EVENTS		33
+#define	MTX_TXN_ACTIVE		34
+#define	MTX_TXN_CHKPT		35
+#define	MTX_TXN_COMMIT		36
+#define	MTX_TXN_MVCC		37
+#define	MTX_TXN_REGION		38
+
+#define	MTX_MAX_ENTRY		38
+
+/* The following macros are defined on some platforms, e.g. QNX. */
+#undef __mutex_init
+#undef __mutex_lock
+#undef __mutex_timedlock
+#undef __mutex_unlock
+#undef __mutex_destroy
+#undef __mutex_trylock
+
+/* Redirect mutex calls to the correct functions. */
+#if !defined(HAVE_MUTEX_HYBRID) && (					\
+    defined(HAVE_MUTEX_PTHREADS) ||					\
+    defined(HAVE_MUTEX_SOLARIS_LWP) ||					\
+    defined(HAVE_MUTEX_UI_THREADS))
+#define	__mutex_init(a, b, c)		__db_pthread_mutex_init(a, b, c)
+#define	__mutex_lock(a, b)		__db_pthread_mutex_lock(a, b, 0)
+#define	__mutex_timedlock(a, b, c)	__db_pthread_mutex_lock(a, b, c)
+#define	__mutex_unlock(a, b)		__db_pthread_mutex_unlock(a, b)
+#define	__mutex_destroy(a, b)		__db_pthread_mutex_destroy(a, b)
+#define	__mutex_trylock(a, b)		__db_pthread_mutex_trylock(a, b)
+/*
+ * These trylock versions do not support DB_ENV_FAILCHK. Callers which loop
+ * checking mutexes which are held by dead processes or threads might spin.
+ * These have ANSI-style definitions because this file can be included by
+ * C++ files, and extern "C" affects linkage only, not argument typing.
+ */
+static inline int __db_pthread_mutex_trylock(ENV *env, db_mutex_t mutex)
+{
+	int ret;
+	DB_MUTEX *mutexp;
+	if (!MUTEX_ON(env) || F_ISSET(env->dbenv, DB_ENV_NOLOCKING))
+		return (0);
+	mutexp = MUTEXP_SET(env, mutex);
+#ifdef HAVE_SHARED_LATCHES
+	if (F_ISSET(mutexp, DB_MUTEX_SHARED))
+		ret = pthread_rwlock_trywrlock(&mutexp->u.rwlock);
+	else
+#endif
+		ret = pthread_mutex_trylock(&mutexp->u.m.mutex);
+	if (ret == EBUSY)
+		ret = DB_LOCK_NOTGRANTED;
+	else if (ret == 0) {
+		F_SET(mutexp, DB_MUTEX_LOCKED);
+		env->dbenv->thread_id(env->dbenv, &mutexp->pid, &mutexp->tid);
+		STAT_INC(env,
+		    mutex, set_nowait, mutexp->mutex_set_nowait, mutex);
+	}
+	return (ret);
+}
+#ifdef HAVE_SHARED_LATCHES
+#define	__mutex_rdlock(a, b)		__db_pthread_mutex_readlock(a, b)
+#define	__mutex_tryrdlock(a, b)		__db_pthread_mutex_tryreadlock(a, b)
+static inline int __db_pthread_mutex_tryreadlock(ENV *env, db_mutex_t mutex)
+{
+	int ret;
+	DB_MUTEX *mutexp;
+	if (!MUTEX_ON(env) || F_ISSET(env->dbenv, DB_ENV_NOLOCKING))
+		return (0);
+	mutexp = MUTEXP_SET(env, mutex);
+	if (F_ISSET(mutexp, DB_MUTEX_SHARED))
+		ret = pthread_rwlock_tryrdlock(&mutexp->u.rwlock);
+	else
+		return (EINVAL);
+	if (ret == EBUSY)
+		ret = DB_LOCK_NOTGRANTED;
+#ifdef HAVE_STATISTICS
+	if (ret == 0)
+		STAT_INC(env,
+		    mutex, set_rd_nowait, mutexp->mutex_set_nowait, mutex);
+#endif
+	return (ret);
+}
+#endif
+#elif defined(HAVE_MUTEX_WIN32) || defined(HAVE_MUTEX_WIN32_GCC)
+#define	__mutex_init(a, b, c)		__db_win32_mutex_init(a, b, c)
+#define	__mutex_lock(a, b)		__db_win32_mutex_lock(a, b, 0)
+#define	__mutex_timedlock(a, b, c)	__db_win32_mutex_lock(a, b, c)
+#define	__mutex_trylock(a, b)		__db_win32_mutex_trylock(a, b)
+#define	__mutex_unlock(a, b)		__db_win32_mutex_unlock(a, b)
+#define	__mutex_destroy(a, b)		__db_win32_mutex_destroy(a, b)
+#ifdef HAVE_SHARED_LATCHES
+#define	__mutex_rdlock(a, b)		__db_win32_mutex_readlock(a, b)
+#define	__mutex_tryrdlock(a, b)		__db_win32_mutex_tryreadlock(a, b)
+#endif
+#elif defined(HAVE_MUTEX_FCNTL)
+#define	__mutex_init(a, b, c)		__db_fcntl_mutex_init(a, b, c)
+#define	__mutex_lock(a, b)		__db_fcntl_mutex_lock(a, b, 0)
+#define	__mutex_timedlock(a, b, c)	__db_fcntl_lock(a, b, c)
+#define	__mutex_trylock(a, b)		__db_fcntl_mutex_trylock(a, b)
+#define	__mutex_unlock(a, b)		__db_fcntl_mutex_unlock(a, b)
+#define	__mutex_destroy(a, b)		__db_fcntl_mutex_destroy(a, b)
+#else
+#define	__mutex_init(a, b, c)		__db_tas_mutex_init(a, b, c)
+#define	__mutex_lock(a, b)		__db_tas_mutex_lock(a, b, 0)
+#define	__mutex_timedlock(a, b, c)	__db_tas_mutex_lock(a, b, c)
+#define	__mutex_trylock(a, b)		__db_tas_mutex_trylock(a, b)
+#define	__mutex_unlock(a, b)		__db_tas_mutex_unlock(a, b)
+#define	__mutex_destroy(a, b)		__db_tas_mutex_destroy(a, b)
+#if defined(HAVE_SHARED_LATCHES)
+#define	__mutex_rdlock(a, b)		__db_tas_mutex_readlock(a, b)
+#define	__mutex_tryrdlock(a,b)		__db_tas_mutex_tryreadlock(a, b)
+#endif
+#endif
+
+/*
+ * When there is no method to get a shared latch, fall back to
+ * implementing __mutex_rdlock() as getting an exclusive one.
+ * This occurs either when !HAVE_SHARED_LATCHES or HAVE_MUTEX_FCNTL.
+ */
+#ifndef __mutex_rdlock
+#define	__mutex_rdlock(a, b)		__mutex_lock(a, b)
+#endif
+#ifndef __mutex_tryrdlock
+#define	__mutex_tryrdlock(a, b)		__mutex_trylock(a, b)
+#endif
+
+/*
+ * Lock/unlock a mutex.  If the mutex was never required, the thread of
+ * control can proceed without it.
+ *
+ * We never fail to acquire or release a mutex without panicing.  Simplify
+ * the macros to always return a panic value rather than saving the actual
+ * return value of the mutex routine.
+ */
+#ifdef HAVE_MUTEX_SUPPORT
+#define	MUTEX_LOCK(env, mutex) do {					\
+	if ((mutex) != MUTEX_INVALID &&					\
+	    __mutex_lock(env, mutex) != 0)				\
+		return (DB_RUNRECOVERY);				\
+} while (0)
+
+/*
+ * Always check the return value of MUTEX_TRYLOCK()!  Expect 0 on success,
+ * or DB_LOCK_NOTGRANTED, or possibly DB_RUNRECOVERY for failchk.
+ */
+#define	MUTEX_TRYLOCK(env, mutex)					\
+	(((mutex) == MUTEX_INVALID) ? 0 : __mutex_trylock(env, mutex))
+
+/*
+ * Acquire a DB_MUTEX_SHARED "mutex" in shared mode.
+ */
+#define	MUTEX_READLOCK(env, mutex) do {					\
+	if ((mutex) != MUTEX_INVALID &&					\
+	    __mutex_rdlock(env, mutex) != 0)				\
+		return (DB_RUNRECOVERY);				\
+} while (0)
+#define	MUTEX_TRY_READLOCK(env, mutex)					\
+	((mutex) != MUTEX_INVALID ? __mutex_tryrdlock(env, mutex) : 0)
+
+#define	MUTEX_UNLOCK(env, mutex) do {					\
+	if ((mutex) != MUTEX_INVALID &&					\
+	    __mutex_unlock(env, mutex) != 0)				\
+		return (DB_RUNRECOVERY);				\
+} while (0)
+
+#define	MUTEX_WAIT(env, mutex, duration) do {			      \
+	int __ret;						      \
+	if ((mutex) != MUTEX_INVALID &&				      \
+	    (__ret = __mutex_timedlock(env, mutex, duration)) != 0 && \
+	    __ret != DB_TIMEOUT)				      \
+		return (DB_RUNRECOVERY);			      \
+} while (0)
+
+/*
+ * Check that a particular mutex is exclusively held at least by someone, not
+ * necessarily the current thread.
+ */
+#define	MUTEX_IS_OWNED(env, mutex)					\
+	(mutex == MUTEX_INVALID || !MUTEX_ON(env) ||			\
+	F_ISSET(env->dbenv, DB_ENV_NOLOCKING) ||			\
+	F_ISSET(MUTEXP_SET(env, mutex), DB_MUTEX_LOCKED))
+#else
+/*
+ * There are calls to lock/unlock mutexes outside of #ifdef's -- replace
+ * the call with something the compiler can discard, but which will make
+ * if-then-else blocks work correctly.
+ */
+#define	MUTEX_LOCK(env, mutex)		(mutex) = (mutex)
+#define	MUTEX_TRYLOCK(env, mutex)	(mutex) = (mutex)
+#define	MUTEX_READLOCK(env, mutex)	(mutex) = (mutex)
+#define	MUTEX_TRY_READLOCK(env, mutex)	(mutex) = (mutex)
+#define	MUTEX_UNLOCK(env, mutex)	(mutex) = (mutex)
+#define	MUTEX_REQUIRED(env, mutex)	(mutex) = (mutex)
+#define	MUTEX_REQUIRED_READ(env, mutex)	(mutex) = (mutex)
+#define	MUTEX_WAIT(env, mutex, duration) (mutex) = (mutex)
+/*
+ * Every MUTEX_IS_OWNED() caller expects to own it. When there is no mutex
+ * support, act as if we have ownership.
+ */
+#define	MUTEX_IS_OWNED(env, mutex)	1
+#endif
+
+/*
+ * Berkeley DB ports may require single-threading at places in the code.
+ */
+#ifdef HAVE_MUTEX_VXWORKS
+#include "taskLib.h"
+/*
+ * Use the taskLock() mutex to eliminate a race where two tasks are
+ * trying to initialize the global lock at the same time.
+ */
+#define	DB_BEGIN_SINGLE_THREAD do {					\
+	if (DB_GLOBAL(db_global_init))					\
+		(void)semTake(DB_GLOBAL(db_global_lock), WAIT_FOREVER);	\
+	else {								\
+		taskLock();						\
+		if (DB_GLOBAL(db_global_init)) {			\
+			taskUnlock();					\
+			(void)semTake(DB_GLOBAL(db_global_lock),	\
+			    WAIT_FOREVER);				\
+			continue;					\
+		}							\
+		DB_GLOBAL(db_global_lock) =				\
+		    semBCreate(SEM_Q_FIFO, SEM_EMPTY);			\
+		if (DB_GLOBAL(db_global_lock) != NULL)			\
+			DB_GLOBAL(db_global_init) = 1;			\
+		taskUnlock();						\
+	}								\
+} while (DB_GLOBAL(db_global_init) == 0)
+#define	DB_END_SINGLE_THREAD	(void)semGive(DB_GLOBAL(db_global_lock))
+#endif
+
+/*
+ * Single-threading defaults to a no-op.
+ */
+#ifndef DB_BEGIN_SINGLE_THREAD
+#define	DB_BEGIN_SINGLE_THREAD
+#endif
+#ifndef DB_END_SINGLE_THREAD
+#define	DB_END_SINGLE_THREAD
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/mutex_ext.h"
+#endif /* !_DB_MUTEX_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/mutex_int.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1079 @@
+/*
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_MUTEX_INT_H_
+#define	_DB_MUTEX_INT_H_
+
+#include "dbinc/atomic.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Mutexes and Shared Latches
+ *
+ * Mutexes may be test-and-set (spinning & yielding when busy),
+ * native versions (pthreads, WaitForSingleObject)
+ * or a hybrid which has the lower no-contention overhead of test-and-set
+ * mutexes, using operating system calls only to block and wakeup.
+ *
+ * Hybrid exclusive-only mutexes include a 'tas' field.
+ * Hybrid DB_MUTEX_SHARED latches also include a 'shared' field.
+ */
+
+/*********************************************************************
+ * POSIX.1 pthreads interface.
+ *********************************************************************/
+#if defined(HAVE_MUTEX_PTHREADS)
+/*
+ * Pthreads-based mutexes (exclusive-only) and latches (possibly shared)
+ * have the same MUTEX_FIELDS union. Different parts of the union are used
+ * depending on:
+ *    -	whether HAVE_SHARED_LATCHES is defined, and
+ *    - if HAVE_SHARED_LATCHES, whether this particular instance of a mutex
+ *	is a shared mutexDB_MUTEX_SHARED.
+ *
+ * The rwlock part of the union is used *only* for non-hybrid shared latches;
+ * in all other cases the mutex and cond fields are the only ones used.
+ *
+ *  configuration &	Who uses the field
+ *  mutex
+ *			mutex	cond	rwlock	tas
+ * Native mutex		y	y
+ * Hybrid mutexes	y	y		y
+ * Native sharedlatches			y
+ * Hybrid sharedlatches	y	y		y
+ *
+ * They all have a condition variable which is used only for
+ * DB_MUTEX_SELF_BLOCK waits.
+ *
+ * There can be no self-blocking shared latches: the pthread_cond_wait() would
+ * require getting a pthread_mutex_t, also it would not make sense.
+ */
+#define	MUTEX_FIELDS							\
+	union {								\
+		struct {						\
+		    pthread_mutex_t mutex;	/* Mutex */		\
+		    pthread_cond_t  cond;	/* Condition variable */ \
+		} m;							\
+		pthread_rwlock_t rwlock;	/* Read/write lock */	\
+	} u;
+
+#if defined(HAVE_SHARED_LATCHES) && !defined(HAVE_MUTEX_HYBRID)
+#define	RET_SET_PTHREAD_LOCK(mutexp, ret) do {				\
+	if (F_ISSET(mutexp, DB_MUTEX_SHARED))				\
+		RET_SET((pthread_rwlock_wrlock(&(mutexp)->u.rwlock)),	\
+		    ret);						\
+	else								\
+		RET_SET((pthread_mutex_lock(&(mutexp)->u.m.mutex)), ret); \
+} while (0)
+#define	RET_SET_PTHREAD_TRYLOCK(mutexp, ret) do {			\
+	if (F_ISSET(mutexp, DB_MUTEX_SHARED))				\
+		RET_SET((pthread_rwlock_trywrlock(&(mutexp)->u.rwlock)), \
+		    ret);						\
+	else								\
+		RET_SET((pthread_mutex_trylock(&(mutexp)->u.m.mutex)),	\
+		    ret);						\
+} while (0)
+#else
+#define	RET_SET_PTHREAD_LOCK(mutexp, ret)				\
+		RET_SET(pthread_mutex_lock(&(mutexp)->u.m.mutex), ret);
+#define	RET_SET_PTHREAD_TRYLOCK(mutexp, ret)				\
+		RET_SET(pthread_mutex_trylock(&(mutexp)->u.m.mutex), ret);
+#endif
+#endif
+
+#ifdef HAVE_MUTEX_UI_THREADS
+#include <thread.h>
+#endif
+
+/*********************************************************************
+ * Solaris lwp threads interface.
+ *
+ * !!!
+ * We use LWP mutexes on Solaris instead of UI or POSIX mutexes (both of
+ * which are available), for two reasons.  First, the Solaris C library
+ * includes versions of the both UI and POSIX thread mutex interfaces, but
+ * they are broken in that they don't support inter-process locking, and
+ * there's no way to detect it, e.g., calls to configure the mutexes for
+ * inter-process locking succeed without error.  So, we use LWP mutexes so
+ * that we don't fail in fairly undetectable ways because the application
+ * wasn't linked with the appropriate threads library.  Second, there were
+ * bugs in SunOS 5.7 (Solaris 7) where if an application loaded the C library
+ * before loading the libthread/libpthread threads libraries (e.g., by using
+ * dlopen to load the DB library), the pwrite64 interface would be translated
+ * into a call to pwrite and DB would drop core.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_SOLARIS_LWP
+/*
+ * XXX
+ * Don't change <synch.h> to <sys/lwp.h> -- although lwp.h is listed in the
+ * Solaris manual page as the correct include to use, it causes the Solaris
+ * compiler on SunOS 2.6 to fail.
+ */
+#include <synch.h>
+
+#define	MUTEX_FIELDS							\
+	lwp_mutex_t mutex;		/* Mutex. */			\
+	lwp_cond_t cond;		/* Condition variable. */
+#endif
+
+/*********************************************************************
+ * Solaris/Unixware threads interface.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_UI_THREADS
+#include <thread.h>
+#include <synch.h>
+
+#define	MUTEX_FIELDS							\
+	mutex_t mutex;			/* Mutex. */			\
+	cond_t  cond;			/* Condition variable. */
+#endif
+
+/*********************************************************************
+ * AIX C library functions.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_AIX_CHECK_LOCK
+#include <sys/atomic_op.h>
+typedef int tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+#define	MUTEX_INIT(x)	0
+#define	MUTEX_SET(x)	(!_check_lock(x, 0, 1))
+#define	MUTEX_UNSET(x)	_clear_lock(x, 0)
+#endif
+#endif
+
+/*********************************************************************
+ * Apple/Darwin library functions.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY
+typedef u_int32_t tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+extern int _spin_lock_try(tsl_t *);
+extern void _spin_unlock(tsl_t *);
+#define	MUTEX_SET(tsl)          _spin_lock_try(tsl)
+#define	MUTEX_UNSET(tsl)        _spin_unlock(tsl)
+#define	MUTEX_INIT(tsl)         (MUTEX_UNSET(tsl), 0)
+#endif
+#endif
+
+/*********************************************************************
+ * General C library functions (msemaphore).
+ *
+ * !!!
+ * Check for HPPA as a special case, because it requires unusual alignment,
+ * and doesn't support semaphores in malloc(3) or shmget(2) memory.
+ *
+ * !!!
+ * Do not remove the MSEM_IF_NOWAIT flag.  The problem is that if a single
+ * process makes two msem_lock() calls in a row, the second one returns an
+ * error.  We depend on the fact that we can lock against ourselves in the
+ * locking subsystem, where we set up a mutex so that we can block ourselves.
+ * Tested on OSF1 v4.0.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_HPPA_MSEM_INIT
+#define	MUTEX_ALIGN	16
+#endif
+
+#if defined(HAVE_MUTEX_MSEM_INIT) || defined(HAVE_MUTEX_HPPA_MSEM_INIT)
+#include <sys/mman.h>
+typedef msemaphore tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+#define	MUTEX_INIT(x)	(msem_init(x, MSEM_UNLOCKED) <= (msemaphore *)0)
+#define	MUTEX_SET(x)	(!msem_lock(x, MSEM_IF_NOWAIT))
+#define	MUTEX_UNSET(x)	msem_unlock(x, 0)
+#endif
+#endif
+
+/*********************************************************************
+ * Plan 9 library functions.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_PLAN9
+typedef Lock tsl_t;
+
+#define	MUTEX_INIT(x)	(memset(x, 0, sizeof(Lock)), 0)
+#define	MUTEX_SET(x)	canlock(x)
+#define	MUTEX_UNSET(x)	unlock(x)
+#endif
+
+/*********************************************************************
+ * Reliant UNIX C library functions.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_RELIANTUNIX_INITSPIN
+#include <ulocks.h>
+typedef spinlock_t tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+#define	MUTEX_INIT(x)	(initspin(x, 1), 0)
+#define	MUTEX_SET(x)	(cspinlock(x) == 0)
+#define	MUTEX_UNSET(x)	spinunlock(x)
+#endif
+#endif
+
+/*********************************************************************
+ * General C library functions (POSIX 1003.1 sema_XXX).
+ *
+ * !!!
+ * Never selected by autoconfig in this release (semaphore calls are known
+ * to not work in Solaris 5.5).
+ *********************************************************************/
+#ifdef HAVE_MUTEX_SEMA_INIT
+#include <synch.h>
+typedef sema_t tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+#define	MUTEX_DESTROY(x) sema_destroy(x)
+#define	MUTEX_INIT(x)	 (sema_init(x, 1, USYNC_PROCESS, NULL) != 0)
+#define	MUTEX_SET(x)	 (sema_wait(x) == 0)
+#define	MUTEX_UNSET(x)	 sema_post(x)
+#endif
+#endif
+
+/*********************************************************************
+ * SGI C library functions.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_SGI_INIT_LOCK
+#include <abi_mutex.h>
+typedef abilock_t tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+#define	MUTEX_INIT(x)	(init_lock(x) != 0)
+#define	MUTEX_SET(x)	(!acquire_lock(x))
+#define	MUTEX_UNSET(x)	release_lock(x)
+#endif
+#endif
+
+/*********************************************************************
+ * Solaris C library functions.
+ *
+ * !!!
+ * These are undocumented functions, but they're the only ones that work
+ * correctly as far as we know.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_SOLARIS_LOCK_TRY
+#include <sys/atomic.h>
+#define	MUTEX_MEMBAR(x)	membar_enter()
+#define	MEMBAR_ENTER()	membar_enter()
+#define	MEMBAR_EXIT()	membar_exit()
+#include <sys/machlock.h>
+typedef lock_t tsl_t;
+
+/*
+ * The functions are declared in <sys/machlock.h>, but under #ifdef KERNEL.
+ * Re-declare them here to avoid warnings.
+ */
+extern  int _lock_try(lock_t *);
+extern void _lock_clear(lock_t *);
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+#define	MUTEX_INIT(x)	0
+#define	MUTEX_SET(x)	_lock_try(x)
+#define	MUTEX_UNSET(x)	_lock_clear(x)
+#endif
+#endif
+
+/*********************************************************************
+ * VMS.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_VMS
+#include <sys/mman.h>
+#include <builtins.h>
+typedef volatile unsigned char tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+#ifdef __ALPHA
+#define	MUTEX_SET(tsl)		(!__TESTBITSSI(tsl, 0))
+#else /* __VAX */
+#define	MUTEX_SET(tsl)		(!(int)_BBSSI(0, tsl))
+#endif
+#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)
+#define	MUTEX_INIT(tsl)         (MUTEX_UNSET(tsl), 0)
+#endif
+#endif
+
+/*********************************************************************
+ * VxWorks
+ * Use basic binary semaphores in VxWorks, as we currently do not need
+ * any special features.  We do need the ability to single-thread the
+ * entire system, however, because VxWorks doesn't support the open(2)
+ * flag O_EXCL, the mechanism we normally use to single thread access
+ * when we're first looking for a DB environment.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_VXWORKS
+#include "taskLib.h"
+typedef SEM_ID tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/*
+ * Uses of this MUTEX_SET() need to have a local 'nowait' variable,
+ * which determines whether to return right away when the semaphore
+ * is busy or to wait until it is available.
+ */
+#define	MUTEX_SET(tsl)							\
+	(semTake((*(tsl)), nowait ? NO_WAIT : WAIT_FOREVER) == OK)
+#define	MUTEX_UNSET(tsl)	(semGive((*tsl)))
+#define	MUTEX_INIT(tsl)							\
+	((*(tsl) = semBCreate(SEM_Q_FIFO, SEM_FULL)) == NULL)
+#define	MUTEX_DESTROY(tsl)	semDelete(*tsl)
+#endif
+#endif
+
+/*********************************************************************
+ * Win16
+ *
+ * Win16 spinlocks are simple because we cannot possibly be preempted.
+ *
+ * !!!
+ * We should simplify this by always returning a no-need-to-lock lock
+ * when we initialize the mutex.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_WIN16
+typedef unsigned int tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+#define	MUTEX_INIT(x)		0
+#define	MUTEX_SET(tsl)		(*(tsl) = 1)
+#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)
+#endif
+#endif
+
+/*********************************************************************
+ * Win32 - always a hybrid mutex
+ *********************************************************************/
+#if defined(HAVE_MUTEX_WIN32) || defined(HAVE_MUTEX_WIN32_GCC)
+typedef LONG volatile tsl_t;
+#define	MUTEX_FIELDS							\
+	LONG nwaiters;							\
+	u_int32_t id;	/* ID used for creating events */		\
+
+#if defined(LOAD_ACTUAL_MUTEX_CODE)
+#define	MUTEX_SET(tsl)		(!InterlockedExchange((PLONG)tsl, 1))
+#define	MUTEX_UNSET(tsl)	InterlockedExchange((PLONG)tsl, 0)
+#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)
+
+/*
+ * From Intel's performance tuning documentation (and see SR #6975):
+ * ftp://download.intel.com/design/perftool/cbts/appnotes/sse2/w_spinlock.pdf
+ *
+ * "For this reason, it is highly recommended that you insert the PAUSE
+ * instruction into all spin-wait code immediately. Using the PAUSE
+ * instruction does not affect the correctness of programs on existing
+ * platforms, and it improves performance on Pentium 4 processor platforms."
+ */
+#ifdef HAVE_MUTEX_WIN32
+#if !defined(_WIN64) && !defined(DB_WINCE)
+#define	MUTEX_PAUSE		{__asm{_emit 0xf3}; __asm{_emit 0x90}}
+#endif
+#endif
+#ifdef HAVE_MUTEX_WIN32_GCC
+#define	MUTEX_PAUSE		__asm__ volatile ("rep; nop" : : );
+#endif
+#endif
+#endif
+
+/*********************************************************************
+ * 68K/gcc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_68K_GCC_ASSEMBLY
+typedef unsigned char tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/* gcc/68K: 0 is clear, 1 is set. */
+#define	MUTEX_SET(tsl) ({						\
+	register tsl_t *__l = (tsl);					\
+	int __r;							\
+	    __asm__ volatile("tas  %1; \n				\
+			  seq  %0"					\
+		: "=dm" (__r), "=m" (*__l)				\
+		: "1" (*__l)						\
+		);							\
+	__r & 1;							\
+})
+
+#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)
+#define	MUTEX_INIT(tsl)         (MUTEX_UNSET(tsl), 0)
+#endif
+#endif
+
+/*********************************************************************
+ * ALPHA/gcc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_ALPHA_GCC_ASSEMBLY
+typedef u_int32_t tsl_t;
+
+#define	MUTEX_ALIGN	4
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/*
+ * For gcc/alpha.  Should return 0 if could not acquire the lock, 1 if
+ * lock was acquired properly.
+ */
+static inline int
+MUTEX_SET(tsl_t *tsl) {
+	register tsl_t *__l = tsl;
+	register tsl_t __r;
+	__asm__ volatile(
+		"1:	ldl_l	%0,%2\n"
+		"	blbs	%0,2f\n"
+		"	or	$31,1,%0\n"
+		"	stl_c	%0,%1\n"
+		"	beq	%0,3f\n"
+		"	mb\n"
+		"	br	3f\n"
+		"2:	xor	%0,%0\n"
+		"3:"
+		: "=&r"(__r), "=m"(*__l) : "1"(*__l) : "memory");
+	return __r;
+}
+
+/*
+ * Unset mutex. Judging by Alpha Architecture Handbook, the mb instruction
+ * might be necessary before unlocking
+ */
+static inline int
+MUTEX_UNSET(tsl_t *tsl) {
+	__asm__ volatile("	mb\n");
+	return *tsl = 0;
+}
+
+#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)
+#endif
+#endif
+
+/*********************************************************************
+ * Tru64/cc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_TRU64_CC_ASSEMBLY
+typedef volatile u_int32_t tsl_t;
+
+#define	MUTEX_ALIGN	4
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+#include <alpha/builtins.h>
+#define	MUTEX_SET(tsl)		(__LOCK_LONG_RETRY((tsl), 1) != 0)
+#define	MUTEX_UNSET(tsl)	(__UNLOCK_LONG(tsl))
+
+#define	MUTEX_INIT(tsl)		(MUTEX_UNSET(tsl), 0)
+#endif
+#endif
+
+/*********************************************************************
+ * ARM/gcc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_ARM_GCC_ASSEMBLY
+typedef unsigned char tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/* gcc/arm: 0 is clear, 1 is set. */
+#define	MUTEX_SET(tsl) ({						\
+	int __r;							\
+	__asm__ volatile(						\
+		"swpb	%0, %1, [%2]\n\t"				\
+		"eor	%0, %0, #1\n\t"					\
+	    : "=&r" (__r)						\
+	    : "r" (1), "r" (tsl)					\
+	    );								\
+	__r & 1;							\
+})
+
+#define	MUTEX_UNSET(tsl)	(*(volatile tsl_t *)(tsl) = 0)
+#define	MUTEX_INIT(tsl)         (MUTEX_UNSET(tsl), 0)
+#endif
+#endif
+
+/*********************************************************************
+ * HPPA/gcc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_HPPA_GCC_ASSEMBLY
+typedef u_int32_t tsl_t;
+
+#define	MUTEX_ALIGN	16
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/*
+ * The PA-RISC has a "load and clear" instead of a "test and set" instruction.
+ * The 32-bit word used by that instruction must be 16-byte aligned.  We could
+ * use the "aligned" attribute in GCC but that doesn't work for stack variables.
+ */
+#define	MUTEX_SET(tsl) ({						\
+	register tsl_t *__l = (tsl);					\
+	int __r;							\
+	__asm__ volatile("ldcws 0(%1),%0" : "=r" (__r) : "r" (__l));	\
+	__r & 1;							\
+})
+
+#define	MUTEX_UNSET(tsl)        (*(volatile tsl_t *)(tsl) = -1)
+#define	MUTEX_INIT(tsl)		(MUTEX_UNSET(tsl), 0)
+#endif
+#endif
+
+/*********************************************************************
+ * IA64/gcc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_IA64_GCC_ASSEMBLY
+typedef volatile unsigned char tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/* gcc/ia64: 0 is clear, 1 is set. */
+#define	MUTEX_SET(tsl) ({						\
+	register tsl_t *__l = (tsl);					\
+	long __r;							\
+	__asm__ volatile("xchg1 %0=%1,%2" :				\
+		     "=r"(__r), "+m"(*__l) : "r"(1));			\
+	__r ^ 1;							\
+})
+
+/*
+ * Store through a "volatile" pointer so we get a store with "release"
+ * semantics.
+ */
+#define	MUTEX_UNSET(tsl)	(*(tsl_t *)(tsl) = 0)
+#define	MUTEX_INIT(tsl)         (MUTEX_UNSET(tsl), 0)
+#endif
+#endif
+
+/*********************************************************************
+ * PowerPC/gcc assembly.
+ *********************************************************************/
+#if defined(HAVE_MUTEX_PPC_GCC_ASSEMBLY)
+typedef u_int32_t tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/*
+ * The PowerPC does a sort of pseudo-atomic locking.  You set up a
+ * 'reservation' on a chunk of memory containing a mutex by loading the
+ * mutex value with LWARX.  If the mutex has an 'unlocked' (arbitrary)
+ * value, you then try storing into it with STWCX.  If no other process or
+ * thread broke your 'reservation' by modifying the memory containing the
+ * mutex, then the STCWX succeeds; otherwise it fails and you try to get
+ * a reservation again.
+ *
+ * While mutexes are explicitly 4 bytes, a 'reservation' applies to an
+ * entire cache line, normally 32 bytes, aligned naturally.  If the mutex
+ * lives near data that gets changed a lot, there's a chance that you'll
+ * see more broken reservations than you might otherwise.  The only
+ * situation in which this might be a problem is if one processor is
+ * beating on a variable in the same cache block as the mutex while another
+ * processor tries to acquire the mutex.  That's bad news regardless
+ * because of the way it bashes caches, but if you can't guarantee that a
+ * mutex will reside in a relatively quiescent cache line, you might
+ * consider padding the mutex to force it to live in a cache line by
+ * itself.  No, you aren't guaranteed that cache lines are 32 bytes.  Some
+ * embedded processors use 16-byte cache lines, while some 64-bit
+ * processors use 128-bit cache lines.  But assuming a 32-byte cache line
+ * won't get you into trouble for now.
+ *
+ * If mutex locking is a bottleneck, then you can speed it up by adding a
+ * regular LWZ load before the LWARX load, so that you can test for the
+ * common case of a locked mutex without wasting cycles making a reservation.
+ *
+ * gcc/ppc: 0 is clear, 1 is set.
+ */
+static inline int
+MUTEX_SET(int *tsl)  {
+	int __r;
+	__asm__ volatile (
+"0:                             \n\t"
+"       lwarx   %0,0,%1         \n\t"
+"       cmpwi   %0,0            \n\t"
+"       bne-    1f              \n\t"
+"       stwcx.  %1,0,%1         \n\t"
+"       isync                   \n\t"
+"       beq+    2f              \n\t"
+"       b       0b              \n\t"
+"1:                             \n\t"
+"       li      %1,0            \n\t"
+"2:                             \n\t"
+	 : "=&r" (__r), "+r" (tsl)
+	 :
+	 : "cr0", "memory");
+	 return (int)tsl;
+}
+
+static inline int
+MUTEX_UNSET(tsl_t *tsl) {
+	 __asm__ volatile("sync" : : : "memory");
+	 return *tsl = 0;
+}
+#define	MUTEX_INIT(tsl)		MUTEX_UNSET(tsl)
+#endif
+#endif
+
+/*********************************************************************
+ * OS/390 C.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_S390_CC_ASSEMBLY
+typedef int tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/*
+ * cs() is declared in <stdlib.h> but is built in to the compiler.
+ * Must use LANGLVL(EXTENDED) to get its declaration.
+ */
+#define	MUTEX_SET(tsl)		(!cs(&zero, (tsl), 1))
+#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)
+#define	MUTEX_INIT(tsl)         (MUTEX_UNSET(tsl), 0)
+#endif
+#endif
+
+/*********************************************************************
+ * S/390 32-bit assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_S390_GCC_ASSEMBLY
+typedef int tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/* gcc/S390: 0 is clear, 1 is set. */
+static inline int
+MUTEX_SET(tsl_t *tsl) {							\
+	register tsl_t *__l = (tsl);					\
+	int __r;							\
+  __asm__ volatile(							\
+       "    la    1,%1\n"						\
+       "    lhi   0,1\n"						\
+       "    l     %0,%1\n"						\
+       "0:  cs    %0,0,0(1)\n"						\
+       "    jl    0b"							\
+       : "=&d" (__r), "+m" (*__l)					\
+       : : "0", "1", "cc");						\
+	return !__r;							\
+}
+
+#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)
+#define	MUTEX_INIT(tsl)         (MUTEX_UNSET(tsl), 0)
+#endif
+#endif
+
+/*********************************************************************
+ * SCO/cc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_SCO_X86_CC_ASSEMBLY
+typedef unsigned char tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/*
+ * UnixWare has threads in libthread, but OpenServer doesn't (yet).
+ *
+ * cc/x86: 0 is clear, 1 is set.
+ */
+#if defined(__USLC__)
+asm int
+_tsl_set(void *tsl)
+{
+%mem tsl
+	movl	tsl, %ecx
+	movl	$1, %eax
+	lock
+	xchgb	(%ecx),%al
+	xorl	$1,%eax
+}
+#endif
+
+#define	MUTEX_SET(tsl)		_tsl_set(tsl)
+#define	MUTEX_UNSET(tsl)	(*(tsl) = 0)
+#define	MUTEX_INIT(tsl)         (MUTEX_UNSET(tsl), 0)
+#endif
+#endif
+
+/*********************************************************************
+ * Sparc/gcc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_SPARC_GCC_ASSEMBLY
+typedef unsigned char tsl_t;
+
+#define	MUTEX_ALIGN	8
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/*
+ * The ldstub instruction takes the location specified by its first argument
+ * (a register containing a memory address) and loads its contents into its
+ * second argument (a register) and atomically sets the contents the location
+ * specified by its first argument to a byte of 1s.  (The value in the second
+ * argument is never read, but only overwritten.)
+ *
+ * Hybrid mutexes require membar #StoreLoad and #LoadStore ordering on multi-
+ * processor v9 systems.
+ *
+ * gcc/sparc: 0 is clear, 1 is set.
+ */
+#define	MUTEX_SET(tsl) ({						\
+	register tsl_t *__l = (tsl);					\
+	register tsl_t __r;						\
+	__asm__ volatile						\
+	    ("ldstub [%1],%0; stbar"					\
+	    : "=r"( __r) : "r" (__l));					\
+	!__r;								\
+})
+
+#define	MUTEX_UNSET(tsl)	(*(tsl) = 0, MUTEX_MEMBAR(tsl))
+#define	MUTEX_INIT(tsl)         (MUTEX_UNSET(tsl), 0)
+#define	MUTEX_MEMBAR(x)	\
+	({ __asm__ volatile ("membar #StoreStore|#StoreLoad|#LoadStore"); })
+#define	MEMBAR_ENTER() \
+	({ __asm__ volatile ("membar #StoreStore|#StoreLoad"); })
+#define	MEMBAR_EXIT() \
+	({ __asm__ volatile ("membar #StoreStore|#LoadStore"); })
+#endif
+#endif
+
+/*********************************************************************
+ * UTS/cc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_UTS_CC_ASSEMBLY
+typedef int tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+#define	MUTEX_INIT(x)	0
+#define	MUTEX_SET(x)	(!uts_lock(x, 1))
+#define	MUTEX_UNSET(x)	(*(x) = 0)
+#endif
+#endif
+
+/*********************************************************************
+ * MIPS/gcc assembly.
+ *********************************************************************/
+#ifdef HAVE_MUTEX_MIPS_GCC_ASSEMBLY
+typedef u_int32_t tsl_t;
+
+#define	MUTEX_ALIGN	4
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/*
+ * For gcc/MIPS.  Should return 0 if could not acquire the lock, 1 if
+ * lock was acquired properly.
+ */
+static inline int
+MUTEX_SET(tsl_t *tsl) {
+       register tsl_t *__l = tsl;
+       register tsl_t __r, __t;
+       __asm__ volatile(
+	       "       .set push           \n"
+	       "       .set mips2          \n"
+	       "       .set noreorder      \n"
+	       "       .set nomacro        \n"
+	       "1:     ll      %0, %3      \n"
+	       "       ori     %2, %0, 1   \n"
+	       "       sc      %2, %1      \n"
+	       "       beqzl   %2, 1b      \n"
+	       "       nop                 \n"
+	       "       andi    %2, %0, 1   \n"
+	       "       sync                \n"
+	       "       .set reorder        \n"
+	       "       .set pop            \n"
+	       : "=&r" (__t), "=m" (*tsl), "=&r" (__r)
+	       : "m" (*tsl)
+	       : "memory");
+       return (!__r);
+}
+
+static inline void
+MUTEX_UNSET(tsl_t *tsl) {
+	__asm__ volatile(
+	       "       .set noreorder      \n"
+	       "       sync                \n"
+	       "       sw      $0, %0      \n"
+	       "       .set reorder        \n"
+	       : "=m" (*tsl)
+	       : "m" (*tsl)
+	       : "memory");
+}
+
+#define	       MUTEX_INIT(tsl)         (*(tsl) = 0)
+#endif
+#endif
+
+/*********************************************************************
+ * x86/gcc (32- and 64-bit) assembly.
+ *********************************************************************/
+#if defined(HAVE_MUTEX_X86_GCC_ASSEMBLY) || \
+    defined(HAVE_MUTEX_X86_64_GCC_ASSEMBLY)
+typedef volatile unsigned char tsl_t;
+
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+/* gcc/x86: 0 is clear, 1 is set. */
+#define	MUTEX_SET(tsl) ({						\
+	tsl_t __r;							\
+	__asm__ volatile("movb $1, %b0\n\t"				\
+		"xchgb %b0,%1"						\
+	    : "=&q" (__r)						\
+	    : "m" (*(tsl_t *)(tsl))					\
+	    : "memory", "cc");						\
+	!__r;	/* return 1 on success, 0 on failure */			\
+})
+
+#define	MUTEX_UNSET(tsl)        (*(tsl_t *)(tsl) = 0)
+#define	MUTEX_INIT(tsl)		(MUTEX_UNSET(tsl), 0)
+/*
+ * We need to pass a valid address to generate the memory barrier
+ * otherwise PURIFY will complain.  Use something referenced recently
+ * and initialized.
+ */
+#if defined(HAVE_MUTEX_X86_GCC_ASSEMBLY)
+#define	MUTEX_MEMBAR(addr)						\
+    ({ __asm__ volatile ("lock; addl $0, %0" ::"m" (addr): "memory"); 1; })
+#else
+#define	MUTEX_MEMBAR(addr)						\
+    ({ __asm__ volatile ("mfence" ::: "memory"); 1; })
+#endif
+
+/*
+ * From Intel's performance tuning documentation (and see SR #6975):
+ * ftp://download.intel.com/design/perftool/cbts/appnotes/sse2/w_spinlock.pdf
+ *
+ * "For this reason, it is highly recommended that you insert the PAUSE
+ * instruction into all spin-wait code immediately. Using the PAUSE
+ * instruction does not affect the correctness of programs on existing
+ * platforms, and it improves performance on Pentium 4 processor platforms."
+ */
+#define	MUTEX_PAUSE		__asm__ volatile ("rep; nop" : : );
+#endif
+#endif
+
+/* End of operating system & hardware architecture-specific definitions */
+
+/*
+ * Mutex alignment defaults to sizeof(unsigned int).
+ *
+ * !!!
+ * Various systems require different alignments for mutexes (the worst we've
+ * seen so far is 16-bytes on some HP architectures).  Malloc(3) is assumed
+ * to return reasonable alignment, all other mutex users must ensure proper
+ * alignment locally.
+ */
+#ifndef	MUTEX_ALIGN
+#define	MUTEX_ALIGN	sizeof(unsigned int)
+#endif
+
+/*
+ * Mutex destruction defaults to a no-op.
+ */
+#ifndef	MUTEX_DESTROY
+#define	MUTEX_DESTROY(x)
+#endif
+
+/*
+ * Mutex pause defaults to a no-op.
+ */
+#ifndef	MUTEX_PAUSE
+#define	MUTEX_PAUSE
+#endif
+
+/*
+ * If no native atomic support is available then use mutexes to
+ * emulate atomic increment, decrement, and compare-and-exchange.
+ * The address of the atomic value selects which of a small number
+ * of mutexes to use to protect the updates.
+ * The number of mutexes should be somewhat larger than the number of
+ * processors in the system in order to minimize unnecessary contention.
+ * It defaults to 8 to handle most small (1-4) cpu systems, if it hasn't
+ * already been defined (e.g. in db_config.h)
+ */
+#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT) && \
+    !defined(MAX_ATOMIC_MUTEXES)
+#define	MAX_ATOMIC_MUTEXES	1
+#endif
+
+/*
+ * DB_MUTEXMGR --
+ *	The mutex manager encapsulates the mutex system.
+ */
+struct __db_mutexmgr {
+	/* These fields are never updated after creation, so not protected. */
+	DB_ENV	*dbenv;			/* Environment */
+	REGINFO	 reginfo;		/* Region information */
+
+	void	*mutex_array;		/* Base of the mutex array */
+};
+
+/* Macros to lock/unlock the mutex region as a whole. */
+#define	MUTEX_SYSTEM_LOCK(dbenv)					\
+	MUTEX_LOCK(dbenv, ((DB_MUTEXREGION *)				\
+	    (dbenv)->mutex_handle->reginfo.primary)->mtx_region)
+#define	MUTEX_SYSTEM_UNLOCK(dbenv)					\
+	MUTEX_UNLOCK(dbenv, ((DB_MUTEXREGION *)				\
+	    (dbenv)->mutex_handle->reginfo.primary)->mtx_region)
+
+/*
+ * DB_MUTEXREGION --
+ *	The primary mutex data structure in the shared memory region.
+ */
+typedef struct __db_mutexregion { /* SHARED */
+	/* These fields are initialized at create time and never modified. */
+	roff_t		mutex_off_alloc;/* Offset of mutex array */
+	roff_t		mutex_off;	/* Adjusted offset of mutex array */
+	db_size_t	mutex_size;	/* Size of the aligned mutex */
+	roff_t		thread_off;	/* Offset of the thread area. */
+
+	db_mutex_t	mtx_region;	/* Region mutex. */
+
+	/* Protected using the region mutex. */
+	db_mutex_t	mutex_next;	/* Next free mutex */
+
+#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT)
+	/* Mutexes for emulating atomic operations. */
+	db_mutex_t	mtx_atomic[MAX_ATOMIC_MUTEXES];
+#endif
+
+	DB_MUTEX_STAT	stat;		/* Mutex statistics */
+} DB_MUTEXREGION;
+
+#ifdef HAVE_MUTEX_SUPPORT
+struct __db_mutex_t { /* SHARED */	/* Mutex. */
+#ifdef MUTEX_FIELDS
+	MUTEX_FIELDS			/* Opaque thread mutex structures. */
+#endif
+#ifndef HAVE_MUTEX_FCNTL
+#if defined(HAVE_MUTEX_HYBRID) || \
+    (defined(HAVE_SHARED_LATCHES) && !defined(HAVE_MUTEX_PTHREADS))
+	/*
+	 * For hybrid and test-and-set shared latches it is a counter:
+	 * 0 means it is free,
+	 * -1 is exclusively locked,
+	 * > 0 is the number of shared readers.
+	 * Pthreads shared latches use pthread_rwlock instead.
+	 */
+	tsl_t		tas;
+	db_atomic_t	sharecount;
+#elif !defined(MUTEX_FIELDS)
+	/*
+	 * This is the Test and Set flag for exclusive latches (mutexes):
+	 * there is a free value (often 0, 1, or -1) and a set value.
+	 */
+	tsl_t		tas;
+#endif
+#endif
+#ifdef HAVE_MUTEX_HYBRID
+	volatile u_int32_t wait;	/* Count of waiters. */
+#endif
+	pid_t		pid;		/* Process owning mutex */
+	db_threadid_t	tid;		/* Thread owning mutex */
+
+	db_mutex_t mutex_next_link;	/* Linked list of free mutexes. */
+
+#ifdef HAVE_STATISTICS
+	int	  alloc_id;		/* Allocation ID. */
+
+	u_int32_t mutex_set_wait;	/* Granted after wait. */
+	u_int32_t mutex_set_nowait;	/* Granted without waiting. */
+#ifdef HAVE_SHARED_LATCHES
+	u_int32_t mutex_set_rd_wait;	/* Granted shared lock after wait. */
+	u_int32_t mutex_set_rd_nowait;	/* Granted shared lock w/out waiting. */
+#endif
+#ifdef HAVE_MUTEX_HYBRID
+	u_int32_t hybrid_wait;
+	u_int32_t hybrid_wakeup;	/* for counting spurious wakeups */
+#endif
+#endif
+
+	/*
+	 * A subset of the flag arguments for __mutex_alloc().
+	 *
+	 * Flags should be an unsigned integer even if it's not required by
+	 * the possible flags values, getting a single byte on some machines
+	 * is expensive, and the mutex structure is a MP hot spot.
+	 */
+	volatile u_int32_t flags;		/* MUTEX_XXX */
+};
+#endif
+
+/* Macro to get a reference to a specific mutex. */
+#define	MUTEXP_SET(env, indx)						\
+	(F_ISSET(env, ENV_PRIVATE) ? (DB_MUTEX *) indx :		\
+	(DB_MUTEX *)((u_int8_t *)env->mutex_handle->mutex_array +	\
+	    (indx) *							\
+	    ((DB_MUTEXREGION *)env->mutex_handle->reginfo.primary)->mutex_size))
+
+#if defined(HAVE_MUTEX_HYBRID) ||  defined(DB_WIN32) ||		\
+	(defined(HAVE_SHARED_LATCHES) && !defined(HAVE_MUTEX_PTHREADS))
+#define	MUTEXP_IS_BUSY(mutexp)					\
+	(F_ISSET(mutexp, DB_MUTEX_SHARED) ?			\
+	(atomic_read(&(mutexp)->sharecount) != 0) :		\
+	F_ISSET(mutexp, DB_MUTEX_LOCKED))
+#define	MUTEXP_BUSY_FIELD(mutexp)		\
+	(F_ISSET(mutexp, DB_MUTEX_SHARED) ?	\
+	(atomic_read(&(mutexp)->sharecount)) : (mutexp)->flags)
+#else
+/* Pthread_rwlocks don't have an low-cost 'is it being shared?' predicate. */
+#define	MUTEXP_IS_BUSY(mutexp)	(F_ISSET((mutexp), DB_MUTEX_LOCKED))
+#define	MUTEXP_BUSY_FIELD(mutexp)	((mutexp)->flags)
+#endif
+
+#define	MUTEX_IS_BUSY(env, mutex)					\
+	(mutex == MUTEX_INVALID || !MUTEX_ON(env) ||			\
+	F_ISSET(env->dbenv, DB_ENV_NOLOCKING) ||			\
+	MUTEXP_IS_BUSY(MUTEXP_SET(env, mutex)))
+
+#define	MUTEX_REQUIRED(env, mutex)					\
+	DB_ASSERT(env, MUTEX_IS_OWNED(env, mutex))
+
+#define	MUTEX_REQUIRED_READ(env, mutex)					\
+	DB_ASSERT(env, MUTEX_IS_OWNED(env, mutex) || MUTEX_IS_BUSY(env, mutex))
+
+/*
+ * Test and set (and thus hybrid) shared latches use compare & exchange
+ * to acquire; the others the mutex-setting primitive defined above.
+ */
+#ifdef LOAD_ACTUAL_MUTEX_CODE
+
+#if defined(HAVE_SHARED_LATCHES)
+/* This is the value of the 'sharecount' of an exclusively held tas latch.
+ * The particular value is not special; it is just unlikely to be caused
+ * by releasing or acquiring a shared latch too many times.
+ */
+#define	MUTEX_SHARE_ISEXCLUSIVE	(-1024)
+
+/*
+ * Get an exclusive lock on a possibly sharable latch. We use the native
+ * MUTEX_SET() operation for non-sharable latches; it usually is faster.
+ */
+#define	MUTEXP_ACQUIRE(mutexp)	\
+	(F_ISSET(mutexp, DB_MUTEX_SHARED) ?			\
+	atomic_compare_exchange(env,				\
+	    &(mutexp)->sharecount, 0, MUTEX_SHARE_ISEXCLUSIVE) :	\
+	MUTEX_SET(&(mutexp)->tas))
+#else
+#define	MUTEXP_ACQUIRE(mutexp)		MUTEX_SET(&(mutexp)->tas)
+#endif
+
+#ifndef MEMBAR_ENTER
+#define	MEMBAR_ENTER()
+#define	MEMBAR_EXIT()
+#endif
+
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_MUTEX_INT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/os.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,200 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_OS_H_
+#define	_DB_OS_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Number of times to retry system calls that return EINTR or EBUSY. */
+#define	DB_RETRY	100
+
+#ifdef __TANDEM
+/*
+ * OSS Tandem problem: fsync can return a Guardian file system error of 70,
+ * which has no symbolic name in OSS.  HP says to retry the fsync. [#12957]
+ */
+#define	RETRY_CHK(op, ret) do {						\
+	int __retries, __t_ret;						\
+	for ((ret) = 0, __retries = DB_RETRY;;) {			\
+		if ((op) == 0)						\
+			break;						\
+		(ret) = __os_get_syserr();				\
+		if (((__t_ret = __os_posix_err(ret)) == EAGAIN ||	\
+		    __t_ret == EBUSY || __t_ret == EINTR ||		\
+		    __t_ret == EIO || __t_ret == 70) && --__retries > 0)\
+			continue;					\
+		break;							\
+	}								\
+} while (0)
+#else
+#define	RETRY_CHK(op, ret) do {						\
+	int __retries, __t_ret;						\
+	for ((ret) = 0, __retries = DB_RETRY;;) {			\
+		if ((op) == 0)						\
+			break;						\
+		(ret) = __os_get_syserr();				\
+		if (((__t_ret = __os_posix_err(ret)) == EAGAIN ||	\
+		    __t_ret == EBUSY || __t_ret == EINTR ||		\
+		    __t_ret == EIO) && --__retries > 0)			\
+			continue;					\
+		break;							\
+	}								\
+} while (0)
+#endif
+
+#define	RETRY_CHK_EINTR_ONLY(op, ret) do {				\
+	int __retries;							\
+	for ((ret) = 0, __retries = DB_RETRY;;) {			\
+		if ((op) == 0)						\
+			break;						\
+		(ret) = __os_get_syserr();				\
+		if (__os_posix_err(ret) == EINTR && --__retries > 0)	\
+			continue;					\
+		break;							\
+	}								\
+} while (0)
+
+/*
+ * Flags understood by __os_open.
+ */
+#define	DB_OSO_ABSMODE	0x0001		/* Absolute mode specified. */
+#define	DB_OSO_CREATE	0x0002		/* POSIX: O_CREAT */
+#define	DB_OSO_DIRECT	0x0004		/* Don't buffer the file in the OS. */
+#define	DB_OSO_DSYNC	0x0008		/* POSIX: O_DSYNC. */
+#define	DB_OSO_EXCL	0x0010		/* POSIX: O_EXCL */
+#define	DB_OSO_RDONLY	0x0020		/* POSIX: O_RDONLY */
+#define	DB_OSO_REGION	0x0040		/* Opening a region file. */
+#define	DB_OSO_SEQ	0x0080		/* Expected sequential access. */
+#define	DB_OSO_TEMP	0x0100		/* Remove after last close. */
+#define	DB_OSO_TRUNC	0x0200		/* POSIX: O_TRUNC */
+
+/*
+ * File modes.
+ */
+#define	DB_MODE_400	(S_IRUSR)
+#define	DB_MODE_600	(S_IRUSR|S_IWUSR)
+#define	DB_MODE_660	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
+#define	DB_MODE_666	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
+#define	DB_MODE_700	(S_IRUSR|S_IWUSR|S_IXUSR)
+
+/*
+ * We group certain seek/write calls into a single function so that we
+ * can use pread(2)/pwrite(2) where they're available.
+ */
+#define	DB_IO_READ	1
+#define	DB_IO_WRITE	2
+
+/*
+ * Make a last "panic" check.  Imagine a thread of control running in Berkeley
+ * DB, going to sleep.  Another thread of control decides to run recovery
+ * because the environment is broken.  The first thing recovery does is panic
+ * the existing environment, but we only check the panic flag when crossing the
+ * public API.  If the sleeping thread wakes up and writes something, we could
+ * have two threads of control writing the log files at the same time.  So,
+ * before reading or writing, make a last panic check.  Obviously, there's still
+ * a window, but it's very, very small.
+ */
+#define	LAST_PANIC_CHECK_BEFORE_IO(env)					\
+	PANIC_CHECK(env);                                               \
+	if (env != NULL &&						\
+	    F_ISSET((env)->dbenv, DB_ENV_NOFLUSH))			\
+	    return (0)							\
+									\
+/* DB filehandle. */
+struct __fh_t {
+	/*
+	 * Linked list of DB_FH's, linked from the DB_ENV, used to keep track
+	 * of all open file handles for resource cleanup.
+	 */
+	 TAILQ_ENTRY(__fh_t) q;
+
+	/*
+	 * The file-handle mutex is only used to protect the handle/fd
+	 * across seek and read/write pairs, it does not protect the
+	 * the reference count, or any other fields in the structure.
+	 */
+	db_mutex_t mtx_fh;		/* Mutex to lock. */
+
+	int	ref;			/* Reference count. */
+
+#if defined(DB_WIN32)
+	HANDLE	handle;			/* Windows/32 file handle. */
+	HANDLE	trunc_handle;		/* Handle for truncate calls. */
+#endif
+	int	fd;			/* POSIX file descriptor. */
+
+	char	*name;			/* File name at open. */
+
+	/*
+	 * Last seek statistics, used for zero-filling on filesystems
+	 * that don't support it directly.
+	 */
+	db_pgno_t pgno;
+	u_int32_t pgsize;
+	off_t offset;
+
+#ifdef HAVE_STATISTICS
+	u_int32_t seek_count;		/* I/O statistics */
+	u_int32_t read_count;
+	u_int32_t write_count;
+#endif
+
+#define	DB_FH_ENVLINK	0x01		/* We're linked on the DB_ENV. */
+#define	DB_FH_NOSYNC	0x02		/* Handle doesn't need to be sync'd. */
+#define	DB_FH_OPENED	0x04		/* Handle is valid. */
+#define	DB_FH_UNLINK	0x08		/* Unlink on close */
+#define	DB_FH_REGION	0x10		/* Opened to contain a region */
+	u_int8_t flags;
+};
+
+/* Standard buffer size for ctime/ctime_r function calls. */
+#define	CTIME_BUFLEN	26
+
+/*
+ * VxWorks requires we cast (const char *) variables to (char *) in order to
+ * pass them to system calls like stat, read and write.
+ */
+#ifdef HAVE_VXWORKS
+#define	CHAR_STAR_CAST	(char *)
+#define	VOID_STAR_CAST	(void *)
+#else
+#define	CHAR_STAR_CAST
+#define VOID_STAR_CAST
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/os_ext.h"
+#endif /* !_DB_OS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/partition.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,79 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * $Id$
+ */
+#ifndef	_DB_PART_H_
+#define	_DB_PART_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef struct __db_partition {
+	u_int32_t	nparts;		/* number of partitions. */
+	DBT		*keys;		/* array of range keys. */
+	void		*data;		/* the partition info. */
+	const char	**dirs;		/* locations for partitions. */
+	DB		**handles;	/* array of partition handles. */
+	u_int32_t	(*callback) (DB *, DBT *);
+#define	PART_CALLBACK	0x01
+#define	PART_RANGE	0x02
+	u_int32_t	flags;
+} DB_PARTITION;
+
+/*
+ * Internal part of a partitioned cursor.
+ */
+typedef struct __part_internal {
+	__DBC_INTERNAL
+	u_int32_t	part_id;
+	DBC		*sub_cursor;
+} PART_CURSOR;
+
+#ifdef HAVE_PARTITION
+#define	PART_NAME	"__dbp.%s.%03d"
+#define	PART_LEN	(strlen("__dbp..")+3)
+#define	PART_PREFIX	"__dbp."
+#define IS_PARTITION_DB_FILE(name)	(strncmp(name, PART_PREFIX,	\
+					    sizeof(PART_PREFIX) - 1) == 0)
+
+#define	DB_IS_PARTITIONED(dbp)						\
+      (dbp->p_internal != NULL &&					\
+      ((DB_PARTITION *)dbp->p_internal)->handles != NULL)
+
+#define	DBC_PART_REFRESH(dbc)	(F_SET(dbc, DBC_PARTITIONED))
+#else
+#define	DBC_PART_REFRESH(dbc)
+#define	DB_IS_PARTITIONED(dbp)	(0)
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/perfmon.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,125 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2010, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_PERFMON_H_
+#define	_DB_PERFMON_H_
+
+/*******************************************************
+ * Oracle Berkeley DB Performance Event Monitoring
+ *
+ * Some events inside of Oracle Berkeley DB can be 'published'
+ * to the operating environment's performance tracing system
+ * as they occur. Current support includes
+ *	--enable-dtrace
+ *		Solaris
+ *		Linux (via SystemTap's dtrace wrappers)
+ *		Darwin (Mac OS X)
+ *		QNX(?)  
+ *
+ ******************************************************/
+
+/*
+ * The performance monitoring system can display many of the statistics which
+ * are obtainable through the {DB,DB_ENV}->xxx_stat() functions. By default
+ * they are excluded. They can be enabled with --enable-perfmon-statistics.
+ */
+#ifdef HAVE_PERFMON_STATISTICS
+#define STAT_PERFMON1(env, cat, id, a1)		PERFMON1(env, cat, id, (a1))
+#define STAT_PERFMON2(env, cat, id, a1, a2) 	\
+    PERFMON2(env, cat, id, (a1), (a2))
+#define STAT_PERFMON3(env, cat, id, a1, a2, a3)	\
+    PERFMON3(env, cat, id, (a1), (a2), (a3))
+#else
+#define STAT_PERFMON1(env, cat, id, a1)		NOP_STATEMENT
+#define STAT_PERFMON2(env, cat, id, a1, a2)	NOP_STATEMENT
+#define STAT_PERFMON3(env, cat, id, a1, a2, a3)	NOP_STATEMENT
+#endif
+
+
+#if defined(HAVE_PERFMON) && defined(HAVE_STATISTICS)
+/*
+ * The DTrace macros which are generated at configure time in db_provider.h can
+ * have full function signatures. These declarations are needed for compilation
+ * when DTrace support is enabled. It is "too early" in the include sequence
+ * to include the header files which define these structs.
+ */
+struct _db_page;
+struct __bh;
+struct __db_dbt;
+struct __sh_dbt;
+struct __db_mutex_t;
+
+#if defined(HAVE_DTRACE)
+/*
+ * Solaris 10, Darwin/Mac OS X starting in 10.6 (Snow Leopard), Linux with
+ * the DTrace-compatible version of SystemTap, possibly QNX.
+ */
+#include "db_provider.h"
+
+#define PERFMON0(env, cat, id)		bdb_##cat##_##id()
+#define PERFMON1(env, cat, id, a1)	bdb_##cat##_##id(a1)
+#define PERFMON2(env, cat, id, a1, a2)					\
+    bdb_##cat##_##id((a1), (a2))
+#define PERFMON3(env, cat, id, a1, a2, a3)				\
+    do {								\
+    	if (PERFMON_ENABLED(env, cat, id))				\
+	    bdb_##cat##_##id((a1), (a2), (a3));			\
+    } while (0)
+#define PERFMON4(env, cat, id, a1, a2, a3, a4)				\
+    do {								\
+    	if (PERFMON_ENABLED(env, cat, id))				\
+	    bdb_##cat##_##id((a1), (a2), (a3), (a4));			\
+    } while (0)
+#define PERFMON5(env, cat, id, a1, a2, a3, a4, a5)			\
+    do {								\
+    	if (PERFMON_ENABLED(env, cat, id))				\
+	    bdb_##cat##_##id((a1), (a2), (a3), (a4), (a5));		\
+    } while (0)
+#define PERFMON6(env, cat, id, a1, a2, a3, a4, a5, a6)			\
+    do {								\
+    	if (PERFMON_ENABLED(env, cat, id))				\
+	    bdb_##cat##_##id((a1), (a2), (a3), (a4), (a5), (a6));	\
+    } while (0)
+#define PERFMON_ENABLED(env, cat, id)	 bdb_##cat##_##id##_enabled()
+#endif
+
+#else
+/* Without HAVE_PERFMON or HAVE_STATISTICS these macros map to null bodies. */
+#define PERFMON0(env, cat, id)				NOP_STATEMENT
+#define PERFMON1(env, cat, id, a1)			NOP_STATEMENT
+#define PERFMON2(env, cat, id, a1, a2)			NOP_STATEMENT
+#define PERFMON3(env, cat, id, a1, a2, a3)		NOP_STATEMENT
+#define PERFMON4(env, cat, id, a1, a2, a3, a4)		NOP_STATEMENT
+#define PERFMON5(env, cat, id, a1, a2, a3, a4, a5)	NOP_STATEMENT
+#define PERFMON6(env, cat, id, a1, a2, a3, a4, a5, a6)	NOP_STATEMENT
+#define PERFMON_ENABLED(env, cat, id)	 		FALSE
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/qam.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,225 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef	_DB_QAM_H_
+#define	_DB_QAM_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * QAM data elements: a status field and the data.
+ */
+typedef struct _qamdata {
+	u_int8_t  flags;	/* 00: delete bit. */
+#define	QAM_VALID	0x01
+#define	QAM_SET		0x02
+	u_int8_t  data[1];	/* Record. */
+} QAMDATA;
+
+struct __queue;		typedef struct __queue QUEUE;
+struct __qcursor;	typedef struct __qcursor QUEUE_CURSOR;
+
+struct __qcursor {
+	/* struct __dbc_internal */
+	__DBC_INTERNAL
+
+	/* Queue private part */
+
+	/* Per-thread information: queue private. */
+	db_recno_t	 recno;		/* Current record number. */
+
+	u_int32_t	 flags;
+};
+
+typedef struct __mpfarray {
+	u_int32_t n_extent;		/* Number of extents in table. */
+	u_int32_t low_extent;		/* First extent open. */
+	u_int32_t hi_extent;		/* Last extent open. */
+	struct __qmpf {
+		int pinref;
+		DB_MPOOLFILE *mpf;
+	} *mpfarray;			 /* Array of open extents. */
+} MPFARRAY;
+
+/*
+ * The in-memory, per-tree queue data structure.
+ */
+struct __queue {
+	db_pgno_t q_meta;		/* Database meta-data page. */
+	db_pgno_t q_root;		/* Database root page. */
+
+	int	  re_pad;		/* Fixed-length padding byte. */
+	u_int32_t re_len;		/* Length for fixed-length records. */
+	u_int32_t rec_page;		/* records per page */
+	u_int32_t page_ext;		/* Pages per extent */
+	MPFARRAY array1, array2;	/* File arrays. */
+
+					/* Extent file configuration: */
+	DBT pgcookie;			/* Initialized pgcookie. */
+	DB_PGINFO pginfo;		/* Initialized pginfo struct. */
+
+	char *path;			/* Space allocated to file pathname. */
+	char *name;			/* The name of the file. */
+	char *dir;			/* The dir of the file. */
+	int mode;			/* Mode to open extents. */
+};
+
+/* Format for queue extent names. */
+#define	QUEUE_EXTENT		"%s%c__dbq.%s.%d"
+#define	QUEUE_EXTENT_HEAD	"__dbq.%s."
+#define	QUEUE_EXTENT_PREFIX	"__dbq."
+
+typedef struct __qam_filelist {
+	DB_MPOOLFILE *mpf;
+	u_int32_t id;
+} QUEUE_FILELIST;
+
+/*
+ * Calculate the page number of a recno.
+ *
+ * Number of records per page =
+ *	Divide the available space on the page by the record len + header.
+ *
+ * Page number for record =
+ *	divide the physical record number by the records per page
+ *	add the root page number
+ *	For now the root page will always be 1, but we might want to change
+ *	in the future (e.g. multiple fixed len queues per file).
+ *
+ * Index of record on page =
+ *	physical record number, less the logical pno times records/page
+ */
+#define	CALC_QAM_RECNO_PER_PAGE(dbp)					\
+    (((dbp)->pgsize - QPAGE_SZ(dbp)) /					\
+    (u_int32_t)DB_ALIGN((uintmax_t)SSZA(QAMDATA, data) +		\
+    ((QUEUE *)(dbp)->q_internal)->re_len, sizeof(u_int32_t)))
+
+#define	QAM_RECNO_PER_PAGE(dbp)	(((QUEUE*)(dbp)->q_internal)->rec_page)
+
+#define	QAM_RECNO_PAGE(dbp, recno)					\
+    (((QUEUE *)(dbp)->q_internal)->q_root				\
+    + (((recno) - 1) / QAM_RECNO_PER_PAGE(dbp)))
+
+#define	QAM_PAGE_EXTENT(dbp, pgno)					\
+    (((pgno) - 1) / ((QUEUE *)(dbp)->q_internal)->page_ext)
+
+#define	QAM_RECNO_EXTENT(dbp, recno)					\
+    QAM_PAGE_EXTENT(dbp, QAM_RECNO_PAGE(dbp, recno))
+
+#define	QAM_RECNO_INDEX(dbp, pgno, recno)				\
+    (u_int32_t)(((recno) - 1) - (QAM_RECNO_PER_PAGE(dbp)		\
+    * (pgno - ((QUEUE *)(dbp)->q_internal)->q_root)))
+
+#define	QAM_GET_RECORD(dbp, page, index)				\
+    ((QAMDATA *)((u_int8_t *)(page) + (QPAGE_SZ(dbp) +			\
+    (DB_ALIGN((uintmax_t)SSZA(QAMDATA, data) +				\
+    ((QUEUE *)(dbp)->q_internal)->re_len, sizeof(u_int32_t)) * index))))
+
+#define QAM_OUTSIDE_QUEUE(meta, recno)					\
+	(((meta)->cur_recno >= (meta)->first_recno ?			\
+	    ((recno) < (meta)->first_recno ||				\
+	         (recno) > (meta)->cur_recno) :				\
+	    ((recno) > (meta)->cur_recno && 				\
+	        (recno) < (meta)->first_recno)))
+
+#define	QAM_AFTER_CURRENT(meta, recno)					\
+	((recno) == (meta)->cur_recno ||				\
+	(QAM_OUTSIDE_QUEUE(meta, recno) &&				\
+        ((recno) - (meta)->cur_recno) <= ((meta)->first_recno - (recno))))
+
+#define	QAM_BEFORE_FIRST(meta, recno)					\
+	(QAM_OUTSIDE_QUEUE(meta, recno) &&				\
+	((meta)->first_recno - (recno)) < ((recno) - (meta)->cur_recno))
+
+#define	QAM_NOT_VALID(meta, recno)					\
+    (recno == RECNO_OOB ||						\
+	QAM_BEFORE_FIRST(meta, recno) || QAM_AFTER_CURRENT(meta, recno))
+
+#define QAM_WAKEUP(dbc, ret) do {					\
+	if (STD_LOCKING(dbc)) {						\
+		dbc->lock.pgno = PGNO_INVALID;				\
+		dbc->lock.type = DB_PAGE_LOCK;				\
+		ret = __lock_wakeup((dbc)->dbp->env, &(dbc)->lock_dbt);	\
+	} else								\
+		ret = 0;						\
+} while (0)
+
+/* Handle wrap around. */
+#define QAM_INC_RECNO(recno) do {					\
+	recno++;							\
+} while (recno == RECNO_OOB)
+
+#define QAM_DEC_RECNO(recno) do {					\
+	recno--;							\
+} while (recno == RECNO_OOB)
+
+
+/*
+ * Log opcodes for the mvptr routine.
+ */
+#define	QAM_SETFIRST		0x01
+#define	QAM_SETCUR		0x02
+#define	QAM_TRUNCATE		0x04
+
+typedef enum {
+	QAM_PROBE_GET,
+	QAM_PROBE_PUT,
+	QAM_PROBE_DIRTY,
+	QAM_PROBE_MPF
+} qam_probe_mode;
+
+/*
+ * Ops for __qam_nameop.
+ */
+typedef enum {
+	QAM_NAME_DISCARD,
+	QAM_NAME_RENAME,
+	QAM_NAME_REMOVE
+} qam_name_op;
+
+#define	__qam_fget(dbc, pgnoaddr, flags, addrp)		\
+	__qam_fprobe(dbc, *pgnoaddr,					\
+	    addrp, QAM_PROBE_GET, DB_PRIORITY_UNCHANGED, flags)
+
+#define	__qam_fput(dbc, pgno, addrp, priority)			\
+	__qam_fprobe(dbc, pgno, addrp, QAM_PROBE_PUT, priority, 0)
+
+#define	__qam_dirty(dbc, pgno, pagep, priority)		\
+	__qam_fprobe(dbc, pgno, pagep, QAM_PROBE_DIRTY, priority, 0)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/qam_auto.h"
+#include "dbinc_auto/qam_ext.h"
+#endif /* !_DB_QAM_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/queue.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,592 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)queue.h	8.5 (Berkeley) 8/20/94
+ * $FreeBSD: src/sys/sys/queue.h,v 1.54 2002/08/05 05:18:43 alfred Exp $
+ */
+
+#ifndef	_DB_QUEUE_H_
+#define	_DB_QUEUE_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * This file defines four types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction.  Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ *			SLIST	LIST	STAILQ	TAILQ
+ * _HEAD		+	+	+	+
+ * _HEAD_INITIALIZER	+	+	+	+
+ * _ENTRY		+	+	+	+
+ * _INIT		+	+	+	+
+ * _EMPTY		+	+	+	+
+ * _FIRST		+	+	+	+
+ * _NEXT		+	+	+	+
+ * _PREV		-	-	-	+
+ * _LAST		-	-	+	+
+ * _FOREACH		+	+	+	+
+ * _FOREACH_REVERSE	-	-	-	+
+ * _INSERT_HEAD		+	+	+	+
+ * _INSERT_BEFORE	-	+	-	+
+ * _INSERT_AFTER	+	+	+	+
+ * _INSERT_TAIL		-	-	+	+
+ * _CONCAT		-	-	+	+
+ * _REMOVE_HEAD		+	-	+	-
+ * _REMOVE		+	+	+	+
+ *
+ */
+
+/*
+ * XXX
+ * We #undef all of the macros because there are incompatible versions of this
+ * file and these macros on various systems.  What makes the problem worse is
+ * they are included and/or defined by system include files which we may have
+ * already loaded into Berkeley DB before getting here.  For example, FreeBSD's
+ * <rpc/rpc.h> includes its system <sys/queue.h>, and VxWorks UnixLib.h defines
+ * several of the LIST_XXX macros.  Visual C.NET 7.0 also defines some of these
+ * same macros in Vc7\PlatformSDK\Include\WinNT.h.  Make sure we use ours.
+ */
+#undef LIST_EMPTY
+#undef LIST_ENTRY
+#undef LIST_FIRST
+#undef LIST_FOREACH
+#undef LIST_HEAD
+#undef LIST_HEAD_INITIALIZER
+#undef LIST_INIT
+#undef LIST_INSERT_AFTER
+#undef LIST_INSERT_BEFORE
+#undef LIST_INSERT_HEAD
+#undef LIST_NEXT
+#undef LIST_REMOVE
+#undef QMD_TRACE_ELEM
+#undef QMD_TRACE_HEAD
+#undef QUEUE_MACRO_DEBUG
+#undef SLIST_EMPTY
+#undef SLIST_ENTRY
+#undef SLIST_FIRST
+#undef SLIST_FOREACH
+#undef SLIST_FOREACH_PREVPTR
+#undef SLIST_HEAD
+#undef SLIST_HEAD_INITIALIZER
+#undef SLIST_INIT
+#undef SLIST_INSERT_AFTER
+#undef SLIST_INSERT_HEAD
+#undef SLIST_NEXT
+#undef SLIST_REMOVE
+#undef SLIST_REMOVE_HEAD
+#undef STAILQ_CONCAT
+#undef STAILQ_EMPTY
+#undef STAILQ_ENTRY
+#undef STAILQ_FIRST
+#undef STAILQ_FOREACH
+#undef STAILQ_HEAD
+#undef STAILQ_HEAD_INITIALIZER
+#undef STAILQ_INIT
+#undef STAILQ_INSERT_AFTER
+#undef STAILQ_INSERT_HEAD
+#undef STAILQ_INSERT_TAIL
+#undef STAILQ_LAST
+#undef STAILQ_NEXT
+#undef STAILQ_REMOVE
+#undef STAILQ_REMOVE_HEAD
+#undef STAILQ_REMOVE_HEAD_UNTIL
+#undef TAILQ_CONCAT
+#undef TAILQ_EMPTY
+#undef TAILQ_ENTRY
+#undef TAILQ_FIRST
+#undef TAILQ_FOREACH
+#undef TAILQ_FOREACH_REVERSE
+#undef TAILQ_HEAD
+#undef TAILQ_HEAD_INITIALIZER
+#undef TAILQ_INIT
+#undef TAILQ_INSERT_AFTER
+#undef TAILQ_INSERT_BEFORE
+#undef TAILQ_INSERT_HEAD
+#undef TAILQ_INSERT_TAIL
+#undef TAILQ_LAST
+#undef TAILQ_NEXT
+#undef TAILQ_PREV
+#undef TAILQ_REMOVE
+#undef TRACEBUF
+#undef TRASHIT
+
+#define	QUEUE_MACRO_DEBUG 0
+#if QUEUE_MACRO_DEBUG
+/* Store the last 2 places the queue element or head was altered */
+struct qm_trace {
+	char * lastfile;
+	int lastline;
+	char * prevfile;
+	int prevline;
+};
+
+#define	TRACEBUF	struct qm_trace trace;
+#define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
+
+#define	QMD_TRACE_HEAD(head) do {					\
+	(head)->trace.prevline = (head)->trace.lastline;		\
+	(head)->trace.prevfile = (head)->trace.lastfile;		\
+	(head)->trace.lastline = __LINE__;				\
+	(head)->trace.lastfile = __FILE__;				\
+} while (0)
+
+#define	QMD_TRACE_ELEM(elem) do {					\
+	(elem)->trace.prevline = (elem)->trace.lastline;		\
+	(elem)->trace.prevfile = (elem)->trace.lastfile;		\
+	(elem)->trace.lastline = __LINE__;				\
+	(elem)->trace.lastfile = __FILE__;				\
+} while (0)
+
+#else
+#define	QMD_TRACE_ELEM(elem)
+#define	QMD_TRACE_HEAD(head)
+#define	TRACEBUF
+#define	TRASHIT(x)
+#endif	/* QUEUE_MACRO_DEBUG */
+
+/*
+ * Singly-linked List declarations.
+ */
+#define	SLIST_HEAD(name, type)						\
+struct name {								\
+	struct type *slh_first;	/* first element */			\
+}
+
+#define	SLIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	SLIST_ENTRY(type)						\
+struct {								\
+	struct type *sle_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
+
+#define	SLIST_FIRST(head)	((head)->slh_first)
+
+#define	SLIST_FOREACH(var, head, field)					\
+	for ((var) = SLIST_FIRST((head));				\
+	    (var);							\
+	    (var) = SLIST_NEXT((var), field))
+
+#define	SLIST_FOREACH_PREVPTR(var, varp, head, field)			\
+	for ((varp) = &SLIST_FIRST((head));				\
+	    ((var) = *(varp)) != NULL;					\
+	    (varp) = &SLIST_NEXT((var), field))
+
+#define	SLIST_INIT(head) do {						\
+	SLIST_FIRST((head)) = NULL;					\
+} while (0)
+
+#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
+	SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);	\
+	SLIST_NEXT((slistelm), field) = (elm);				\
+} while (0)
+
+#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
+	SLIST_NEXT((elm), field) = SLIST_FIRST((head));			\
+	SLIST_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
+
+#define	SLIST_REMOVE(head, elm, type, field) do {			\
+	if (SLIST_FIRST((head)) == (elm)) {				\
+		SLIST_REMOVE_HEAD((head), field);			\
+	}								\
+	else {								\
+		struct type *curelm = SLIST_FIRST((head));		\
+		while (curelm != NULL && 				\
+		    SLIST_NEXT(curelm, field) != (elm))			\
+			curelm = SLIST_NEXT(curelm, field);		\
+		if (curelm != NULL)					\
+			SLIST_NEXT(curelm, field) =			\
+			    SLIST_NEXT(SLIST_NEXT(curelm, field), field);\
+	}								\
+} while (0)
+
+#define	SLIST_REMOVE_HEAD(head, field) do {				\
+	SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	\
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define	STAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *stqh_first;/* first element */			\
+	struct type **stqh_last;/* addr of last next element */		\
+}
+
+#define	STAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).stqh_first }
+
+#define	STAILQ_ENTRY(type)						\
+struct {								\
+	struct type *stqe_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define	STAILQ_CONCAT(head1, head2) do {				\
+	if (!STAILQ_EMPTY((head2))) {					\
+		*(head1)->stqh_last = (head2)->stqh_first;		\
+		(head1)->stqh_last = (head2)->stqh_last;		\
+		STAILQ_INIT((head2));					\
+	}								\
+} while (0)
+
+#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
+
+#define	STAILQ_FIRST(head)	((head)->stqh_first)
+
+#define	STAILQ_FOREACH(var, head, field)				\
+	for ((var) = STAILQ_FIRST((head));				\
+	   (var);							\
+	   (var) = STAILQ_NEXT((var), field))
+
+#define	STAILQ_INIT(head) do {						\
+	STAILQ_FIRST((head)) = NULL;					\
+	(head)->stqh_last = &STAILQ_FIRST((head));			\
+} while (0)
+
+#define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_NEXT((tqelm), field) = (elm);				\
+} while (0)
+
+#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
+	STAILQ_NEXT((elm), field) = NULL;				\
+	*(head)->stqh_last = (elm);					\
+	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
+} while (0)
+
+#define	STAILQ_LAST(head, type, field)					\
+	(STAILQ_EMPTY((head)) ?						\
+		NULL :							\
+		((struct type *)					\
+		((char *)((head)->stqh_last) - __offsetof(struct type, field))))
+
+#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
+
+#define	STAILQ_REMOVE(head, elm, type, field) do {			\
+	if (STAILQ_FIRST((head)) == (elm)) {				\
+		STAILQ_REMOVE_HEAD((head), field);			\
+	}								\
+	else {								\
+		struct type *curelm = STAILQ_FIRST((head));		\
+		while (STAILQ_NEXT(curelm, field) != (elm))		\
+			curelm = STAILQ_NEXT(curelm, field);		\
+		if ((STAILQ_NEXT(curelm, field) =			\
+		     STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
+			(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
+	}								\
+} while (0)
+
+#define	STAILQ_REMOVE_HEAD(head, field) do {				\
+	if ((STAILQ_FIRST((head)) =					\
+	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+#define	STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {			\
+	if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL)	\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+/*
+ * List declarations.
+ */
+#define	LIST_HEAD(name, type)						\
+struct name {								\
+	struct type *lh_first;	/* first element */			\
+}
+
+#define	LIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	LIST_ENTRY(type)						\
+struct {								\
+	struct type *le_next;	/* next element */			\
+	struct type **le_prev;	/* address of previous next element */	\
+}
+
+/*
+ * List functions.
+ */
+
+#define	LIST_EMPTY(head)	((head)->lh_first == NULL)
+
+#define	LIST_FIRST(head)	((head)->lh_first)
+
+#define	LIST_FOREACH(var, head, field)					\
+	for ((var) = LIST_FIRST((head));				\
+	    (var);							\
+	    (var) = LIST_NEXT((var), field))
+
+#define	LIST_INIT(head) do {						\
+	LIST_FIRST((head)) = NULL;					\
+} while (0)
+
+#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
+	if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
+		LIST_NEXT((listelm), field)->field.le_prev =		\
+		    &LIST_NEXT((elm), field);				\
+	LIST_NEXT((listelm), field) = (elm);				\
+	(elm)->field.le_prev = &LIST_NEXT((listelm), field);		\
+} while (0)
+
+#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.le_prev = (listelm)->field.le_prev;		\
+	LIST_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.le_prev = (elm);				\
+	(listelm)->field.le_prev = &LIST_NEXT((elm), field);		\
+} while (0)
+
+#define	LIST_INSERT_HEAD(head, elm, field) do {				\
+	if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)	\
+		LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
+	LIST_FIRST((head)) = (elm);					\
+	(elm)->field.le_prev = &LIST_FIRST((head));			\
+} while (0)
+
+#define	LIST_NEXT(elm, field)	((elm)->field.le_next)
+
+#define	LIST_REMOVE(elm, field) do {					\
+	if (LIST_NEXT((elm), field) != NULL)				\
+		LIST_NEXT((elm), field)->field.le_prev =		\
+		    (elm)->field.le_prev;				\
+	*(elm)->field.le_prev = LIST_NEXT((elm), field);		\
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#define	TAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *tqh_first;	/* first element */			\
+	struct type **tqh_last;	/* addr of last next element */		\
+	TRACEBUF							\
+}
+
+#define	TAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).tqh_first }
+
+#define	TAILQ_ENTRY(type)						\
+struct {								\
+	struct type *tqe_next;	/* next element */			\
+	struct type **tqe_prev;	/* address of previous next element */	\
+	TRACEBUF							\
+}
+
+/*
+ * Tail queue functions.
+ */
+#define	TAILQ_CONCAT(head1, head2, field) do {				\
+	if (!TAILQ_EMPTY(head2)) {					\
+		*(head1)->tqh_last = (head2)->tqh_first;		\
+		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
+		(head1)->tqh_last = (head2)->tqh_last;			\
+		TAILQ_INIT((head2));					\
+		QMD_TRACE_HEAD(head);					\
+		QMD_TRACE_HEAD(head2);					\
+	}								\
+} while (0)
+
+#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
+
+#define	TAILQ_FIRST(head)	((head)->tqh_first)
+
+#define	TAILQ_FOREACH(var, head, field)					\
+	for ((var) = TAILQ_FIRST((head));				\
+	    (var);							\
+	    (var) = TAILQ_NEXT((var), field))
+
+#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    (var);							\
+	    (var) = TAILQ_PREV((var), headname, field))
+
+#define	TAILQ_INIT(head) do {						\
+	TAILQ_FIRST((head)) = NULL;					\
+	(head)->tqh_last = &TAILQ_FIRST((head));			\
+	QMD_TRACE_HEAD(head);						\
+} while (0)
+
+#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
+		TAILQ_NEXT((elm), field)->field.tqe_prev =		\
+		    &TAILQ_NEXT((elm), field);				\
+	else {								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+		QMD_TRACE_HEAD(head);					\
+	}								\
+	TAILQ_NEXT((listelm), field) = (elm);				\
+	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+	QMD_TRACE_ELEM(&listelm->field);				\
+} while (0)
+
+#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
+	TAILQ_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.tqe_prev = (elm);				\
+	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+	QMD_TRACE_ELEM(&listelm->field);				\
+} while (0)
+
+#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
+		TAILQ_FIRST((head))->field.tqe_prev =			\
+		    &TAILQ_NEXT((elm), field);				\
+	else								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+	TAILQ_FIRST((head)) = (elm);					\
+	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
+	QMD_TRACE_HEAD(head);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
+	TAILQ_NEXT((elm), field) = NULL;				\
+	(elm)->field.tqe_prev = (head)->tqh_last;			\
+	*(head)->tqh_last = (elm);					\
+	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
+	QMD_TRACE_HEAD(head);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define	TAILQ_LAST(head, headname)					\
+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define	TAILQ_PREV(elm, headname, field)				\
+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define	TAILQ_REMOVE(head, elm, field) do {				\
+	if ((TAILQ_NEXT((elm), field)) != NULL)				\
+		TAILQ_NEXT((elm), field)->field.tqe_prev =		\
+		    (elm)->field.tqe_prev;				\
+	else {								\
+		(head)->tqh_last = (elm)->field.tqe_prev;		\
+		QMD_TRACE_HEAD(head);					\
+	}								\
+	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
+	TRASHIT((elm)->field.tqe_next);					\
+	TRASHIT((elm)->field.tqe_prev);					\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#if defined(__cplusplus)
+}
+#endif
+#endif	/* !_DB_QUEUE_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/region.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,351 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_REGION_H_
+#define	_DB_REGION_H_
+
+/*
+ * The DB environment consists of some number of "regions", which are described
+ * by the following four structures:
+ *
+ *	REGENV	   -- shared information about the environment
+ *	REGENV_REF -- file describing system memory version of REGENV
+ *	REGION	   -- shared information about a single region
+ *	REGINFO	   -- per-process information about a REGION
+ *
+ * There are three types of memory that hold regions:
+ *	per-process heap (malloc)
+ *	file mapped into memory (mmap, MapViewOfFile)
+ *	system memory (shmget, CreateFileMapping)
+ *
+ * By default, regions are created in filesystem-backed shared memory.  They
+ * can also be created in system shared memory (DB_SYSTEM_MEM), or, if private
+ * to a process, in heap memory (DB_PRIVATE).
+ *
+ * Regions in the filesystem are named "__db.001", "__db.002" and so on.  If
+ * we're not using a private environment allocated in heap, "__db.001" will
+ * always exist, as we use it to synchronize on the regions, whether they are
+ * in filesystem-backed memory or system memory.
+ *
+ * The file "__db.001" contains a REGENV structure pointing to  an
+ * array of REGION structures.  Each REGION structures describes an
+ * underlying chunk of shared memory.
+ *
+ *	__db.001
+ *	+---------+
+ *	|REGENV   |
+ *	+---------+
+ *          |
+ *         \/
+ *	+---------+   +----------+
+ *	|REGION   |-> | __db.001 |
+ *	|	  |   +----------+
+ *	+---------+   +----------+
+ *	|REGION   |-> | __db.002 |
+ *	|	  |   +----------+
+ *	+---------+   +----------+
+ *	|REGION   |-> | __db.003 |
+ *	|	  |   +----------+
+ *	+---------+   +----------+
+ *	|REGION   |-> | __db.004 |
+ *	|	  |   +----------+
+ *	+---------+
+ *
+ * The tricky part about manipulating the regions is creating or joining the
+ * database environment.  We have to be sure only a single thread of control
+ * creates and/or recovers a database environment.  All other threads should
+ * then join without seeing inconsistent data.
+ *
+ * We do this in two parts: first, we use the underlying O_EXCL flag to the
+ * open system call to serialize creation of the __db.001 file.  The thread
+ * of control creating that file then proceeds to create the remaining
+ * regions in the environment, including the mutex region.  Once the mutex
+ * region has been created, the creating thread of control fills in the
+ * __db.001 file's magic number.  Other threads of control (the ones that
+ * didn't create the __db.001 file), wait on the initialization of the
+ * __db.001 file's magic number.  After it has been initialized, all threads
+ * of control can proceed, using normal shared mutex locking procedures for
+ * exclusion.
+ *
+ * REGIONs are not moved or removed during the life of the environment, and
+ * so processes can have long-lived references to them.
+ *
+ * One of the REGION structures describes the environment region itself.
+ *
+ * The REGION array is not locked in any way.  It's an array so we don't have
+ * to manipulate data structures after a crash -- on some systems, we have to
+ * join and clean up the mutex region after application failure.  Using an
+ * array means we don't have to worry about broken links or other nastiness
+ * after the failure.
+ *
+ * All requests to create or join a region return a REGINFO structure, which
+ * is held by the caller and used to open and subsequently close the reference
+ * to the region.  The REGINFO structure contains the per-process information
+ * that we need to access the region.
+ *
+ * The one remaining complication.  If the regions (including the environment
+ * region) live in system memory, and the system memory isn't "named" somehow
+ * in the filesystem name space, we need some way of finding it.  Do this by
+ * by writing the REGENV_REF structure into the "__db.001" file.  When we find
+ * a __db.001 file that is too small to be a real, on-disk environment, we use
+ * the information it contains to redirect to the real "__db.001" file/memory.
+ * This currently only happens when the REGENV file is in shared system memory.
+ *
+ * Although DB does not currently grow regions when they run out of memory, it
+ * would be possible to do so.  To grow a region, allocate a new region of the
+ * appropriate size, then copy the old region over it and insert the additional
+ * memory into the already existing shalloc arena.  Region users must reset
+ * their base addresses and any local pointers into the memory, of course.
+ * This failed in historic versions of DB because the region mutexes lived in
+ * the mapped memory, and when it was unmapped and remapped (or copied),
+ * threads could lose track of it.  Also, some systems didn't support mutex
+ * copying, e.g., from OSF1 V4.0:
+ *
+ *	The address of an msemaphore structure may be significant.  If the
+ *	msemaphore structure contains any value copied from an msemaphore
+ *	structure at a different address, the result is undefined.
+ *
+ * All mutexes are now maintained in a separate region which is never unmapped,
+ * so growing regions should be possible.
+ */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define	DB_REGION_PREFIX	"__db"		/* DB file name prefix. */
+#define	DB_REGION_FMT		"__db.%03d"	/* Region file name format. */
+#define	DB_REGION_ENV		"__db.001"	/* Primary environment name. */
+#define IS_DB_FILE(name)	(strncmp(name, DB_REGION_PREFIX,	\
+				    sizeof(DB_REGION_PREFIX) - 1) == 0)
+
+#define	INVALID_REGION_ID	0	/* Out-of-band region ID. */
+#define	REGION_ID_ENV		1	/* Primary environment ID. */
+
+typedef enum {
+	INVALID_REGION_TYPE=0,		/* Region type. */
+	REGION_TYPE_ENV,
+	REGION_TYPE_LOCK,
+	REGION_TYPE_LOG,
+	REGION_TYPE_MPOOL,
+	REGION_TYPE_MUTEX,
+	REGION_TYPE_TXN } reg_type_t;
+
+#define	INVALID_REGION_SEGID	-1	/* Segment IDs are either shmget(2) or
+					 * Win16 segment identifiers.  They are
+					 * both stored in a "long", and we need
+					 * an out-of-band value.
+					 */
+/*
+ * Nothing can live at region offset 0, because, in all cases, that's where
+ * we store *something*.  Lots of code needs an out-of-band value for region
+ * offsets, so we use 0.
+ */
+#define	INVALID_ROFF		0
+
+/* Reference describing system memory version of REGENV. */
+typedef struct __db_reg_env_ref {
+	roff_t	   size;		/* Region size. */
+	roff_t	   max;			/* Region max in bytes. */
+	long	   segid;		/* UNIX shmget ID, VxWorks ID. */
+} REGENV_REF;
+
+/* Per-environment region information. */
+typedef struct __db_reg_env { /* SHARED */
+	/*
+	 * !!!
+	 * The magic, panic, version, envid and signature fields of the region
+	 * are fixed in size, the timestamp field is the first field which is
+	 * variable length.  These fields must never change in order, to
+	 * guarantee we can always read them, no matter what release we have.
+	 *
+	 * !!!
+	 * The magic and panic fields are NOT protected by any mutex, and for
+	 * this reason cannot be anything more complicated than zero/non-zero.
+	 */
+	u_int32_t magic;		/* Valid region magic number. */
+	u_int32_t panic;		/* Environment is dead. */
+
+	u_int32_t majver;		/* Major DB version number. */
+	u_int32_t minver;		/* Minor DB version number. */
+	u_int32_t patchver;		/* Patch DB version number. */
+
+	u_int32_t envid;		/* Unique environment ID. */
+
+	u_int32_t signature;		/* Structure signatures. */
+
+	time_t	  timestamp;		/* Creation time. */
+
+	/*
+	 * Flags saved in the init_flags field of the environment, representing
+	 * flags to DB_ENV->set_flags and DB_ENV->open that need to be set.
+	 */
+	u_int32_t init_flags;
+#define	DB_INITENV_CDB		0x0001	/* DB_INIT_CDB */
+#define	DB_INITENV_CDB_ALLDB	0x0002	/* DB_INIT_CDB_ALLDB */
+#define	DB_INITENV_LOCK		0x0004	/* DB_INIT_LOCK */
+#define	DB_INITENV_LOG		0x0008	/* DB_INIT_LOG */
+#define	DB_INITENV_MPOOL	0x0010	/* DB_INIT_MPOOL */
+#define	DB_INITENV_REP		0x0020	/* DB_INIT_REP */
+#define	DB_INITENV_TXN		0x0040	/* DB_INIT_TXN */
+
+
+	/*
+	 * The mtx_regenv mutex protects the environment reference count and
+	 * memory allocation from the primary shared region (the crypto, thread
+	 * control block and replication implementations allocate memory from
+	 * the primary shared region).
+	 *
+	 * The rest of the fields are initialized at creation time, and don't
+	 * need mutex protection.  The flags, op_timestamp and rep_timestamp
+	 * fields are used by replication only and are protected by the
+	 * replication mutex.  The rep_timestamp is is not protected when it
+	 * is used in recovery as that is already single threaded.
+	 */
+	db_mutex_t mtx_regenv;		/* Refcnt, region allocation mutex. */
+	u_int32_t  refcnt;		/* References to the environment. */
+
+	u_int32_t region_cnt;		/* Number of REGIONs. */
+	roff_t	  region_off;		/* Offset of region array */
+	roff_t    lt_primary;		/* Lock primary. */
+	roff_t    lg_primary;		/* Log primary. */
+	roff_t    tx_primary;		/* Txn primary. */
+
+	roff_t	  cipher_off;		/* Offset of cipher area */
+
+	roff_t	  thread_off;		/* Offset of the thread area. */
+
+	roff_t	  rep_off;		/* Offset of the replication area. */
+#define	DB_REGENV_REPLOCKED	0x0001	/* Env locked for rep backup. */
+	u_int32_t flags;		/* Shared environment flags. */
+#define	DB_REGENV_TIMEOUT	30	/* Backup timeout. */
+	time_t	  op_timestamp;		/* Timestamp for operations. */
+	time_t	  rep_timestamp;	/* Timestamp for rep db handles. */
+	u_int32_t reg_panic;		/* DB_REGISTER triggered panic */
+	uintmax_t unused;		/* The ALLOC_LAYOUT structure follows
+					 * the REGENV structure in memory and
+					 * contains uintmax_t fields.  Force
+					 * proper alignment of that structure.
+					 */
+} REGENV;
+
+/* Per-region shared region information. */
+typedef struct __db_region { /* SHARED */
+	roff_t	size;			/* Region size in bytes. */
+	roff_t  max;			/* Region max in bytes. */
+	long	segid;			/* UNIX shmget(2), Win16 segment ID. */
+
+	u_int32_t	id;		/* Region id. */
+	reg_type_t	type;		/* Region type. */
+
+	roff_t	primary;		/* Primary data structure offset. */
+	roff_t  alloc;			/* Region allocation size in bytes. */
+} REGION;
+
+/*
+ * Per-process/per-attachment information about a single region.
+ */
+
+/*
+ * Structure used for tracking allocations in DB_PRIVATE regions. 
+ */
+struct __db_region_mem_t;	typedef struct __db_region_mem_t REGION_MEM;
+struct __db_region_mem_t {
+	REGION_MEM *next;
+};
+
+struct __db_reginfo_t {		/* __env_region_attach IN parameters. */
+	ENV	   *env;		/* Enclosing environment. */
+	reg_type_t  type;		/* Region type. */
+	u_int32_t   id;			/* Region id. */
+
+				/* env_region_attach OUT parameters. */
+	REGION	   *rp;			/* Shared region. */
+
+	char	   *name;		/* Region file name. */
+	DB_FH	   *fhp;		/* Region file handle */
+
+	void	   *addr;		/* Region address. */
+	void	   *head;		/* Head of the allocation struct. */
+	void	   *primary;		/* Primary data structure address. */
+
+					/* Private Memory Tracking. */
+	size_t	    max_alloc;		/* Maximum bytes allocated. */
+	size_t	    allocated;		/* Bytes allocated. */
+	REGION_MEM  *mem;		/* List of memory to free */
+
+	db_mutex_t  mtx_alloc;		/* number of mutex for allocation. */
+
+#ifdef DB_WIN32
+	HANDLE	wnt_handle;		/* Win/NT HANDLE. */
+#endif
+
+#define	REGION_CREATE		0x01	/* Caller created region. */
+#define	REGION_CREATE_OK	0x02	/* Caller willing to create region. */
+#define	REGION_JOIN_OK		0x04	/* Caller is looking for a match. */
+#define	REGION_SHARED		0x08	/* Region is shared. */
+#define	REGION_TRACKED		0x10	/* Region private memory is tracked. */
+	u_int32_t   flags;
+};
+
+/*
+ * R_ADDR	Return a per-process address for a shared region offset.
+ * R_OFFSET	Return a shared region offset for a per-process address.
+ */
+#define	R_ADDR(reginfop, offset)					\
+	(F_ISSET((reginfop)->env, ENV_PRIVATE) ?			\
+	    ROFF_TO_P(offset) :						\
+	    (void *)((u_int8_t *)((reginfop)->addr) + (offset)))
+#define	R_OFFSET(reginfop, p)						\
+	(F_ISSET((reginfop)->env, ENV_PRIVATE) ?			\
+	    P_TO_ROFF(p) :						\
+	    (roff_t)((u_int8_t *)(p) - (u_int8_t *)(reginfop)->addr))
+
+/*
+ * PANIC_ISSET, PANIC_CHECK:
+ *	Check to see if the DB environment is dead.
+ */
+#define	PANIC_ISSET(env)						\
+	((env) != NULL && (env)->reginfo != NULL &&			\
+	    ((REGENV *)(env)->reginfo->primary)->panic != 0 &&		\
+	    !F_ISSET((env)->dbenv, DB_ENV_NOPANIC))
+
+#define	PANIC_CHECK(env)						\
+	if (PANIC_ISSET(env))						\
+		return (__env_panic_msg(env));
+
+#define	PANIC_CHECK_RET(env, ret)			       		\
+	if (PANIC_ISSET(env))						\
+		ret = (__env_panic_msg(env));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_REGION_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/rep.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1126 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_REP_H_
+#define	_DB_REP_H_
+
+#include "dbinc_auto/rep_automsg.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Names of client temp databases.
+ */
+#define	REPFILEPREFIX	"__db.rep"
+#define	REPDBNAME	"__db.rep.db"
+#define	REPPAGENAME     "__db.reppg.db"
+
+/*
+ * Name of replicated system database file, and LSN history subdatabase within
+ * it.  If the INMEM config flag is set, we create the database in memory, with
+ * the REPLSNHIST name (so that is why it also follows the __db naming
+ * convention).
+ */
+#define	REPSYSDBNAME	"__db.rep.system"
+#define	REPLSNHIST	"__db.lsn.history"
+#define	REPMEMBERSHIP	"__db.membership"
+#define	REPSYSDBPGSZ	1024
+#define IS_REP_FILE(name)	(strcmp(name, REPSYSDBNAME) == 0)
+				    
+
+/* Current version of commit token format, and LSN history database format. */
+#define	REP_COMMIT_TOKEN_FMT_VERSION	1
+#define	REP_LSN_HISTORY_FMT_VERSION	1
+
+/*
+ * Message types
+ */
+#define	REP_INVALID	0	/* Invalid message type. */
+#define	REP_ALIVE	1	/* I am alive message. */
+#define	REP_ALIVE_REQ	2	/* Request for alive messages. */
+#define	REP_ALL_REQ	3	/* Request all log records greater than LSN. */
+#define	REP_BULK_LOG	4	/* Bulk transfer of log records. */
+#define	REP_BULK_PAGE	5	/* Bulk transfer of pages. */
+#define	REP_DUPMASTER	6	/* Duplicate master detected; propagate. */
+#define	REP_FILE	7	/* Page of a database file. NOTUSED */
+#define	REP_FILE_FAIL	8	/* File requested does not exist. */
+#define	REP_FILE_REQ	9	/* Request for a database file. NOTUSED */
+#define	REP_LEASE_GRANT	10	/* Client grants a lease to a master. */
+#define	REP_LOG		11	/* Log record. */
+#define	REP_LOG_MORE	12	/* There are more log records to request. */
+#define	REP_LOG_REQ	13	/* Request for a log record. */
+#define	REP_MASTER_REQ	14	/* Who is the master */
+#define	REP_NEWCLIENT	15	/* Announces the presence of a new client. */
+#define	REP_NEWFILE	16	/* Announce a log file change. */
+#define	REP_NEWMASTER	17	/* Announces who the master is. */
+#define	REP_NEWSITE	18	/* Announces that a site has heard from a new
+				 * site; like NEWCLIENT, but indirect.  A
+				 * NEWCLIENT message comes directly from the new
+				 * client while a NEWSITE comes indirectly from
+				 * someone who heard about a NEWSITE.
+				 */
+#define	REP_PAGE	19	/* Database page. */
+#define	REP_PAGE_FAIL	20	/* Requested page does not exist. */
+#define	REP_PAGE_MORE	21	/* There are more pages to request. */
+#define	REP_PAGE_REQ	22	/* Request for a database page. */
+#define	REP_REREQUEST	23	/* Force rerequest. */
+#define	REP_START_SYNC	24	/* Tell client to begin syncing a ckp.*/
+#define	REP_UPDATE	25	/* Environment hotcopy information. */
+#define	REP_UPDATE_REQ	26	/* Request for hotcopy information. */
+#define	REP_VERIFY	27	/* A log record for verification. */
+#define	REP_VERIFY_FAIL	28	/* The client is outdated. */
+#define	REP_VERIFY_REQ	29	/* Request for a log record to verify. */
+#define	REP_VOTE1	30	/* Send out your information for an election. */
+#define	REP_VOTE2	31	/* Send a "you are master" vote. */
+/*
+ * Maximum message number for conversion tables.  Update this
+ * value as the largest message number above increases.
+ * It might make processing messages more straightforward if
+ * the *_MORE and BULK* messages were flags within the regular
+ * message type instead of separate message types themselves.
+ *
+ * !!!
+ * NOTE: When changing messages above, the two tables for upgrade support
+ * need adjusting.  They are in rep_util.c.
+ */
+#define	REP_MAX_MSG	31
+
+/*
+ * This is the list of client-to-client requests messages.
+ * We use this to decide if we're doing client-to-client and
+ * might need to send a rerequest.
+ */
+#define	REP_MSG_REQ(rectype)			\
+    (rectype == REP_ALL_REQ ||			\
+    rectype == REP_LOG_REQ ||			\
+    rectype == REP_PAGE_REQ ||			\
+    rectype == REP_VERIFY_REQ)
+
+/*
+ * Note that the version information should be at the beginning of the
+ * structure, so that we can rearrange the rest of it while letting the
+ * version checks continue to work.  DB_REPVERSION should be revved any time
+ * the rest of the structure changes or when the message numbers change.
+ *
+ * Define also, the corresponding log versions that are tied to the
+ * replication/release versions.  These are only needed in replication
+ * and that is why they're defined here. db_printlog takes notice as well.
+ */
+#define	DB_LOGVERSION_42	8
+#define	DB_LOGVERSION_43	10
+#define	DB_LOGVERSION_44	11
+#define	DB_LOGVERSION_45	12
+#define	DB_LOGVERSION_46	13
+#define	DB_LOGVERSION_47	14
+#define	DB_LOGVERSION_48	15
+#define	DB_LOGVERSION_48p2	16
+#define	DB_LOGVERSION_50	17
+#define	DB_LOGVERSION_51	17
+#define	DB_LOGVERSION_52	18
+#define	DB_LOGVERSION_53	19
+#define	DB_LOGVERSION_60	20
+#define	DB_LOGVERSION_MIN	DB_LOGVERSION_44
+#define	DB_REPVERSION_INVALID	0
+#define	DB_REPVERSION_44	3
+#define	DB_REPVERSION_45	3
+#define	DB_REPVERSION_46	4
+#define	DB_REPVERSION_47	5
+#define	DB_REPVERSION_48	5
+#define	DB_REPVERSION_50	5
+#define	DB_REPVERSION_51	5
+#define	DB_REPVERSION_52	6
+#define	DB_REPVERSION_53	7
+#define	DB_REPVERSION_60	7
+#define	DB_REPVERSION		DB_REPVERSION_60
+#define	DB_REPVERSION_MIN	DB_REPVERSION_44
+
+/*
+ * RPRINT - Replication diagnostic output
+ * VPRINT - Replication verbose output (superset of RPRINT).
+ * REP_PRINT_MESSAGE
+ *	Macros for verbose replication messages.
+ *
+ * Everything using RPRINT will go to the system diag file (if it
+ * is configured) and also to the user's verbose output if
+ * they have that verbose level configured.
+ * Messages using VPRINT do not ever go to the system diag file,
+ * but will go to the user's verbose output if configured.
+ *
+ * Use VPRINT for anything that might be printed on a standard,
+ * successful transaction.  Use RPRINT for error paths, rep
+ * state changes, elections, etc.
+ */
+#define	REP_DIAGNAME	"__db.rep.diag%02d"
+#define	REP_DIAGSIZE	MEGABYTE
+#define	RPRINT(env, x) do {						\
+	if ((env)->dbenv->verbose != 0)					\
+		(void)__rep_print_system x;				\
+} while (0)
+#define	VPRINT(env, x) do {						\
+	if ((env)->dbenv->verbose != 0)					\
+		(void)__rep_print x;					\
+} while (0)
+#define	REP_PRINT_MESSAGE(env, eid, rp, str, fl) do {			\
+	if ((env)->dbenv->verbose != 0)					\
+		__rep_print_message(env, eid, rp, str, fl);		\
+} while (0)
+
+/*
+ * Election gen file name
+ * The file contains an egen number for an election this client has NOT
+ * participated in.  I.e. it is the number of a future election.  We
+ * create it when we create the rep region, if it doesn't already exist
+ * and initialize egen to 1.  If it does exist, we read it when we create
+ * the rep region.  We write it immediately before sending our VOTE1 in
+ * an election.  That way, if a client has ever sent a vote for any
+ * election, the file is already going to be updated to reflect a future
+ * election, should it crash.
+ */
+#define	REP_EGENNAME	"__db.rep.egen"
+#define	REP_GENNAME	"__db.rep.gen"
+
+/*
+ * Internal init flag file name:
+ * The existence of this file serves as an indication that the client is in the
+ * process of Internal Initialization, in case it crashes before completing.
+ * During internal init the client's partially reconstructed database pages and
+ * logs may be in an inconsistent state, so much so that running recovery must
+ * be avoided.  Furthermore, there is no other way to reliably recognize this
+ * condition.  Therefore, when we open an environment, and we're just about to
+ * run recovery, we check for this file first.  If it exists we must discard all
+ * logs and databases.  This avoids the recovery problems, and leads to a fresh
+ * attempt at internal init if the environment becomes a replication client and
+ * finds a master.  The list of databases which may need to be removed is stored
+ * in this file.
+ */
+#define	REP_INITNAME	"__db.rep.init"
+#define	REP_INITVERSION_46	1
+#define	REP_INITVERSION_47	2
+#define	REP_INITVERSION		3
+
+/*
+ * Database types for __rep_client_dbinit
+ */
+typedef enum {
+	REP_DB,		/* Log record database. */
+	REP_PG		/* Pg database. */
+} repdb_t;
+
+/* Macros to lock/unlock the replication region as a whole. */
+#define	REP_SYSTEM_LOCK(env)						\
+	MUTEX_LOCK(env, (env)->rep_handle->region->mtx_region)
+#define	REP_SYSTEM_UNLOCK(env)						\
+	MUTEX_UNLOCK(env, (env)->rep_handle->region->mtx_region)
+
+/*
+ * Macros for manipulating the event synchronization.  We use a separate mutex
+ * so that an application's call-back function can be invoked without locking
+ * the whole region.
+ */
+#define	REP_EVENT_LOCK(env)						\
+	MUTEX_LOCK(env, (env)->rep_handle->region->mtx_event)
+#define	REP_EVENT_UNLOCK(env)						\
+	MUTEX_UNLOCK(env, (env)->rep_handle->region->mtx_event)
+
+/*
+ * Synchronization states
+ * Please change __rep_syncstate_to_string (rep_stat.c) to track any changes
+ * made to these states.
+ *
+ * The states are in alphabetical order (except for OFF).  The usual
+ * order of progression for a full internal init is:
+ * VERIFY, UPDATE, PAGE, LOG (then back to OFF when we're done).
+ */
+typedef enum {
+	SYNC_OFF,	/* No recovery. */
+	SYNC_LOG,	/* Recovery - log. */
+	SYNC_PAGE,	/* Recovery - pages. */
+	SYNC_UPDATE,	/* Recovery - update. */
+	SYNC_VERIFY 	/* Recovery - verify. */
+} repsync_t;
+
+/*
+ * A record of the contents of the VOTE1 msg we sent out at current egen, in
+ * case we need to send out a duplicate VOTE1 to a late-joining client in a full
+ * election.  The nsites, nvotes, and priority fields of the REP struct can't be
+ * used, because those could change.  It's only safe to send out a dup if we
+ * send out the exact same info.
+ */
+typedef struct {
+	DB_LSN lsn;
+	u_int32_t nsites;
+	u_int32_t nvotes;
+	u_int32_t priority;
+	u_int32_t tiebreaker;
+	u_int32_t ctlflags;
+	u_int32_t data_gen;
+} VOTE1_CONTENT;
+
+/*
+ * REP --
+ * Shared replication structure.
+ */
+typedef struct __rep { /* SHARED */
+	db_mutex_t	mtx_region;	/* Region mutex. */
+	db_mutex_t	mtx_clientdb;	/* Client database mutex. */
+	db_mutex_t	mtx_ckp;	/* Checkpoint mutex. */
+	db_mutex_t	mtx_diag;	/* Diagnostic message mutex. */
+	db_mutex_t	mtx_repstart;	/* Role change mutex. */
+	int		diag_index;	/* Diagnostic file index. */
+	off_t		diag_off;	/* Diagnostic message offset. */
+	roff_t		lease_off;	/* Offset of the lease table. */
+	roff_t		tally_off;	/* Offset of the tally region. */
+	roff_t		v2tally_off;	/* Offset of the vote2 tally region. */
+	int		eid;		/* Environment id. */
+	int		master_id;	/* ID of the master site. */
+	u_int32_t	version;	/* Current replication version. */
+	u_int32_t	egen;		/* Replication election generation. */
+	u_int32_t	spent_egen;	/* Egen satisfied by rep_elect call. */
+	u_int32_t	gen;		/* Replication generation number. */
+	u_int32_t	mgen;		/* Master gen seen by client. */
+	u_int32_t	asites;		/* Space allocated for sites. */
+	u_int32_t	nsites;		/* Number of sites in group. */
+	u_int32_t	nvotes;		/* Number of votes needed. */
+	u_int32_t	priority;	/* My priority in an election. */
+	u_int32_t	config_nsites;
+
+	db_timeout_t	elect_timeout;	/* Normal/full election timeouts. */
+	db_timeout_t	full_elect_timeout;
+
+	db_timeout_t	chkpt_delay;	/* Master checkpoint delay. */
+
+#define	REP_DEFAULT_THROTTLE	(10 * MEGABYTE) /* Default value is < 1Gig. */
+	u_int32_t	gbytes;		/* Limit on data sent in single... */
+	u_int32_t	bytes;		/* __rep_process_message call. */
+#define	DB_REP_REQUEST_GAP	40000	/* 40 msecs */
+#define	DB_REP_MAX_GAP		1280000	/* 1.28 seconds */
+	db_timespec	request_gap;	/* Minimum time to wait before we
+					 * request a missing log record. */
+	db_timespec	max_gap;	/* Maximum time to wait before
+					 * requesting a missing log record. */
+	/* Status change information */
+	u_int32_t	apply_th;	/* Number of callers in rep_apply. */
+	u_int32_t	arch_th;	/* Number of callers in log_archive. */
+	u_int32_t	elect_th;	/* Elect threads in lock-out. */
+	u_int32_t	msg_th;		/* Number of callers in rep_proc_msg.*/
+	u_int32_t	handle_cnt;	/* Count of handles in library. */
+	u_int32_t	op_cnt;		/* Multi-step operation count.*/
+	DB_LSN		ckp_lsn;	/* LSN for syncing a checkpoint. */
+	DB_LSN		max_prep_lsn;	/* Max LSN of txn_prepare record. */
+
+	/*
+	 * Event notification synchronization: the mtx_event and associate
+	 * fields which it protects govern event notification to the
+	 * application.  They form a guarantee that no matter how crazy the
+	 * thread scheduling gets, the application sees a sensible, orderly
+	 * progression of events.
+	 */
+	db_mutex_t	mtx_event;	/* Serializes event notification. */
+	/*
+	 * Latest generation whose NEWMASTER event the application has been
+	 * notified of.  Also serves to force STARTUPDONE to occur after
+	 * NEWMASTER.
+	 */
+	u_int32_t	newmaster_event_gen;
+	/*
+	 * Latest local victory of an election that the application has been
+	 * notified of, expressed as the election generation number.  This
+	 * ensures we notify the application exactly once when it wins an
+	 * election.
+	 */
+	u_int32_t	notified_egen;
+
+	/* Internal init information. */
+	u_int32_t	nfiles;		/* Number of files we have info on. */
+	u_int32_t	curfile;	/* Cur file we're getting (0-based). */
+	roff_t		originfo_off;	/* Offset of original file info. */
+	u_int32_t	infolen;	/* Remaining length file info buffer. */
+	u_int32_t	originfolen;	/* Original length file info buffer. */
+	u_int32_t	infoversion;	/* Original file info version. */
+	DB_LSN		first_lsn;	/* Earliest LSN we need. */
+	u_int32_t	first_vers;	/* Log version of first log file. */
+	DB_LSN		last_lsn;	/* Latest LSN we need. */
+	/* These are protected by mtx_clientdb. */
+	db_timespec	last_pg_ts;	/* Last page stored timestamp. */
+	db_pgno_t	ready_pg;	/* Next pg expected. */
+	db_pgno_t	waiting_pg;	/* First pg after gap. */
+	db_pgno_t	max_wait_pg;	/* Maximum pg requested. */
+	u_int32_t	npages;		/* Num of pages rcvd for this file. */
+	roff_t		curinfo_off;	/* Offset of current file info. */
+					/* Always access with GET_CURINFO(). */
+
+	/* Vote tallying information. */
+	u_int32_t	sites;		/* Sites heard from. */
+	int		winner;		/* Current winner EID. */
+	u_int32_t	w_priority;	/* Winner priority. */
+	u_int32_t	w_gen;		/* Winner generation. */
+	u_int32_t	w_datagen;	/* Winner data generation. */
+	DB_LSN		w_lsn;		/* Winner LSN. */
+	u_int32_t	w_tiebreaker;	/* Winner tiebreaking value. */
+	u_int32_t	votes;		/* Number of votes for this site. */
+
+	VOTE1_CONTENT	vote1;		/* Valid until rep->egen changes. */
+
+	db_timespec	etime;		/* Election start timestamp. */
+	int		full_elect;	/* Is current election a "full" one? */
+
+	/* Leases. */
+	db_timeout_t	lease_timeout;	/* Lease timeout. */
+	db_timespec	lease_duration;	/* Lease timeout with clock skew. */
+	u_int32_t	clock_skew;	/* Clock skew. */
+	u_int32_t	clock_base;	/* Clock scale factor base. */
+	db_timespec	grant_expire;	/* Local grant expiration time. */
+
+	/* Cached LSN history, matching current gen. */
+	DB_LSN		gen_base_lsn;	/* Base LSN of current generation. */
+	u_int32_t	master_envid;	/* Current master's "unique" env ID. */
+
+	SH_TAILQ_HEAD(__wait) waiters;	/* List of threads in txn_applied(). */
+	SH_TAILQ_HEAD(__wfree) free_waiters;/* Free list of waiter structs. */
+
+#ifdef HAVE_REPLICATION_THREADS
+	/*
+	 * Replication Framework (repmgr) shared config information.
+	 */
+	db_mutex_t	mtx_repmgr;	/* Region mutex. */
+	roff_t		siteinfo_off;	/* Offset of site array region. */
+	u_int		site_cnt;	/* Array slots in use. */
+	u_int		site_max;	/* Total array slots allocated. */
+	int		self_eid;	/* Where to find the local site. */
+	u_int		siteinfo_seq;	/* Number of updates to this info. */
+	u_int32_t	min_log_file;	/* Earliest log needed by repgroup. */
+
+	pid_t		listener;
+
+	int		perm_policy;
+	db_timeout_t	ack_timeout;
+	db_timeout_t	election_retry_wait;
+	db_timeout_t	connection_retry_wait;
+	db_timeout_t	heartbeat_frequency; /* Max period between msgs. */
+	db_timeout_t	heartbeat_monitor_timeout;
+#endif  /* HAVE_REPLICATION_THREADS */
+
+	/* Statistics. */
+	DB_REP_STAT	stat;
+#if defined(HAVE_REPLICATION_THREADS) && defined(HAVE_STATISTICS)
+	DB_REPMGR_STAT	mstat;
+#endif
+
+	/*
+	 * Please change __rep_print_all (rep_stat.c) to track any changes made
+	 * to all these flag families below.
+	 */
+	/* Configuration. */
+#define	REP_C_2SITE_STRICT	0x00001		/* Don't cheat on elections. */
+#define	REP_C_AUTOINIT		0x00002		/* Auto initialization. */
+#define	REP_C_AUTOROLLBACK	0x00004		/* Discard client txns: sync. */
+#define	REP_C_BULK		0x00008		/* Bulk transfer. */
+#define	REP_C_DELAYCLIENT	0x00010		/* Delay client sync-up. */
+#define	REP_C_ELECTIONS		0x00020		/* Repmgr to use elections. */
+#define	REP_C_INMEM		0x00040		/* In-memory replication. */
+#define	REP_C_LEASE		0x00080		/* Leases configured. */
+#define	REP_C_NOWAIT		0x00100		/* Immediate error return. */
+	u_int32_t	config;		/* Configuration flags. */
+
+	/* Election. */
+#define	REP_E_PHASE0		0x00000001	/* In phase 0 of election. */
+#define	REP_E_PHASE1		0x00000002	/* In phase 1 of election. */
+#define	REP_E_PHASE2		0x00000004	/* In phase 2 of election. */
+#define	REP_E_TALLY		0x00000008	/* Tallied vote before elect. */
+	u_int32_t	elect_flags;	/* Election flags. */
+
+	/* Lockout. */
+#define	REP_LOCKOUT_API		0x00000001	/* BDB API - handle_cnt. */
+#define	REP_LOCKOUT_APPLY	0x00000002	/* apply msgs - apply_th. */
+#define	REP_LOCKOUT_ARCHIVE	0x00000004	/* log_archive. */
+#define	REP_LOCKOUT_MSG		0x00000008	/* Message process - msg_th. */
+#define	REP_LOCKOUT_OP		0x00000010	/* BDB ops txn,curs - op_cnt. */
+	u_int32_t	lockout_flags;	/* Lockout flags. */
+
+	/* See above for enumerated sync states. */
+	repsync_t	sync_state;	/* Recovery/synchronization flags. */
+
+	/*
+	 * When adding a new flag value, consider whether it should be
+	 * cleared in rep_start() when starting as a master or a client.
+	 */
+#define	REP_F_ABBREVIATED	0x00000001	/* Recover NIMDB pages only. */
+#define	REP_F_APP_BASEAPI	0x00000002	/* Base API application. */
+#define	REP_F_APP_REPMGR	0x00000004	/* repmgr application. */
+#define	REP_F_CLIENT		0x00000008	/* Client replica. */
+#define	REP_F_DELAY		0x00000010	/* Delaying client sync-up. */
+#define	REP_F_GROUP_ESTD	0x00000020	/* Rep group is established. */
+#define	REP_F_INUPDREQ		0x00000040	/* Thread in rep_update_req. */
+#define	REP_F_LEASE_EXPIRED	0x00000080	/* Leases guaranteed expired. */
+#define	REP_F_MASTER		0x00000100	/* Master replica. */
+#define	REP_F_MASTERELECT	0x00000200	/* Master elect. */
+#define	REP_F_NEWFILE		0x00000400	/* Newfile in progress. */
+#define	REP_F_NIMDBS_LOADED	0x00000800	/* NIMDBs are materialized. */
+#define	REP_F_SKIPPED_APPLY	0x00001000	/* Skipped applying a record. */
+#define	REP_F_START_CALLED	0x00002000	/* Rep_start called. */
+#define	REP_F_SYS_DB_OP		0x00004000	/* Operation in progress. */
+	u_int32_t	flags;
+} REP;
+
+/* Information about a thread waiting in txn_applied(). */
+typedef enum {
+	AWAIT_GEN,		/* Client's gen is behind token gen. */
+	AWAIT_HISTORY,		/* Haven't received master's LSN db update. */
+	AWAIT_LSN,		/* Awaiting replication of user txn. */
+	AWAIT_NIMDB,		/* LSN db missing: maybe it's INMEM. */
+	LOCKOUT			/* Thread awoken due to pending lockout. */
+} rep_waitreason_t;
+
+struct rep_waitgoal {
+	rep_waitreason_t	why;
+	union {
+		DB_LSN	lsn;	/* For AWAIT_LSN and AWAIT_HISTORY. */
+		u_int32_t gen;	/* AWAIT_GEN */
+	} u;
+};
+
+struct __rep_waiter {
+	db_mutex_t	mtx_repwait; /* Self-blocking mutex. */
+	struct rep_waitgoal	goal;
+	SH_TAILQ_ENTRY	links;	     /* On either free or waiting list. */
+
+#define	REP_F_PENDING_LOCKOUT	0x00000001
+#define	REP_F_WOKEN		0x00000002
+	u_int32_t	flags;
+};
+
+/*
+ * Macros to check and clear the BDB lockouts.  Currently they are
+ * locked out/set individually because they pertain to different pieces of
+ * the BDB API, they are otherwise always checked and cleared together.
+ */
+#define ISSET_LOCKOUT_BDB(R) 						\
+    (FLD_ISSET((R)->lockout_flags, (REP_LOCKOUT_API | REP_LOCKOUT_OP)))
+
+#define CLR_LOCKOUT_BDB(R) 						\
+    (FLD_CLR((R)->lockout_flags, (REP_LOCKOUT_API | REP_LOCKOUT_OP)))
+
+/*
+ * Recovery flag mask to easily check any/all recovery bits.  That is
+ * REP_LOCKOUT_{API|OP} and most REP_S_*.  This must change if the values
+ * of the flags change.  NOTE:  We do not include REP_LOCKOUT_MSG in
+ * this mask because it is used frequently in non-recovery related
+ * areas and we want to manipulate it separately (see especially
+ * in __rep_new_master).
+ */
+#define CLR_RECOVERY_SETTINGS(R)					\
+do {									\
+	(R)->sync_state = SYNC_OFF;					\
+	CLR_LOCKOUT_BDB(R);						\
+} while (0)
+
+#define	IS_REP_RECOVERING(R)						\
+    ((R)->sync_state != SYNC_OFF || ISSET_LOCKOUT_BDB(R))
+
+/*
+ * REP_F_EPHASE0 is not a *real* election phase.  It is used for
+ * master leases and allowing the client to find the master or
+ * expire its lease.
+ */
+#define	IN_ELECTION(R)							\
+	FLD_ISSET((R)->elect_flags, REP_E_PHASE1 | REP_E_PHASE2)
+#define	IN_ELECTION_TALLY(R) \
+	FLD_ISSET((R)->elect_flags, REP_E_PHASE1 | REP_E_PHASE2 | REP_E_TALLY)
+#define	ELECTION_MAJORITY(n) (((n) / 2) + 1)
+
+#define	IN_INTERNAL_INIT(R) \
+	((R)->sync_state == SYNC_LOG || (R)->sync_state == SYNC_PAGE)
+
+#define	IS_REP_MASTER(env)						\
+	(REP_ON(env) &&							\
+	    F_ISSET(((env)->rep_handle->region), REP_F_MASTER))
+
+#define	IS_REP_CLIENT(env)						\
+	(REP_ON(env) &&							\
+	    F_ISSET(((env)->rep_handle->region), REP_F_CLIENT))
+
+#define	IS_REP_STARTED(env)						\
+	(REP_ON(env) &&							\
+	    F_ISSET(((env)->rep_handle->region), REP_F_START_CALLED))
+
+#define	IS_USING_LEASES(env)						\
+	(REP_ON(env) &&							\
+	    FLD_ISSET(((env)->rep_handle->region)->config, REP_C_LEASE))
+
+#define	IS_CLIENT_PGRECOVER(env)					\
+	(IS_REP_CLIENT(env) &&						\
+	    (((env)->rep_handle->region)->sync_state ==  SYNC_PAGE))
+
+/*
+ * Macros to figure out if we need to do replication pre/post-amble processing.
+ * Skip for specific DB handles owned by the replication layer, either because
+ * replication is running recovery or because it's a handle entirely owned by
+ * the replication code (replication opens its own databases to track state).
+ */
+#define REP_FLAGS_SET(env)						\
+	((env)->rep_handle->region->flags != 0 ||			\
+	(env)->rep_handle->region->elect_flags != 0 ||			\
+	(env)->rep_handle->region->lockout_flags != 0)
+
+#define	IS_ENV_REPLICATED(env)						\
+	(REP_ON(env) && REP_FLAGS_SET(env))
+
+/*
+ * Update the temporary log archive block timer.
+ */
+#define	MASTER_UPDATE(env, renv) do {					\
+	REP_SYSTEM_LOCK(env);						\
+	F_SET((renv), DB_REGENV_REPLOCKED);				\
+	(void)time(&(renv)->op_timestamp);				\
+	REP_SYSTEM_UNLOCK(env);						\
+} while (0)
+
+/*
+ * Macro to set a new generation number.  Cached values from the LSN history
+ * database are associated with the current gen, so when the gen changes we must
+ * invalidate the cache.  Use this macro for all gen changes, to avoid
+ * forgetting to do so.  This macro should be used while holding the rep system
+ * mutex (unless we know we're single-threaded for some other reason, like at
+ * region create time).
+ */
+#define	SET_GEN(g) do {							\
+	rep->gen = (g);							\
+	ZERO_LSN(rep->gen_base_lsn);					\
+} while (0)
+
+
+/*
+ * Gap processing flags.  These provide control over the basic
+ * gap processing algorithm for some special cases.
+ */
+#define	REP_GAP_FORCE		0x001	/* Force a request for a gap. */
+#define	REP_GAP_REREQUEST	0x002	/* Gap request is a forced rerequest. */
+					/* REREQUEST is a superset of FORCE. */
+
+/*
+ * Flags indicating what kind of record we want to back up to, in the log.
+ */
+#define	REP_REC_COMMIT		0x001 	/* Most recent commit record. */
+#define	REP_REC_PERM		0x002	/* Most recent perm record. */
+					/* PERM is a superset of COMMIT. */
+
+/*
+ * Basic pre/post-amble processing.
+ */
+#define	REPLICATION_WRAP(env, func_call, checklock, ret) do {		\
+	int __rep_check, __t_ret;					\
+	__rep_check = IS_ENV_REPLICATED(env) ? 1 : 0;			\
+	(ret) = __rep_check ? __env_rep_enter(env, checklock) : 0;	\
+	if ((ret) == 0) {						\
+		(ret) = func_call;					\
+		if (__rep_check && (__t_ret =				\
+		    __env_db_rep_exit(env)) != 0 && (ret) == 0)		\
+		(ret) = __t_ret;					\
+	}								\
+} while (0)
+
+/*
+ * Macro to safely access curinfo and its internal DBT pointers from
+ * any process.  This should always be used to access curinfo.  If
+ * the internal DBT pointers are to be used, mtx_clientdb must be held
+ * between the time of this call and the use of the pointers.
+ *
+ * The current file information (curinfo) is stored in shared region
+ * memory and accessed via an offset.  It contains DBTs that themselves
+ * point to allocated data.  __rep_nextfile() manages this information in a
+ * single chunk of shared memory.
+ *
+ * If different processes access curinfo, they may have different shared
+ * region addresses.  This means that curinfo and its pointers to DBT data
+ * must be recalculated for each process starting with the offset.
+ */
+#define GET_CURINFO(rep, infop, curinfo)				\
+do {									\
+	curinfo = R_ADDR(infop, rep->curinfo_off);			\
+	if ((curinfo)->uid.size > 0)					\
+		(curinfo)->uid.data = R_ADDR(infop,			\
+		    rep->curinfo_off + sizeof(__rep_fileinfo_args));	\
+	else								\
+		(curinfo)->uid.data = NULL;				\
+	if ((curinfo)->info.size > 0)					\
+		(curinfo)->info.data = R_ADDR(infop, rep->curinfo_off +	\
+		    sizeof(__rep_fileinfo_args) + (curinfo)->uid.size);	\
+	else								\
+		(curinfo)->info.data = NULL;				\
+	if ((curinfo)->dir.size > 0)					\
+		(curinfo)->dir.data = R_ADDR(infop, rep->curinfo_off +	\
+		    sizeof(__rep_fileinfo_args) + (curinfo)->uid.size +	\
+		    (curinfo)->info.size);				\
+	else								\
+		(curinfo)->dir.data = NULL;				\
+} while (0)
+
+/*
+ * Per-process replication structure.
+ *
+ * There are 2 mutexes used in the Base replication API.  (See LOCK_MUTEX in
+ * repmgr.h for a discussion of repmgr.)
+ * 1.  mtx_region - This protects the fields of the rep region above.
+ * 2.  mtx_clientdb - This protects the per-process flags, and bookkeeping
+ * database and all of the components that maintain it.  Those
+ * components include the following fields in the log region (see log.h):
+ *	a. ready_lsn
+ *	b. waiting_lsn
+ *	c. verify_lsn
+ *	d. wait_recs
+ *	e. rcvd_recs
+ *	f. max_wait_lsn
+ * These fields in the log region are NOT protected by the log region lock at
+ * all.
+ *
+ * Note that the per-process flags should truly be protected by a special
+ * per-process thread mutex, but it is currently set in so isolated a manner
+ * that it didn't make sense to do so and in most case we're already holding
+ * the mtx_clientdb anyway.
+ *
+ * The lock ordering protocol is that mtx_clientdb must be acquired first and
+ * then either REP->mtx_region, or the LOG->mtx_region mutex may be acquired if
+ * necessary.
+ *
+ * Note that the appropriate mutex is needed any time one or more related
+ * values are read or written that could possibly use more than one atomic
+ * machine instruction.  A single 32-bit integer value is safe without a
+ * mutex, but most other types of value should use a mutex.
+ *
+ * Any use of a mutex must be inside a matched pair of ENV_ENTER() and
+ * ENV_LEAVE() macros.  This ensures that if a thread dies while holding
+ * a lock (i.e. a mutex), recovery can clean it up so that it does not
+ * indefinitely block other threads.
+ */
+struct __db_rep {
+	/*
+	 * Shared configuration information -- copied to and maintained in the
+	 * shared region as soon as the shared region is created.
+	 */
+	int		eid;		/* Environment ID. */
+
+	u_int32_t	gbytes;		/* Limit on data sent in single... */
+	u_int32_t	bytes;		/* __rep_process_message call. */
+
+	db_timespec	request_gap;	/* Minimum time to wait before we
+					 * request a missing log record. */
+	db_timespec	max_gap;	/* Maximum time to wait before
+					 * requesting a missing log record. */
+
+	u_int32_t	clock_skew;	/* Clock skew factor. */
+	u_int32_t	clock_base;	/* Clock skew base. */
+	u_int32_t	config;		/* Configuration flags. */
+	u_int32_t	config_nsites;
+
+	db_timeout_t	elect_timeout;	/* Normal/full election timeouts. */
+	db_timeout_t	full_elect_timeout;
+
+	db_timeout_t	chkpt_delay;	/* Master checkpoint delay. */
+
+	u_int32_t	my_priority;
+	db_timeout_t	lease_timeout;	/* Master leases. */
+	/*
+	 * End of shared configuration information.
+	 */
+	int		(*send)		/* Send function. */
+			    __P((DB_ENV *, const DBT *, const DBT *,
+			    const DB_LSN *, int, u_int32_t));
+
+	DB		*rep_db;	/* Bookkeeping database. */
+	DB		*lsn_db;	/* (Replicated) LSN history database. */
+
+	REP		*region;	/* In memory structure. */
+	u_int8_t	*bulk;		/* Shared memory bulk area. */
+
+#define	DBREP_DIAG_FILES	2
+	DB_FH		*diagfile[DBREP_DIAG_FILES];	/* Diag files fhp. */
+	off_t		diag_off;	/* Current diag file offset. */
+
+	/* These are protected by mtx_clientdb. */
+	DB_MPOOLFILE	*file_mpf;	/* Mpoolfile for current database. */
+	DB		*file_dbp;	/* This file's page info. */
+	DBC		*queue_dbc;	/* Dbc for a queue file. */
+
+	/*
+	 * Please change __rep_print_all (rep_stat.c) to track any changes made
+	 * to these flags.
+	 */
+#define	DBREP_APP_BASEAPI	0x0001	/* Base API application. */
+#define	DBREP_APP_REPMGR	0x0002	/* repmgr application. */
+#define	DBREP_OPENFILES		0x0004	/* This handle has opened files. */
+	u_int32_t	flags;		/* per-process flags. */
+
+#ifdef HAVE_REPLICATION_THREADS
+	/*
+	 * Replication Framework (repmgr) per-process information.
+	 */
+	u_int		nthreads;	/* Msg processing threads. */
+	u_int		athreads;	/* Space allocated for msg threads. */
+	u_int		non_rep_th;	/* Threads in GMDB or channel msgs. */
+	u_int		aelect_threads; /* Space allocated for elect threads. */
+	u_int32_t	init_policy;
+	int		perm_policy;
+	DB_LSN		perm_lsn; /* Last perm LSN we've announced. */
+	db_timeout_t	ack_timeout;
+	db_timeout_t	election_retry_wait;
+	db_timeout_t	connection_retry_wait;
+	db_timeout_t	heartbeat_frequency; /* Max period between msgs. */
+	db_timeout_t	heartbeat_monitor_timeout;
+
+	/* Thread synchronization. */
+	REPMGR_RUNNABLE *selector, **messengers, **elect_threads;
+	REPMGR_RUNNABLE	*preferred_elect_thr;
+	db_timespec	repstart_time;
+	mgr_mutex_t	*mutex;
+	cond_var_t	check_election, gmdb_idle, msg_avail;
+	waiter_t	ack_waiters; /* For threads awaiting PERM acks. */
+#ifdef DB_WIN32
+	HANDLE		signaler;
+#else
+	int		read_pipe, write_pipe;
+#endif
+
+	/* Operational stuff. */
+	REPMGR_SITE	*sites;		/* Array of known sites. */
+	u_int		site_cnt;	/* Array slots in use. */
+	u_int		site_max;	/* Total array slots allocated. */
+	int		self_eid;	/* Where to find the local site. */
+	u_int		siteinfo_seq;	/* Last known update to this list. */
+
+	/*
+	 * The connections list contains only those connections not actively
+	 * associated with a known site (see repmgr.h).
+	 */
+	CONNECTION_LIST	connections;
+	RETRY_Q_HEADER	retries;	/* Sites needing connection retry. */
+	struct {
+		int	size;
+		STAILQ_HEAD(__repmgr_q_header, __repmgr_message) header;
+	} input_queue;
+
+	socket_t	listen_fd;
+	db_timespec	last_bcast;	/* Time of last broadcast msg. */
+
+	/*
+	 * Status of repmgr.  It is ready when repmgr is not yet started.  It
+	 * is running after repmgr is (re)started.  It is stopped if the env
+	 * of the running repmgr is closed, or the site is removed. 
+	 */
+	enum { ready, running, stopped } repmgr_status;
+	int		new_connection;	  /* Since last master seek attempt. */
+	int		takeover_pending; /* We've been elected master. */
+	int		gmdb_busy;
+	int		client_intent;	/* Will relinquish master role. */
+	int		gmdb_dirty;
+	int		have_gmdb;
+	int		seen_repmsg;
+
+	/*
+	 * Flag to show what kind of transaction is currently in progress.
+	 * Primary means we're doing the first (critical) phase of a membership
+	 * DB update, where we care about perm failures.  In the secondary phase
+	 * we don't care.  Usually the value is "none", when normal user
+	 * transactions are happening.  We need to use this global flag because
+	 * we don't have a more proper direct channel to communicate information
+	 * between the originator of a transaction and the replication send()
+	 * function that has to wait for acks and decide what to do about them.
+	 */ 
+	enum { none, gmdb_primary, gmdb_secondary } active_gmdb_update;
+	int		limbo_resolution_needed;
+
+	/*
+	 * GMDB update sequence count.  On creation we write version 1; so, once
+	 * repmgr has started and tried to read, a 0 here can be taken to mean
+	 * that the DB doesn't exist yet.
+	 */
+	u_int32_t	membership_version;
+	u_int32_t	member_version_gen;
+
+	/* LSN of GMDB txn that got a perm failure. */
+	DB_LSN		limbo_failure;
+	/* EID whose membership status is therefore unresolved */
+	int		limbo_victim;
+	/* LSN of a later txn that achieves perm success. */
+	DB_LSN		durable_lsn;
+	DB		*gmdb;	/* Membership database handle. */
+	/*
+	 * Membership list restored from init file after crash during internal init.
+	 */
+	u_int8_t	*restored_list;
+	size_t		restored_list_length;
+
+	/* Application's message dispatch call-back function. */
+	void  (*msg_dispatch) __P((DB_ENV *, DB_CHANNEL *,
+		DBT *, u_int32_t, u_int32_t));
+#endif  /* HAVE_REPLICATION_THREADS */
+};
+
+/*
+ * Determine whether application is repmgr or base replication API.  If
+ * repmgr was configured, base the test on internal replication flags for
+ * APP_REPMGR and APP_BASEAPI.  These flags get set by the appropriate parts
+ * of the various replication APIs.
+ */
+#ifdef HAVE_REPLICATION_THREADS
+/*
+ * Application type is set to be repmgr when:
+ *   1. A local site is defined.
+ *   2. A remote site is defined.
+ *   3. An acknowledgement policy is configured.
+ *   4. A repmgr flag is configured.
+ *   5. A timeout value is configured for one of the repmgr timeouts.
+ */
+#define	APP_IS_REPMGR(env)						\
+	(REP_ON(env) ?							\
+	    F_ISSET((env)->rep_handle->region, REP_F_APP_REPMGR) :	\
+	    F_ISSET((env)->rep_handle, DBREP_APP_REPMGR))
+
+/*
+ * Application type is set to be base replication API when:
+ *   1. Transport send function is defined and is not the repmgr send
+ *      function.
+ */
+#define	APP_IS_BASEAPI(env)						\
+	(REP_ON(env) ?							\
+	    F_ISSET((env)->rep_handle->region, REP_F_APP_BASEAPI) :	\
+	    F_ISSET((env)->rep_handle, DBREP_APP_BASEAPI))
+
+/*
+ * Set application type.  These macros do extra checking to guarantee that
+ * only one application type is ever set.
+ */
+#define	APP_SET_REPMGR(env) do {					\
+	if (REP_ON(env)) {						\
+		ENV_ENTER(env, ip);					\
+		REP_SYSTEM_LOCK(env);					\
+		if (!F_ISSET((env)->rep_handle->region,			\
+		    REP_F_APP_BASEAPI))					\
+			F_SET((env)->rep_handle->region,		\
+			    REP_F_APP_REPMGR);				\
+		REP_SYSTEM_UNLOCK(env);					\
+		ENV_LEAVE(env, ip);					\
+	} else if (!F_ISSET((env)->rep_handle, DBREP_APP_BASEAPI))	\
+		F_SET((env)->rep_handle, DBREP_APP_REPMGR);		\
+} while (0)
+#define	APP_SET_BASEAPI(env) do {					\
+	if (REP_ON(env)) {						\
+		ENV_ENTER(env, ip);					\
+		REP_SYSTEM_LOCK(env);					\
+		if (!F_ISSET((env)->rep_handle->region,			\
+		    REP_F_APP_REPMGR))					\
+			F_SET((env)->rep_handle->region,		\
+			    REP_F_APP_BASEAPI);				\
+		REP_SYSTEM_UNLOCK(env);					\
+		ENV_LEAVE(env, ip);					\
+	} else if (!F_ISSET((env)->rep_handle, DBREP_APP_REPMGR))	\
+		F_SET((env)->rep_handle, DBREP_APP_BASEAPI);		\
+} while (0)
+
+#else
+/*
+ * We did not configure repmgr, application must be base replication API.
+ * The APP_SET_* macros are noops in this case, but they must be defined
+ * with a null body to avoid compiler warnings on some platforms.
+ */
+#define	APP_IS_REPMGR(env) 0
+#define	APP_SET_REPMGR(env) do {					\
+	;								\
+} while (0)
+#define	APP_IS_BASEAPI(env) 1
+#define	APP_SET_BASEAPI(env) do {					\
+	;								\
+} while (0)
+#endif  /* HAVE_REPLICATION_THREADS */
+
+/*
+ * Control structure flags for replication communication infrastructure.
+ */
+/*
+ * Define old DB_LOG_ values that we must support here.  For reasons of
+ * compatibility with old versions, these values must be reserved explicitly in
+ * the list of flag values (below)
+ */
+#define	DB_LOG_PERM_42_44	0x20
+#define	DB_LOG_RESEND_42_44	0x40
+#define	REPCTL_INIT_45		0x02	/* Back compatible flag value. */
+
+#define	REPCTL_ELECTABLE	0x01	/* Upgraded client is electable. */
+#define	REPCTL_FLUSH		0x02	/* Record should be flushed. */
+#define	REPCTL_GROUP_ESTD	0x04	/* Message from site in a group. */
+#define	REPCTL_INIT		0x08	/* Internal init message. */
+#define	REPCTL_LEASE		0x10	/* Lease related message.. */
+			/*
+			 * Skip over reserved values 0x20
+			 * and 0x40, as explained above.
+			 */
+#define	REPCTL_LOG_END		0x80	/* Approximate end of group-wide log. */
+#define	REPCTL_PERM		DB_LOG_PERM_42_44
+#define	REPCTL_RESEND		DB_LOG_RESEND_42_44
+
+/*
+ * File info flags for internal init.  The per-database (i.e., file) flag
+ * represents the on-disk format of the file, and is conveyed from the master to
+ * the initializing client in the UPDATE message, so that the client can know
+ * how to create the file.  The per-page flag is conveyed along with each PAGE
+ * message, describing the format of the page image being transmitted; it is of
+ * course set by the site serving the PAGE_REQ.  The serving site gets the page
+ * image from its own mpool, and thus the page is in the native format of the
+ * serving site.  This format may be different (i.e., opposite) from the on-disk
+ * format, and in fact can vary per-page, since with client-to-client sync it is
+ * possible for various different sites to serve the various PAGE_REQ requests.
+ */
+#define	REPINFO_DB_LITTLEENDIAN	0x0001	/* File is little-endian lorder. */
+#define	REPINFO_PG_LITTLEENDIAN	0x0002	/* Page is little-endian lorder. */
+
+/*
+ * Control message format for 4.6 release.  The db_timespec_t is
+ * not a portable structure.  Therefore, in 4.6, replication among
+ * mixed OSs such as Linux and Windows, which have different time_t
+ * sizes, does not work.
+ */
+typedef struct {
+	u_int32_t	rep_version;	/* Replication version number. */
+	u_int32_t	log_version;	/* Log version number. */
+
+	DB_LSN		lsn;		/* Log sequence number. */
+	u_int32_t	rectype;	/* Message type. */
+	u_int32_t	gen;		/* Generation number. */
+	db_timespec	msg_time;	/* Timestamp seconds for leases. */
+	u_int32_t	flags;		/* log_put flag value. */
+} REP_46_CONTROL;
+
+/*
+ * Control message format for 4.5 release and earlier.
+ */
+typedef struct {
+	u_int32_t	rep_version;	/* Replication version number. */
+	u_int32_t	log_version;	/* Log version number. */
+
+	DB_LSN		lsn;		/* Log sequence number. */
+	u_int32_t	rectype;	/* Message type. */
+	u_int32_t	gen;		/* Generation number. */
+	u_int32_t	flags;		/* log_put flag value. */
+} REP_OLD_CONTROL;
+
+#define	LEASE_REFRESH_MIN	30	/* Minimum number of refresh retries. */
+#define	LEASE_REFRESH_USEC	50000	/* Microseconds between refresh tries. */
+
+/* Master granted lease information. */
+typedef struct __rep_lease_entry {
+	int		eid;		/* EID of client grantor. */
+	db_timespec	start_time;	/* Start time clients echo back. */
+	db_timespec	end_time;	/* Master lease expiration time. */
+	DB_LSN		lease_lsn;	/* Durable LSN lease applies to. */
+} REP_LEASE_ENTRY;
+
+/*
+ * Old vote info where some fields were not fixed size.
+ */
+typedef struct {
+	u_int32_t	egen;		/* Election generation. */
+	int		nsites;		/* Number of sites I've been in
+					 * communication with. */
+	int		nvotes;		/* Number of votes needed to win. */
+	int		priority;	/* My site's priority. */
+	u_int32_t	tiebreaker;	/* Tie-breaking quasi-random value. */
+} REP_OLD_VOTE_INFO;
+
+typedef struct {
+	u_int32_t	egen;		/* Voter's election generation. */
+	int		eid;		/* Voter's ID. */
+} REP_VTALLY;
+
+/*
+ * The REP_THROTTLE_ONLY flag is used to do throttle processing only.
+ * If set, it will only allow sending the REP_*_MORE message, but not
+ * the normal, non-throttled message.  It is used to support throttling
+ * with bulk transfer.
+ */
+/* Flags for __rep_send_throttle. */
+#define	REP_THROTTLE_ONLY	0x0001	/* Send _MORE message only. */
+
+/* Throttled message processing information. */
+typedef struct {
+	DB_LSN		lsn;		/* LSN of this record. */
+	DBT		*data_dbt;	/* DBT of this record. */
+	u_int32_t	gbytes;		/* This call's max gbytes sent. */
+	u_int32_t	bytes;		/* This call's max bytes sent. */
+	u_int32_t	type;		/* Record type. */
+} REP_THROTTLE;
+
+/* Bulk processing information. */
+/*
+ * !!!
+ * We use a roff_t for the offset.  We'd really like to use a ptrdiff_t
+ * since that really is what it is.  But ptrdiff_t is not portable and
+ * doesn't exist everywhere.
+ */
+typedef struct {
+	u_int8_t	*addr;		/* Address of bulk buffer. */
+	roff_t		*offp;		/* Ptr to current offset into buffer. */
+	u_int32_t	len;		/* Bulk buffer length. */
+	u_int32_t	type;		/* Item type in buffer (log, page). */
+	DB_LSN		lsn;		/* First LSN in buffer. */
+	int		eid;		/* ID of potential recipients. */
+#define	BULK_XMIT	0x001		/* Buffer in transit. */
+	u_int32_t	*flagsp;	/* Buffer flags. */
+} REP_BULK;
+
+/*
+ * This structure takes care of representing a transaction.
+ * It holds all the records, sorted by page number so that
+ * we can obtain locks and apply updates in a deadlock free
+ * order.
+ */
+typedef struct {
+	u_int nlsns;
+	u_int nalloc;
+	DB_LSN *array;
+} LSN_COLLECTION;
+
+/*
+ * This is used by the page-prep routines to do the lock_vec call to
+ * apply the updates for a single transaction or a collection of
+ * transactions.
+ */
+typedef struct {
+	int		n;
+	DB_LOCKREQ	*reqs;
+	DBT		*objs;
+} linfo_t;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/rep_ext.h"
+#endif	/* !_DB_REP_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/repmgr.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,865 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2006, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_REPMGR_H_
+#define	_DB_REPMGR_H_
+
+#include "dbinc_auto/repmgr_automsg.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Replication Manager message format types.  These few format codes identify
+ * enough information to describe, at the lowest level, how a message should be
+ * read from the wire, including how much memory should be allocated to hold the
+ * result.  (Often we want to allocate more than just enough to hold the
+ * received bytes, if we know that we will need more during processing.)
+ *
+ * These values are transmitted between sites, even sites running differing BDB
+ * versions.  Therefore, once assigned, the values are permanently "frozen".
+ *
+ * For example, in repmgr wire protocol version 1 the highest assigned message
+ * type value was 3, for REPMGR_REP_MESSAGE.  Wire protocol version 2 added the
+ * HEARTBEAT message type (4).
+ *
+ * New message types added in later versions always get new (higher) values.  We
+ * still list them in alphabetical order, for ease of reference.  But this
+ * generally does not correspond to numerical order.
+ */
+#define	REPMGR_APP_MESSAGE	5	/* Msg sent from app. on DB_CHANNEL. */
+#define	REPMGR_APP_RESPONSE	6	/* Response to a channel request. */
+#define	REPMGR_OWN_MSG		8	/* Repmgr's own messages, to peers. */
+#define	REPMGR_HANDSHAKE	2	/* Connection establishment sequence. */
+#define	REPMGR_HEARTBEAT	4	/* Monitor connection health. */
+#define	REPMGR_PERMLSN		1	/* My perm LSN. */
+#define	REPMGR_REP_MESSAGE	3	/* Normal replication message. */
+#define	REPMGR_RESP_ERROR	7	/* Sys-gen'd error resp to request. */
+
+/*
+ * Largest known message type code known in each protocol version we support.
+ * In protocol version one there were only three message types: 1, 2, and 3; so
+ * 3 was the max.  In protocol version 2 we introduced heartbeats, type 4.
+ * (Protocol version 3 did not introduce any new message types.)  In version 4
+ * we introduced a few more new message types, the largest of which had value 7.
+ */
+#define	REPMGR_MAX_V1_MSG_TYPE	3
+#define	REPMGR_MAX_V2_MSG_TYPE	4
+#define	REPMGR_MAX_V3_MSG_TYPE	4
+#define	REPMGR_MAX_V4_MSG_TYPE	8
+#define	HEARTBEAT_MIN_VERSION	2
+#define	CHANNEL_MIN_VERSION	4
+#define	CONN_COLLISION_VERSION	4
+#define	GM_MIN_VERSION		4
+#define	OWN_MIN_VERSION		4
+
+/* The range of protocol versions we're willing to support. */
+#define	DB_REPMGR_VERSION	4
+#define	DB_REPMGR_MIN_VERSION	1
+
+/*
+ * For messages with the "REPMGR_OWN_MSG" format code, a message type (see
+ * REPMGR_OWN_MSG_TYPE, below) is included in the header.  While at the lowest
+ * level, the format codes identify only enough to read and allocate memory, at
+ * the next higher level the following message type codes identify the content
+ * of the message: how to unmarshal and dispatch it.
+ *
+ * Like the message format types, these message type values should be
+ * permanently frozen.
+ */
+#define	REPMGR_CONNECT_REJECT	1
+#define	REPMGR_GM_FAILURE	2
+#define	REPMGR_GM_FORWARD	3
+#define	REPMGR_JOIN_REQUEST	4
+#define	REPMGR_JOIN_SUCCESS	5
+#define	REPMGR_PARM_REFRESH	6
+#define	REPMGR_REJOIN		7
+#define	REPMGR_REMOVE_REQUEST	8
+#define	REPMGR_REMOVE_SUCCESS	9
+#define	REPMGR_RESOLVE_LIMBO	10
+#define	REPMGR_SHARING		11
+
+
+struct __repmgr_connection;
+    typedef struct __repmgr_connection REPMGR_CONNECTION;
+struct __repmgr_queue; typedef struct __repmgr_queue REPMGR_QUEUE;
+struct __queued_output; typedef struct __queued_output QUEUED_OUTPUT;
+struct __repmgr_response; typedef struct __repmgr_response REPMGR_RESPONSE;
+struct __repmgr_retry; typedef struct __repmgr_retry REPMGR_RETRY;
+struct __repmgr_runnable; typedef struct __repmgr_runnable REPMGR_RUNNABLE;
+struct __repmgr_site; typedef struct __repmgr_site REPMGR_SITE;
+struct __cond_waiters_table;
+    typedef struct __cond_waiters_table COND_WAITERS_TABLE;
+
+/* Current Group Membership DB format ID. */
+#define	REPMGR_GMDB_FMT_VERSION	1
+
+#ifdef DB_WIN32
+typedef SOCKET socket_t;
+typedef HANDLE thread_id_t;
+typedef HANDLE mgr_mutex_t;
+typedef HANDLE cond_var_t;
+
+typedef COND_WAITERS_TABLE *waiter_t;
+typedef WSABUF db_iovec_t;
+#else
+typedef int socket_t;
+typedef pthread_t thread_id_t;
+typedef pthread_mutex_t mgr_mutex_t;
+typedef pthread_cond_t cond_var_t;
+typedef pthread_cond_t waiter_t;
+typedef struct iovec db_iovec_t;
+#endif
+
+/*
+ * The (arbitrary) maximum number of outgoing messages we're willing to hold, on
+ * a queue per connection, waiting for TCP buffer space to become available in
+ * the kernel.  Rather than exceeding this limit, we simply discard additional
+ * messages (since this is always allowed by the replication protocol).
+ *    As a special dispensation, if a message is destined for a specific remote
+ * site (i.e., it's not a broadcast), then we first try blocking the sending
+ * thread, waiting for space to become available (though we only wait a limited
+ * time).  This is so as to be able to handle the immediate flood of (a
+ * potentially large number of) outgoing messages that replication generates, in
+ * a tight loop, when handling PAGE_REQ, LOG_REQ and ALL_REQ requests.
+ */
+#define	OUT_QUEUE_LIMIT	10
+
+/*
+ * The system value is available from sysconf(_SC_HOST_NAME_MAX).
+ * Historically, the maximum host name was 256.
+ */
+#ifndef MAXHOSTNAMELEN
+#define	MAXHOSTNAMELEN	256
+#endif
+
+/* A buffer big enough for the string "site host.domain.com:65535". */
+#define	MAX_SITE_LOC_STRING (MAXHOSTNAMELEN+20)
+typedef char SITE_STRING_BUFFER[MAX_SITE_LOC_STRING+1];
+
+#define	MAX_MSG_BUF	(__REPMGR_MAXMSG_SIZE + MAXHOSTNAMELEN + 1)
+
+/* Default timeout values, in seconds. */
+#define	DB_REPMGR_DEFAULT_ACK_TIMEOUT		(1 * US_PER_SEC)
+#define	DB_REPMGR_DEFAULT_CONNECTION_RETRY	(30 * US_PER_SEC)
+#define	DB_REPMGR_DEFAULT_ELECTION_RETRY	(10 * US_PER_SEC)
+#define	DB_REPMGR_DEFAULT_CHANNEL_TIMEOUT	(5 * US_PER_SEC)
+
+typedef TAILQ_HEAD(__repmgr_conn_list, __repmgr_connection) CONNECTION_LIST;
+typedef STAILQ_HEAD(__repmgr_out_q_head, __queued_output) OUT_Q_HEADER;
+typedef TAILQ_HEAD(__repmgr_retry_q, __repmgr_retry) RETRY_Q_HEADER;
+
+/* Information about threads managed by Replication Framework. */
+struct __repmgr_runnable {
+	ENV *env;
+	thread_id_t thread_id;
+	void *(*run) __P((void *));
+	int finished;		/* Boolean: thread is exiting, may be joined. */
+	int quit_requested;	/* Boolean: thread has been asked to quit. */
+#ifdef DB_WIN32
+	HANDLE quit_event;
+#endif
+	union {
+
+/*
+ * Options governing requested behavior of election thread.
+ */
+#define	ELECT_F_EVENT_NOTIFY	0x01 /* Notify application of master failure. */
+#define	ELECT_F_FAST		0x02 /* First election "fast" (n-1 trick). */
+#define	ELECT_F_IMMED		0x04 /* Start with immediate election. */
+#define	ELECT_F_INVITEE		0x08 /* Honor (remote) inviter's nsites. */
+#define	ELECT_F_STARTUP		0x10 /* Observe repmgr_start() policy. */
+		u_int32_t flags;
+
+		int eid;	/* For Connector thread. */
+
+		/*
+		 * Args for other thread types can be added here in the future
+		 * as needed.
+		 */
+	} args;
+};
+
+/*
+ * Information about pending connection establishment retry operations.
+ *
+ * We keep these in order by time.  This works, under the assumption that the
+ * DB_REP_CONNECTION_RETRY never changes once we get going (though that
+ * assumption is of course wrong, so this needs to be fixed).
+ *
+ * Usually, we put things onto the tail end of the list.  But when we add a new
+ * site while threads are running, we trigger its first connection attempt by
+ * scheduling a retry for "0" microseconds from now, putting its retry element
+ * at the head of the list instead.
+ *
+ * TODO: I think this can be fixed by defining "time" to be the time the element
+ * was added (with some convention like "0" meaning immediate), rather than the
+ * deadline time.
+ */
+struct __repmgr_retry {
+	TAILQ_ENTRY(__repmgr_retry) entries;
+	int eid;
+	db_timespec time;
+};
+
+/*
+ * We use scatter/gather I/O for both reading and writing.  Repmgr messages
+ * (including rep messages) use 3 segments: envelope, control and rec.
+ * Application messages can have any number of segments (the number they
+ * specify, plus 1 for our envelope).  REPMGR_IOVECS_ALLOC_SZ should (only) be
+ * used when n > 3.
+ */
+#define	REPMGR_IOVECS_ALLOC_SZ(n) \
+	(sizeof(REPMGR_IOVECS) + ((n) - MIN_IOVEC) * sizeof(db_iovec_t))
+typedef struct {
+	/*
+	 * Index of the first iovec to be used.  Initially of course this is
+	 * zero.  But as we progress through partial I/O transfers, it ends up
+	 * pointing to the first iovec to be used on the next operation.
+	 */
+	int offset;
+
+	/*
+	 * Total number of pieces defined for this message; equal to the number
+	 * of times add_buffer and/or add_dbt were called to populate it.  We do
+	 * *NOT* revise this as we go along.  So subsequent I/O operations must
+	 * use count-offset to get the number of active vector pieces still
+	 * remaining.
+	 */
+	int count;
+
+	/*
+	 * Total number of bytes accounted for in all the pieces of this
+	 * message.  We do *NOT* revise this as we go along.
+	 */
+	size_t total_bytes;
+
+#define	MIN_IOVEC	3
+	db_iovec_t vectors[MIN_IOVEC];	/* Variable length array. */
+} REPMGR_IOVECS;
+
+typedef struct {
+	size_t length;		/* number of bytes in data */
+	int ref_count;		/* # of sites' send queues pointing to us */
+	u_int8_t data[1];	/* variable size data area */
+} REPMGR_FLAT;
+
+struct __queued_output {
+	STAILQ_ENTRY(__queued_output) entries;
+	REPMGR_FLAT *msg;
+	size_t offset;
+};
+
+/*
+ * The following is for input.  Once we know the sizes of the pieces of an
+ * incoming message, we can create this struct (and also the data areas for the
+ * pieces themselves, in the same memory allocation).  This is also the struct
+ * in which the message lives while it's waiting to be processed by message
+ * threads.
+ */
+typedef struct __repmgr_message {
+	STAILQ_ENTRY(__repmgr_message) entries;
+	__repmgr_msg_hdr_args msg_hdr;
+	union {
+		struct {
+			int originating_eid;
+			DBT control, rec;
+		} repmsg;
+		struct {
+			REPMGR_CONNECTION *conn;
+			DBT request;
+		} gmdb_msg;
+		struct {
+			/*
+			 * Connection from which the message arrived; NULL if
+			 * generated on the local site.
+			 */
+			REPMGR_CONNECTION *conn;
+
+			DBT buf; /* for reading */
+			DBT segments[1]; /* expanded in msg th. before callbk */
+		} appmsg;
+	} v;			/* Variants */
+} REPMGR_MESSAGE;
+
+typedef enum {
+	SIZES_PHASE,
+	DATA_PHASE
+} phase_t;
+
+typedef enum {
+	APP_CONNECTION,
+	REP_CONNECTION,
+	UNKNOWN_CONN_TYPE
+} conn_type_t;
+
+struct __repmgr_connection {
+	TAILQ_ENTRY(__repmgr_connection) entries;
+
+	socket_t fd;
+#ifdef DB_WIN32
+	WSAEVENT event_object;
+#endif
+
+	/*
+	 * Number of other structures referring to this conn struct.  This
+	 * ref_count must be reduced to zero before this conn struct can be
+	 * destroyed.  Referents include:
+	 *
+	 * - the select() loop, which owns the right to do all reading, as well
+	 *   as the exclusive right to eventually close the socket
+	 *
+	 * - a "channel" that owns this APP_CONNECTION (on the originating side)
+	 *
+	 * - a message received on this APP_CONNECTION, queued for processing
+	 *
+	 * - any writer blocked on waiting for the outbound queue to drain
+	 */
+	u_int32_t	ref_count;
+
+	conn_type_t type;
+	u_int32_t version;	/* Wire protocol version on this connection. */
+				/* (0 means not yet determined.) */
+
+/*
+ * When we make an outgoing connection, it starts in CONNECTED state.  When we
+ * get the response to our version negotiation, we move to READY.
+ *     For incoming connections that we accept, we start in NEGOTIATE, then to
+ * PARAMETERS, and then to READY.
+ *     CONGESTED is a hierarchical substate of READY: it's just like READY, with
+ * the additional wrinkle that we don't bother waiting for the outgoing queue to
+ * drain in certain circumstances.
+ */
+#define	CONN_CONGESTED	1	/* Long-lived full outgoing queue. */
+#define	CONN_CONNECTED	2	/* Awaiting reply to our version negotiation. */
+#define	CONN_DEFUNCT	3	/* Basically dead, awaiting clean-up. */
+#define	CONN_NEGOTIATE	4	/* Awaiting version proposal. */
+#define	CONN_PARAMETERS	5	/* Awaiting parameters handshake. */
+#define	CONN_READY	6	/* Everything's fine. */
+	int state;
+
+	/*
+	 * Input: while we're reading a message, we keep track of what phase
+	 * we're in.  In both phases, we use a REPMGR_IOVECS to keep track of
+	 * our progress within the phase.  Depending upon the message type, we
+	 * end up with either a rep_message (which is a wrapper for the control
+	 * and rec DBTs), or a single generic DBT.
+	 *     Any time we're in DATA_PHASE, it means we have already received
+	 * the message header (consisting of msg_type and 2 sizes), and
+	 * therefore we have allocated buffer space to read the data.  (This is
+	 * important for resource clean-up.)
+	 */
+	phase_t		reading_phase;
+	REPMGR_IOVECS iovecs;
+
+	u_int8_t	msg_type;
+	u_int8_t	msg_hdr_buf[__REPMGR_MSG_HDR_SIZE];
+
+	union {
+		REPMGR_MESSAGE *rep_message;
+		struct {
+			DBT cntrl, rec;
+		} repmgr_msg;
+	} input;
+
+	/*
+	 * Output: usually we just simply write messages right in line, in the
+	 * send() function's thread.  But if TCP doesn't have enough network
+	 * buffer space for us when we first try it, we instead allocate some
+	 * memory, and copy the message, and then send it as space becomes
+	 * available in our main select() thread.  In some cases, if the queue
+	 * gets too long we wait until it's drained, and then append to it.
+	 * This condition variable's associated mutex is the normal per-repmgr
+	 * db_rep->mutex, because that mutex is always held anyway whenever the
+	 * output queue is consulted.
+	 */
+	OUT_Q_HEADER outbound_queue;
+	int out_queue_length;
+	cond_var_t drained;
+
+	/* =-=-=-=-= app-channel stuff =-=-=-=-= */
+	waiter_t	response_waiters;
+
+	/*
+	 * Array of info about pending responses to requests.  This info is here
+	 * (rather than on the stack of the thread calling send_request())
+	 * because it provides an easy way to allocate available numbers for
+	 * message tags, and also so that we can easily find the right info when
+	 * we get the tag back in the msg header of the response.
+	 */
+	REPMGR_RESPONSE *responses;
+	u_int32_t	aresp;	/* Array size. */
+	u_int32_t	cur_resp; /* Index of response currently reading. */
+
+	/* =-=-=-=-= for normal repmgr connections =-=-=-=-= */
+	/*
+	 * Generally on a REP_CONNECTION type, we have an associated EID (which
+	 * is an index into the sites array, by the way).  When we initiate the
+	 * connection ("outgoing"), we know from the start what the EID is; the
+	 * connection struct is linked from the site struct.  On the other hand,
+	 * when we receive an incoming connection, we don't know at first what
+	 * site it may be associated with (or even whether it's an
+	 * APP_CONNECTION or REP_CONNECTION, for that matter).  During that
+	 * initial uncertain time, the eid is -1.  Also, when a connection
+	 * becomes defunct, but the conn struct hasn't yet been destroyed, the
+	 * eid also becomes -1.
+	 *
+	 * The eid should be -1 if and only if the connection is on the orphans
+	 * list.
+	 */
+	int eid;
+
+};
+
+#define	IS_READY_STATE(s)	((s) == CONN_READY || (s) == CONN_CONGESTED)
+
+#ifdef HAVE_GETADDRINFO
+typedef struct addrinfo	ADDRINFO;
+typedef struct sockaddr_storage ACCEPT_ADDR;
+#else
+typedef struct sockaddr_in ACCEPT_ADDR;
+/*
+ * Some windows platforms have getaddrinfo (Windows XP), some don't.  We don't
+ * support conditional compilation in our Windows build, so we always use our
+ * own getaddrinfo implementation.  Rename everything so that we don't collide
+ * with the system libraries.
+ */
+#undef	AI_PASSIVE
+#define	AI_PASSIVE	0x01
+#undef	AI_CANONNAME
+#define	AI_CANONNAME	0x02
+#undef	AI_NUMERICHOST
+#define	AI_NUMERICHOST	0x04
+
+typedef struct __addrinfo {
+	int ai_flags;		/* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
+	int ai_family;		/* PF_xxx */
+	int ai_socktype;	/* SOCK_xxx */
+	int ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+	size_t ai_addrlen;	/* length of ai_addr */
+	char *ai_canonname;	/* canonical name for nodename */
+	struct sockaddr *ai_addr;	/* binary address */
+	struct __addrinfo *ai_next;	/* next structure in linked list */
+} ADDRINFO;
+#endif /* HAVE_GETADDRINFO */
+
+/*
+ * Unprocessed network address configuration.
+ */
+typedef struct {
+	roff_t host;		/* Separately allocated copy of string. */
+	u_int16_t port;		/* Stored in plain old host-byte-order. */
+} SITEADDR;
+
+/*
+ * Site information, as stored in shared region.
+ */
+typedef struct {
+	SITEADDR addr;		/* Unprocessed network address of site. */
+	u_int32_t config;	/* Configuration flags: peer, helper, etc. */
+	u_int32_t status;	/* Group membership status. */
+} SITEINFO;
+
+/*
+ * A site address, as stored locally.
+ */
+typedef struct {
+	char *host;		/* Separately allocated copy of string. */
+	u_int16_t port;		/* Stored in plain old host-byte-order. */
+} repmgr_netaddr_t;
+
+/*
+ * We store site structs in a dynamically allocated, growable array, indexed by
+ * EID.  We allocate EID numbers for all sites simply according to their
+ * index within this array.
+ */
+#define	SITE_FROM_EID(eid)	(&db_rep->sites[eid])
+#define	EID_FROM_SITE(s)	((int)((s) - (&db_rep->sites[0])))
+#define	IS_VALID_EID(e)		((e) >= 0)
+#define	IS_KNOWN_REMOTE_SITE(e)	((e) >= 0 && ((e) != db_rep->self_eid) && \
+	    (((u_int)(e)) < db_rep->site_cnt))
+#define	FOR_EACH_REMOTE_SITE_INDEX(i)                    \
+	for ((i) = (db_rep->self_eid == 0 ? 1 : 0);	\
+	     ((u_int)i) < db_rep->site_cnt;		 \
+	     (int)(++(i)) == db_rep->self_eid ? ++(i) : i)
+
+struct __repmgr_site {
+	repmgr_netaddr_t net_addr;
+
+	/*
+	 * Group membership status: a copy of the status from the membership
+	 * database, or the out-of-band value 0, meaning that it doesn't exist.
+	 * We keep track of a "non-existent" site because the associated
+	 * host/port network address is promised to be associated with the
+	 * locally known EID for the life of the environment.
+	 */
+	u_int32_t	membership; /* Status flags from GMDB. */
+	u_int32_t	config;	    /* Flags from site->set_config() */
+
+	/*
+	 * Everything below here is applicable only to remote sites.
+	 */
+	DB_LSN max_ack;		/* Best ack we've heard from this site. */
+	int ack_policy;		/* Or 0 if unknown. */
+	u_int16_t alignment;	/* Requirements for app channel msgs. */
+	db_timespec last_rcvd_timestamp;
+
+	/* Contents depends on state. */
+	struct {
+		struct {		 /* when CONNECTED */
+			/*
+			 * The only time we ever have two connections is in case
+			 * of a "collision" on the "server" side.  In that case,
+			 * the incoming connection either will be closed
+			 * promptly by the remote "client", or it is a half-open
+			 * connection due to the remote client system having
+			 * crashed and rebooted, in which case KEEPALIVE will
+			 * eventually clear it.
+			 */ 
+			REPMGR_CONNECTION *in; /* incoming connection */
+			REPMGR_CONNECTION *out; /* outgoing connection */
+		} conn;
+		REPMGR_RETRY *retry; /* when PAUSING */
+		/* Unused when CONNECTING. */
+	} ref;
+
+	/*
+	 * Subordinate connections (connections from subordinate processes at a
+	 * multi-process site).  Note that the SITE_CONNECTED state, and all the
+	 * ref.retry stuff above is irrelevant to subordinate connections.  If a
+	 * connection is on this list, it exists; and we never bother trying to
+	 * reconnect lost connections (indeed we can't, for these are always
+	 * incoming-only).
+	 */
+	CONNECTION_LIST	sub_conns;
+	REPMGR_RUNNABLE	*connector;	/* Thread to open a connection. */
+
+#define	SITE_CONNECTED 1	/* We have a (main) connection. */
+#define	SITE_CONNECTING 2	/* Trying to establish (main) connection. */
+#define	SITE_IDLE 3		/* Doing nothing. */
+#define	SITE_PAUSING 4		/* Waiting til time to retry connecting. */
+	int state;
+
+#define	SITE_HAS_PRIO	0x01	/* Set if "electable" flag bit is valid. */
+#define	SITE_ELECTABLE	0x02
+#define	SITE_TOUCHED	0x04	/* Seen GMDB record during present scan. */
+	u_int32_t flags;
+};
+
+/*
+ * Flag values for the public DB_SITE handle.
+ */
+#define	DB_SITE_PREOPEN	0x01	/* Provisional EID; may change at env open. */
+
+struct __repmgr_response {
+	DBT		dbt;
+	int		ret;
+
+#define	RESP_COMPLETE		0x01
+#define	RESP_DUMMY_BUF		0x02
+#define	RESP_IN_USE		0x04
+#define	RESP_READING		0x08
+#define	RESP_THREAD_WAITING	0x10
+	u_int32_t	flags;
+};
+
+/*
+ * Private structure for managing comms "channels."  This is separate from
+ * DB_CHANNEL so as to avoid dragging in other private structures (e.g.,
+ * REPMGR_CONNECTION) into db.h, similar to the relationship between DB_ENV and
+ * ENV.
+ */
+struct __channel {
+	DB_CHANNEL *db_channel;
+	ENV *env;
+
+	union {
+		/* For simple, specific-EID channels. */
+		REPMGR_CONNECTION *conn;
+
+		/* For EID_MASTER or EID_BROADCAST channels. */
+		struct {
+			mgr_mutex_t *mutex;  /* For connection establishment. */
+			REPMGR_CONNECTION **array;
+			u_int32_t cnt;
+		} conns;
+	} c;
+	REPMGR_MESSAGE *msg;	/* Incoming channel only; NULL otherwise. */
+	int	responded;	/* Boolean flag. */
+	__repmgr_msg_metadata_args *meta;
+
+	/* Used only in send-to-self request case. */
+	struct __repmgr_response	response;
+};
+
+/*
+ * Repmgr keeps track of references to connection information (instances
+ * of struct __repmgr_connection).  There are three kinds of places
+ * connections may be found: (1) SITE->ref.conn, (2) SITE->sub_conns, and
+ * (3) db_rep->connections.
+ *
+ * 1. SITE->ref.conn points to our connection with the main process running
+ * at the given site, if such a connection exists.  We may have initiated
+ * the connection to the site ourselves, or we may have received it as an
+ * incoming connection.  Once it is established there is very little
+ * difference between those two cases.
+ *
+ * 2. SITE->sub_conns is a list of connections we have with subordinate
+ * processes running at the given site.  There can be any number of these
+ * connections, one per subordinate process.  Note that these connections
+ * are always incoming: there's no way for us to initiate this kind of
+ * connection because subordinate processes do not "listen".
+ *
+ * 3. The db_rep->connections list contains the references to any
+ * connections that are not actively associated with any site (we
+ * sometimes call these "orphans").  There are two times when this can
+ * be:
+ *
+ *   a) When we accept an incoming connection, we don't know what site it
+ *      comes from until we read the initial handshake message.
+ *
+ *   b) When an error occurs on a connection, we first mark it as DEFUNCT
+ *      and stop using it.  Then, at a later, well-defined time, we close
+ *      the connection's file descriptor and get rid of the connection
+ *      struct.
+ *
+ * In light of the above, we can see that the following describes the
+ * rules for how connections may be moved among these three kinds of
+ * "places":
+ *
+ * - when we initiate an outgoing connection, we of course know what site
+ *   it's going to be going to, and so we immediately put the pointer to
+ *   the connection struct into SITE->ref.conn
+ *
+ * - when we accept an incoming connection, we don't immediately know
+ *   whom it's from, so we have to put it on the orphans list
+ *   (db_rep->connections).
+ *
+ * - (incoming, cont.) But as soon as we complete the initial "handshake"
+ *   message exchange, we will know which site it's from and whether it's
+ *   a subordinate or main connection.  At that point we remove it from
+ *   db_rep->connections and either point to it by SITE->ref.conn, or add
+ *   it to the SITE->sub_conns list.
+ *
+ * - (for any active connection) when an error occurs, we move the
+ *   connection to the orphans list until we have a chance to close it.
+ */
+
+/*
+ * Repmgr message formats.
+ *
+ * Declarative definitions of current message formats appear in repmgr.msg.
+ * (The s_message/gen_msg.awk utility generates C code.)  In general, we send
+ * the buffers marshaled from those structure formats in the "control" portion
+ * of a message.
+ *
+ * Each message is prefaced by a 9-byte message header (as described in
+ * repmgr_net.c).  Different message types use the two available 32-bit integers
+ * in different ways, as codified here:
+ */
+#define	REPMGR_HDR1(hdr)		((hdr).word1)
+#define	REPMGR_HDR2(hdr)		((hdr).word2)
+
+/* REPMGR_APP_MESSAGE */
+#define APP_MSG_BUFFER_SIZE		REPMGR_HDR1
+#define	APP_MSG_SEGMENT_COUNT		REPMGR_HDR2
+
+/* REPMGR_REP_MESSAGE and the other traditional repmgr message types. */
+#define	REP_MSG_CONTROL_SIZE		REPMGR_HDR1
+#define	REP_MSG_REC_SIZE		REPMGR_HDR2
+
+/* REPMGR_APP_RESPONSE */
+#define	APP_RESP_BUFFER_SIZE		REPMGR_HDR1
+#define	APP_RESP_TAG			REPMGR_HDR2
+
+/* REPMGR_RESP_ERROR.  Note that a zero-length message body is implied. */
+#define	RESP_ERROR_CODE			REPMGR_HDR1
+#define	RESP_ERROR_TAG			REPMGR_HDR2
+
+/* REPMGR_OWN_MSG */
+#define	REPMGR_OWN_BUF_SIZE		REPMGR_HDR1
+#define	REPMGR_OWN_MSG_TYPE		REPMGR_HDR2
+
+/*
+ * Flags for the handshake message.  As with repmgr message types, these values
+ * are transmitted between sites, and must therefore be "frozen" permanently.
+ * Names are alphabetized here for easy reference, but values reflect historical
+ * usage.
+ */
+#define	APP_CHANNEL_CONNECTION	0x02	/* Connection used for app channel. */
+#define	ELECTABLE_SITE		0x04
+#define	REPMGR_SUBORDINATE	0x01	/* This is a subordinate connection. */
+
+/*
+ * Flags for application-message meta-data.
+ */
+#define	REPMGR_MULTI_RESP	0x01
+#define	REPMGR_REQUEST_MSG_TYPE	0x02
+#define	REPMGR_RESPONSE_LIMIT	0x04
+
+/*
+ * Legacy V1 handshake message format.  For compatibility, we send this as part
+ * of version negotiation upon connection establishment.
+ */
+typedef struct {
+	u_int32_t version;
+	u_int16_t port;
+	u_int32_t priority;
+} DB_REPMGR_V1_HANDSHAKE;
+
+/*
+ * Storage formats.
+ *
+ * As with message formats, stored formats are defined in repmgr.msg.
+ */
+/*
+ * Flags for the Group Membership data portion of a record.  Like message type
+ * codes, these values are frozen across releases, in order to avoid pointless
+ * churn.
+ */
+#define	SITE_ADDING	0x01
+#define	SITE_DELETING	0x02
+#define	SITE_PRESENT	0x04
+
+/*
+ * Message types whose processing could take a long time.  We're careful to
+ * avoid using up all our message processing threads on these message types, so
+ * that we don't starve out the more important rep messages.
+ */ 
+#define	IS_DEFERRABLE(t) ((t) == REPMGR_OWN_MSG || (t) == REPMGR_APP_MESSAGE)
+/*
+ * When using leases there are times when a thread processing a message
+ * must block, waiting for leases to be refreshed.  But refreshing the
+ * leases requires another thread to accept the lease grant messages.
+ */
+#define	RESERVED_MSG_TH(env) (IS_USING_LEASES(env) ? 2 : 1)
+
+#define	IS_SUBORDINATE(db_rep)	(db_rep->listen_fd == INVALID_SOCKET)
+
+#define	IS_PEER_POLICY(p) ((p) == DB_REPMGR_ACKS_ALL_PEERS ||		\
+    (p) == DB_REPMGR_ACKS_QUORUM ||		\
+    (p) == DB_REPMGR_ACKS_ONE_PEER)
+
+/*
+ * Most of the code in repmgr runs while holding repmgr's main mutex, which
+ * resides in db_rep->mutex.  This mutex is owned by a single repmgr process,
+ * and serializes access to the (large) critical sections among threads in the
+ * process.  Unlike many other mutexes in DB, it is specifically coded as either
+ * a POSIX threads mutex or a Win32 mutex.  Note that although it's a large
+ * fraction of the code, it's a tiny fraction of the time: repmgr spends most of
+ * its time in a call to select(), and as well a bit in calls into the Base
+ * replication API.  All of those release the mutex.
+ *     Access to repmgr's shared list of site addresses is protected by
+ * another mutex: mtx_repmgr.  And, when changing space allocation for that site
+ * list we conform to the convention of acquiring renv->mtx_regenv.  These are
+ * less frequent of course.
+ *     When it's necessary to acquire more than one of these mutexes, the
+ * ordering priority (or "lock ordering protocol") is:
+ *        db_rep->mutex (first)
+ *        mtx_repmgr    (briefly)
+ *        mtx_regenv    (last, and most briefly)
+ *
+ * There are also mutexes for app message "channels".  Each channel has a mutex,
+ * which is used to serialize any connection re-establishment that may become
+ * necessary during its lifetime (such as when a master changes).  This never
+ * happens on a simple, specific-EID channel, but in other cases multiple app
+ * threads could be making send_xxx() calls concurrently, and it would not do to
+ * have two of them try to re-connect concurrently.
+ *     When re-establishing a connection, the channel lock is held while
+ * grabbing first the mtx_repmgr, and then the db_rep mutex (but not both
+ * together).  I.e., we have:
+ *        channel->mutex (first)
+ *        [mtx_repmgr (very briefly)] and then [db_rep->mutex (very briefly)]
+ */
+
+#define	LOCK_MUTEX(m) do {						\
+	if (__repmgr_lock_mutex(m) != 0)				\
+		return (DB_RUNRECOVERY);				\
+} while (0)
+
+#define	UNLOCK_MUTEX(m) do {						\
+		if (__repmgr_unlock_mutex(m) != 0)			\
+		return (DB_RUNRECOVERY);				\
+} while (0)
+
+/* POSIX/Win32 socket (and other) portability. */
+#ifdef DB_WIN32
+#define	WOULDBLOCK		WSAEWOULDBLOCK
+#undef	DB_REPMGR_EAGAIN
+
+#define	net_errno		WSAGetLastError()
+typedef int socklen_t;
+typedef char * sockopt_t;
+#define	sendsocket(s, buf, len, flags) send((s), (buf), (int)(len), (flags))
+
+#define	iov_len len
+#define	iov_base buf
+
+typedef DWORD threadsync_timeout_t;
+
+#define	REPMGR_INITED(db_rep) (db_rep->signaler != NULL)
+#else
+
+#define	INVALID_SOCKET		-1
+#define	SOCKET_ERROR		-1
+#define	WOULDBLOCK		EWOULDBLOCK
+#define	DB_REPMGR_EAGAIN	EAGAIN
+
+#define	net_errno		errno
+typedef void * sockopt_t;
+
+#define	sendsocket(s, buf, len, flags) send((s), (buf), (len), (flags))
+#define	closesocket(fd)		close(fd)
+
+typedef struct timespec threadsync_timeout_t;
+
+#define	REPMGR_INITED(db_rep) (db_rep->read_pipe >= 0)
+#endif
+
+#define	SELECTOR_RUNNING(db_rep)	((db_rep)->selector != NULL)
+
+/*
+ * Generic definition of some action to be performed on each connection, in the
+ * form of a call-back function.
+ */
+typedef int (*CONNECTION_ACTION) __P((ENV *, REPMGR_CONNECTION *, void *));
+
+/*
+ * Generic predicate to test a condition that a thread is waiting for.
+ */
+typedef int (*PREDICATE) __P((ENV *, void *));
+
+#include "dbinc_auto/repmgr_ext.h"
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_REPMGR_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/shqueue.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,432 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef	_DB_SHQUEUE_H_
+#define	_DB_SHQUEUE_H_
+
+/*
+ * This file defines three types of data structures: chains, lists and
+ * tail queues similarly to the include file <sys/queue.h>.
+ *
+ * The difference is that this set of macros can be used for structures that
+ * reside in shared memory that may be mapped at different addresses in each
+ * process.  In most cases, the macros for shared structures exactly mirror
+ * the normal macros, although the macro calls require an additional type
+ * parameter, only used by the HEAD and ENTRY macros of the standard macros.
+ *
+ * Since we use relative offsets of type ssize_t rather than pointers, 0
+ * (aka NULL) is a valid offset and cannot be used to indicate the end
+ * of a list.  Therefore, we use -1 to indicate end of list.
+ *
+ * The macros ending in "P" return pointers without checking for end or
+ * beginning of lists, the others check for end of list and evaluate to
+ * either a pointer or NULL.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define	SH_PTR_TO_OFF(src, dest)					\
+	((db_ssize_t)(((u_int8_t *)(dest)) - ((u_int8_t *)(src))))
+
+#define SH_OFF_TO_PTR(base, off, type)           \
+       ((type *) (((u_int8_t *)(base)) + (db_ssize_t) (off)))
+
+
+/*
+ * Shared memory chain definitions.
+ */
+#define	SH_CHAIN_ENTRY							\
+struct {								\
+	db_ssize_t sce_next;	/* relative offset to next element */	\
+	db_ssize_t sce_prev;	/* relative offset of prev element */	\
+}
+
+#define	SH_CHAIN_INIT(elm, field)					\
+	(elm)->field.sce_next = (elm)->field.sce_prev =	-1
+
+#define	SH_CHAIN_HASNEXT(elm, field)	((elm)->field.sce_next != -1)
+#define	SH_CHAIN_NEXTP(elm, field, type)				\
+    ((struct type *)((u_int8_t *)(elm) + (elm)->field.sce_next))
+#define	SH_CHAIN_NEXT(elm, field, type)	(SH_CHAIN_HASNEXT(elm, field) ?	\
+    SH_CHAIN_NEXTP(elm, field, type) : (struct type *)NULL)
+
+#define	SH_CHAIN_HASPREV(elm, field)	((elm)->field.sce_prev != -1)
+#define	SH_CHAIN_PREVP(elm, field, type)				\
+    ((struct type *)((u_int8_t *)(elm) + (elm)->field.sce_prev))
+#define	SH_CHAIN_PREV(elm, field, type)	(SH_CHAIN_HASPREV(elm, field) ?	\
+     SH_CHAIN_PREVP(elm, field, type) : (struct type *)NULL)
+
+#define	SH_CHAIN_SINGLETON(elm, field)					\
+    (!(SH_CHAIN_HASNEXT(elm, field) || SH_CHAIN_HASPREV(elm, field)))
+
+#define	SH_CHAIN_INSERT_AFTER(listelm, elm, field, type) do {		\
+	struct type *__next = SH_CHAIN_NEXT(listelm, field, type);	\
+	if (__next != NULL) {						\
+		(elm)->field.sce_next =	SH_PTR_TO_OFF(elm, __next);	\
+		__next->field.sce_prev = SH_PTR_TO_OFF(__next, elm);	\
+	} else								\
+		(elm)->field.sce_next = -1;				\
+	(elm)->field.sce_prev = SH_PTR_TO_OFF(elm, listelm);		\
+	(listelm)->field.sce_next = SH_PTR_TO_OFF(listelm, elm);	\
+} while (0)
+
+#define	SH_CHAIN_INSERT_BEFORE(listelm, elm, field, type) do {		\
+	struct type *__prev = SH_CHAIN_PREV(listelm, field, type);	\
+	if (__prev != NULL) {						\
+		(elm)->field.sce_prev = SH_PTR_TO_OFF(elm, __prev);	\
+		__prev->field.sce_next = SH_PTR_TO_OFF(__prev, elm);	\
+	} else								\
+		(elm)->field.sce_prev = -1;				\
+	(elm)->field.sce_next = SH_PTR_TO_OFF(elm, listelm);		\
+	(listelm)->field.sce_prev = SH_PTR_TO_OFF(listelm, elm);	\
+} while (0)
+
+#define	SH_CHAIN_REMOVE(elm, field, type) do {				\
+	struct type *__prev = SH_CHAIN_PREV(elm, field, type);		\
+	struct type *__next = SH_CHAIN_NEXT(elm, field, type);		\
+	if (__next != NULL)						\
+		__next->field.sce_prev = (__prev == NULL) ? -1 :	\
+		    SH_PTR_TO_OFF(__next, __prev);			\
+	if (__prev != NULL)						\
+		__prev->field.sce_next = (__next == NULL) ? -1 :	\
+		    SH_PTR_TO_OFF(__prev, __next);			\
+	SH_CHAIN_INIT(elm, field);					\
+} while (0)
+
+/*
+ * Shared memory list definitions.
+ */
+#define	SH_LIST_HEAD(name)						\
+struct name {								\
+	db_ssize_t slh_first;	/* first element */			\
+}
+
+#define	SH_LIST_HEAD_INITIALIZER(head)					\
+	{ -1 }
+
+#define	SH_LIST_ENTRY							\
+struct {								\
+	db_ssize_t sle_next;	/* relative offset to next element */	\
+	db_ssize_t sle_prev;	/* relative offset of prev element */	\
+}
+
+/*
+ * Shared memory list functions.
+ */
+#define	SH_LIST_EMPTY(head)						\
+	((head)->slh_first == -1)
+
+#define	SH_LIST_FIRSTP(head, type)					\
+	((struct type *)(((u_int8_t *)(head)) + (head)->slh_first))
+
+#define	SH_LIST_FIRST(head, type)					\
+	(SH_LIST_EMPTY(head) ? NULL :					\
+	((struct type *)(((u_int8_t *)(head)) + (head)->slh_first)))
+
+#define	SH_LIST_NEXTP(elm, field, type)					\
+	((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next))
+
+#define	SH_LIST_NEXT(elm, field, type)					\
+	((elm)->field.sle_next == -1 ? NULL :				\
+	((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next)))
+
+  /*
+   *__SH_LIST_PREV_OFF is private API.  It calculates the address of
+   * the elm->field.sle_next member of a SH_LIST structure.  All offsets
+   * between elements are relative to that point in SH_LIST structures.
+   */
+#define	__SH_LIST_PREV_OFF(elm, field)					\
+	((db_ssize_t *)(((u_int8_t *)(elm)) + (elm)->field.sle_prev))
+
+#define	SH_LIST_PREV(elm, field, type)					\
+	(struct type *)((db_ssize_t)(elm) - (*__SH_LIST_PREV_OFF(elm, field)))
+
+#define	SH_LIST_FOREACH(var, head, field, type)				\
+	for ((var) = SH_LIST_FIRST((head), type);			\
+	    (var) != NULL;						\
+	    (var) = SH_LIST_NEXT((var), field, type))
+
+/*
+ * Given correct A.next: B.prev = SH_LIST_NEXT_TO_PREV(A)
+ * in a list [A, B]
+ * The prev value is always the offset from an element to its preceding
+ * element's next location, not the beginning of the structure.  To get
+ * to the beginning of an element structure in memory given an element
+ * do the following:
+ * A = B - (B.prev + (&B.next - B))
+ * Take the element's next pointer and calculate what the corresponding
+ * Prev pointer should be -- basically it is the negation plus the offset
+ * of the next field in the structure.
+ */
+#define	SH_LIST_NEXT_TO_PREV(elm, field)				\
+	(((elm)->field.sle_next == -1 ? 0 : -(elm)->field.sle_next) +	\
+	   SH_PTR_TO_OFF(elm, &(elm)->field.sle_next))
+
+#define	SH_LIST_INIT(head) (head)->slh_first = -1
+
+#define	SH_LIST_INSERT_BEFORE(head, listelm, elm, field, type) do {	\
+	if (listelm == SH_LIST_FIRST(head, type)) {			\
+	SH_LIST_INSERT_HEAD(head, elm, field, type);			\
+	} else {							\
+		(elm)->field.sle_next = SH_PTR_TO_OFF(elm, listelm);	\
+		(elm)->field.sle_prev = SH_LIST_NEXT_TO_PREV(		\
+			SH_LIST_PREV((listelm), field, type), field) +	\
+		(elm)->field.sle_next;					\
+		(SH_LIST_PREV(listelm, field, type))->field.sle_next =	\
+			(SH_PTR_TO_OFF((SH_LIST_PREV(listelm, field,	\
+						     type)), elm));	\
+	(listelm)->field.sle_prev = SH_LIST_NEXT_TO_PREV(elm, field);	\
+	}								\
+} while (0)
+
+#define	SH_LIST_INSERT_AFTER(listelm, elm, field, type) do {		\
+	if ((listelm)->field.sle_next != -1) {				\
+		(elm)->field.sle_next = SH_PTR_TO_OFF(elm,		\
+		    SH_LIST_NEXTP(listelm, field, type));		\
+		SH_LIST_NEXTP(listelm, field, type)->field.sle_prev =	\
+			SH_LIST_NEXT_TO_PREV(elm, field);		\
+	} else								\
+		(elm)->field.sle_next = -1;				\
+	(listelm)->field.sle_next = SH_PTR_TO_OFF(listelm, elm);	\
+	(elm)->field.sle_prev = SH_LIST_NEXT_TO_PREV(listelm, field);	\
+} while (0)
+
+#define	SH_LIST_INSERT_HEAD(head, elm, field, type) do {		\
+	if ((head)->slh_first != -1) {					\
+		(elm)->field.sle_next =					\
+		    (head)->slh_first - SH_PTR_TO_OFF(head, elm);	\
+		SH_LIST_FIRSTP(head, type)->field.sle_prev =		\
+			SH_LIST_NEXT_TO_PREV(elm, field);		\
+	} else								\
+		(elm)->field.sle_next = -1;				\
+	(head)->slh_first = SH_PTR_TO_OFF(head, elm);			\
+	(elm)->field.sle_prev = SH_PTR_TO_OFF(elm, &(head)->slh_first);	\
+} while (0)
+
+#define	SH_LIST_REMOVE(elm, field, type) do {				\
+	if ((elm)->field.sle_next != -1) {				\
+		SH_LIST_NEXTP(elm, field, type)->field.sle_prev =	\
+			(elm)->field.sle_prev - (elm)->field.sle_next;	\
+		*__SH_LIST_PREV_OFF(elm, field) += (elm)->field.sle_next;\
+	} else								\
+		*__SH_LIST_PREV_OFF(elm, field) = -1;			\
+} while (0)
+
+#define	SH_LIST_REMOVE_HEAD(head, field, type) do {			\
+	if (!SH_LIST_EMPTY(head)) {					\
+		SH_LIST_REMOVE(SH_LIST_FIRSTP(head, type), field, type);\
+	}								\
+} while (0)
+
+/*
+ * Shared memory tail queue definitions.
+ */
+#define	SH_TAILQ_HEAD(name)						\
+struct name {								\
+	db_ssize_t stqh_first;	/* relative offset of first element */	\
+	db_ssize_t stqh_last;	/* relative offset of last's next */	\
+}
+
+#define	SH_TAILQ_HEAD_INITIALIZER(head)					\
+	{ -1, 0 }
+
+#define	SH_TAILQ_ENTRY							\
+struct {								\
+	db_ssize_t stqe_next;	/* relative offset of next element */	\
+	db_ssize_t stqe_prev;	/* relative offset of prev's next */	\
+}
+
+/*
+ * Shared memory tail queue functions.
+ */
+
+#define	SH_TAILQ_EMPTY(head)						\
+	((head)->stqh_first == -1)
+
+#define	SH_TAILQ_FIRSTP(head, type)					\
+	((struct type *)((u_int8_t *)(head) + (head)->stqh_first))
+
+#define	SH_TAILQ_FIRST(head, type)					\
+	(SH_TAILQ_EMPTY(head) ? NULL : SH_TAILQ_FIRSTP(head, type))
+
+#define	SH_TAILQ_NEXTP(elm, field, type)				\
+	((struct type *)((u_int8_t *)(elm) + (elm)->field.stqe_next))
+
+#define	SH_TAILQ_NEXT(elm, field, type)					\
+	((elm)->field.stqe_next == -1 ? NULL :				\
+	((struct type *)((u_int8_t *)(elm) + (elm)->field.stqe_next)))
+
+  /*
+   * __SH_TAILQ_PREV_OFF is private API.  It calculates the address of
+   * the elm->field.stqe_next member of a SH_TAILQ structure.  All
+   * offsets between elements are relative to that point in SH_TAILQ
+   * structures.
+   */
+#define	__SH_TAILQ_PREV_OFF(elm, field)					\
+	((db_ssize_t *)(((u_int8_t *)(elm)) + (elm)->field.stqe_prev))
+
+#define	SH_TAILQ_PREVP(elm, field, type)				\
+	(struct type *)((db_ssize_t)elm - (*__SH_TAILQ_PREV_OFF(elm, field)))
+
+#define	SH_TAILQ_PREV(head, elm, field, type)				\
+	(((elm) == SH_TAILQ_FIRST(head, type)) ? NULL :		\
+	  (struct type *)((db_ssize_t)elm - (*__SH_TAILQ_PREV_OFF(elm, field))))
+
+  /*
+   * __SH_TAILQ_LAST_OFF is private API.  It calculates the address of
+   * the stqe_next member of a SH_TAILQ structure in the last element
+   * of this list.  All offsets between elements are relative to that
+   * point in SH_TAILQ structures.
+   */
+#define	__SH_TAILQ_LAST_OFF(head)					\
+	((db_ssize_t *)(((u_int8_t *)(head)) + (head)->stqh_last))
+
+#define	SH_TAILQ_LASTP(head, field, type)				\
+	((struct type *)((db_ssize_t)(head) +				\
+	 ((db_ssize_t)((head)->stqh_last) -				\
+	 ((db_ssize_t)SH_PTR_TO_OFF(SH_TAILQ_FIRST(head, type),		\
+		&(SH_TAILQ_FIRSTP(head, type)->field.stqe_next))))))
+
+#define	SH_TAILQ_LAST(head, field, type)				\
+	(SH_TAILQ_EMPTY(head) ? NULL : SH_TAILQ_LASTP(head, field, type))
+
+/*
+ * Given correct A.next: B.prev = SH_TAILQ_NEXT_TO_PREV(A)
+ * in a list [A, B]
+ * The prev value is always the offset from an element to its preceding
+ * element's next location, not the beginning of the structure.  To get
+ * to the beginning of an element structure in memory given an element
+ * do the following:
+ * A = B - (B.prev + (&B.next - B))
+ */
+#define	SH_TAILQ_NEXT_TO_PREV(elm, field)				\
+	(((elm)->field.stqe_next == -1 ? 0 :				\
+		(-(elm)->field.stqe_next) +				\
+		SH_PTR_TO_OFF(elm, &(elm)->field.stqe_next)))
+
+#define	SH_TAILQ_FOREACH(var, head, field, type)			\
+	for ((var) = SH_TAILQ_FIRST((head), type);			\
+	    (var) != NULL;						\
+	    (var) = SH_TAILQ_NEXT((var), field, type))
+
+#define	SH_TAILQ_FOREACH_REVERSE(var, head, field, type)		\
+	for ((var) = SH_TAILQ_LAST((head), field, type);		\
+	    (var) != NULL;						\
+	    (var) = SH_TAILQ_PREV((head), (var), field, type))
+
+#define	SH_TAILQ_INIT(head) {						\
+	(head)->stqh_first = -1;					\
+	(head)->stqh_last = SH_PTR_TO_OFF(head, &(head)->stqh_first);	\
+}
+
+#define	SH_TAILQ_INSERT_HEAD(head, elm, field, type) do {		\
+	if ((head)->stqh_first != -1) {					\
+		(elm)->field.stqe_next =				\
+		    (head)->stqh_first - SH_PTR_TO_OFF(head, elm);	\
+		SH_TAILQ_FIRSTP(head, type)->field.stqe_prev =		\
+			SH_TAILQ_NEXT_TO_PREV(elm, field);		\
+	} else {							\
+		(head)->stqh_last =					\
+		    SH_PTR_TO_OFF(head, &(elm)->field.stqe_next);	\
+		(elm)->field.stqe_next = -1;				\
+	}								\
+	(head)->stqh_first = SH_PTR_TO_OFF(head, elm);			\
+	(elm)->field.stqe_prev =					\
+	    SH_PTR_TO_OFF(elm, &(head)->stqh_first);			\
+} while (0)
+
+#define	SH_TAILQ_INSERT_TAIL(head, elm, field) do {			\
+	(elm)->field.stqe_next = -1;					\
+	(elm)->field.stqe_prev =					\
+	    -SH_PTR_TO_OFF(head, elm) + (head)->stqh_last;		\
+	if ((head)->stqh_last ==					\
+	    SH_PTR_TO_OFF((head), &(head)->stqh_first))			\
+		(head)->stqh_first = SH_PTR_TO_OFF(head, elm);		\
+	else								\
+		*__SH_TAILQ_LAST_OFF(head) = -(head)->stqh_last +	\
+		    SH_PTR_TO_OFF((elm), &(elm)->field.stqe_next) +	\
+		    SH_PTR_TO_OFF(head, elm);				\
+	(head)->stqh_last =						\
+	    SH_PTR_TO_OFF(head, &((elm)->field.stqe_next));		\
+} while (0)
+
+#define	SH_TAILQ_INSERT_BEFORE(head, listelm, elm, field, type) do {	\
+	if (listelm == SH_TAILQ_FIRST(head, type)) {			\
+		SH_TAILQ_INSERT_HEAD(head, elm, field, type);		\
+	} else {							\
+		(elm)->field.stqe_next = SH_PTR_TO_OFF(elm, listelm);	\
+		(elm)->field.stqe_prev = SH_TAILQ_NEXT_TO_PREV(		\
+			SH_TAILQ_PREVP((listelm), field, type), field) + \
+			(elm)->field.stqe_next;				\
+		(SH_TAILQ_PREVP(listelm, field, type))->field.stqe_next =\
+		(SH_PTR_TO_OFF((SH_TAILQ_PREVP(listelm, field, type)),	\
+			elm));						\
+		(listelm)->field.stqe_prev =				\
+			SH_TAILQ_NEXT_TO_PREV(elm, field);		\
+	}								\
+} while (0)
+
+#define	SH_TAILQ_INSERT_AFTER(head, listelm, elm, field, type) do {	\
+	if ((listelm)->field.stqe_next != -1) {				\
+		(elm)->field.stqe_next = (listelm)->field.stqe_next -	\
+		    SH_PTR_TO_OFF(listelm, elm);			\
+		SH_TAILQ_NEXTP(listelm, field, type)->field.stqe_prev =	\
+		    SH_TAILQ_NEXT_TO_PREV(elm, field);			\
+	} else {							\
+		(elm)->field.stqe_next = -1;				\
+		(head)->stqh_last =					\
+		    SH_PTR_TO_OFF(head, &(elm)->field.stqe_next);	\
+	}								\
+	(listelm)->field.stqe_next = SH_PTR_TO_OFF(listelm, elm);	\
+	(elm)->field.stqe_prev = SH_TAILQ_NEXT_TO_PREV(listelm, field);	\
+} while (0)
+
+#define	SH_TAILQ_REMOVE(head, elm, field, type) do {			\
+	if ((elm)->field.stqe_next != -1) {				\
+		SH_TAILQ_NEXTP(elm, field, type)->field.stqe_prev =	\
+		    (elm)->field.stqe_prev +				\
+		    SH_PTR_TO_OFF(SH_TAILQ_NEXTP(elm,			\
+		    field, type), elm);					\
+		*__SH_TAILQ_PREV_OFF(elm, field) += (elm)->field.stqe_next;\
+	} else {							\
+		(head)->stqh_last = (elm)->field.stqe_prev +		\
+			SH_PTR_TO_OFF(head, elm);			\
+		*__SH_TAILQ_PREV_OFF(elm, field) = -1;			\
+	}								\
+} while (0)
+
+#if defined(__cplusplus)
+}
+#endif
+#endif	/* !_DB_SHQUEUE_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/tcl_db.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,338 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_TCL_DB_H_
+#define	_DB_TCL_DB_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define	MSG_SIZE 100		/* Message size */
+
+enum INFOTYPE {
+	I_AUX, I_DB, I_DBC, I_ENV, I_LOCK, I_LOGC, I_MP, I_NDBM, I_PG, I_SEQ, I_TXN};
+
+#define	MAX_ID		8	/* Maximum number of sub-id's we need */
+#define	DBTCL_PREP	64	/* Size of txn_recover preplist */
+
+#define	DBTCL_DBM	1
+#define	DBTCL_NDBM	2
+
+#define	DBTCL_GETCLOCK		0
+#define	DBTCL_GETLIMIT		1
+#define	DBTCL_GETREQ		2
+
+#define	DBTCL_MUT_ALIGN	0
+#define	DBTCL_MUT_INCR	1
+#define	DBTCL_MUT_INIT	2
+#define	DBTCL_MUT_MAX	3
+#define	DBTCL_MUT_TAS	4
+
+/*
+ * Data structure to record information about events that have occurred.  Tcl
+ * command "env event_info" can retrieve the information.  For now, we record
+ * only one occurrence per event type; "env event_info -clear" can be used to
+ * reset the info.
+ *
+ * Besides the bit flag that records the fact that an event type occurred, some
+ * event types have associated "info" and we record that here too.  When new
+ * event types are invented that have associated info, we should add a field
+ * here to record that info as well, so that it can be returned to the script
+ * with the "env event_info" results.
+ */
+typedef struct dbtcl_event_info {
+	u_int32_t	events;	/* Bit flag on for each event fired. */
+	int		panic_error;
+	int		newmaster_eid;
+	int		added_eid;
+	int		removed_eid;
+	pid_t		attached_process;
+	int		connected_eid;
+	DB_REPMGR_CONN_ERR conn_broken_info;
+	DB_REPMGR_CONN_ERR conn_failed_try_info;
+	DB_LSN		sync_point;
+} DBTCL_EVENT_INFO;
+
+/*
+ * Why use a home grown package over the Tcl_Hash functions?
+ *
+ * We could have implemented the stuff below without maintaining our
+ * own list manipulation, efficiently hashing it with the available
+ * Tcl functions (Tcl_CreateHashEntry, Tcl_GetHashValue, etc).  I chose
+ * not to do so for these reasons:
+ *
+ * We still need the information below.  Using the hashing only removes
+ * us from needing the next/prev pointers.  We still need the structure
+ * itself because we need more than one value associated with a widget.
+ * We need to keep track of parent pointers for sub-widgets (like cursors)
+ * so we can correctly close.  We need to keep track of individual widget's
+ * id counters for any sub-widgets they may have.  We need to be able to
+ * associate the name/client data outside the scope of the widget.
+ *
+ * So, is it better to use the hashing rather than
+ * the linear list we have now?  I decided against it for the simple reason
+ * that to access the structure would require two calls.  The first is
+ * Tcl_FindHashEntry(table, key) and then, once we have the entry, we'd
+ * have to do Tcl_GetHashValue(entry) to get the pointer of the structure.
+ *
+ * I believe the number of simultaneous DB widgets in existence at one time
+ * is not going to be that large (more than several dozen) such that
+ * linearly searching the list is not going to impact performance in a
+ * noticeable way.  Should performance be impacted due to the size of the
+ * info list, then perhaps it is time to revisit this decision.
+ */
+typedef struct dbtcl_info {
+	LIST_ENTRY(dbtcl_info) entries;
+	Tcl_Interp *i_interp;
+	char *i_name;
+	enum INFOTYPE i_type;
+	union infop {
+		DB *dbp;
+		DBC *dbcp;
+		DB_ENV *envp;
+		DB_LOCK *lock;
+		DB_LOGC *logc;
+		DB_MPOOLFILE *mp;
+		DB_TXN *txnp;
+		void *anyp;
+	} un;
+	union data {
+		int anydata;
+		db_pgno_t pgno;		      /* For I_MP. */
+		u_int32_t lockid;	      /* For I_LOCK. */
+		DBTCL_EVENT_INFO *event_info; /* For I_ENV. */
+		DB_TXN_TOKEN *commit_token;   /* For I_TXN. */
+	} und;
+	union data2 {
+		int anydata;
+		int pagesz;	    /* For I_MP. */
+		DB_COMPACT *c_data; /* For I_DB. */
+		db_mutex_t mutex;   /* Protects event_info (I_ENV). */
+	} und2;
+	DBT i_lockobj;
+	FILE *i_err;
+	char *i_errpfx;
+	FILE *i_msg;
+
+	/* Callbacks--Tcl_Objs containing proc names */
+	Tcl_Obj *i_compare;
+	Tcl_Obj *i_dupcompare;
+	Tcl_Obj *i_foreign_call;
+	Tcl_Obj *i_hashproc;
+	Tcl_Obj *i_isalive;
+	Tcl_Obj *i_part_callback;
+	Tcl_Obj *i_rep_send;
+	Tcl_Obj *i_second_call;
+
+	/* Environment ID for the i_rep_send callback. */
+	Tcl_Obj *i_rep_eid;
+
+	struct dbtcl_info *i_parent;
+	int	i_otherid[MAX_ID];
+
+	/* Heap dbs have an associated recno db, and secondary db. */
+	DB *hrdbp;
+	DB *hsdbp;
+} DBTCL_INFO;
+
+#define	i_anyp un.anyp
+#define	i_dbp un.dbp
+#define	i_dbcp un.dbcp
+#define	i_envp un.envp
+#define	i_lock un.lock
+#define	i_logc un.logc
+#define	i_mp un.mp
+#define	i_pagep un.anyp
+#define	i_txnp un.txnp
+
+#define	i_data und.anydata
+#define	i_pgno und.pgno
+#define	i_locker und.lockid
+#define	i_event_info und.event_info
+#define	i_commit_token und.commit_token
+#define	i_data2 und2.anydata
+#define	i_pgsz und2.pagesz
+#define	i_cdata und2.c_data
+#define	i_mutex und2.mutex
+
+#define	i_envtxnid i_otherid[0]
+#define	i_envmpid i_otherid[1]
+#define	i_envlockid i_otherid[2]
+#define	i_envlogcid i_otherid[3]
+
+#define	i_mppgid  i_otherid[0]
+
+#define	i_dbdbcid i_otherid[0]
+
+extern int __debug_on, __debug_print, __debug_stop, __debug_test;
+
+typedef struct dbtcl_global {
+	LIST_HEAD(infohead, dbtcl_info) g_infohead;
+} DBTCL_GLOBAL;
+#define	__db_infohead __dbtcl_global.g_infohead
+
+extern DBTCL_GLOBAL __dbtcl_global;
+
+/*
+ * Tcl_NewStringObj takes an "int" length argument, when the typical use is to
+ * call it with a size_t length (for example, returned by strlen).  Tcl is in
+ * the wrong, but that doesn't help us much -- cast the argument.
+ */
+#define	NewStringObj(a, b)						\
+	Tcl_NewStringObj((a), (int)(b))
+
+#define	NAME_TO_DB(name)	(DB *)_NameToPtr((name))
+#define	NAME_TO_DBC(name)	(DBC *)_NameToPtr((name))
+#define	NAME_TO_ENV(name)	(DB_ENV *)_NameToPtr((name))
+#define	NAME_TO_LOCK(name)	(DB_LOCK *)_NameToPtr((name))
+#define	NAME_TO_MP(name)	(DB_MPOOLFILE *)_NameToPtr((name))
+#define	NAME_TO_TXN(name)	(DB_TXN *)_NameToPtr((name))
+#define	NAME_TO_SEQUENCE(name)	(DB_SEQUENCE *)_NameToPtr((name))
+
+/*
+ * MAKE_STAT_LIST appends a {name value} pair to a result list that MUST be
+ * called 'res' that is a Tcl_Obj * in the local function.  This macro also
+ * assumes a label "error" to go to in the event of a Tcl error.  For stat
+ * functions this will typically go before the "free" function to free the
+ * stat structure returned by DB.
+ */
+#define	MAKE_STAT_LIST(s, v) do {					\
+	result = _SetListElemInt(interp, res, (s), (long)(v));		\
+	if (result != TCL_OK)						\
+		goto error;						\
+} while (0)
+
+#define	MAKE_WSTAT_LIST(s, v) do {					\
+	result = _SetListElemWideInt(interp, res, (s), (int64_t)(v));	\
+	if (result != TCL_OK)						\
+		goto error;						\
+} while (0)
+
+/*
+ * MAKE_STAT_LSN appends a {name {LSNfile LSNoffset}} pair to a result list
+ * that MUST be called 'res' that is a Tcl_Obj * in the local
+ * function.  This macro also assumes a label "error" to go to
+ * in the even of a Tcl error.  For stat functions this will
+ * typically go before the "free" function to free the stat structure
+ * returned by DB.
+ */
+#define	MAKE_STAT_LSN(s, lsn) do {					\
+	myobjc = 2;							\
+	myobjv[0] = Tcl_NewLongObj((long)(lsn)->file);			\
+	myobjv[1] = Tcl_NewLongObj((long)(lsn)->offset);		\
+	lsnlist = Tcl_NewListObj(myobjc, myobjv);			\
+	myobjc = 2;							\
+	myobjv[0] = Tcl_NewStringObj((s), (int)strlen(s));		\
+	myobjv[1] = lsnlist;						\
+	thislist = Tcl_NewListObj(myobjc, myobjv);			\
+	result = Tcl_ListObjAppendElement(interp, res, thislist);	\
+	if (result != TCL_OK)						\
+		goto error;						\
+} while (0)
+
+/*
+ * MAKE_STAT_STRLIST appends a {name string} pair to a result list
+ * that MUST be called 'res' that is a Tcl_Obj * in the local
+ * function.  This macro also assumes a label "error" to go to
+ * in the even of a Tcl error.  For stat functions this will
+ * typically go before the "free" function to free the stat structure
+ * returned by DB.
+ */
+#define	MAKE_STAT_STRLIST(s,s1) do {					\
+	result = _SetListElem(interp, res, (s), (u_int32_t)strlen(s),	\
+	    (s1), (u_int32_t)strlen(s1));				\
+	if (result != TCL_OK)						\
+		goto error;						\
+} while (0)
+
+/*
+ * MAKE_SITE_LIST appends a {eid host port status} tuple to a result list
+ * that MUST be called 'res' that is a Tcl_Obj * in the local function.
+ * This macro also assumes a label "error" to go to in the event of a Tcl
+ * error.
+ */
+#define	MAKE_SITE_LIST(e, h, p, s, pr) do {				\
+	myobjc = 5;							\
+	myobjv[0] = Tcl_NewIntObj(e);					\
+	myobjv[1] = Tcl_NewStringObj((h), (int)strlen(h));		\
+	myobjv[2] = Tcl_NewIntObj((int)p);				\
+	myobjv[3] = Tcl_NewStringObj((s), (int)strlen(s));		\
+	myobjv[4] = Tcl_NewStringObj((pr), (int)strlen(pr));		\
+	thislist = Tcl_NewListObj(myobjc, myobjv);			\
+	result = Tcl_ListObjAppendElement(interp, res, thislist);	\
+	if (result != TCL_OK)						\
+		goto error;						\
+} while (0)
+
+/*
+ * FLAG_CHECK checks that the given flag is not set yet.
+ * If it is, it sets up an error message.
+ */
+#define	FLAG_CHECK(flag) do {						\
+	if ((flag) != 0) {						\
+		Tcl_SetResult(interp,					\
+		    " Only 1 policy can be specified.\n",		\
+		    TCL_STATIC);					\
+		result = TCL_ERROR;					\
+		break;							\
+	}								\
+} while (0)
+
+/*
+ * FLAG_CHECK2 checks that the given flag is not set yet or is
+ * only set to the given allowed value.
+ * If it is, it sets up an error message.
+ */
+#define	FLAG_CHECK2(flag, val) do {					\
+	if (((flag) & ~(val)) != 0) {					\
+		Tcl_SetResult(interp,					\
+		    " Only 1 policy can be specified.\n",		\
+		    TCL_STATIC);					\
+		result = TCL_ERROR;					\
+		break;							\
+	}								\
+} while (0)
+
+/*
+ * IS_HELP checks whether the arg we bombed on is -?, which is a help option.
+ * If it is, we return TCL_OK (but leave the result set to whatever
+ * Tcl_GetIndexFromObj says, which lists all the valid options.  Otherwise
+ * return TCL_ERROR.
+ */
+#define	IS_HELP(s)						\
+    (strcmp(Tcl_GetStringFromObj(s,NULL), "-?") == 0) ? TCL_OK : TCL_ERROR
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/tcl_ext.h"
+#endif /* !_DB_TCL_DB_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/txn.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,310 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef	_DB_TXN_H_
+#define	_DB_TXN_H_
+
+#include "dbinc/xa.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Operation parameters to the delayed commit processing code. */
+typedef enum {
+	TXN_CLOSE,		/* Close a DB handle whose close had failed. */
+	TXN_REMOVE,		/* Remove a file. */
+	TXN_TRADE,		/* Trade lockers. */
+	TXN_TRADED,		/* Already traded; downgrade lock. */
+	TXN_XTRADE		/* Trade lockers on exclusive db handle. */
+} TXN_EVENT_T;
+
+struct __db_txnregion;	typedef struct __db_txnregion DB_TXNREGION;
+struct __db_txn_stat_int;
+typedef struct __db_txn_stat_int DB_TXN_STAT_INT;
+struct __txn_logrec;	typedef struct __txn_logrec DB_TXNLOGREC;
+
+/*
+ * !!!
+ * TXN_MINIMUM = (DB_LOCK_MAXID + 1) but this makes compilers complain.
+ */
+#define	TXN_MINIMUM	0x80000000
+#define	TXN_MAXIMUM	0xffffffff	/* Maximum number of txn ids. */
+#define	TXN_INVALID	0		/* Invalid transaction ID. */
+
+#define	DEF_MAX_TXNS	100		/* Default max transactions. */
+#define	TXN_NSLOTS	4		/* Initial slots to hold DB refs */
+
+#define	TXN_PRIORITY_DEFAULT	DB_LOCK_DEFPRIORITY
+
+/*
+ * This structure must contain the same fields as the __db_txn_stat struct
+ * except for any pointer fields that are filled in only when the struct is
+ * being populated for output through the API.
+ */
+DB_ALIGN8 struct __db_txn_stat_int { /* SHARED */
+	u_int32_t st_nrestores;		/* number of restored transactions
+					   after recovery. */
+#ifndef __TEST_DB_NO_STATISTICS
+	DB_LSN	  st_last_ckp;		/* lsn of the last checkpoint */
+	time_t	  st_time_ckp;		/* time of last checkpoint */
+	u_int32_t st_last_txnid;	/* last transaction id given out */
+	u_int32_t st_inittxns;		/* initial txns allocated */
+	u_int32_t st_maxtxns;		/* maximum txns possible */
+	uintmax_t st_naborts;		/* number of aborted transactions */
+	uintmax_t st_nbegins;		/* number of begun transactions */
+	uintmax_t st_ncommits;		/* number of committed transactions */
+	u_int32_t st_nactive;		/* number of active transactions */
+	u_int32_t st_nsnapshot;		/* number of snapshot transactions */
+	u_int32_t st_maxnactive;	/* maximum active transactions */
+	u_int32_t st_maxnsnapshot;	/* maximum snapshot transactions */
+	uintmax_t st_region_wait;	/* Region lock granted after wait. */
+	uintmax_t st_region_nowait;	/* Region lock granted without wait. */
+	roff_t	  st_regsize;		/* Region size. */
+#endif
+};
+
+/*
+ * Internal data maintained in shared memory for each transaction.
+ */
+typedef struct __txn_detail {
+	u_int32_t txnid;		/* current transaction id
+					   used to link free list also */
+	pid_t pid;			/* Process owning txn */
+	db_threadid_t tid;		/* Thread owning txn */
+
+	DB_LSN	last_lsn;		/* Last LSN written for this txn. */
+	DB_LSN	begin_lsn;		/* LSN of begin record. */
+	roff_t	parent;			/* Offset of transaction's parent. */
+	roff_t	name;			/* Offset of txn name. */
+	
+	u_int32_t	nlog_dbs;	/* Number of databases used. */
+	u_int32_t	nlog_slots;	/* Number of allocated slots. */
+	roff_t		log_dbs;	/* Databases used. */
+
+	DB_LSN	read_lsn;		/* Read LSN for MVCC. */
+	DB_LSN	visible_lsn;		/* LSN at which this transaction's
+					   changes are visible. */
+	db_mutex_t	mvcc_mtx;	/* Version mutex. */
+	u_int32_t	mvcc_ref;	/* Number of buffers created by this
+					   transaction still in cache.  */
+
+	u_int32_t	priority;	/* Deadlock resolution priority. */
+
+	SH_TAILQ_HEAD(__tdkids)	kids;	/* Linked list of child txn detail. */
+	SH_TAILQ_ENTRY		klinks;
+
+	/* TXN_{ABORTED, COMMITTED PREPARED, RUNNING} */
+	u_int32_t status;		/* status of the transaction */
+
+#define	TXN_DTL_COLLECTED	0x01	/* collected during txn_recover */
+#define	TXN_DTL_RESTORED	0x02	/* prepared txn restored */
+#define	TXN_DTL_INMEMORY	0x04	/* uses in memory logs */
+#define	TXN_DTL_SNAPSHOT	0x08	/* On the list of snapshot txns. */
+#define	TXN_DTL_NOWAIT		0x10	/* Don't block on locks. */
+	u_int32_t flags;
+
+	SH_TAILQ_ENTRY	links;		/* active/free/snapshot list */
+
+	u_int32_t xa_ref;		/* XA: reference count; number
+					   of DB_TXNs reffing this struct */
+	/* TXN_XA_{ACTIVE, DEADLOCKED, IDLE, PREPARED, ROLLEDBACK} */
+	u_int32_t xa_br_status;		/* status of XA branch */
+	u_int8_t gid[DB_GID_SIZE];	/* global transaction id */
+	u_int32_t bqual;		/* bqual_length from XID */
+	u_int32_t gtrid;		/* gtrid_length from XID */
+	int32_t format;			/* XA format */
+	roff_t slots[TXN_NSLOTS];	/* Initial DB slot allocation. */
+} TXN_DETAIL;
+
+/*
+ * DB_TXNMGR --
+ *	The transaction manager encapsulates the transaction system.
+ */
+struct __db_txnmgr {
+	/*
+	 * These fields need to be protected for multi-threaded support.
+	 *
+	 * Lock list of active transactions (including the content of each
+	 * TXN_DETAIL structure on the list).
+	 */
+	db_mutex_t mutex;
+					/* List of active transactions. */
+	TAILQ_HEAD(_chain, __db_txn)	txn_chain;
+
+	u_int32_t n_discards;		/* Number of txns discarded. */
+
+	/* These fields are never updated after creation, so not protected. */
+	ENV	*env;			/* Environment. */
+	REGINFO	 reginfo;		/* Region information. */
+};
+
+/* Macros to lock/unlock the transaction region as a whole. */
+#define	TXN_SYSTEM_LOCK(env)						\
+	MUTEX_LOCK(env, ((DB_TXNREGION *)				\
+	    (env)->tx_handle->reginfo.primary)->mtx_region)
+#define	TXN_SYSTEM_UNLOCK(env)						\
+	MUTEX_UNLOCK(env, ((DB_TXNREGION *)				\
+	    (env)->tx_handle->reginfo.primary)->mtx_region)
+
+/*
+ * DB_TXNREGION --
+ *	The primary transaction data structure in the shared memory region.
+ */
+struct __db_txnregion { /* SHARED */
+	db_mutex_t	mtx_region;	/* Region mutex. */
+
+	u_int32_t	inittxns;	/* initial number of active TXNs */
+	u_int32_t	curtxns;	/* current number of active TXNs */
+	u_int32_t	maxtxns;	/* maximum number of active TXNs */
+	u_int32_t	last_txnid;	/* last transaction id given out */
+	u_int32_t	cur_maxid;	/* current max unused id. */
+
+	db_mutex_t	mtx_ckp;	/* Single thread checkpoints. */
+	DB_LSN		last_ckp;	/* lsn of the last checkpoint */
+	time_t		time_ckp;	/* time of last checkpoint */
+
+	DB_TXN_STAT_INT	stat;		/* Statistics for txns. */
+
+	u_int32_t n_bulk_txn;		/* Num. bulk txns in progress. */
+	u_int32_t n_hotbackup;		/* Num. of outstanding backup notices.*/
+
+#define	TXN_IN_RECOVERY	 0x01		/* environment is being recovered */
+	u_int32_t	flags;
+					/* active TXN list */
+	SH_TAILQ_HEAD(__active) active_txn;
+	SH_TAILQ_HEAD(__mvcc) mvcc_txn;
+};
+
+/*
+ * DB_COMMIT_INFO --
+ *	Meta-data uniquely describing a transaction commit across a replication
+ *	group.
+ */
+struct __db_commit_info {
+	u_int32_t	version;	/* Stored format version. */
+	u_int32_t	gen;		/* Replication master generation. */
+	u_int32_t	envid;		/* Unique env ID of master. */
+	DB_LSN		lsn;		/* LSN of commit log record. */
+};
+
+/*
+ * DB_TXNLOGREC --
+ *	An in-memory, linked-list copy of a log record.
+ */
+struct __txn_logrec {
+	STAILQ_ENTRY(__txn_logrec) links;/* Linked list. */
+
+	u_int8_t data[1];		/* Log record. */
+};
+
+/*
+ * Log record types.  Note that these are *not* alphabetical.  This is
+ * intentional so that we don't change the meaning of values between
+ * software upgrades.
+ *
+ * EXPECTED, UNEXPECTED, IGNORE, and OK are used in the txnlist functions.
+ * Here is an explanation of how the statuses are used.
+ *
+ * TXN_OK
+ *	BEGIN records for transactions found on the txnlist during
+ *	OPENFILES (BEGIN records are those with a prev_lsn of 0,0)
+ *
+ * TXN_COMMIT
+ *	Transaction committed and should be rolled forward.
+ *
+ * TXN_ABORT
+ *	This transaction's changes must be undone.  Either there was
+ *	never a prepare or commit record for this transaction OR there
+ *	was a commit, but we are recovering to a timestamp or particular
+ *	LSN and that point is before this transaction's commit.
+ *
+ * TXN_PREPARE
+ *	Prepare record, but no commit record is in the log.
+ *
+ * TXN_IGNORE
+ *	Generic meaning is that this transaction should not be
+ *	processed during later recovery passes.  We use it in a
+ *	number of different manners:
+ *
+ *	1. We never saw its BEGIN record.  Therefore, the logs have
+ *	   been reclaimed and we *know* that this transaction doesn't
+ *	   need to be aborted, because in order for it to be
+ *	   reclaimed, there must have been a subsequent checkpoint
+ *	   (and any dirty pages for this transaction made it to
+ *	   disk).
+ *
+ *	2. This is a child transaction that created a database.
+ *	   For some reason, we don't want to recreate that database
+ *	   (i.e., it already exists or some other database created
+ *	   after it exists).
+ *
+ *	3. During recovery open of subdatabases, if the master check fails,
+ *	   we use a TXN_IGNORE on the create of the subdb in the nested
+ *	   transaction.
+ *
+ *	4. During a remove, the file with the name being removed isn't
+ *	   the file for which we are recovering a remove.
+ *
+ * TXN_EXPECTED
+ *	After a successful open during recovery, we update the
+ *	transaction's status to TXN_EXPECTED.  The open was done
+ *	in the parent, but in the open log record, we record the
+ *	child transaction's ID if we also did a create.  When there
+ *	is a valid ID in that field, we use it and mark the child's
+ *	status as TXN_EXPECTED (indicating that we don't need to redo
+ *	a create for this file).
+ *
+ *	When recovering a remove, if we don't find or can't open
+ *	the file, the child (which does the remove) gets marked
+ *	EXPECTED (indicating that we don't need to redo the remove).
+ *
+ * TXN_UNEXPECTED
+ *	During recovery, we attempted an open that should have succeeded
+ *	and we got ENOENT, so like with the EXPECTED case, we indicate
+ *	in the child that we got the UNEXPECTED return so that we do redo
+ *	the creating/deleting operation.
+ *
+ */
+#define	TXN_OK		0
+#define	TXN_COMMIT	1
+#define	TXN_PREPARE	2
+#define	TXN_ABORT	3
+#define	TXN_IGNORE	4
+#define	TXN_EXPECTED	5
+#define	TXN_UNEXPECTED	6
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "dbinc_auto/txn_auto.h"
+#include "dbinc_auto/txn_ext.h"
+#endif /* !_DB_TXN_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/win_db.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,170 @@
+/*-
+ * Copyright (c) 2010, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * The following provides the information necessary to build Berkeley
+ * DB on native Windows, and other Windows environments such as MinGW.
+ */
+
+/*
+ * Berkeley DB requires at least Windows 2000, tell Visual Studio of the
+ * requirement.
+ */
+#ifndef _WIN32_WINNT
+#define	_WIN32_WINNT 0x0500
+#endif
+
+#ifndef DB_WINCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/timeb.h>
+
+#include <direct.h>
+#include <fcntl.h>
+#include <io.h>
+#include <limits.h>
+#include <memory.h>
+#include <process.h>
+#include <signal.h>
+#endif /* DB_WINCE */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <tchar.h>
+#include <time.h>
+
+/*
+ * To build Tcl interface libraries, the include path must be configured to
+ * use the directory containing <tcl.h>, usually the include directory in
+ * the Tcl distribution.
+ */
+#ifdef DB_TCL_SUPPORT
+#include <tcl.h>
+#endif
+
+#define	WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock2.h>
+#ifndef DB_WINCE
+#include <WinIoCtl.h>
+#endif
+
+#ifdef HAVE_GETADDRINFO
+/*
+ * Need explicit includes for IPv6 support on Windows.  Both are necessary to
+ * ensure that pre WinXP versions have an implementation of the getaddrinfo API.
+ */
+#include <ws2tcpip.h>
+#include <wspiapi.h>
+#endif
+
+/*
+ * Microsoft's C runtime library has fsync, getcwd, getpid, snprintf and
+ * vsnprintf, but under different names.
+ */
+#define	fsync			_commit
+
+#ifndef DB_WINCE
+#define	getcwd(buf, size)	_getcwd(buf, size)
+#endif
+#define	getpid			GetCurrentProcessId
+#define	snprintf		_snprintf
+#define	strcasecmp		_stricmp
+#define	strncasecmp		_strnicmp
+#define	vsnprintf		_vsnprintf
+
+#define	h_errno			WSAGetLastError()
+
+/*
+ * Win32 does not have getopt.
+ *
+ * The externs are here, instead of using db_config.h and clib_port.h, because
+ * that approach changes function names to BDB specific names, and the example
+ * programs use getopt and can't use BDB specific names.
+ */
+#if defined(__cplusplus)
+extern "C" {
+#endif
+extern int getopt(int, char * const *, const char *);
+#if defined(__cplusplus)
+}
+#endif
+
+/*
+ * Microsoft's compiler _doesn't_ define __STDC__ unless you invoke it with
+ * arguments turning OFF all vendor extensions.  Even more unfortunately, if
+ * we do that, it fails to parse windows.h!!!!!  So, we define __STDC__ here,
+ * after windows.h comes in.  Note: the compiler knows we've defined it, and
+ * starts enforcing strict ANSI compliance from this point on.
+ */
+#ifndef __STDC__
+#define	__STDC__ 1
+#endif
+
+#ifdef _UNICODE
+#define	TO_TSTRING(dbenv, s, ts, ret) do {				\
+		int __len = (int)strlen(s) + 1;				\
+		ts = NULL;						\
+		if ((ret = __os_malloc((dbenv),				\
+		    __len * sizeof(_TCHAR), &(ts))) == 0 &&		\
+		    MultiByteToWideChar(CP_UTF8, 0,			\
+		    (s), -1, (ts), __len) == 0)				\
+			ret = __os_posix_err(__os_get_syserr());	\
+	} while (0)
+
+#define	FROM_TSTRING(dbenv, ts, s, ret) {				\
+		int __len = WideCharToMultiByte(CP_UTF8, 0, ts, -1,	\
+		    NULL, 0, NULL, NULL);				\
+		s = NULL;						\
+		if ((ret = __os_malloc((dbenv), __len, &(s))) == 0 &&	\
+		    WideCharToMultiByte(CP_UTF8, 0,			\
+		    (ts), -1, (s), __len, NULL, NULL) == 0)		\
+			ret = __os_posix_err(__os_get_syserr());	\
+	} while (0)
+
+#define	FREE_STRING(dbenv, s) do {					\
+		if ((s) != NULL) {					\
+			__os_free((dbenv), (s));			\
+			(s) = NULL;					\
+		}							\
+	} while (0)
+
+#else
+#define	TO_TSTRING(dbenv, s, ts, ret) (ret) = 0, (ts) = (_TCHAR *)(s)
+#define	FROM_TSTRING(dbenv, ts, s, ret) (ret) = 0, (s) = (char *)(ts)
+#define	FREE_STRING(dbenv, ts)
+#endif
+
+#ifndef INVALID_HANDLE_VALUE
+#define	INVALID_HANDLE_VALUE ((HANDLE)-1)
+#endif
+
+#ifndef INVALID_FILE_ATTRIBUTES
+#define	INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+#endif
+
+#ifndef INVALID_SET_FILE_POINTER
+#define	INVALID_SET_FILE_POINTER ((DWORD)-1)
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc/xa.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,205 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+/*
+ * Start of xa.h header
+ *
+ * Define a symbol to prevent multiple inclusions of this header file
+ */
+#ifndef	_DB_XA_H_
+#define	_DB_XA_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * Transaction branch identification: XID and NULLXID:
+ */
+#define	XIDDATASIZE	128		/* size in bytes */
+#define	MAXGTRIDSIZE	 64		/* maximum size in bytes of gtrid */
+#define	MAXBQUALSIZE	 64		/* maximum size in bytes of bqual */
+
+struct xid_t {
+	long formatID;			/* format identifier */
+	long gtrid_length;		/* value from 1 through 64 */
+	long bqual_length;		/* value from 1 through 64 */
+	char data[XIDDATASIZE];
+};
+typedef	struct xid_t XID;
+/*
+ * A value of -1 in formatID means that the XID is null.
+ */
+
+/*
+ * Declarations of routines by which RMs call TMs:
+ */
+extern int ax_reg __P((int, XID *, long));
+extern int ax_unreg __P((int, long));
+
+/*
+ * XA Switch Data Structure
+ */
+#define	RMNAMESZ	32		/* length of resource manager name, */
+					/* including the null terminator */
+#define	MAXINFOSIZE	256		/* maximum size in bytes of xa_info */
+					/* strings, including the null
+					terminator */
+struct xa_switch_t {
+	char name[RMNAMESZ];		/* name of resource manager */
+	long flags;			/* resource manager specific options */
+	long version;			/* must be 0 */
+	int (*xa_open_entry)		/* xa_open function pointer */
+	    __P((char *, int, long));
+	int (*xa_close_entry)		/* xa_close function pointer */
+	    __P((char *, int, long));
+	int (*xa_start_entry)		/* xa_start function pointer */
+	    __P((XID *, int, long));
+	int (*xa_end_entry)		/* xa_end function pointer */
+	    __P((XID *, int, long));
+	int (*xa_rollback_entry)	/* xa_rollback function pointer */
+	    __P((XID *, int, long));
+	int (*xa_prepare_entry)		/* xa_prepare function pointer */
+	    __P((XID *, int, long));
+	int (*xa_commit_entry)		/* xa_commit function pointer */
+	    __P((XID *, int, long));
+	int (*xa_recover_entry)		/* xa_recover function pointer */
+	    __P((XID *, long, int, long));
+	int (*xa_forget_entry)		/* xa_forget function pointer */
+	    __P((XID *, int, long));
+	int (*xa_complete_entry)	/* xa_complete function pointer */
+	    __P((int *, int *, int, long));
+};
+
+/*
+ * Flag definitions for the RM switch
+ */
+#define	TMNOFLAGS	0x00000000L	/* no resource manager features
+					selected */
+#define	TMREGISTER	0x00000001L	/* resource manager dynamically
+					registers */
+#define	TMNOMIGRATE	0x00000002L	/* resource manager does not support
+					association migration */
+#define	TMUSEASYNC	0x00000004L	/* resource manager supports
+					asynchronous operations */
+/*
+ * Flag definitions for xa_ and ax_ routines
+ */
+/* use TMNOFLAGGS, defined above, when not specifying other flags */
+#define	TMASYNC		0x80000000L	/* perform routine asynchronously */
+#define	TMONEPHASE	0x40000000L	/* caller is using one-phase commit
+					optimisation */
+#define	TMFAIL		0x20000000L	/* dissociates caller and marks
+					transaction branch rollback-only */
+#define	TMNOWAIT	0x10000000L	/* return if blocking condition
+					exists */
+#define	TMRESUME	0x08000000L	/* caller is resuming association with
+					suspended transaction branch */
+#define	TMSUCCESS	0x04000000L	/* dissociate caller from transaction
+					branch */
+#define	TMSUSPEND	0x02000000L	/* caller is suspending, not ending,
+					association */
+#define	TMSTARTRSCAN	0x01000000L	/* start a recovery scan */
+#define	TMENDRSCAN	0x00800000L	/* end a recovery scan */
+#define	TMMULTIPLE	0x00400000L	/* wait for any asynchronous
+					operation */
+#define	TMJOIN		0x00200000L	/* caller is joining existing
+					transaction branch */
+#define	TMMIGRATE	0x00100000L	/* caller intends to perform
+					migration */
+
+/*
+ * ax_() return codes (transaction manager reports to resource manager)
+ */
+#define	TM_JOIN		2		/* caller is joining existing
+					transaction branch */
+#define	TM_RESUME	1		/* caller is resuming association with
+					suspended transaction branch */
+#define	TM_OK		0		/* normal execution */
+#define	TMER_TMERR	-1		/* an error occurred in the transaction
+					manager */
+#define	TMER_INVAL	-2		/* invalid arguments were given */
+#define	TMER_PROTO	-3		/* routine invoked in an improper
+					context */
+
+/*
+ * xa_() return codes (resource manager reports to transaction manager)
+ */
+#define	XA_RBBASE	100		/* The inclusive lower bound of the
+					rollback codes */
+#define	XA_RBROLLBACK	XA_RBBASE	/* The rollback was caused by an
+					unspecified reason */
+#define	XA_RBCOMMFAIL	XA_RBBASE+1	/* The rollback was caused by a
+					communication failure */
+#define	XA_RBDEADLOCK	XA_RBBASE+2	/* A deadlock was detected */
+#define	XA_RBINTEGRITY	XA_RBBASE+3	/* A condition that violates the
+					integrity of the resources was
+					detected */
+#define	XA_RBOTHER	XA_RBBASE+4	/* The resource manager rolled back the
+					transaction branch for a reason not
+					on this list */
+#define	XA_RBPROTO	XA_RBBASE+5	/* A protocol error occurred in the
+					resource manager */
+#define	XA_RBTIMEOUT	XA_RBBASE+6	/* A transaction branch took too long */
+#define	XA_RBTRANSIENT	XA_RBBASE+7	/* May retry the transaction branch */
+#define	XA_RBEND	XA_RBTRANSIENT	/* The inclusive upper bound of the
+					rollback codes */
+#define	XA_NOMIGRATE	9		/* resumption must occur where
+					suspension occurred */
+#define	XA_HEURHAZ	8		/* the transaction branch may have
+					been heuristically completed */
+#define	XA_HEURCOM	7		/* the transaction branch has been
+					heuristically committed */
+#define	XA_HEURRB	6		/* the transaction branch has been
+					heuristically rolled back */
+#define	XA_HEURMIX	5		/* the transaction branch has been
+					heuristically committed and rolled
+					back */
+#define	XA_RETRY	4		/* routine returned with no effect and
+					may be re-issued */
+#define	XA_RDONLY	3		/* the transaction branch was read-only
+					and has been committed */
+#define	XA_OK		0		/* normal execution */
+#define	XAER_ASYNC	-2		/* asynchronous operation already
+					outstanding */
+#define	XAER_RMERR	-3		/* a resource manager error occurred in
+					 the transaction branch */
+#define	XAER_NOTA	-4		/* the XID is not valid */
+#define	XAER_INVAL	-5		/* invalid arguments were given */
+#define	XAER_PROTO	-6		/* routine invoked in an improper
+					context */
+#define	XAER_RMFAIL	-7		/* resource manager unavailable */
+#define	XAER_DUPID	-8		/* the XID already exists */
+#define	XAER_OUTSIDE	-9		/* resource manager doing work outside
+					transaction */
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_XA_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/api_flags.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,254 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#define	DB_AGGRESSIVE				0x00000001
+#define	DB_ARCH_ABS				0x00000001
+#define	DB_ARCH_DATA				0x00000002
+#define	DB_ARCH_LOG				0x00000004
+#define	DB_ARCH_REMOVE				0x00000008
+#define	DB_AUTO_COMMIT				0x00000100
+#define	DB_BACKUP_CLEAN				0x00000002
+#define	DB_BACKUP_FILES				0x00000008
+#define	DB_BACKUP_NO_LOGS			0x00000010
+#define	DB_BACKUP_SINGLE_DIR			0x00000020
+#define	DB_BACKUP_UPDATE			0x00000040
+#define	DB_BOOTSTRAP_HELPER			0x00000001
+#define	DB_CDB_ALLDB				0x00000040
+#define	DB_CHKSUM				0x00000008
+#define	DB_CKP_INTERNAL				0x00000002
+#define	DB_CREATE				0x00000001
+#define	DB_CURSOR_BULK				0x00000001
+#define	DB_CURSOR_TRANSIENT			0x00000008
+#define	DB_CXX_NO_EXCEPTIONS			0x00000002
+#define	DB_DATABASE_LOCKING			0x00000080
+#define	DB_DIRECT				0x00000020
+#define	DB_DIRECT_DB				0x00000200
+#define	DB_DSYNC_DB				0x00000400
+#define	DB_DUP					0x00000010
+#define	DB_DUPSORT				0x00000002
+#define	DB_DURABLE_UNKNOWN			0x00000040
+#define	DB_ENCRYPT				0x00000001
+#define	DB_ENCRYPT_AES				0x00000001
+#define	DB_EXCL					0x00000004
+#define	DB_EXTENT				0x00000100
+#define	DB_FAILCHK				0x00000010
+#define	DB_FAILCHK_ISALIVE			0x00000040
+#define	DB_FAST_STAT				0x00000001
+#define	DB_FCNTL_LOCKING			0x00000800
+#define	DB_FLUSH				0x00000002
+#define	DB_FORCE				0x00000001
+#define	DB_FORCESYNC				0x00000001
+#define	DB_FOREIGN_ABORT			0x00000001
+#define	DB_FOREIGN_CASCADE			0x00000002
+#define	DB_FOREIGN_NULLIFY			0x00000004
+#define	DB_FREELIST_ONLY			0x00000001
+#define	DB_FREE_SPACE				0x00000002
+#define	DB_GROUP_CREATOR			0x00000002
+#define	DB_HOTBACKUP_IN_PROGRESS		0x00000800
+#define	DB_IGNORE_LEASE				0x00001000
+#define	DB_IMMUTABLE_KEY			0x00000002
+#define	DB_INIT_CDB				0x00000080
+#define	DB_INIT_LOCK				0x00000100
+#define	DB_INIT_LOG				0x00000200
+#define	DB_INIT_MPOOL				0x00000400
+#define	DB_INIT_MUTEX				0x00000800
+#define	DB_INIT_REP				0x00001000
+#define	DB_INIT_TXN				0x00002000
+#define	DB_INORDER				0x00000020
+#define	DB_INTERNAL_PERSISTENT_DB		0x00001000
+#define	DB_INTERNAL_TEMPORARY_DB		0x00002000
+#define	DB_JOIN_NOSORT				0x00000001
+#define	DB_LEGACY				0x00000004
+#define	DB_LOCAL_SITE				0x00000008
+#define	DB_LOCKDOWN				0x00004000
+#define	DB_LOCK_CHECK				0x00000001
+#define	DB_LOCK_IGNORE_REC			0x00000002
+#define	DB_LOCK_NOWAIT				0x00000004
+#define	DB_LOCK_RECORD				0x00000008
+#define	DB_LOCK_SET_TIMEOUT			0x00000010
+#define	DB_LOCK_SWITCH				0x00000020
+#define	DB_LOCK_UPGRADE				0x00000040
+#define	DB_LOG_AUTO_REMOVE			0x00000001
+#define	DB_LOG_CHKPNT				0x00000001
+#define	DB_LOG_COMMIT				0x00000004
+#define	DB_LOG_DIRECT				0x00000002
+#define	DB_LOG_DSYNC				0x00000004
+#define	DB_LOG_IN_MEMORY			0x00000008
+#define	DB_LOG_NOCOPY				0x00000008
+#define	DB_LOG_NOT_DURABLE			0x00000010
+#define	DB_LOG_NO_DATA				0x00000002
+#define	DB_LOG_VERIFY_CAF			0x00000001
+#define	DB_LOG_VERIFY_DBFILE			0x00000002
+#define	DB_LOG_VERIFY_ERR			0x00000004
+#define	DB_LOG_VERIFY_FORWARD			0x00000008
+#define	DB_LOG_VERIFY_INTERR			0x00000010
+#define	DB_LOG_VERIFY_PARTIAL			0x00000020
+#define	DB_LOG_VERIFY_VERBOSE			0x00000040
+#define	DB_LOG_VERIFY_WARNING			0x00000080
+#define	DB_LOG_WRNOSYNC				0x00000020
+#define	DB_LOG_ZERO				0x00000010
+#define	DB_MPOOL_CREATE				0x00000001
+#define	DB_MPOOL_DIRTY				0x00000002
+#define	DB_MPOOL_DISCARD			0x00000001
+#define	DB_MPOOL_EDIT				0x00000004
+#define	DB_MPOOL_FREE				0x00000008
+#define	DB_MPOOL_LAST				0x00000010
+#define	DB_MPOOL_NEW				0x00000020
+#define	DB_MPOOL_NOFILE				0x00000001
+#define	DB_MPOOL_NOLOCK				0x00000004
+#define	DB_MPOOL_TRY				0x00000040
+#define	DB_MPOOL_UNLINK				0x00000002
+#define	DB_MULTIPLE				0x00000800
+#define	DB_MULTIPLE_KEY				0x00004000
+#define	DB_MULTIVERSION				0x00000008
+#define	DB_MUTEX_ALLOCATED			0x00000001
+#define	DB_MUTEX_LOCKED				0x00000002
+#define	DB_MUTEX_LOGICAL_LOCK			0x00000004
+#define	DB_MUTEX_PROCESS_ONLY			0x00000008
+#define	DB_MUTEX_SELF_BLOCK			0x00000010
+#define	DB_MUTEX_SHARED				0x00000020
+#define	DB_NOERROR				0x00004000
+#define	DB_NOFLUSH				0x00001000
+#define	DB_NOLOCKING				0x00002000
+#define	DB_NOMMAP				0x00000010
+#define	DB_NOORDERCHK				0x00000002
+#define	DB_NOPANIC				0x00004000
+#define	DB_NOSYNC				0x00000001
+#define	DB_NO_AUTO_COMMIT			0x00008000
+#define	DB_NO_CHECKPOINT			0x00008000
+#define	DB_ODDFILESIZE				0x00000080
+#define	DB_ORDERCHKONLY				0x00000004
+#define	DB_OVERWRITE				0x00008000
+#define	DB_PANIC_ENVIRONMENT			0x00010000
+#define	DB_PRINTABLE				0x00000008
+#define	DB_PRIVATE				0x00010000
+#define	DB_PR_PAGE				0x00000010
+#define	DB_PR_RECOVERYTEST			0x00000020
+#define	DB_RDONLY				0x00000400
+#define	DB_RDWRMASTER				0x00010000
+#define	DB_READ_COMMITTED			0x00000400
+#define	DB_READ_UNCOMMITTED			0x00000200
+#define	DB_RECNUM				0x00000040
+#define	DB_RECOVER				0x00000002
+#define	DB_RECOVER_FATAL			0x00020000
+#define	DB_REGION_INIT				0x00020000
+#define	DB_REGISTER				0x00040000
+#define	DB_RENUMBER				0x00000080
+#define	DB_REPMGR_CONF_2SITE_STRICT		0x00000001
+#define	DB_REPMGR_CONF_ELECTIONS		0x00000002
+#define	DB_REPMGR_NEED_RESPONSE			0x00000001
+#define	DB_REPMGR_PEER				0x00000010
+#define	DB_REP_ANYWHERE				0x00000001
+#define	DB_REP_CLIENT				0x00000001
+#define	DB_REP_CONF_AUTOINIT			0x00000004
+#define	DB_REP_CONF_AUTOROLLBACK		0x00000008
+#define	DB_REP_CONF_BULK			0x00000010
+#define	DB_REP_CONF_DELAYCLIENT			0x00000020
+#define	DB_REP_CONF_INMEM			0x00000040
+#define	DB_REP_CONF_LEASE			0x00000080
+#define	DB_REP_CONF_NOWAIT			0x00000100
+#define	DB_REP_ELECTION				0x00000004
+#define	DB_REP_MASTER				0x00000002
+#define	DB_REP_NOBUFFER				0x00000002
+#define	DB_REP_PERMANENT			0x00000004
+#define	DB_REP_REREQUEST			0x00000008
+#define	DB_REVSPLITOFF				0x00000100
+#define	DB_RMW					0x00002000
+#define	DB_SALVAGE				0x00000040
+#define	DB_SA_SKIPFIRSTKEY			0x00000080
+#define	DB_SA_UNKNOWNKEY			0x00000100
+#define	DB_SEQ_DEC				0x00000001
+#define	DB_SEQ_INC				0x00000002
+#define	DB_SEQ_RANGE_SET			0x00000004
+#define	DB_SEQ_WRAP				0x00000008
+#define	DB_SEQ_WRAPPED				0x00000010
+#define	DB_SET_LOCK_TIMEOUT			0x00000001
+#define	DB_SET_REG_TIMEOUT			0x00000004
+#define	DB_SET_TXN_NOW				0x00000008
+#define	DB_SET_TXN_TIMEOUT			0x00000002
+#define	DB_SHALLOW_DUP				0x00000100
+#define	DB_SNAPSHOT				0x00000200
+#define	DB_STAT_ALL				0x00000004
+#define	DB_STAT_ALLOC				0x00000008
+#define	DB_STAT_CLEAR				0x00000001
+#define	DB_STAT_LOCK_CONF			0x00000010
+#define	DB_STAT_LOCK_LOCKERS			0x00000020
+#define	DB_STAT_LOCK_OBJECTS			0x00000040
+#define	DB_STAT_LOCK_PARAMS			0x00000080
+#define	DB_STAT_MEMP_HASH			0x00000010
+#define	DB_STAT_MEMP_NOERROR			0x00000020
+#define	DB_STAT_SUBSYSTEM			0x00000002
+#define	DB_STAT_SUMMARY				0x00000010
+#define	DB_ST_DUPOK				0x00000200
+#define	DB_ST_DUPSET				0x00000400
+#define	DB_ST_DUPSORT				0x00000800
+#define	DB_ST_IS_RECNO				0x00001000
+#define	DB_ST_OVFL_LEAF				0x00002000
+#define	DB_ST_RECNUM				0x00004000
+#define	DB_ST_RELEN				0x00008000
+#define	DB_ST_TOPLEVEL				0x00010000
+#define	DB_SYSTEM_MEM				0x00080000
+#define	DB_THREAD				0x00000020
+#define	DB_TIME_NOTGRANTED			0x00040000
+#define	DB_TRUNCATE				0x00020000
+#define	DB_TXN_BULK				0x00000010
+#define	DB_TXN_FAMILY				0x00000040
+#define	DB_TXN_NOSYNC				0x00000001
+#define	DB_TXN_NOT_DURABLE			0x00000004
+#define	DB_TXN_NOWAIT				0x00000002
+#define	DB_TXN_SNAPSHOT				0x00000004
+#define	DB_TXN_SYNC				0x00000008
+#define	DB_TXN_WAIT				0x00000080
+#define	DB_TXN_WRITE_NOSYNC			0x00000020
+#define	DB_UNREF				0x00020000
+#define	DB_UPGRADE				0x00000001
+#define	DB_USE_ENVIRON				0x00000004
+#define	DB_USE_ENVIRON_ROOT			0x00000008
+#define	DB_VERB_BACKUP				0x00000001
+#define	DB_VERB_DEADLOCK			0x00000002
+#define	DB_VERB_FILEOPS				0x00000004
+#define	DB_VERB_FILEOPS_ALL			0x00000008
+#define	DB_VERB_RECOVERY			0x00000010
+#define	DB_VERB_REGISTER			0x00000020
+#define	DB_VERB_REPLICATION			0x00000040
+#define	DB_VERB_REPMGR_CONNFAIL			0x00000080
+#define	DB_VERB_REPMGR_MISC			0x00000100
+#define	DB_VERB_REP_ELECT			0x00000200
+#define	DB_VERB_REP_LEASE			0x00000400
+#define	DB_VERB_REP_MISC			0x00000800
+#define	DB_VERB_REP_MSGS			0x00001000
+#define	DB_VERB_REP_SYNC			0x00002000
+#define	DB_VERB_REP_SYSTEM			0x00004000
+#define	DB_VERB_REP_TEST			0x00008000
+#define	DB_VERB_WAITSFOR			0x00010000
+#define	DB_VERIFY				0x00000002
+#define	DB_VERIFY_PARTITION			0x00040000
+#define	DB_WRITECURSOR				0x00000010
+#define	DB_WRITELOCK				0x00000020
+#define	DB_WRITEOPEN				0x00040000
+#define	DB_XA_CREATE				0x00000001
+#define	DB_YIELDCPU				0x00080000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/btree_auto.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,481 @@
+/* Do not edit: automatically built by gen_rec.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__bam_AUTO_H
+#define	__bam_AUTO_H
+#include "dbinc/log.h"
+#define	DB___bam_split	62
+typedef struct ___bam_split_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	u_int32_t	opflags;
+	db_pgno_t	left;
+	DB_LSN	llsn;
+	db_pgno_t	right;
+	DB_LSN	rlsn;
+	u_int32_t	indx;
+	db_pgno_t	npgno;
+	DB_LSN	nlsn;
+	db_pgno_t	ppgno;
+	DB_LSN	plsn;
+	u_int32_t	pindx;
+	DBT	pg;
+	DBT	pentry;
+	DBT	rentry;
+} __bam_split_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_split_desc[];
+static inline int
+__bam_split_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, u_int32_t opflags, db_pgno_t left, DB_LSN * llsn, db_pgno_t right,
+    DB_LSN * rlsn, u_int32_t indx, db_pgno_t npgno, DB_LSN * nlsn, db_pgno_t ppgno,
+    DB_LSN * plsn, u_int32_t pindx, const DBT *pg, const DBT *pentry, const DBT *rentry)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___bam_split, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(*llsn) + sizeof(u_int32_t) + sizeof(*rlsn) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*nlsn) +
+	    sizeof(u_int32_t) + sizeof(*plsn) + sizeof(u_int32_t) +
+	    LOG_DBT_SIZE(pg) + LOG_DBT_SIZE(pentry) + LOG_DBT_SIZE(rentry),
+	    __bam_split_desc, opflags, left, llsn, right, rlsn, indx, npgno,
+	    nlsn, ppgno, plsn, pindx, pg, pentry, rentry));
+}
+
+static inline int __bam_split_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_split_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_split_desc, sizeof(__bam_split_args), (void**)arg));
+}
+#define	DB___bam_split_48	62
+typedef struct ___bam_split_48_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	left;
+	DB_LSN	llsn;
+	db_pgno_t	right;
+	DB_LSN	rlsn;
+	u_int32_t	indx;
+	db_pgno_t	npgno;
+	DB_LSN	nlsn;
+	db_pgno_t	ppgno;
+	DB_LSN	plsn;
+	u_int32_t	pindx;
+	DBT	pg;
+	DBT	pentry;
+	DBT	rentry;
+	u_int32_t	opflags;
+} __bam_split_48_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_split_48_desc[];
+static inline int __bam_split_48_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_split_48_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_split_48_desc, sizeof(__bam_split_48_args), (void**)arg));
+}
+#define	DB___bam_split_42	62
+typedef struct ___bam_split_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	left;
+	DB_LSN	llsn;
+	db_pgno_t	right;
+	DB_LSN	rlsn;
+	u_int32_t	indx;
+	db_pgno_t	npgno;
+	DB_LSN	nlsn;
+	db_pgno_t	root_pgno;
+	DBT	pg;
+	u_int32_t	opflags;
+} __bam_split_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_split_42_desc[];
+static inline int __bam_split_42_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_split_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_split_42_desc, sizeof(__bam_split_42_args), (void**)arg));
+}
+#define	DB___bam_rsplit	63
+typedef struct ___bam_rsplit_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DBT	pgdbt;
+	db_pgno_t	root_pgno;
+	db_pgno_t	nrec;
+	DBT	rootent;
+	DB_LSN	rootlsn;
+} __bam_rsplit_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_rsplit_desc[];
+static inline int
+__bam_rsplit_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, const DBT *pgdbt, db_pgno_t root_pgno, db_pgno_t nrec,
+    const DBT *rootent, DB_LSN * rootlsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___bam_rsplit, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(pgdbt) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(rootent) +
+	    sizeof(*rootlsn),
+	    __bam_rsplit_desc, pgno, pgdbt, root_pgno, nrec, rootent, rootlsn));
+}
+
+static inline int __bam_rsplit_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_rsplit_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_rsplit_desc, sizeof(__bam_rsplit_args), (void**)arg));
+}
+#define	DB___bam_adj	55
+typedef struct ___bam_adj_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	lsn;
+	u_int32_t	indx;
+	u_int32_t	indx_copy;
+	u_int32_t	is_insert;
+} __bam_adj_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_adj_desc[];
+static inline int
+__bam_adj_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, DB_LSN * lsn, u_int32_t indx, u_int32_t indx_copy,
+    u_int32_t is_insert)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___bam_adj, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*lsn) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __bam_adj_desc, pgno, lsn, indx, indx_copy, is_insert));
+}
+
+static inline int __bam_adj_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_adj_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_adj_desc, sizeof(__bam_adj_args), (void**)arg));
+}
+#define	DB___bam_cadjust	56
+typedef struct ___bam_cadjust_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	lsn;
+	u_int32_t	indx;
+	int32_t	adjust;
+	u_int32_t	opflags;
+} __bam_cadjust_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_cadjust_desc[];
+static inline int
+__bam_cadjust_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, DB_LSN * lsn, u_int32_t indx, int32_t adjust,
+    u_int32_t opflags)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___bam_cadjust, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*lsn) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __bam_cadjust_desc, pgno, lsn, indx, adjust, opflags));
+}
+
+static inline int __bam_cadjust_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_cadjust_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_cadjust_desc, sizeof(__bam_cadjust_args), (void**)arg));
+}
+#define	DB___bam_cdel	57
+typedef struct ___bam_cdel_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	lsn;
+	u_int32_t	indx;
+} __bam_cdel_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_cdel_desc[];
+static inline int
+__bam_cdel_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, DB_LSN * lsn, u_int32_t indx)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___bam_cdel, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*lsn) +
+	    sizeof(u_int32_t),
+	    __bam_cdel_desc, pgno, lsn, indx));
+}
+
+static inline int __bam_cdel_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_cdel_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_cdel_desc, sizeof(__bam_cdel_args), (void**)arg));
+}
+#define	DB___bam_repl	58
+typedef struct ___bam_repl_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	lsn;
+	u_int32_t	indx;
+	u_int32_t	isdeleted;
+	DBT	orig;
+	DBT	repl;
+	u_int32_t	prefix;
+	u_int32_t	suffix;
+} __bam_repl_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_repl_desc[];
+static inline int
+__bam_repl_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, DB_LSN * lsn, u_int32_t indx, u_int32_t isdeleted,
+    const DBT *orig, const DBT *repl, u_int32_t prefix, u_int32_t suffix)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___bam_repl, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*lsn) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(orig) +
+	    LOG_DBT_SIZE(repl) + sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __bam_repl_desc, pgno, lsn, indx, isdeleted, orig, repl, prefix,
+	    suffix));
+}
+
+static inline int __bam_repl_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_repl_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_repl_desc, sizeof(__bam_repl_args), (void**)arg));
+}
+#define	DB___bam_irep	67
+typedef struct ___bam_irep_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	lsn;
+	u_int32_t	indx;
+	u_int32_t	ptype;
+	DBT	hdr;
+	DBT	data;
+	DBT	old;
+} __bam_irep_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_irep_desc[];
+static inline int
+__bam_irep_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, DB_LSN * lsn, u_int32_t indx, u_int32_t ptype,
+    const DBT *hdr, const DBT *data, const DBT *old)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___bam_irep, 1,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*lsn) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(hdr) +
+	    LOG_DBT_SIZE(data) + LOG_DBT_SIZE(old),
+	    __bam_irep_desc, pgno, lsn, indx, ptype, hdr, data, old));
+}
+
+static inline int __bam_irep_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_irep_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_irep_desc, sizeof(__bam_irep_args), (void**)arg));
+}
+#define	DB___bam_root	59
+typedef struct ___bam_root_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	meta_pgno;
+	db_pgno_t	root_pgno;
+	DB_LSN	meta_lsn;
+} __bam_root_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_root_desc[];
+static inline int
+__bam_root_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t meta_pgno, db_pgno_t root_pgno, DB_LSN * meta_lsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___bam_root, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(*meta_lsn),
+	    __bam_root_desc, meta_pgno, root_pgno, meta_lsn));
+}
+
+static inline int __bam_root_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_root_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_root_desc, sizeof(__bam_root_args), (void**)arg));
+}
+#define	DB___bam_curadj	64
+typedef struct ___bam_curadj_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_ca_mode	mode;
+	db_pgno_t	from_pgno;
+	db_pgno_t	to_pgno;
+	db_pgno_t	left_pgno;
+	u_int32_t	first_indx;
+	u_int32_t	from_indx;
+	u_int32_t	to_indx;
+} __bam_curadj_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_curadj_desc[];
+static inline int
+__bam_curadj_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_ca_mode mode, db_pgno_t from_pgno, db_pgno_t to_pgno, db_pgno_t left_pgno,
+    u_int32_t first_indx, u_int32_t from_indx, u_int32_t to_indx)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___bam_curadj, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __bam_curadj_desc, mode, from_pgno, to_pgno, left_pgno, first_indx, from_indx, to_indx));
+}
+
+static inline int __bam_curadj_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_curadj_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_curadj_desc, sizeof(__bam_curadj_args), (void**)arg));
+}
+#define	DB___bam_rcuradj	65
+typedef struct ___bam_rcuradj_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	ca_recno_arg	mode;
+	db_pgno_t	root;
+	db_recno_t	recno;
+	u_int32_t	order;
+} __bam_rcuradj_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_rcuradj_desc[];
+static inline int
+__bam_rcuradj_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, ca_recno_arg mode, db_pgno_t root, db_recno_t recno, u_int32_t order)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___bam_rcuradj, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __bam_rcuradj_desc, mode, root, recno, order));
+}
+
+static inline int __bam_rcuradj_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_rcuradj_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_rcuradj_desc, sizeof(__bam_rcuradj_args), (void**)arg));
+}
+#define	DB___bam_relink_43	147
+typedef struct ___bam_relink_43_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	lsn;
+	db_pgno_t	prev;
+	DB_LSN	lsn_prev;
+	db_pgno_t	next;
+	DB_LSN	lsn_next;
+} __bam_relink_43_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_relink_43_desc[];
+static inline int __bam_relink_43_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_relink_43_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_relink_43_desc, sizeof(__bam_relink_43_args), (void**)arg));
+}
+#define	DB___bam_merge_44	148
+typedef struct ___bam_merge_44_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	lsn;
+	db_pgno_t	npgno;
+	DB_LSN	nlsn;
+	DBT	hdr;
+	DBT	data;
+	DBT	ind;
+} __bam_merge_44_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __bam_merge_44_desc[];
+static inline int __bam_merge_44_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __bam_merge_44_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __bam_merge_44_desc, sizeof(__bam_merge_44_args), (void**)arg));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/btree_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,173 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_btree_ext_h_
+#define	_btree_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __bam_compact_int __P((DBC *, DBT *, DBT *, u_int32_t, int *, DB_COMPACT *, int *));
+int __bam_compact_opd __P((DBC *, db_pgno_t, PAGE **, u_int32_t, DB_COMPACT *, int *));
+int __bam_truncate_ipages __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB_COMPACT *));
+int __bam_cmp __P((DBC *, const DBT *, PAGE *, u_int32_t, int (*)(DB *, const DBT *, const DBT *), int *));
+int __bam_defcmp __P((DB *, const DBT *, const DBT *));
+size_t __bam_defpfx __P((DB *, const DBT *, const DBT *));
+int __bam_compress_dupcmp __P((DB *, const DBT *, const DBT *));
+int __bam_defcompress __P((DB *, const DBT *, const DBT *, const DBT *, const DBT *, DBT *));
+int __bam_defdecompress __P((DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *));
+int __bamc_compress_get __P((DBC *, DBT *, DBT *, u_int32_t));
+int __bamc_compress_put __P((DBC *, DBT *, DBT *, u_int32_t));
+int __bamc_compress_del __P((DBC *, u_int32_t));
+int __bamc_compress_bulk_del __P((DBC *, DBT *, u_int32_t));
+int __bamc_compress_count __P((DBC *, db_recno_t *));
+int __bamc_compress_cmp __P((DBC *, DBC *, int *));
+int __bamc_compress_dup __P((DBC *, DBC *, u_int32_t));
+int __bam_compress_salvage __P((DB *, VRFY_DBINFO *, void *, int (*)(void *, const void *), DBT *, DBT *));
+int __bam_compress_count __P((DBC *, u_int32_t *, u_int32_t *));
+int __bam_pgin __P((DB *, db_pgno_t, void *, DBT *));
+int __bam_pgout __P((DB *, db_pgno_t, void *, DBT *));
+int __bam_mswap __P((ENV *, PAGE *));
+int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, int, u_int32_t *));
+int __ram_ca_delete __P((DB *, db_pgno_t, u_int32_t *));
+int __bam_ca_di __P((DBC *, db_pgno_t, u_int32_t, int));
+int __bam_ca_dup __P((DBC *, u_int32_t, db_pgno_t, u_int32_t, db_pgno_t, u_int32_t));
+int __bam_ca_undodup __P((DB *, u_int32_t, db_pgno_t, u_int32_t, u_int32_t));
+int __bam_ca_rsplit __P((DBC *, db_pgno_t, db_pgno_t));
+int __bam_ca_split __P((DBC *, db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t, int));
+int __bam_ca_undosplit __P((DB *, db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t));
+int __bamc_init __P((DBC *, DBTYPE));
+int __bamc_refresh __P((DBC *));
+int __bamc_cmp __P((DBC *, DBC *, int *));
+int __bamc_count __P((DBC *, db_recno_t *));
+int __bamc_dup __P((DBC *, DBC *, u_int32_t));
+int __bam_bulk_overflow __P((DBC *, u_int32_t, db_pgno_t, u_int8_t *));
+int __bam_bulk_duplicates __P((DBC *, db_pgno_t, u_int8_t *, int32_t *, int32_t **, u_int8_t **, u_int32_t *, int));
+int __bamc_rget __P((DBC *, DBT *));
+int  __bam_opd_exists __P((DBC *, db_pgno_t));
+int __bam_ditem __P((DBC *, PAGE *, u_int32_t));
+int __bam_adjindx __P((DBC *, PAGE *, u_int32_t, u_int32_t, int));
+int __bam_dpages __P((DBC *, int, int));
+int __bam_pupdate __P((DBC *, PAGE *));
+int __bam_db_create __P((DB *));
+int __bam_db_close __P((DB *));
+void __bam_map_flags __P((DB *, u_int32_t *, u_int32_t *));
+int __bam_set_flags __P((DB *, u_int32_t *flagsp));
+int __bam_set_bt_compare __P((DB *, int (*)(DB *, const DBT *, const DBT *)));
+int __bam_set_bt_compress __P((DB *, int (*)(DB *, const DBT *, const DBT *, const DBT *, const DBT *, DBT *), int (*)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *)));
+int __bam_get_bt_minkey __P((DB *, u_int32_t *));
+void __bam_copy_config __P((DB *, DB*, u_int32_t));
+void __ram_map_flags __P((DB *, u_int32_t *, u_int32_t *));
+int __ram_set_flags __P((DB *, u_int32_t *flagsp));
+int __ram_get_re_len __P((DB *, u_int32_t *));
+int __ram_get_re_pad __P((DB *, int *));
+int __bam_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, db_pgno_t, u_int32_t));
+int __bam_metachk __P((DB *, const char *, BTMETA *));
+int __bam_read_root __P((DB *, DB_THREAD_INFO *, DB_TXN *, db_pgno_t, u_int32_t));
+int __bam_new_file __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *));
+int __bam_new_subdb __P((DB *, DB *, DB_THREAD_INFO *, DB_TXN *));
+int __bam_iitem __P((DBC *, DBT *, DBT *, u_int32_t, u_int32_t));
+int __bam_ritem __P((DBC *, PAGE *, u_int32_t, DBT *, u_int32_t));
+int __bam_ritem_nolog __P((DBC *, PAGE *, u_int32_t, DBT *, DBT *, u_int32_t));
+int __bam_irep __P((DBC *, PAGE *, u_int32_t, DBT *, DBT *));
+int __bam_split_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_split_48_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_split_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_rsplit_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_adj_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_cadjust_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_cdel_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_repl_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_irep_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_root_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_curadj_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_rcuradj_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_merge_44_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_relink_43_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_reclaim __P((DB *, DB_THREAD_INFO *, DB_TXN *, u_int32_t));
+int __bam_truncate __P((DBC *, u_int32_t *));
+int __ram_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, db_pgno_t, u_int32_t));
+int __ram_append __P((DBC *, DBT *, DBT *));
+int __ramc_del __P((DBC *, u_int32_t));
+int __ramc_get __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
+int __ramc_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
+int __ram_ca __P((DBC *, ca_recno_arg, int *));
+int __ram_getno __P((DBC *, const DBT *, db_recno_t *, int));
+int __ram_writeback __P((DB *));
+int __bam_rsearch __P((DBC *, db_recno_t *, u_int32_t, int, int *));
+int __bam_adjust __P((DBC *, int32_t));
+int __bam_nrecs __P((DBC *, db_recno_t *));
+db_recno_t __bam_total __P((DB *, PAGE *));
+int __bam_get_root __P((DBC *, db_pgno_t, int, u_int32_t, int *));
+int __bam_search __P((DBC *, db_pgno_t, const DBT *, u_int32_t, int, db_recno_t *, int *));
+int __bam_stkrel __P((DBC *, u_int32_t));
+int __bam_stkgrow __P((ENV *, BTREE_CURSOR *));
+int __bam_split __P((DBC *, void *, db_pgno_t *));
+int __bam_broot __P((DBC *, PAGE *, u_int32_t, PAGE *, PAGE *));
+int __ram_root __P((DBC *, PAGE *, PAGE *, PAGE *));
+int __bam_pinsert __P((DBC *, EPG *, u_int32_t, PAGE *, PAGE *, int));
+int __bam_copy __P((DB *, PAGE *, PAGE *, u_int32_t, u_int32_t));
+int __bam_stat __P((DBC *, void *, u_int32_t));
+int __bam_stat_print __P((DBC *, u_int32_t));
+int __bam_stat_callback __P((DBC *, PAGE *, void *, int *));
+void __bam_print_cursor __P((DBC *));
+int __bam_key_range __P((DBC *, DBT *, DB_KEY_RANGE *, u_int32_t));
+int __bam_traverse __P((DBC *, db_lockmode_t, db_pgno_t, int (*)(DBC *, PAGE *, void *, int *), void *));
+int __bam_30_btreemeta __P((DB *, char *, u_int8_t *));
+int __bam_31_btreemeta __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
+int __bam_31_lbtree __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
+int __bam_vrfy_meta __P((DB *, VRFY_DBINFO *, BTMETA *, db_pgno_t, u_int32_t));
+int __ram_vrfy_leaf __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
+int __bam_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
+int __bam_vrfy_itemorder __P((DB *, VRFY_DBINFO *, DB_THREAD_INFO *, PAGE *, db_pgno_t, u_int32_t, int, int, u_int32_t));
+int __bam_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t, void *, void *, u_int32_t));
+int __bam_vrfy_subtree __P((DB *, VRFY_DBINFO *, db_pgno_t, void *, void *, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *));
+int __bam_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, PAGE *, void *, int (*)(void *, const void *), DBT *, u_int32_t));
+int __bam_salvage_walkdupint __P((DB *, VRFY_DBINFO *, PAGE *, DBT *, void *, int (*)(void *, const void *), u_int32_t));
+int __bam_meta2pgset __P((DB *, VRFY_DBINFO *, BTMETA *, u_int32_t, DB *));
+int __bam_init_recover __P((ENV *, DB_DISTAB *));
+int __bam_split_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_split_48_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_split_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_rsplit_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_adj_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_cadjust_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_cdel_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_repl_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_irep_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_root_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_curadj_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_rcuradj_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_relink_43_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_merge_44_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_init_print __P((ENV *, DB_DISTAB *));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_btree_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/clib_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,139 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_clib_ext_h_
+#define	_clib_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#ifndef HAVE_ATOI
+int atoi __P((const char *));
+#endif
+#ifndef HAVE_ATOL
+long atol __P((const char *));
+#endif
+#ifndef HAVE_BSEARCH
+void *bsearch __P((const void *, const void *, size_t, size_t, int (*)(const void *, const void *)));
+#endif
+#ifndef HAVE_GETCWD
+char *getcwd __P((char *, size_t));
+#endif
+#ifndef HAVE_GETOPT
+int getopt __P((int, char * const *, const char *));
+#endif
+#ifndef HAVE_ISALPHA
+int isalpha __P((int));
+#endif
+#ifndef HAVE_ISDIGIT
+int isdigit __P((int));
+#endif
+#ifndef HAVE_ISPRINT
+int isprint __P((int));
+#endif
+#ifndef HAVE_ISSPACE
+int isspace __P((int));
+#endif
+#ifndef HAVE_MEMCMP
+int memcmp __P((const void *, const void *, size_t));
+#endif
+#ifndef HAVE_MEMCPY
+void *memcpy __P((void *, const void *, size_t));
+#endif
+#ifndef HAVE_MEMMOVE
+void *memmove __P((void *, const void *, size_t));
+#endif
+#ifndef HAVE_PRINTF
+int printf __P((const char *, ...));
+#endif
+#ifndef HAVE_PRINTF
+int fprintf __P((FILE *, const char *, ...));
+#endif
+#ifndef HAVE_PRINTF
+int vfprintf __P((FILE *, const char *, va_list));
+#endif
+#ifndef HAVE_QSORT
+void qsort __P((void *, size_t, size_t, int(*)(const void *, const void *)));
+#endif
+#ifndef HAVE_RAISE
+int raise __P((int));
+#endif
+#ifndef HAVE_RAND
+int rand __P((void));
+void srand __P((unsigned int));
+#endif
+#ifndef HAVE_SNPRINTF
+int snprintf __P((char *, size_t, const char *, ...));
+#endif
+#ifndef HAVE_VSNPRINTF
+int vsnprintf __P((char *, size_t, const char *, va_list));
+#endif
+#ifndef HAVE_STRCASECMP
+int strcasecmp __P((const char *, const char *));
+#endif
+#ifndef HAVE_STRCASECMP
+int strncasecmp __P((const char *, const char *, size_t));
+#endif
+#ifndef HAVE_STRCAT
+char *strcat __P((char *, const char *));
+#endif
+#ifndef HAVE_STRCHR
+char *strchr __P((const char *,  int));
+#endif
+#ifndef HAVE_STRDUP
+char *strdup __P((const char *));
+#endif
+#ifndef HAVE_STRERROR
+char *strerror __P((int));
+#endif
+#ifndef HAVE_STRNCAT
+char *strncat __P((char *, const char *, size_t));
+#endif
+#ifndef HAVE_STRNCMP
+int strncmp __P((const char *, const char *, size_t));
+#endif
+#ifndef HAVE_STRRCHR
+char *strrchr __P((const char *, int));
+#endif
+#ifndef HAVE_STRSEP
+char *strsep __P((char **, const char *));
+#endif
+#ifndef HAVE_STRTOL
+long strtol __P((const char *, char **, int));
+#endif
+#ifndef HAVE_STRTOUL
+unsigned long strtoul __P((const char *, char **, int));
+#endif
+#ifndef HAVE_TIME
+time_t time __P((time_t *));
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_clib_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/common_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,99 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_common_ext_h_
+#define	_common_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+void __clock_set_expires __P((ENV *, db_timespec *, db_timeout_t));
+int __clock_expired __P((ENV *, db_timespec *, db_timespec *));
+int __crypto_region_init __P((ENV *));
+int __db_isbigendian __P((void));
+int __db_byteorder __P((ENV *, int));
+u_int32_t __db_compress_count_int __P((u_int64_t));
+int __db_compress_int __P((u_int8_t *, u_int64_t));
+u_int32_t __db_decompress_count_int __P((const u_int8_t *));
+int __db_decompress_int __P((const u_int8_t *, u_int64_t *));
+int __db_decompress_int32 __P((const u_int8_t *, u_int32_t *));
+int __db_fchk __P((ENV *, const char *, u_int32_t, u_int32_t));
+int __db_fcchk __P((ENV *, const char *, u_int32_t, u_int32_t, u_int32_t));
+int __db_ferr __P((const ENV *, const char *, int));
+int __db_fnl __P((const ENV *, const char *));
+int __db_pgerr __P((DB *, db_pgno_t, int));
+int __db_pgfmt __P((ENV *, db_pgno_t));
+#ifdef DIAGNOSTIC
+void __db_assert __P((ENV *, const char *, const char *, int));
+#endif
+int __env_panic_msg __P((ENV *));
+int __env_panic __P((ENV *, int));
+char *__db_unknown_error __P((int));
+void __db_syserr __P((const ENV *, int, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4)));
+void __db_err __P((const ENV *, int, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4)));
+void __db_errx __P((const ENV *, const char *, ...)) __attribute__ ((__format__ (__printf__, 2, 3)));
+void __db_errcall __P((const DB_ENV *, int, db_error_set_t, const char *, va_list));
+void __db_errfile __P((const DB_ENV *, int, db_error_set_t, const char *, va_list));
+void __db_msgadd __P((ENV *, DB_MSGBUF *, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4)));
+void __db_msgadd_ap __P((ENV *, DB_MSGBUF *, const char *, va_list));
+void __db_msg __P((const ENV *, const char *, ...)) __attribute__ ((__format__ (__printf__, 2, 3)));
+void __db_repmsg __P((const ENV *, const char *, ...)) __attribute__ ((__format__ (__printf__, 2, 3)));
+int __db_unknown_flag __P((ENV *, char *, u_int32_t));
+int __db_unknown_type __P((ENV *, char *, DBTYPE));
+int __db_unknown_path __P((ENV *, char *));
+int __db_not_txn_env __P((ENV *));
+int __db_rec_toobig __P((ENV *, u_int32_t, u_int32_t));
+int __db_rec_repl __P((ENV *, u_int32_t, u_int32_t));
+int __dbc_logging __P((DBC *));
+int __db_check_lsn __P((ENV *, DB_LSN *, DB_LSN *));
+int __db_rdonly __P((const ENV *, const char *));
+int __db_space_err __P((const DB *));
+int __db_failed __P((const ENV *, const char *, pid_t, db_threadid_t));
+int __db_getlong __P((DB_ENV *, const char *, char *, long, long, long *));
+int __db_getulong __P((DB_ENV *, const char *, char *, u_long, u_long, u_long *));
+void __db_idspace __P((u_int32_t *, int, u_int32_t *, u_int32_t *));
+u_int32_t __db_log2 __P((u_int32_t));
+u_int32_t __db_tablesize __P((u_int32_t));
+void __db_hashinit __P((void *, u_int32_t));
+int __dbt_usercopy __P((ENV *, DBT *));
+void __dbt_userfree __P((ENV *, DBT *, DBT *, DBT *));
+int __db_mkpath __P((ENV *, const char *));
+u_int32_t __db_openflags __P((int));
+int __db_util_arg __P((char *, char *, int *, char ***));
+int __db_util_cache __P((DB *, u_int32_t *, int *));
+int __db_util_logset __P((const char *, char *));
+void __db_util_siginit __P((void));
+int __db_util_interrupted __P((void));
+void __db_util_sigresend __P((void));
+int __db_zero_fill __P((ENV *, DB_FH *));
+int __db_zero_extend __P((ENV *, DB_FH *, db_pgno_t, db_pgno_t, u_int32_t));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_common_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/crdel_auto.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,152 @@
+/* Do not edit: automatically built by gen_rec.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__crdel_AUTO_H
+#define	__crdel_AUTO_H
+#include "dbinc/log.h"
+#define	DB___crdel_metasub	142
+typedef struct ___crdel_metasub_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DBT	page;
+	DB_LSN	lsn;
+} __crdel_metasub_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __crdel_metasub_desc[];
+static inline int
+__crdel_metasub_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, const DBT *page, DB_LSN * lsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___crdel_metasub, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(page) +
+	    sizeof(*lsn),
+	    __crdel_metasub_desc, pgno, page, lsn));
+}
+
+static inline int __crdel_metasub_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __crdel_metasub_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __crdel_metasub_desc, sizeof(__crdel_metasub_args), (void**)arg));
+}
+#define	DB___crdel_inmem_create	138
+typedef struct ___crdel_inmem_create_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	DBT	name;
+	DBT	fid;
+	u_int32_t	pgsize;
+} __crdel_inmem_create_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __crdel_inmem_create_desc[];
+static inline int
+__crdel_inmem_create_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    int32_t fileid, const DBT *name, const DBT *fid, u_int32_t pgsize)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___crdel_inmem_create, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + LOG_DBT_SIZE(name) + LOG_DBT_SIZE(fid) +
+	    sizeof(u_int32_t),
+	    __crdel_inmem_create_desc,
+	    fileid, name, fid, pgsize));
+}
+
+static inline int __crdel_inmem_create_read(ENV *env, 
+    void *data, __crdel_inmem_create_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __crdel_inmem_create_desc, sizeof(__crdel_inmem_create_args), (void**)arg));
+}
+#define	DB___crdel_inmem_rename	139
+typedef struct ___crdel_inmem_rename_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DBT	oldname;
+	DBT	newname;
+	DBT	fid;
+} __crdel_inmem_rename_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __crdel_inmem_rename_desc[];
+static inline int
+__crdel_inmem_rename_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    const DBT *oldname, const DBT *newname, const DBT *fid)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___crdel_inmem_rename, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    LOG_DBT_SIZE(oldname) + LOG_DBT_SIZE(newname) + LOG_DBT_SIZE(fid),
+	    __crdel_inmem_rename_desc,
+	    oldname, newname, fid));
+}
+
+static inline int __crdel_inmem_rename_read(ENV *env, 
+    void *data, __crdel_inmem_rename_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __crdel_inmem_rename_desc, sizeof(__crdel_inmem_rename_args), (void**)arg));
+}
+#define	DB___crdel_inmem_remove	140
+typedef struct ___crdel_inmem_remove_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DBT	name;
+	DBT	fid;
+} __crdel_inmem_remove_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __crdel_inmem_remove_desc[];
+static inline int
+__crdel_inmem_remove_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    const DBT *name, const DBT *fid)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___crdel_inmem_remove, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    LOG_DBT_SIZE(name) + LOG_DBT_SIZE(fid),
+	    __crdel_inmem_remove_desc,
+	    name, fid));
+}
+
+static inline int __crdel_inmem_remove_read(ENV *env, 
+    void *data, __crdel_inmem_remove_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __crdel_inmem_remove_desc, sizeof(__crdel_inmem_remove_args), (void**)arg));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/crypto_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,64 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_crypto_ext_h_
+#define	_crypto_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __aes_setup __P((ENV *, DB_CIPHER *));
+u_int __aes_adj_size __P((size_t));
+int __aes_close __P((ENV *, void *));
+int __aes_decrypt __P((ENV *, void *, void *, u_int8_t *, size_t));
+int __aes_encrypt __P((ENV *, void *, void *, u_int8_t *, size_t));
+int __aes_init __P((ENV *, DB_CIPHER *));
+int __crypto_env_close __P((ENV *));
+int __crypto_env_refresh __P((ENV *));
+int __crypto_algsetup __P((ENV *, DB_CIPHER *, u_int32_t, int));
+int __crypto_decrypt_meta __P((ENV *, DB *, u_int8_t *, int));
+int __crypto_set_passwd __P((ENV *, ENV *));
+int __db_generate_iv __P((ENV *, u_int32_t *));
+int __db_rijndaelKeySetupEnc __P((u32 *, const u8 *, int));
+int __db_rijndaelKeySetupDec __P((u32 *, const u8 *, int));
+void __db_rijndaelEncrypt __P((u32 *, int, const u8 *, u8 *));
+void __db_rijndaelDecrypt __P((u32 *, int, const u8 *, u8 *));
+void __db_rijndaelEncryptRound __P((const u32 *, int, u8 *, int));
+void __db_rijndaelDecryptRound __P((const u32 *, int, u8 *, int));
+int __db_makeKey __P((keyInstance *, int, int, char *));
+int __db_cipherInit __P((cipherInstance *, int, char *));
+int __db_blockEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *, size_t, u_int8_t *));
+int __db_padEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *, int, u_int8_t *));
+int __db_blockDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *, size_t, u_int8_t *));
+int __db_padDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *, int, u_int8_t *));
+int __db_cipherUpdateRounds __P((cipherInstance *, keyInstance *, u_int8_t *, int, u_int8_t *, int));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_crypto_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/db_auto.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,691 @@
+/* Do not edit: automatically built by gen_rec.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__db_AUTO_H
+#define	__db_AUTO_H
+#include "dbinc/log.h"
+#define	DB___db_addrem	41
+typedef struct ___db_addrem_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	u_int32_t	indx;
+	u_int32_t	nbytes;
+	DBT	hdr;
+	DBT	dbt;
+	DB_LSN	pagelsn;
+} __db_addrem_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_addrem_desc[];
+static inline int
+__db_addrem_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t opcode, db_pgno_t pgno, u_int32_t indx, u_int32_t nbytes,
+    const DBT *hdr, const DBT *dbt, DB_LSN * pagelsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_addrem, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(hdr) +
+	    LOG_DBT_SIZE(dbt) + sizeof(*pagelsn),
+	    __db_addrem_desc,
+	    opcode, pgno, indx, nbytes, hdr, dbt, pagelsn));
+}
+
+static inline int __db_addrem_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_addrem_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_addrem_desc, sizeof(__db_addrem_args), (void**)arg));
+}
+#define	DB___db_addrem_42	41
+typedef struct ___db_addrem_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	u_int32_t	indx;
+	u_int32_t	nbytes;
+	DBT	hdr;
+	DBT	dbt;
+	DB_LSN	pagelsn;
+} __db_addrem_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_addrem_42_desc[];
+static inline int __db_addrem_42_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_addrem_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_addrem_42_desc, sizeof(__db_addrem_42_args), (void**)arg));
+}
+#define	DB___db_big	43
+typedef struct ___db_big_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	db_pgno_t	prev_pgno;
+	db_pgno_t	next_pgno;
+	DBT	dbt;
+	DB_LSN	pagelsn;
+	DB_LSN	prevlsn;
+	DB_LSN	nextlsn;
+} __db_big_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_big_desc[];
+static inline int
+__db_big_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t opcode, db_pgno_t pgno, db_pgno_t prev_pgno, db_pgno_t next_pgno,
+    const DBT *dbt, DB_LSN * pagelsn, DB_LSN * prevlsn, DB_LSN * nextlsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_big, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(dbt) +
+	    sizeof(*pagelsn) + sizeof(*prevlsn) + sizeof(*nextlsn),
+	    __db_big_desc,
+	    opcode, pgno, prev_pgno, next_pgno, dbt, pagelsn, prevlsn,
+	    nextlsn));
+}
+
+static inline int __db_big_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_big_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_big_desc, sizeof(__db_big_args), (void**)arg));
+}
+#define	DB___db_big_42	43
+typedef struct ___db_big_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	db_pgno_t	prev_pgno;
+	db_pgno_t	next_pgno;
+	DBT	dbt;
+	DB_LSN	pagelsn;
+	DB_LSN	prevlsn;
+	DB_LSN	nextlsn;
+} __db_big_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_big_42_desc[];
+static inline int __db_big_42_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_big_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_big_42_desc, sizeof(__db_big_42_args), (void**)arg));
+}
+#define	DB___db_ovref	44
+typedef struct ___db_ovref_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	int32_t	adjust;
+	DB_LSN	lsn;
+} __db_ovref_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_ovref_desc[];
+static inline int
+__db_ovref_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, int32_t adjust, DB_LSN * lsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_ovref, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(*lsn),
+	    __db_ovref_desc, pgno, adjust, lsn));
+}
+
+static inline int __db_ovref_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_ovref_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_ovref_desc, sizeof(__db_ovref_args), (void**)arg));
+}
+#define	DB___db_relink_42	45
+typedef struct ___db_relink_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	lsn;
+	db_pgno_t	prev;
+	DB_LSN	lsn_prev;
+	db_pgno_t	next;
+	DB_LSN	lsn_next;
+} __db_relink_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_relink_42_desc[];
+static inline int __db_relink_42_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_relink_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_relink_42_desc, sizeof(__db_relink_42_args), (void**)arg));
+}
+#define	DB___db_debug	47
+typedef struct ___db_debug_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DBT	op;
+	int32_t	fileid;
+	DBT	key;
+	DBT	data;
+	u_int32_t	arg_flags;
+} __db_debug_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_debug_desc[];
+static inline int
+__db_debug_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    const DBT *op, int32_t fileid, const DBT *key, const DBT *data, u_int32_t arg_flags)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___db_debug, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    LOG_DBT_SIZE(op) + sizeof(u_int32_t) + LOG_DBT_SIZE(key) +
+	    LOG_DBT_SIZE(data) + sizeof(u_int32_t),
+	    __db_debug_desc,
+	    op, fileid, key, data, arg_flags));
+}
+
+static inline int __db_debug_read(ENV *env, 
+    void *data, __db_debug_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __db_debug_desc, sizeof(__db_debug_args), (void**)arg));
+}
+#define	DB___db_noop	48
+typedef struct ___db_noop_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	prevlsn;
+} __db_noop_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_noop_desc[];
+static inline int
+__db_noop_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, DB_LSN * prevlsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_noop, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*prevlsn),
+	    __db_noop_desc, pgno, prevlsn));
+}
+
+static inline int __db_noop_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_noop_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_noop_desc, sizeof(__db_noop_args), (void**)arg));
+}
+#define	DB___db_pg_alloc_42	49
+typedef struct ___db_pg_alloc_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	DB_LSN	meta_lsn;
+	db_pgno_t	meta_pgno;
+	DB_LSN	page_lsn;
+	db_pgno_t	pgno;
+	u_int32_t	ptype;
+	db_pgno_t	next;
+} __db_pg_alloc_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_pg_alloc_42_desc[];
+static inline int __db_pg_alloc_42_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_pg_alloc_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_pg_alloc_42_desc, sizeof(__db_pg_alloc_42_args), (void**)arg));
+}
+#define	DB___db_pg_alloc	49
+typedef struct ___db_pg_alloc_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	DB_LSN	meta_lsn;
+	db_pgno_t	meta_pgno;
+	DB_LSN	page_lsn;
+	db_pgno_t	pgno;
+	u_int32_t	ptype;
+	db_pgno_t	next;
+	db_pgno_t	last_pgno;
+} __db_pg_alloc_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_pg_alloc_desc[];
+static inline int
+__db_pg_alloc_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, DB_LSN * meta_lsn, db_pgno_t meta_pgno, DB_LSN * page_lsn, db_pgno_t pgno,
+    u_int32_t ptype, db_pgno_t next, db_pgno_t last_pgno)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_pg_alloc, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(*meta_lsn) + sizeof(u_int32_t) +
+	    sizeof(*page_lsn) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __db_pg_alloc_desc, meta_lsn, meta_pgno, page_lsn, pgno, ptype, next, last_pgno));
+}
+
+static inline int __db_pg_alloc_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_pg_alloc_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_pg_alloc_desc, sizeof(__db_pg_alloc_args), (void**)arg));
+}
+#define	DB___db_pg_free_42	50
+typedef struct ___db_pg_free_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	meta_lsn;
+	db_pgno_t	meta_pgno;
+	DBT	header;
+	db_pgno_t	next;
+} __db_pg_free_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_pg_free_42_desc[];
+static inline int __db_pg_free_42_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_pg_free_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_pg_free_42_desc, sizeof(__db_pg_free_42_args), (void**)arg));
+}
+#define	DB___db_pg_free	50
+typedef struct ___db_pg_free_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	meta_lsn;
+	db_pgno_t	meta_pgno;
+	DBT	header;
+	db_pgno_t	next;
+	db_pgno_t	last_pgno;
+} __db_pg_free_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_pg_free_desc[];
+static inline int
+__db_pg_free_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, DB_LSN * meta_lsn, db_pgno_t meta_pgno, const DBT *header,
+    db_pgno_t next, db_pgno_t last_pgno)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_pg_free, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*meta_lsn) +
+	    sizeof(u_int32_t) + LOG_DBT_SIZE(header) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t),
+	    __db_pg_free_desc, pgno, meta_lsn, meta_pgno, header, next, last_pgno));
+}
+
+static inline int __db_pg_free_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_pg_free_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_pg_free_desc, sizeof(__db_pg_free_args), (void**)arg));
+}
+#define	DB___db_cksum	51
+typedef struct ___db_cksum_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+} __db_cksum_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_cksum_desc[];
+static inline int
+__db_cksum_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___db_cksum, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN),
+	    __db_cksum_desc));
+}
+
+static inline int __db_cksum_read(ENV *env, 
+    void *data, __db_cksum_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __db_cksum_desc, sizeof(__db_cksum_args), (void**)arg));
+}
+#define	DB___db_pg_freedata_42	52
+typedef struct ___db_pg_freedata_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	meta_lsn;
+	db_pgno_t	meta_pgno;
+	DBT	header;
+	db_pgno_t	next;
+	DBT	data;
+} __db_pg_freedata_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_pg_freedata_42_desc[];
+static inline int __db_pg_freedata_42_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_pg_freedata_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_pg_freedata_42_desc, sizeof(__db_pg_freedata_42_args), (void**)arg));
+}
+#define	DB___db_pg_freedata	52
+typedef struct ___db_pg_freedata_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	meta_lsn;
+	db_pgno_t	meta_pgno;
+	DBT	header;
+	db_pgno_t	next;
+	db_pgno_t	last_pgno;
+	DBT	data;
+} __db_pg_freedata_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_pg_freedata_desc[];
+static inline int
+__db_pg_freedata_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, DB_LSN * meta_lsn, db_pgno_t meta_pgno, const DBT *header,
+    db_pgno_t next, db_pgno_t last_pgno, const DBT *data)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_pg_freedata, 1,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*meta_lsn) +
+	    sizeof(u_int32_t) + LOG_DBT_SIZE(header) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + LOG_DBT_SIZE(data),
+	    __db_pg_freedata_desc, pgno, meta_lsn, meta_pgno, header, next, last_pgno, data));
+}
+
+static inline int __db_pg_freedata_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_pg_freedata_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_pg_freedata_desc, sizeof(__db_pg_freedata_args), (void**)arg));
+}
+#define	DB___db_pg_init	60
+typedef struct ___db_pg_init_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DBT	header;
+	DBT	data;
+} __db_pg_init_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_pg_init_desc[];
+static inline int
+__db_pg_init_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, const DBT *header, const DBT *data)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_pg_init, 1,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(header) +
+	    LOG_DBT_SIZE(data),
+	    __db_pg_init_desc, pgno, header, data));
+}
+
+static inline int __db_pg_init_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_pg_init_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_pg_init_desc, sizeof(__db_pg_init_args), (void**)arg));
+}
+#define	DB___db_pg_sort_44	61
+typedef struct ___db_pg_sort_44_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	meta;
+	DB_LSN	meta_lsn;
+	db_pgno_t	last_free;
+	DB_LSN	last_lsn;
+	db_pgno_t	last_pgno;
+	DBT	list;
+} __db_pg_sort_44_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_pg_sort_44_desc[];
+static inline int __db_pg_sort_44_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_pg_sort_44_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_pg_sort_44_desc, sizeof(__db_pg_sort_44_args), (void**)arg));
+}
+#define	DB___db_pg_trunc	66
+typedef struct ___db_pg_trunc_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	meta;
+	DB_LSN	meta_lsn;
+	db_pgno_t	last_free;
+	DB_LSN	last_lsn;
+	db_pgno_t	next_free;
+	db_pgno_t	last_pgno;
+	DBT	list;
+} __db_pg_trunc_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_pg_trunc_desc[];
+static inline int
+__db_pg_trunc_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t meta, DB_LSN * meta_lsn, db_pgno_t last_free, DB_LSN * last_lsn,
+    db_pgno_t next_free, db_pgno_t last_pgno, const DBT *list)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_pg_trunc, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*meta_lsn) +
+	    sizeof(u_int32_t) + sizeof(*last_lsn) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + LOG_DBT_SIZE(list),
+	    __db_pg_trunc_desc, meta, meta_lsn, last_free, last_lsn, next_free, last_pgno, list));
+}
+
+static inline int __db_pg_trunc_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_pg_trunc_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_pg_trunc_desc, sizeof(__db_pg_trunc_args), (void**)arg));
+}
+#define	DB___db_realloc	36
+typedef struct ___db_realloc_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	prev_pgno;
+	DB_LSN	page_lsn;
+	db_pgno_t	next_free;
+	u_int32_t	ptype;
+	DBT	list;
+} __db_realloc_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_realloc_desc[];
+static inline int
+__db_realloc_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t prev_pgno, DB_LSN * page_lsn, db_pgno_t next_free, u_int32_t ptype,
+    const DBT *list)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_realloc, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*page_lsn) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(list),
+	    __db_realloc_desc, prev_pgno, page_lsn, next_free, ptype, list));
+}
+
+static inline int __db_realloc_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_realloc_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_realloc_desc, sizeof(__db_realloc_args), (void**)arg));
+}
+#define	DB___db_relink	147
+typedef struct ___db_relink_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	db_pgno_t	new_pgno;
+	db_pgno_t	prev_pgno;
+	DB_LSN	lsn_prev;
+	db_pgno_t	next_pgno;
+	DB_LSN	lsn_next;
+} __db_relink_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_relink_desc[];
+static inline int
+__db_relink_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, db_pgno_t new_pgno, db_pgno_t prev_pgno, DB_LSN * lsn_prev,
+    db_pgno_t next_pgno, DB_LSN * lsn_next)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_relink, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(*lsn_prev) + sizeof(u_int32_t) +
+	    sizeof(*lsn_next),
+	    __db_relink_desc, pgno, new_pgno, prev_pgno, lsn_prev, next_pgno, lsn_next));
+}
+
+static inline int __db_relink_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_relink_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_relink_desc, sizeof(__db_relink_args), (void**)arg));
+}
+#define	DB___db_merge	148
+typedef struct ___db_merge_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	lsn;
+	db_pgno_t	npgno;
+	DB_LSN	nlsn;
+	DBT	hdr;
+	DBT	data;
+	int32_t	pg_copy;
+} __db_merge_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_merge_desc[];
+static inline int
+__db_merge_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, DB_LSN * lsn, db_pgno_t npgno, DB_LSN * nlsn,
+    const DBT *hdr, const DBT *data, int32_t pg_copy)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_merge, 1,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*lsn) +
+	    sizeof(u_int32_t) + sizeof(*nlsn) + LOG_DBT_SIZE(hdr) +
+	    LOG_DBT_SIZE(data) + sizeof(u_int32_t),
+	    __db_merge_desc, pgno, lsn, npgno, nlsn, hdr, data, pg_copy));
+}
+
+static inline int __db_merge_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_merge_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_merge_desc, sizeof(__db_merge_args), (void**)arg));
+}
+#define	DB___db_pgno	149
+typedef struct ___db_pgno_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	lsn;
+	u_int32_t	indx;
+	db_pgno_t	opgno;
+	db_pgno_t	npgno;
+} __db_pgno_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __db_pgno_desc[];
+static inline int
+__db_pgno_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, DB_LSN * lsn, u_int32_t indx, db_pgno_t opgno,
+    db_pgno_t npgno)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___db_pgno, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*lsn) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __db_pgno_desc, pgno, lsn, indx, opgno, npgno));
+}
+
+static inline int __db_pgno_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __db_pgno_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __db_pgno_desc, sizeof(__db_pgno_args), (void**)arg));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/db_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,367 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_db_ext_h_
+#define	_db_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __crdel_init_recover __P((ENV *, DB_DISTAB *));
+int __crdel_metasub_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __crdel_inmem_create_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __crdel_inmem_rename_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __crdel_inmem_remove_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __crdel_init_print __P((ENV *, DB_DISTAB *));
+int __crdel_metasub_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __crdel_inmem_create_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __crdel_inmem_rename_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __crdel_inmem_remove_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_master_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, u_int32_t, int, DB **));
+int __db_master_update __P((DB *, DB *, DB_THREAD_INFO *, DB_TXN *, const char *, DBTYPE, mu_action, const char *, u_int32_t));
+int __env_dbreg_setup __P((DB *, DB_TXN *, const char *, const char *, u_int32_t));
+int __env_setup __P((DB *, DB_TXN *, const char *, const char *, u_int32_t, u_int32_t));
+int __env_mpool __P((DB *, const char *, u_int32_t));
+int __db_close __P((DB *, DB_TXN *, u_int32_t));
+int __db_refresh __P((DB *, DB_TXN *, u_int32_t, int *, int));
+int __db_log_page __P((DB *, DB_TXN *, DB_LSN *, db_pgno_t, PAGE *));
+int __db_walk_cursors __P((DB *, DBC *, int (*) __P((DBC *, DBC *, u_int32_t *, db_pgno_t, u_int32_t, void *)), u_int32_t *, db_pgno_t, u_int32_t, void *));
+int __db_backup_name __P((ENV *, const char *, DB_TXN *, char **));
+#ifdef CONFIG_TEST
+int __db_testcopy __P((ENV *, DB *, const char *));
+#endif
+int __db_testdocopy __P((ENV *, const char *));
+int __db_cursor_int __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBTYPE, db_pgno_t, int, DB_LOCKER *, DBC **));
+int __db_put __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, u_int32_t));
+int __db_del __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, u_int32_t));
+int __db_sync __P((DB *));
+int __db_associate __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB *, int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t));
+int __db_secondary_close __P((DB *, u_int32_t));
+int __db_associate_foreign __P((DB *, DB *, int (*)(DB *, const DBT *, DBT *, const DBT *, int *), u_int32_t));
+int __db_init_recover __P((ENV *, DB_DISTAB *));
+int __db_addrem_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_addrem_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_big_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_big_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_ovref_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_relink_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_debug_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_noop_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_alloc_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_alloc_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_free_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_free_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_cksum_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_freedata_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_freedata_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_init_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_sort_44_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_trunc_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_realloc_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_relink_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_merge_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pgno_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_init_print __P((ENV *, DB_DISTAB *));
+int __db_dbbackup_pp __P((DB_ENV *, const char *, const char *, u_int32_t));
+int __db_dbbackup __P((DB_ENV *, DB_THREAD_INFO *, const char *, const char *, u_int32_t));
+int __db_backup __P((DB_ENV *, const char *, u_int32_t));
+int __dbc_close __P((DBC *));
+int __dbc_destroy __P((DBC *));
+int __dbc_cmp __P((DBC *, DBC *, int *));
+int __dbc_count __P((DBC *, db_recno_t *));
+int __dbc_del __P((DBC *, u_int32_t));
+int __dbc_idel __P((DBC *, u_int32_t));
+#ifdef HAVE_COMPRESSION
+int __dbc_bulk_del __P((DBC *, DBT *, u_int32_t));
+#endif
+int __dbc_dup __P((DBC *, DBC **, u_int32_t));
+int __dbc_idup __P((DBC *, DBC **, u_int32_t));
+int __dbc_newopd __P((DBC *, db_pgno_t, DBC *, DBC **));
+int __dbc_get __P((DBC *, DBT *, DBT *, u_int32_t));
+int __dbc_iget __P((DBC *, DBT *, DBT *, u_int32_t));
+int __dbc_put __P((DBC *, DBT *, DBT *, u_int32_t));
+int __dbc_iput __P((DBC *, DBT *, DBT *, u_int32_t));
+int __db_duperr __P((DB *, u_int32_t));
+int __dbc_cleanup __P((DBC *, DBC *, int));
+int __dbc_secondary_get_pp __P((DBC *, DBT *, DBT *, u_int32_t));
+int __dbc_pget __P((DBC *, DBT *, DBT *, DBT *, u_int32_t));
+int __dbc_del_primary __P((DBC *));
+int __db_s_first __P((DB *, DB **));
+int __db_s_next __P((DB **, DB_TXN *));
+int __db_s_done __P((DB *, DB_TXN *));
+int __db_buildpartial __P((DB *, DBT *, DBT *, DBT *));
+u_int32_t __db_partsize __P((u_int32_t, DBT *));
+int __db_secondary_corrupt __P((DB *));
+#ifdef DIAGNOSTIC
+void __db_check_skeyset __P((DB *, DBT *));
+#endif
+int __cdsgroup_begin __P((ENV *, DB_TXN **));
+int __cdsgroup_begin_pp __P((DB_ENV *, DB_TXN **));
+int __db_compact_pp __P((DB *, DB_TXN *, DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *));
+int __db_associate_foreign_pp __P((DB *, DB *, int (*)(DB *, const DBT *, DBT *, const DBT *, int *), u_int32_t));
+int __db_compact_int __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *));
+int __db_exchange_page __P((DBC *, PAGE **, PAGE *, db_pgno_t, int));
+int __db_truncate_overflow __P((DBC *, db_pgno_t, PAGE **, DB_COMPACT *));
+int __db_truncate_root __P((DBC *, PAGE *, u_int32_t, db_pgno_t *, u_int32_t));
+int __db_find_free __P((DBC *, u_int32_t, u_int32_t, db_pgno_t, db_pgno_t *));
+int __db_move_metadata __P((DBC *, DBMETA **, DB_COMPACT *));
+int __db_pgin __P((DB_ENV *, db_pgno_t, void *, DBT *));
+int __db_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *));
+int __db_decrypt_pg __P((ENV *, DB *, PAGE *));
+int __db_encrypt_and_checksum_pg __P((ENV *, DB *, PAGE *));
+void __db_metaswap __P((PAGE *));
+int __db_byteswap __P((DB *, db_pgno_t, PAGE *, size_t, int));
+int __db_pageswap __P((ENV *, DB *, void *, size_t, DBT *, int));
+void __db_recordswap __P((u_int32_t, u_int32_t, void *, void *, u_int32_t));
+int __db_dispatch __P((ENV *, DB_DISTAB *, DBT *, DB_LSN *, db_recops, void *));
+int __db_add_recovery __P((DB_ENV *, DB_DISTAB *, int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops), u_int32_t));
+int __db_add_recovery_int __P((ENV *, DB_DISTAB *, int (*)(ENV *, DBT *, DB_LSN *, db_recops, void *), u_int32_t));
+int __db_txnlist_init __P((ENV *, DB_THREAD_INFO *, u_int32_t, u_int32_t, DB_LSN *, DB_TXNHEAD **));
+int __db_txnlist_add __P((ENV *, DB_TXNHEAD *, u_int32_t, u_int32_t, DB_LSN *));
+int __db_txnlist_remove __P((ENV *, DB_TXNHEAD *, u_int32_t));
+void __db_txnlist_ckp __P((ENV *, DB_TXNHEAD *, DB_LSN *));
+void __db_txnlist_end __P((ENV *, DB_TXNHEAD *));
+int __db_txnlist_find __P((ENV *, DB_TXNHEAD *, u_int32_t, u_int32_t *));
+int __db_txnlist_update __P((ENV *, DB_TXNHEAD *, u_int32_t, u_int32_t, DB_LSN *, u_int32_t *, int));
+int __db_txnlist_gen __P((ENV *, DB_TXNHEAD *, int, u_int32_t, u_int32_t));
+int __db_txnlist_lsnadd __P((ENV *, DB_TXNHEAD *, DB_LSN *));
+int __db_txnlist_lsnget __P((ENV *, DB_TXNHEAD *, DB_LSN *, u_int32_t));
+int __db_txnlist_lsninit __P((ENV *, DB_TXNHEAD *, DB_LSN *));
+void __db_txnlist_print __P((DB_TXNHEAD *));
+int __db_ditem_nolog __P((DBC *, PAGE *, u_int32_t, u_int32_t));
+int __db_ditem __P((DBC *, PAGE *, u_int32_t, u_int32_t));
+int __db_pitem_nolog __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *));
+int __db_pitem __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *));
+int __db_associate_pp __P((DB *, DB_TXN *, DB *, int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t));
+int __db_close_pp __P((DB *, u_int32_t));
+int __db_cursor_pp __P((DB *, DB_TXN *, DBC **, u_int32_t));
+int __db_cursor __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBC **, u_int32_t));
+int __db_del_pp __P((DB *, DB_TXN *, DBT *, u_int32_t));
+int __db_exists __P((DB *, DB_TXN *, DBT *, u_int32_t));
+int __db_fd_pp __P((DB *, int *));
+int __db_get_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
+int __db_get __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, u_int32_t));
+int __db_key_range_pp __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t));
+int __db_open_pp __P((DB *, DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int));
+int __db_pget_pp __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t));
+int __db_pget __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t));
+int __db_put_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
+int __db_sync_pp __P((DB *, u_int32_t));
+int __dbc_close_pp __P((DBC *));
+int __dbc_cmp_pp __P((DBC *, DBC *, int*, u_int32_t));
+int __dbc_count_pp __P((DBC *, db_recno_t *, u_int32_t));
+int __dbc_del_pp __P((DBC *, u_int32_t));
+int __dbc_dup_pp __P((DBC *, DBC **, u_int32_t));
+int __dbc_get_pp __P((DBC *, DBT *, DBT *, u_int32_t));
+int __dbc_get_arg __P((DBC *, DBT *, DBT *, u_int32_t));
+int __db_secondary_close_pp __P((DB *, u_int32_t));
+int __dbc_pget_pp __P((DBC *, DBT *, DBT *, DBT *, u_int32_t));
+int __dbc_put_pp __P((DBC *, DBT *, DBT *, u_int32_t));
+int __db_txn_auto_init __P((ENV *, DB_THREAD_INFO *, DB_TXN **));
+int __db_txn_auto_resolve __P((ENV *, DB_TXN *, int, int));
+int __db_join_pp __P((DB *, DBC **, DBC **, u_int32_t));
+int __db_join __P((DB *, DBC **, DBC **, u_int32_t));
+int __db_join_close __P((DBC *));
+int __db_new __P((DBC *, u_int32_t, DB_LOCK *, PAGE **));
+int __db_free __P((DBC *, PAGE *, u_int32_t));
+#ifdef HAVE_FTRUNCATE
+void __db_freelist_pos __P((db_pgno_t, db_pgno_t *, u_int32_t, u_int32_t *));
+#endif
+void __db_freelist_sort __P((db_pglist_t *, u_int32_t));
+#ifdef HAVE_FTRUNCATE
+int __db_pg_truncate __P((DBC *, DB_TXN *, db_pglist_t *, DB_COMPACT *, u_int32_t *, db_pgno_t , db_pgno_t *, DB_LSN *, int));
+#endif
+#ifdef HAVE_FTRUNCATE
+int __db_free_truncate __P((DB *, DB_THREAD_INFO *, DB_TXN *, u_int32_t, DB_COMPACT *, db_pglist_t **, u_int32_t *, db_pgno_t *));
+#endif
+int __db_create_internal  __P((DB **, ENV *, u_int32_t));
+int __dbh_am_chk __P((DB *, u_int32_t));
+int __db_get_flags __P((DB *, u_int32_t *));
+int  __db_set_flags __P((DB *, u_int32_t));
+int  __db_get_lorder __P((DB *, int *));
+int  __db_set_lorder __P((DB *, int));
+int  __db_set_pagesize __P((DB *, u_int32_t));
+int __db_relink __P((DBC *, PAGE *, PAGE *, db_pgno_t));
+#ifdef DIAGNOSTIC
+int __db_haslock __P((ENV *, DB_LOCKER *, DB_MPOOLFILE *, db_pgno_t, db_lockmode_t, u_int32_t));
+#endif
+#ifdef DIAGNOSTIC
+int __db_has_pagelock __P((ENV *, DB_LOCKER *, DB_MPOOLFILE *, PAGE *, db_lockmode_t));
+#endif
+int __db_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int, db_pgno_t));
+int __db_get_open_flags __P((DB *, u_int32_t *));
+int __db_new_file __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *));
+int __db_init_subdb __P((DB *, DB *, const char *, DB_THREAD_INFO *, DB_TXN *));
+int __db_chk_meta __P((ENV *, DB *, DBMETA *, u_int32_t));
+int __db_meta_setup __P((ENV *, DB *, const char *, DBMETA *, u_int32_t, u_int32_t));
+int __db_reopen __P((DBC *));
+int __db_goff __P((DBC *, DBT *, u_int32_t, db_pgno_t, void **, u_int32_t *));
+int __db_poff __P((DBC *, const DBT *, db_pgno_t *));
+int __db_ovref __P((DBC *, db_pgno_t));
+int __db_doff __P((DBC *, db_pgno_t));
+int __db_moff __P((DBC *, const DBT *, db_pgno_t, u_int32_t, int (*)(DB *, const DBT *, const DBT *), int *));
+int __db_coff __P((DBC *, const DBT *, const DBT *, int (*)(DB *, const DBT *, const DBT *), int *));
+int __db_vrfy_overflow __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
+int __db_vrfy_ovfl_structure __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, u_int32_t));
+int __db_safe_goff __P((DB *, VRFY_DBINFO *, db_pgno_t, DBT *, void *, u_int32_t *, u_int32_t));
+void __db_loadme __P((void));
+int __db_dumptree __P((DB *, DB_TXN *, char *, char *, db_pgno_t, db_pgno_t));
+const FN * __db_get_flags_fn __P((void));
+int __db_prnpage __P((DB *, DB_TXN *, db_pgno_t));
+int __db_prpage __P((DB *, PAGE *, u_int32_t));
+const char * __db_lockmode_to_string __P((db_lockmode_t));
+int __db_dumptree __P((DB *, DB_TXN *, char *, char *, db_pgno_t, db_pgno_t));
+const FN * __db_get_flags_fn __P((void));
+int __db_prpage_int __P((ENV *, DB_MSGBUF *, DB *, char *, PAGE *, u_int32_t, u_int8_t *, u_int32_t));
+void __db_prbytes __P((ENV *, DB_MSGBUF *, u_int8_t *, u_int32_t));
+void __db_prflags __P((ENV *, DB_MSGBUF *, u_int32_t, const FN *, const char *, const char *));
+int __db_name_to_val __P((FN const *, char *));
+const char *__db_pagetype_to_string __P((u_int32_t));
+int __db_dump_pp __P((DB *, const char *, int (*)(void *, const void *), void *, int, int));
+int __db_dump __P((DB *, const char *, int (*)(void *, const void *), void *, int, int));
+int __db_prdbt __P((DBT *, int, const char *, void *, int (*)(void *, const void *), int, int));
+int	__db_prheader __P((DB *, const char *, int, int, void *, int (*)(void *, const void *), VRFY_DBINFO *, db_pgno_t));
+int __db_prfooter __P((void *, int (*)(void *, const void *)));
+int  __db_pr_callback __P((void *, const void *));
+const char * __db_dbtype_to_string __P((DBTYPE));
+int __db_addrem_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_addrem_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_big_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_big_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_ovref_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_debug_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_noop_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_alloc_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_free_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_freedata_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_cksum_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_init_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_trunc_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_realloc_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_sort_44_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_alloc_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_free_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_freedata_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_relink_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_relink_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_merge_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pgno_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+void __db_pglist_swap __P((u_int32_t, void *));
+void __db_pglist_print __P((ENV *, DB_MSGBUF *, DBT *));
+int __db_traverse_big __P((DBC *, db_pgno_t, int (*)(DBC *, PAGE *, void *, int *), void *));
+int __db_reclaim_callback __P((DBC *, PAGE *, void *, int *));
+int __db_truncate_callback __P((DBC *, PAGE *, void *, int *));
+int __env_dbremove_pp __P((DB_ENV *, DB_TXN *, const char *, const char *, u_int32_t));
+int __db_remove_pp __P((DB *, const char *, const char *, u_int32_t));
+int __db_remove __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, u_int32_t));
+int __db_remove_int __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, u_int32_t));
+int __db_inmem_remove __P((DB *, DB_TXN *, const char *));
+int __env_dbrename_pp __P((DB_ENV *, DB_TXN *, const char *, const char *, const char *, u_int32_t));
+int __db_rename_pp __P((DB *, const char *, const char *, const char *, u_int32_t));
+int __db_rename_int __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, const char *, u_int32_t));
+int __db_ret __P((DBC *, PAGE *, u_int32_t, DBT *, void **, u_int32_t *));
+int __db_retcopy __P((ENV *, DBT *, void *, u_int32_t, void **, u_int32_t *));
+int __db_dbt_clone __P((ENV *, DBT *, const DBT *));
+int __db_dbt_clone_free __P((ENV *, DBT *));
+int __env_fileid_reset_pp __P((DB_ENV *, const char *, u_int32_t));
+int __env_fileid_reset __P((ENV *, DB_THREAD_INFO *, const char *, int));
+int __env_lsn_reset_pp __P((DB_ENV *, const char *, u_int32_t));
+int __db_lsn_reset __P((DB_MPOOLFILE *, DB_THREAD_INFO *));
+int __db_compare_both __P((DB *, const DBT *, const DBT *, const DBT *, const DBT *));
+int __db_sort_multiple __P((DB *, DBT *, DBT *, u_int32_t));
+int __db_stat_pp __P((DB *, DB_TXN *, void *, u_int32_t));
+int __db_stat_print_pp __P((DB *, u_int32_t));
+int __db_stat_print __P((DB *, DB_THREAD_INFO *, u_int32_t));
+int __db_truncate_pp __P((DB *, DB_TXN *, u_int32_t *, u_int32_t));
+int __db_truncate __P((DB *, DB_THREAD_INFO *, DB_TXN *, u_int32_t *));
+int __db_upgrade_pp __P((DB *, const char *, u_int32_t));
+int __db_upgrade __P((DB *, const char *, u_int32_t));
+int __db_lastpgno __P((DB *, char *, DB_FH *, db_pgno_t *));
+int __db_31_offdup __P((DB *, char *, DB_FH *, int, db_pgno_t *));
+int __db_verify_pp __P((DB *, const char *, const char *, FILE *, u_int32_t));
+int __db_verify_internal __P((DB *, const char *, const char *, void *, int (*)(void *, const void *), u_int32_t));
+int   __db_verify __P((DB *, DB_THREAD_INFO *, const char *, const char *, void *, int (*)(void *, const void *), void *, void *, u_int32_t));
+int  __db_vrfy_common __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
+int __db_vrfy_datapage __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
+int __db_vrfy_meta __P((DB *, VRFY_DBINFO *, DBMETA *, db_pgno_t, u_int32_t));
+void __db_vrfy_struct_feedback __P((DB *, VRFY_DBINFO *));
+int __db_salvage_pg __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, void *, int (*)(void *, const void *), u_int32_t));
+int __db_salvage_leaf __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, void *, int (*)(void *, const void *), u_int32_t));
+int __db_vrfy_inpitem __P((DB *, PAGE *, db_pgno_t, u_int32_t, int, u_int32_t, u_int32_t *, u_int32_t *));
+int __db_vrfy_duptype __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t));
+int __db_salvage_duptree __P((DB *, VRFY_DBINFO *, db_pgno_t, DBT *, void *, int (*)(void *, const void *), u_int32_t));
+int __db_vrfy_dbinfo_create __P((ENV *, DB_THREAD_INFO *, u_int32_t, VRFY_DBINFO **));
+int __db_vrfy_dbinfo_destroy __P((ENV *, VRFY_DBINFO *));
+int __db_vrfy_getpageinfo __P((VRFY_DBINFO *, db_pgno_t, VRFY_PAGEINFO **));
+int __db_vrfy_putpageinfo __P((ENV *, VRFY_DBINFO *, VRFY_PAGEINFO *));
+int __db_vrfy_pgset __P((ENV *, DB_THREAD_INFO *, u_int32_t, DB **));
+int __db_vrfy_pgset_get __P((DB *, DB_THREAD_INFO *, DB_TXN *, db_pgno_t, int *));
+int __db_vrfy_pgset_inc __P((DB *, DB_THREAD_INFO *, DB_TXN *, db_pgno_t));
+int __db_vrfy_pgset_next __P((DBC *, db_pgno_t *));
+int __db_vrfy_childcursor __P((VRFY_DBINFO *, DBC **));
+int __db_vrfy_childput __P((VRFY_DBINFO *, db_pgno_t, VRFY_CHILDINFO *));
+int __db_vrfy_ccset __P((DBC *, db_pgno_t, VRFY_CHILDINFO **));
+int __db_vrfy_ccnext __P((DBC *, VRFY_CHILDINFO **));
+int __db_vrfy_ccclose __P((DBC *));
+int  __db_salvage_init __P((VRFY_DBINFO *));
+int  __db_salvage_destroy __P((VRFY_DBINFO *));
+int __db_salvage_getnext __P((VRFY_DBINFO *, DBC **, db_pgno_t *, u_int32_t *, int));
+int __db_salvage_isdone __P((VRFY_DBINFO *, db_pgno_t));
+int __db_salvage_markdone __P((VRFY_DBINFO *, db_pgno_t));
+int __db_salvage_markneeded __P((VRFY_DBINFO *, db_pgno_t, u_int32_t));
+int __db_vrfy_prdbt __P((DBT *, int, const char *, void *, int (*)(void *, const void *), int, int, VRFY_DBINFO *));
+int __db_lget __P((DBC *, int, db_pgno_t, db_lockmode_t, u_int32_t, DB_LOCK *));
+int __db_lput __P((DBC *, DB_LOCK *));
+int __db_lprint __P((DBC *));
+int __partition_init __P((DB *, u_int32_t));
+int __partition_set __P((DB *, u_int32_t, DBT *, u_int32_t (*callback)(DB *, DBT *key)));
+int __partition_set_dirs __P((DB *, const char **));
+int __partition_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, DBTYPE, u_int32_t, int, int));
+int __partition_get_callback __P((DB *, u_int32_t *, u_int32_t (**callback)(DB *, DBT *key)));
+int __partition_get_keys __P((DB *, u_int32_t *, DBT **));
+int __partition_get_dirs __P((DB *, const char ***));
+int __partc_init __P((DBC *));
+int __partc_get __P((DBC*, DBT *, DBT *, u_int32_t));
+int __partition_close __P((DB *, DB_TXN *, u_int32_t));
+int __partition_sync __P((DB *));
+int __partition_stat __P((DBC *, void *, u_int32_t));
+int __part_truncate __P((DBC *, u_int32_t *));
+int __part_compact __P((DB *, DB_THREAD_INFO *, DB_TXN *, DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *));
+int __part_lsn_reset __P((DB *, DB_THREAD_INFO *));
+int __part_fileid_reset __P((ENV *, DB_THREAD_INFO *, const char *, u_int32_t, int));
+int __part_key_range __P((DBC *, DBT *, DB_KEY_RANGE *, u_int32_t));
+int __part_remove __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, u_int32_t));
+int __part_rename __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, const char *));
+int __part_verify __P((DB *, VRFY_DBINFO *, const char *, void *, int (*)(void *, const void *), u_int32_t));
+int __part_testdocopy __P((DB *, const char *));
+int __db_no_partition __P((ENV *));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_db_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/dbreg_auto.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,68 @@
+/* Do not edit: automatically built by gen_rec.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__dbreg_AUTO_H
+#define	__dbreg_AUTO_H
+#include "dbinc/log.h"
+#define	DB___dbreg_register	2
+typedef struct ___dbreg_register_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	DBT	name;
+	DBT	uid;
+	int32_t	fileid;
+	DBTYPE	ftype;
+	db_pgno_t	meta_pgno;
+	u_int32_t	id;
+} __dbreg_register_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __dbreg_register_desc[];
+static inline int
+__dbreg_register_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t opcode, const DBT *name, const DBT *uid, int32_t fileid, DBTYPE ftype,
+    db_pgno_t meta_pgno, u_int32_t id)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___dbreg_register, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + LOG_DBT_SIZE(name) + LOG_DBT_SIZE(uid) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t),
+	    __dbreg_register_desc,
+	    opcode, name, uid, fileid, ftype, meta_pgno, id));
+}
+
+static inline int __dbreg_register_read(ENV *env, 
+    void *data, __dbreg_register_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __dbreg_register_desc, sizeof(__dbreg_register_args), (void**)arg));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/dbreg_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,72 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_dbreg_ext_h_
+#define	_dbreg_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __dbreg_setup __P((DB *, const char *, const char *, u_int32_t));
+int __dbreg_teardown __P((DB *));
+int __dbreg_teardown_int __P((ENV *, FNAME *));
+int __dbreg_new_id __P((DB *, DB_TXN *));
+int __dbreg_get_id __P((DB *, DB_TXN *, int32_t *));
+int __dbreg_assign_id __P((DB *, int32_t, int));
+int __dbreg_revoke_id __P((DB *, int, int32_t));
+int __dbreg_revoke_id_int __P((ENV *, FNAME *, int, int, int32_t));
+int __dbreg_close_id __P((DB *, DB_TXN *, u_int32_t));
+int __dbreg_close_id_int __P((ENV *, FNAME *, u_int32_t, int));
+int __dbreg_failchk __P((ENV *));
+int __dbreg_log_close __P((ENV *, FNAME *, DB_TXN *, u_int32_t));
+int __dbreg_log_id __P((DB *, DB_TXN *, int32_t, int));
+int __dbreg_init_recover __P((ENV *, DB_DISTAB *));
+int __dbreg_register_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __dbreg_init_print __P((ENV *, DB_DISTAB *));
+int __dbreg_register_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __dbreg_stat_print __P((ENV *, u_int32_t));
+void __dbreg_print_fname __P((ENV *, FNAME *));
+int __dbreg_add_dbentry __P((ENV *, DB_LOG *, DB *, int32_t));
+int __dbreg_rem_dbentry __P((DB_LOG *, int32_t));
+int __dbreg_log_files __P((ENV *, u_int32_t));
+int __dbreg_log_nofiles __P((ENV *));
+int __dbreg_close_files __P((ENV *, int));
+int __dbreg_close_file __P((ENV *, FNAME *));
+int __dbreg_mark_restored __P((ENV *));
+int __dbreg_invalidate_files __P((ENV *, int));
+int __dbreg_id_to_db __P((ENV *, DB_TXN *, DB **, int32_t, int));
+int __dbreg_id_to_fname __P((DB_LOG *, int32_t, int, FNAME **));
+int __dbreg_fid_to_fname __P((DB_LOG *, u_int8_t *, int, FNAME **));
+int __dbreg_get_name __P((ENV *, u_int8_t *, char **, char **));
+int __dbreg_do_open __P((ENV *, DB_TXN *, DB_LOG *, u_int8_t *, char *, DBTYPE, int32_t, db_pgno_t, void *, u_int32_t, u_int32_t));
+int __dbreg_lazy_id __P((DB *));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_dbreg_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/env_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,184 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_env_ext_h_
+#define	_env_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+void __env_alloc_init __P((REGINFO *, size_t));
+size_t __env_alloc_overhead __P((void));
+size_t __env_alloc_size __P((size_t));
+int __env_alloc __P((REGINFO *, size_t, void *));
+void __env_alloc_free __P((REGINFO *, void *));
+int __env_alloc_extend __P((REGINFO *, void *, size_t *));
+int __env_region_extend __P((ENV *, REGINFO *));
+uintmax_t __env_elem_size __P((ENV *, void *));
+void * __env_get_chunk __P((REGINFO *, void **, uintmax_t *));
+void __env_alloc_print __P((REGINFO *, u_int32_t));
+int __env_get_backup_config __P((DB_ENV *, DB_BACKUP_CONFIG, u_int32_t*));
+int __env_set_backup_config __P((DB_ENV *, DB_BACKUP_CONFIG, u_int32_t));
+int __env_get_backup_callbacks __P((DB_ENV *, int (**)(DB_ENV *, const char *, const char *, void **), int (**)(DB_ENV *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), int (**)(DB_ENV *, const char *, void *)));
+int __env_set_backup_callbacks __P((DB_ENV *, int (*)(DB_ENV *, const char *, const char *, void **), int (*)(DB_ENV *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), int (*)(DB_ENV *, const char *, void *)));
+int __env_read_db_config __P((ENV *));
+int __env_failchk_pp __P((DB_ENV *, u_int32_t));
+int __env_failchk_int __P((DB_ENV *));
+size_t __env_thread_size __P((ENV *, size_t));
+size_t __env_thread_max __P((ENV *));
+int __env_thread_init __P((ENV *, int));
+void __env_thread_destroy __P((ENV *));
+int __env_set_state __P((ENV *, DB_THREAD_INFO **, DB_THREAD_STATE));
+int __db_file_extend __P((ENV *, DB_FH *, size_t));
+int __db_file_multi_write __P((ENV *, const char *));
+int __db_file_write __P((ENV *, DB_FH *, u_int32_t, u_int32_t, int));
+void __db_env_destroy __P((DB_ENV *));
+int  __env_get_alloc __P((DB_ENV *, void *(**)(size_t), void *(**)(void *, size_t), void (**)(void *)));
+int  __env_set_alloc __P((DB_ENV *, void *(*)(size_t), void *(*)(void *, size_t), void (*)(void *)));
+int  __env_get_memory_init __P((DB_ENV *, DB_MEM_CONFIG, u_int32_t *));
+int  __env_set_memory_init __P((DB_ENV *, DB_MEM_CONFIG, u_int32_t));
+int  __env_get_memory_max __P((DB_ENV *, u_int32_t *, u_int32_t *));
+int  __env_set_memory_max __P((DB_ENV *, u_int32_t, u_int32_t));
+int __env_get_encrypt_flags __P((DB_ENV *, u_int32_t *));
+int __env_set_encrypt __P((DB_ENV *, const char *, u_int32_t));
+void __env_map_flags __P((const FLAG_MAP *, u_int, u_int32_t *, u_int32_t *));
+void __env_fetch_flags __P((const FLAG_MAP *, u_int, u_int32_t *, u_int32_t *));
+int  __env_set_flags __P((DB_ENV *, u_int32_t, int));
+int __env_set_backup __P((ENV *, int));
+int  __env_set_data_dir __P((DB_ENV *, const char *));
+int  __env_add_data_dir __P((DB_ENV *, const char *));
+int  __env_set_create_dir __P((DB_ENV *, const char *));
+int  __env_set_metadata_dir __P((DB_ENV *, const char *));
+int  __env_set_data_len __P((DB_ENV *, u_int32_t));
+int  __env_set_intermediate_dir_mode __P((DB_ENV *, const char *));
+void __env_get_errcall __P((DB_ENV *, void (**)(const DB_ENV *, const char *, const char *)));
+void __env_set_errcall __P((DB_ENV *, void (*)(const DB_ENV *, const char *, const char *)));
+void __env_get_errfile __P((DB_ENV *, FILE **));
+void __env_set_errfile __P((DB_ENV *, FILE *));
+void __env_get_errpfx __P((DB_ENV *, const char **));
+void __env_set_errpfx __P((DB_ENV *, const char *));
+int  __env_set_thread_count __P((DB_ENV *, u_int32_t));
+void __env_get_msgcall __P((DB_ENV *, void (**)(const DB_ENV *, const char *)));
+void __env_set_msgcall __P((DB_ENV *, void (*)(const DB_ENV *, const char *)));
+void __env_get_msgfile __P((DB_ENV *, FILE **));
+void __env_set_msgfile __P((DB_ENV *, FILE *));
+int  __env_set_paniccall __P((DB_ENV *, void (*)(DB_ENV *, int)));
+int  __env_set_shm_key __P((DB_ENV *, long));
+int  __env_set_tmp_dir __P((DB_ENV *, const char *));
+int  __env_set_verbose __P((DB_ENV *, u_int32_t, int));
+int __db_mi_env __P((ENV *, const char *));
+int __db_mi_open __P((ENV *, const char *, int));
+int __env_not_config __P((ENV *, char *, u_int32_t));
+int __env_set_timeout __P((DB_ENV *, db_timeout_t, u_int32_t));
+char *__env_thread_id_string __P((DB_ENV *, pid_t, db_threadid_t, char *));
+int __db_appname __P((ENV *, APPNAME, const char *, const char **, char **));
+int __db_tmp_open __P((ENV *, u_int32_t, DB_FH **));
+int __env_open_pp __P((DB_ENV *, const char *, u_int32_t, int));
+int __env_open __P((DB_ENV *, const char *, u_int32_t, int));
+int __env_remove __P((DB_ENV *, const char *, u_int32_t));
+int __env_config __P((DB_ENV *, const char *, u_int32_t *, int));
+int __env_close_pp __P((DB_ENV *, u_int32_t));
+int __env_close __P((DB_ENV *, u_int32_t));
+int __env_refresh __P((DB_ENV *, u_int32_t, int));
+int __env_get_open_flags __P((DB_ENV *, u_int32_t *));
+int __env_attach_regions __P((DB_ENV *,  u_int32_t, u_int32_t, int));
+int __db_apprec __P((ENV *, DB_THREAD_INFO *, DB_LSN *, DB_LSN *, int, u_int32_t));
+int __env_openfiles __P((ENV *, DB_LOGC *, void *, DBT *, DB_LSN *, DB_LSN *, double, int));
+int __env_init_rec __P((ENV *, u_int32_t));
+int __env_attach __P((ENV *, u_int32_t *, int, int));
+int __env_turn_on __P((ENV *));
+int __env_turn_off __P((ENV *, u_int32_t));
+void __env_panic_set __P((ENV *, int));
+int __env_ref_increment __P((ENV *));
+int __env_ref_decrement __P((ENV *));
+int __env_ref_get __P((DB_ENV *, u_int32_t *));
+int __env_detach __P((ENV *, int));
+int __env_remove_env __P((ENV *));
+int __env_region_attach __P((ENV *, REGINFO *, size_t, size_t));
+int __env_region_share __P((ENV *, REGINFO *));
+int __env_region_detach __P((ENV *, REGINFO *, int));
+int __envreg_register __P((ENV *, int *, u_int32_t));
+int __envreg_unregister __P((ENV *, int));
+int __envreg_xunlock __P((ENV *));
+int __envreg_isalive __P((DB_ENV *, pid_t, db_threadid_t, u_int32_t));
+u_int32_t __env_struct_sig __P((void));
+int __env_stat_print_pp __P((DB_ENV *, u_int32_t));
+void __db_print_fh __P((ENV *, const char *, DB_FH *, u_int32_t));
+void __db_print_fileid __P((ENV *, u_int8_t *, const char *));
+void __db_dl __P((ENV *, const char *, u_long));
+void __db_dl_pct __P((ENV *, const char *, u_long, int, const char *));
+void __db_dlbytes __P((ENV *, const char *, u_long, u_long, u_long));
+void __db_print_reginfo __P((ENV *, REGINFO *, const char *, u_int32_t));
+int __db_stat_not_built __P((ENV *));
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_close __P((ENV *));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_get_ack_policy __P((DB_ENV *, int *));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_set_ack_policy __P((DB_ENV *, int));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_site __P((DB_ENV *, const char *, u_int, DB_SITE **, u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_site_by_eid __P((DB_ENV *, int, DB_SITE **));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_local_site __P((DB_ENV *, DB_SITE **));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_site_list __P((DB_ENV *, u_int *, DB_REPMGR_SITE **));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_start __P((DB_ENV *, int, u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_stat_pp __P((DB_ENV *, DB_REPMGR_STAT **, u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_stat_print_pp __P((DB_ENV *, u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_handle_event __P((ENV *, u_int32_t, void *));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_channel __P((DB_ENV *, int, DB_CHANNEL **, u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_set_msg_dispatch __P((DB_ENV *, void (*)(DB_ENV *, DB_CHANNEL *, DBT *, u_int32_t, u_int32_t), u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_init_recover __P((ENV *, DB_DISTAB *));
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_env_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/ext_185_def.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,38 @@
+
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_DB_EXT_185_DEF_IN_
+#define	_DB_EXT_185_DEF_IN_
+
+#ifdef _DB185_INT_H_
+#define	__db185_open __db185_open@DB_VERSION_UNIQUE_NAME@
+#else
+#define	__db185_open __db185_open@DB_VERSION_UNIQUE_NAME@
+#endif
+
+#endif /* !_DB_EXT_185_DEF_IN_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/ext_185_prot.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,45 @@
+
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_DB_EXT_185_PROT_IN_
+#define	_DB_EXT_185_PROT_IN_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#ifdef _DB185_INT_H_
+DB185 *__db185_open __P((const char *, int, int, DBTYPE, const void *));
+#else
+DB *__db185_open __P((const char *, int, int, DBTYPE, const void *));
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_EXT_185_PROT_IN_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/ext_def.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,92 @@
+
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_DB_EXT_DEF_IN_
+#define	_DB_EXT_DEF_IN_
+
+#define	db_copy db_copy@DB_VERSION_UNIQUE_NAME@
+#define	db_create db_create@DB_VERSION_UNIQUE_NAME@
+#define	db_strerror db_strerror@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_assert db_env_set_func_assert@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_close db_env_set_func_close@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_dirfree db_env_set_func_dirfree@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_dirlist db_env_set_func_dirlist@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_exists db_env_set_func_exists@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_free db_env_set_func_free@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_fsync db_env_set_func_fsync@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_ftruncate db_env_set_func_ftruncate@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_ioinfo db_env_set_func_ioinfo@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_malloc db_env_set_func_malloc@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_file_map db_env_set_func_file_map@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_region_map db_env_set_func_region_map@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_pread db_env_set_func_pread@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_pwrite db_env_set_func_pwrite@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_open db_env_set_func_open@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_read db_env_set_func_read@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_realloc db_env_set_func_realloc@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_rename db_env_set_func_rename@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_seek db_env_set_func_seek@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_unlink db_env_set_func_unlink@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_write db_env_set_func_write@DB_VERSION_UNIQUE_NAME@
+#define	db_env_set_func_yield db_env_set_func_yield@DB_VERSION_UNIQUE_NAME@
+#define	db_env_create db_env_create@DB_VERSION_UNIQUE_NAME@
+#define	db_version db_version@DB_VERSION_UNIQUE_NAME@
+#define	db_full_version db_full_version@DB_VERSION_UNIQUE_NAME@
+#define	log_compare log_compare@DB_VERSION_UNIQUE_NAME@
+#if defined(DB_WIN32) && !defined(DB_WINCE)
+#define	db_env_set_win_security db_env_set_win_security@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	db_sequence_create db_sequence_create@DB_VERSION_UNIQUE_NAME@
+#if DB_DBM_HSEARCH != 0
+#define	__db_ndbm_clearerr __db_ndbm_clearerr@DB_VERSION_UNIQUE_NAME@
+#define	__db_ndbm_close __db_ndbm_close@DB_VERSION_UNIQUE_NAME@
+#define	__db_ndbm_delete __db_ndbm_delete@DB_VERSION_UNIQUE_NAME@
+#define	__db_ndbm_dirfno __db_ndbm_dirfno@DB_VERSION_UNIQUE_NAME@
+#define	__db_ndbm_error __db_ndbm_error@DB_VERSION_UNIQUE_NAME@
+#define	__db_ndbm_fetch __db_ndbm_fetch@DB_VERSION_UNIQUE_NAME@
+#define	__db_ndbm_firstkey __db_ndbm_firstkey@DB_VERSION_UNIQUE_NAME@
+#define	__db_ndbm_nextkey __db_ndbm_nextkey@DB_VERSION_UNIQUE_NAME@
+#define	__db_ndbm_open __db_ndbm_open@DB_VERSION_UNIQUE_NAME@
+#define	__db_ndbm_pagfno __db_ndbm_pagfno@DB_VERSION_UNIQUE_NAME@
+#define	__db_ndbm_rdonly __db_ndbm_rdonly@DB_VERSION_UNIQUE_NAME@
+#define	__db_ndbm_store __db_ndbm_store@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbm_close __db_dbm_close@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbm_delete __db_dbm_delete@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbm_fetch __db_dbm_fetch@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbm_firstkey __db_dbm_firstkey@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbm_init __db_dbm_init@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbm_nextkey __db_dbm_nextkey@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbm_store __db_dbm_store@DB_VERSION_UNIQUE_NAME@
+#endif
+#if DB_DBM_HSEARCH != 0
+#define	__db_hcreate __db_hcreate@DB_VERSION_UNIQUE_NAME@
+#define	__db_hsearch __db_hsearch@DB_VERSION_UNIQUE_NAME@
+#define	__db_hdestroy __db_hdestroy@DB_VERSION_UNIQUE_NAME@
+#endif
+
+#endif /* !_DB_EXT_DEF_IN_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/ext_prot.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,99 @@
+
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_DB_EXT_PROT_IN_
+#define	_DB_EXT_PROT_IN_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int db_copy __P((DB_ENV *, const char *, const char *, const char *));
+int db_create __P((DB **, DB_ENV *, u_int32_t));
+char *db_strerror __P((int));
+int db_env_set_func_assert __P((void (*)(const char *, const char *, int)));
+int db_env_set_func_close __P((int (*)(int)));
+int db_env_set_func_dirfree __P((void (*)(char **, int)));
+int db_env_set_func_dirlist __P((int (*)(const char *, char ***, int *)));
+int db_env_set_func_exists __P((int (*)(const char *, int *)));
+int db_env_set_func_free __P((void (*)(void *)));
+int db_env_set_func_fsync __P((int (*)(int)));
+int db_env_set_func_ftruncate __P((int (*)(int, off_t)));
+int db_env_set_func_ioinfo __P((int (*)(const char *, int, u_int32_t *, u_int32_t *, u_int32_t *)));
+int db_env_set_func_malloc __P((void *(*)(size_t)));
+int db_env_set_func_file_map __P((int (*)(DB_ENV *, char *, size_t, int, void **), int (*)(DB_ENV *, void *)));
+int db_env_set_func_region_map __P((int (*)(DB_ENV *, char *, size_t, int *, void **), int (*)(DB_ENV *, void *)));
+int db_env_set_func_pread __P((ssize_t (*)(int, void *, size_t, off_t)));
+int db_env_set_func_pwrite __P((ssize_t (*)(int, const void *, size_t, off_t)));
+int db_env_set_func_open __P((int (*)(const char *, int, ...)));
+int db_env_set_func_read __P((ssize_t (*)(int, void *, size_t)));
+int db_env_set_func_realloc __P((void *(*)(void *, size_t)));
+int db_env_set_func_rename __P((int (*)(const char *, const char *)));
+int db_env_set_func_seek __P((int (*)(int, off_t, int)));
+int db_env_set_func_unlink __P((int (*)(const char *)));
+int db_env_set_func_write __P((ssize_t (*)(int, const void *, size_t)));
+int db_env_set_func_yield __P((int (*)(u_long, u_long)));
+int db_env_create __P((DB_ENV **, u_int32_t));
+char *db_version __P((int *, int *, int *));
+char *db_full_version __P((int *, int *, int *, int *, int *));
+int log_compare __P((const DB_LSN *, const DB_LSN *));
+#if defined(DB_WIN32) && !defined(DB_WINCE)
+int db_env_set_win_security __P((SECURITY_ATTRIBUTES *sa));
+#endif
+int db_sequence_create __P((DB_SEQUENCE **, DB *, u_int32_t));
+#if DB_DBM_HSEARCH != 0
+int	 __db_ndbm_clearerr __P((DBM *));
+void	 __db_ndbm_close __P((DBM *));
+int	 __db_ndbm_delete __P((DBM *, datum));
+int	 __db_ndbm_dirfno __P((DBM *));
+int	 __db_ndbm_error __P((DBM *));
+datum __db_ndbm_fetch __P((DBM *, datum));
+datum __db_ndbm_firstkey __P((DBM *));
+datum __db_ndbm_nextkey __P((DBM *));
+DBM	*__db_ndbm_open __P((const char *, int, int));
+int	 __db_ndbm_pagfno __P((DBM *));
+int	 __db_ndbm_rdonly __P((DBM *));
+int	 __db_ndbm_store __P((DBM *, datum, datum, int));
+int	 __db_dbm_close __P((void));
+int	 __db_dbm_delete __P((datum));
+datum __db_dbm_fetch __P((datum));
+datum __db_dbm_firstkey __P((void));
+int	 __db_dbm_init __P((char *));
+datum __db_dbm_nextkey __P((datum));
+int	 __db_dbm_store __P((datum, datum));
+#endif
+#if DB_DBM_HSEARCH != 0
+int __db_hcreate __P((size_t));
+ENTRY *__db_hsearch __P((ENTRY, ACTION));
+void __db_hdestroy __P((void));
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_EXT_PROT_IN_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/fileops_auto.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,287 @@
+/* Do not edit: automatically built by gen_rec.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__fop_AUTO_H
+#define	__fop_AUTO_H
+#include "dbinc/log.h"
+#define	DB___fop_create_42	143
+typedef struct ___fop_create_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DBT	name;
+	u_int32_t	appname;
+	u_int32_t	mode;
+} __fop_create_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __fop_create_42_desc[];
+static inline int __fop_create_42_read(ENV *env, 
+    void *data, __fop_create_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __fop_create_42_desc, sizeof(__fop_create_42_args), (void**)arg));
+}
+#define	DB___fop_create	143
+typedef struct ___fop_create_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DBT	name;
+	DBT	dirname;
+	u_int32_t	appname;
+	u_int32_t	mode;
+} __fop_create_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __fop_create_desc[];
+static inline int
+__fop_create_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    const DBT *name, const DBT *dirname, u_int32_t appname, u_int32_t mode)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___fop_create, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    LOG_DBT_SIZE(name) + LOG_DBT_SIZE(dirname) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t),
+	    __fop_create_desc,
+	    name, dirname, appname, mode));
+}
+
+static inline int __fop_create_read(ENV *env, 
+    void *data, __fop_create_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __fop_create_desc, sizeof(__fop_create_args), (void**)arg));
+}
+#define	DB___fop_remove	144
+typedef struct ___fop_remove_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DBT	name;
+	DBT	fid;
+	u_int32_t	appname;
+} __fop_remove_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __fop_remove_desc[];
+static inline int
+__fop_remove_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    const DBT *name, const DBT *fid, u_int32_t appname)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___fop_remove, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    LOG_DBT_SIZE(name) + LOG_DBT_SIZE(fid) + sizeof(u_int32_t),
+	    __fop_remove_desc,
+	    name, fid, appname));
+}
+
+static inline int __fop_remove_read(ENV *env, 
+    void *data, __fop_remove_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __fop_remove_desc, sizeof(__fop_remove_args), (void**)arg));
+}
+#define	DB___fop_write_42	145
+typedef struct ___fop_write_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DBT	name;
+	u_int32_t	appname;
+	u_int32_t	pgsize;
+	db_pgno_t	pageno;
+	u_int32_t	offset;
+	DBT	page;
+	u_int32_t	flag;
+} __fop_write_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __fop_write_42_desc[];
+static inline int __fop_write_42_read(ENV *env, 
+    void *data, __fop_write_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __fop_write_42_desc, sizeof(__fop_write_42_args), (void**)arg));
+}
+#define	DB___fop_write	145
+typedef struct ___fop_write_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DBT	name;
+	DBT	dirname;
+	u_int32_t	appname;
+	u_int32_t	pgsize;
+	db_pgno_t	pageno;
+	u_int32_t	offset;
+	DBT	page;
+	u_int32_t	flag;
+} __fop_write_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __fop_write_desc[];
+static inline int
+__fop_write_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    const DBT *name, const DBT *dirname, u_int32_t appname, u_int32_t pgsize, db_pgno_t pageno,
+    u_int32_t offset, const DBT *page, u_int32_t flag)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___fop_write, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    LOG_DBT_SIZE(name) + LOG_DBT_SIZE(dirname) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    LOG_DBT_SIZE(page) + sizeof(u_int32_t),
+	    __fop_write_desc,
+	    name, dirname, appname, pgsize, pageno, offset, page, flag));
+}
+
+static inline int __fop_write_read(ENV *env, 
+    void *data, __fop_write_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __fop_write_desc, sizeof(__fop_write_args), (void**)arg));
+}
+#define	DB___fop_rename_42	146
+#define	DB___fop_rename_noundo_46	150
+typedef struct ___fop_rename_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DBT	oldname;
+	DBT	newname;
+	DBT	fileid;
+	u_int32_t	appname;
+} __fop_rename_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __fop_rename_42_desc[];
+static inline int __fop_rename_42_read(ENV *env, 
+    void *data, __fop_rename_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __fop_rename_42_desc, sizeof(__fop_rename_42_args), (void**)arg));
+}
+extern __DB_IMPORT DB_LOG_RECSPEC __fop_rename_noundo_46_desc[];
+static inline int __fop_rename_noundo_46_read(ENV *env, 
+    void *data, __fop_rename_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __fop_rename_noundo_46_desc, sizeof(__fop_rename_42_args), (void**)arg));
+}
+#define	DB___fop_rename	146
+#define	DB___fop_rename_noundo	150
+typedef struct ___fop_rename_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DBT	oldname;
+	DBT	newname;
+	DBT	dirname;
+	DBT	fileid;
+	u_int32_t	appname;
+} __fop_rename_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __fop_rename_desc[];
+static inline int
+__fop_rename_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    const DBT *oldname, const DBT *newname, const DBT *dirname, const DBT *fileid, u_int32_t appname)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___fop_rename, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    LOG_DBT_SIZE(oldname) + LOG_DBT_SIZE(newname) + LOG_DBT_SIZE(dirname) +
+	    LOG_DBT_SIZE(fileid) + sizeof(u_int32_t),
+	    __fop_rename_desc,
+	    oldname, newname, dirname, fileid, appname));
+}
+
+static inline int __fop_rename_read(ENV *env, 
+    void *data, __fop_rename_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __fop_rename_desc, sizeof(__fop_rename_args), (void**)arg));
+}
+extern __DB_IMPORT DB_LOG_RECSPEC __fop_rename_noundo_desc[];
+static inline int
+__fop_rename_noundo_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    const DBT *oldname, const DBT *newname, const DBT *dirname, const DBT *fileid, u_int32_t appname)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___fop_rename_noundo, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    LOG_DBT_SIZE(oldname) + LOG_DBT_SIZE(newname) + LOG_DBT_SIZE(dirname) +
+	    LOG_DBT_SIZE(fileid) + sizeof(u_int32_t),
+	    __fop_rename_noundo_desc,
+	    oldname, newname, dirname, fileid, appname));
+}
+
+static inline int __fop_rename_noundo_read(ENV *env, 
+    void *data, __fop_rename_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __fop_rename_noundo_desc, sizeof(__fop_rename_args), (void**)arg));
+}
+#define	DB___fop_file_remove	141
+typedef struct ___fop_file_remove_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DBT	real_fid;
+	DBT	tmp_fid;
+	DBT	name;
+	u_int32_t	appname;
+	u_int32_t	child;
+} __fop_file_remove_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __fop_file_remove_desc[];
+static inline int
+__fop_file_remove_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    const DBT *real_fid, const DBT *tmp_fid, const DBT *name, u_int32_t appname, u_int32_t child)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___fop_file_remove, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    LOG_DBT_SIZE(real_fid) + LOG_DBT_SIZE(tmp_fid) + LOG_DBT_SIZE(name) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __fop_file_remove_desc,
+	    real_fid, tmp_fid, name, appname, child));
+}
+
+static inline int __fop_file_remove_read(ENV *env, 
+    void *data, __fop_file_remove_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __fop_file_remove_desc, sizeof(__fop_file_remove_args), (void**)arg));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/fileops_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,70 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_fileops_ext_h_
+#define	_fileops_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __fop_init_recover __P((ENV *, DB_DISTAB *));
+int __fop_create_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_create_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_remove_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_write_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_write_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_rename_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_rename_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_file_remove_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_init_print __P((ENV *, DB_DISTAB *));
+int __fop_create __P((ENV *, DB_TXN *, DB_FH **, const char *, const char **, APPNAME, int, u_int32_t));
+int __fop_remove __P((ENV *, DB_TXN *, u_int8_t *, const char *, const char **, APPNAME, u_int32_t));
+int __fop_write __P((ENV *, DB_TXN *, const char *, const char *, APPNAME, DB_FH *, u_int32_t, db_pgno_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t));
+int __fop_rename __P((ENV *, DB_TXN *, const char *, const char *, const char **, u_int8_t *, APPNAME, int, u_int32_t));
+int __fop_create_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_create_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_remove_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_write_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_write_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_rename_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_rename_noundo_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_rename_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_rename_noundo_46_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_file_remove_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_lock_handle __P((ENV *, DB *, DB_LOCKER *, db_lockmode_t, DB_LOCK *, u_int32_t));
+int __fop_file_setup __P((DB *, DB_THREAD_INFO *ip, DB_TXN *, const char *, int, u_int32_t, u_int32_t *));
+int __fop_subdb_setup __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, int, u_int32_t));
+int __fop_remove_setup __P((DB *, DB_TXN *, const char *, u_int32_t));
+int __fop_read_meta __P((ENV *, const char *, u_int8_t *, size_t, DB_FH *, int, size_t *));
+int __fop_dummy __P((DB *, DB_TXN *, const char *, const char *));
+int __fop_dbrename __P((DB *, const char *, const char *));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_fileops_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/hash_auto.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,509 @@
+/* Do not edit: automatically built by gen_rec.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__ham_AUTO_H
+#define	__ham_AUTO_H
+#ifdef HAVE_HASH
+#include "dbinc/log.h"
+#define	DB___ham_insdel	21
+typedef struct ___ham_insdel_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	u_int32_t	ndx;
+	DB_LSN	pagelsn;
+	u_int32_t	keytype;
+	DBT	key;
+	u_int32_t	datatype;
+	DBT	data;
+} __ham_insdel_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_insdel_desc[];
+static inline int
+__ham_insdel_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t opcode, db_pgno_t pgno, u_int32_t ndx, DB_LSN * pagelsn,
+    u_int32_t keytype, const DBT *key, u_int32_t datatype, const DBT *data)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___ham_insdel, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(*pagelsn) + sizeof(u_int32_t) +
+	    LOG_DBT_SIZE(key) + sizeof(u_int32_t) + LOG_DBT_SIZE(data),
+	    __ham_insdel_desc,
+	    opcode, pgno, ndx, pagelsn, keytype, key, datatype,
+	    data));
+}
+
+static inline int __ham_insdel_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_insdel_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_insdel_desc, sizeof(__ham_insdel_args), (void**)arg));
+}
+#define	DB___ham_insdel_42	21
+typedef struct ___ham_insdel_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	u_int32_t	ndx;
+	DB_LSN	pagelsn;
+	DBT	key;
+	DBT	data;
+} __ham_insdel_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_insdel_42_desc[];
+static inline int __ham_insdel_42_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_insdel_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_insdel_42_desc, sizeof(__ham_insdel_42_args), (void**)arg));
+}
+#define	DB___ham_newpage	22
+typedef struct ___ham_newpage_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	fileid;
+	db_pgno_t	prev_pgno;
+	DB_LSN	prevlsn;
+	db_pgno_t	new_pgno;
+	DB_LSN	pagelsn;
+	db_pgno_t	next_pgno;
+	DB_LSN	nextlsn;
+} __ham_newpage_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_newpage_desc[];
+static inline int
+__ham_newpage_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t opcode, db_pgno_t prev_pgno, DB_LSN * prevlsn, db_pgno_t new_pgno,
+    DB_LSN * pagelsn, db_pgno_t next_pgno, DB_LSN * nextlsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___ham_newpage, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(*prevlsn) + sizeof(u_int32_t) + sizeof(*pagelsn) +
+	    sizeof(u_int32_t) + sizeof(*nextlsn),
+	    __ham_newpage_desc,
+	    opcode, prev_pgno, prevlsn, new_pgno, pagelsn, next_pgno, nextlsn));
+}
+
+static inline int __ham_newpage_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_newpage_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_newpage_desc, sizeof(__ham_newpage_args), (void**)arg));
+}
+#define	DB___ham_splitdata	24
+typedef struct ___ham_splitdata_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	u_int32_t	opcode;
+	db_pgno_t	pgno;
+	DBT	pageimage;
+	DB_LSN	pagelsn;
+} __ham_splitdata_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_splitdata_desc[];
+static inline int
+__ham_splitdata_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, u_int32_t opcode, db_pgno_t pgno, const DBT *pageimage, DB_LSN * pagelsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___ham_splitdata, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    LOG_DBT_SIZE(pageimage) + sizeof(*pagelsn),
+	    __ham_splitdata_desc, opcode, pgno, pageimage, pagelsn));
+}
+
+static inline int __ham_splitdata_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_splitdata_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_splitdata_desc, sizeof(__ham_splitdata_args), (void**)arg));
+}
+#define	DB___ham_replace	25
+typedef struct ___ham_replace_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	u_int32_t	ndx;
+	DB_LSN	pagelsn;
+	int32_t	off;
+	u_int32_t	oldtype;
+	DBT	olditem;
+	u_int32_t	newtype;
+	DBT	newitem;
+} __ham_replace_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_replace_desc[];
+static inline int
+__ham_replace_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, u_int32_t ndx, DB_LSN * pagelsn, int32_t off,
+    u_int32_t oldtype, const DBT *olditem, u_int32_t newtype, const DBT *newitem)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___ham_replace, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(*pagelsn) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    LOG_DBT_SIZE(olditem) + sizeof(u_int32_t) + LOG_DBT_SIZE(newitem),
+	    __ham_replace_desc, pgno, ndx, pagelsn, off, oldtype, olditem, newtype,
+	    newitem));
+}
+
+static inline int __ham_replace_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_replace_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_replace_desc, sizeof(__ham_replace_args), (void**)arg));
+}
+#define	DB___ham_replace_42	25
+typedef struct ___ham_replace_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	u_int32_t	ndx;
+	DB_LSN	pagelsn;
+	int32_t	off;
+	DBT	olditem;
+	DBT	newitem;
+	u_int32_t	makedup;
+} __ham_replace_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_replace_42_desc[];
+static inline int __ham_replace_42_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_replace_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_replace_42_desc, sizeof(__ham_replace_42_args), (void**)arg));
+}
+#define	DB___ham_copypage	28
+typedef struct ___ham_copypage_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DB_LSN	pagelsn;
+	db_pgno_t	next_pgno;
+	DB_LSN	nextlsn;
+	db_pgno_t	nnext_pgno;
+	DB_LSN	nnextlsn;
+	DBT	page;
+} __ham_copypage_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_copypage_desc[];
+static inline int
+__ham_copypage_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, DB_LSN * pagelsn, db_pgno_t next_pgno, DB_LSN * nextlsn,
+    db_pgno_t nnext_pgno, DB_LSN * nnextlsn, const DBT *page)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___ham_copypage, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*pagelsn) +
+	    sizeof(u_int32_t) + sizeof(*nextlsn) + sizeof(u_int32_t) +
+	    sizeof(*nnextlsn) + LOG_DBT_SIZE(page),
+	    __ham_copypage_desc, pgno, pagelsn, next_pgno, nextlsn, nnext_pgno, nnextlsn, page));
+}
+
+static inline int __ham_copypage_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_copypage_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_copypage_desc, sizeof(__ham_copypage_args), (void**)arg));
+}
+#define	DB___ham_metagroup_42	29
+typedef struct ___ham_metagroup_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	u_int32_t	bucket;
+	db_pgno_t	mmpgno;
+	DB_LSN	mmetalsn;
+	db_pgno_t	mpgno;
+	DB_LSN	metalsn;
+	db_pgno_t	pgno;
+	DB_LSN	pagelsn;
+	u_int32_t	newalloc;
+} __ham_metagroup_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_metagroup_42_desc[];
+static inline int __ham_metagroup_42_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_metagroup_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_metagroup_42_desc, sizeof(__ham_metagroup_42_args), (void**)arg));
+}
+#define	DB___ham_metagroup	29
+typedef struct ___ham_metagroup_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	u_int32_t	bucket;
+	db_pgno_t	mmpgno;
+	DB_LSN	mmetalsn;
+	db_pgno_t	mpgno;
+	DB_LSN	metalsn;
+	db_pgno_t	pgno;
+	DB_LSN	pagelsn;
+	u_int32_t	newalloc;
+	db_pgno_t	last_pgno;
+} __ham_metagroup_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_metagroup_desc[];
+static inline int
+__ham_metagroup_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, u_int32_t bucket, db_pgno_t mmpgno, DB_LSN * mmetalsn, db_pgno_t mpgno,
+    DB_LSN * metalsn, db_pgno_t pgno, DB_LSN * pagelsn, u_int32_t newalloc, db_pgno_t last_pgno)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___ham_metagroup, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(*mmetalsn) + sizeof(u_int32_t) + sizeof(*metalsn) +
+	    sizeof(u_int32_t) + sizeof(*pagelsn) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t),
+	    __ham_metagroup_desc, bucket, mmpgno, mmetalsn, mpgno, metalsn, pgno, pagelsn,
+	    newalloc, last_pgno));
+}
+
+static inline int __ham_metagroup_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_metagroup_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_metagroup_desc, sizeof(__ham_metagroup_args), (void**)arg));
+}
+#define	DB___ham_groupalloc_42	32
+typedef struct ___ham_groupalloc_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	DB_LSN	meta_lsn;
+	db_pgno_t	start_pgno;
+	u_int32_t	num;
+	db_pgno_t	free;
+} __ham_groupalloc_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_groupalloc_42_desc[];
+static inline int __ham_groupalloc_42_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_groupalloc_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_groupalloc_42_desc, sizeof(__ham_groupalloc_42_args), (void**)arg));
+}
+#define	DB___ham_groupalloc	32
+typedef struct ___ham_groupalloc_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	DB_LSN	meta_lsn;
+	db_pgno_t	start_pgno;
+	u_int32_t	num;
+	db_pgno_t	unused;
+	db_pgno_t	last_pgno;
+} __ham_groupalloc_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_groupalloc_desc[];
+static inline int
+__ham_groupalloc_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, DB_LSN * meta_lsn, db_pgno_t start_pgno, u_int32_t num, db_pgno_t unused,
+    db_pgno_t last_pgno)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___ham_groupalloc, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(*meta_lsn) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __ham_groupalloc_desc, meta_lsn, start_pgno, num, unused, last_pgno));
+}
+
+static inline int __ham_groupalloc_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_groupalloc_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_groupalloc_desc, sizeof(__ham_groupalloc_args), (void**)arg));
+}
+#define	DB___ham_changeslot	35
+typedef struct ___ham_changeslot_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	DB_LSN	meta_lsn;
+	u_int32_t	slot;
+	db_pgno_t	old;
+	db_pgno_t	new;
+} __ham_changeslot_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_changeslot_desc[];
+static inline int
+__ham_changeslot_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, DB_LSN * meta_lsn, u_int32_t slot, db_pgno_t old, db_pgno_t new)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___ham_changeslot, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(*meta_lsn) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __ham_changeslot_desc, meta_lsn, slot, old, new));
+}
+
+static inline int __ham_changeslot_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_changeslot_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_changeslot_desc, sizeof(__ham_changeslot_args), (void**)arg));
+}
+#define	DB___ham_contract	37
+typedef struct ___ham_contract_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	meta;
+	DB_LSN	meta_lsn;
+	u_int32_t	bucket;
+	db_pgno_t	pgno;
+} __ham_contract_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_contract_desc[];
+static inline int
+__ham_contract_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t meta, DB_LSN * meta_lsn, u_int32_t bucket, db_pgno_t pgno)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___ham_contract, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(*meta_lsn) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __ham_contract_desc, meta, meta_lsn, bucket, pgno));
+}
+
+static inline int __ham_contract_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_contract_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_contract_desc, sizeof(__ham_contract_args), (void**)arg));
+}
+#define	DB___ham_curadj	33
+typedef struct ___ham_curadj_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	u_int32_t	indx;
+	u_int32_t	len;
+	u_int32_t	dup_off;
+	int	add;
+	int	is_dup;
+	u_int32_t	order;
+} __ham_curadj_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_curadj_desc[];
+static inline int
+__ham_curadj_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, u_int32_t indx, u_int32_t len, u_int32_t dup_off,
+    int add, int is_dup, u_int32_t order)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___ham_curadj, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __ham_curadj_desc, pgno, indx, len, dup_off, add, is_dup, order));
+}
+
+static inline int __ham_curadj_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_curadj_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_curadj_desc, sizeof(__ham_curadj_args), (void**)arg));
+}
+#define	DB___ham_chgpg	34
+typedef struct ___ham_chgpg_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_ham_mode	mode;
+	db_pgno_t	old_pgno;
+	db_pgno_t	new_pgno;
+	u_int32_t	old_indx;
+	u_int32_t	new_indx;
+} __ham_chgpg_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __ham_chgpg_desc[];
+static inline int
+__ham_chgpg_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_ham_mode mode, db_pgno_t old_pgno, db_pgno_t new_pgno, u_int32_t old_indx,
+    u_int32_t new_indx)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___ham_chgpg, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __ham_chgpg_desc, mode, old_pgno, new_pgno, old_indx, new_indx));
+}
+
+static inline int __ham_chgpg_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __ham_chgpg_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __ham_chgpg_desc, sizeof(__ham_chgpg_args), (void**)arg));
+}
+#endif /* HAVE_HASH */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/hash_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,155 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_hash_ext_h_
+#define	_hash_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __ham_quick_delete __P((DBC *));
+int __hamc_init __P((DBC *));
+int __hamc_count __P((DBC *, db_recno_t *));
+int __hamc_cmp __P((DBC *, DBC *, int *));
+int __hamc_dup __P((DBC *, DBC *));
+int  __ham_contract_table __P((DBC *, DB_COMPACT *));
+u_int32_t __ham_call_hash __P((DBC *, u_int8_t *, u_int32_t));
+int  __ham_overwrite __P((DBC *, DBT *, u_int32_t));
+int  __ham_lookup __P((DBC *, const DBT *, u_int32_t, db_lockmode_t, db_pgno_t *));
+int __ham_init_dbt __P((ENV *, DBT *, u_int32_t, void **, u_int32_t *));
+int __hamc_update __P((DBC *, u_int32_t, db_ham_curadj, int));
+int __ham_get_clist __P((DB *, db_pgno_t, u_int32_t, DBC ***));
+int __ham_init_recover __P((ENV *, DB_DISTAB *));
+int __ham_insdel_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_insdel_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_newpage_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_splitdata_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_replace_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_replace_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_copypage_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_metagroup_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_metagroup_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_groupalloc_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_groupalloc_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_changeslot_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_contract_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_curadj_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_chgpg_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_init_print __P((ENV *, DB_DISTAB *));
+int __ham_compact_int __P((DBC *, DBT *, DBT *, u_int32_t, DB_COMPACT *, int *, u_int32_t));
+int __ham_compact_bucket __P((DBC *, DB_COMPACT *, int *));
+int __ham_compact_hash __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB_COMPACT *));
+int __ham_pgin __P((DB *, db_pgno_t, void *, DBT *));
+int __ham_pgout __P((DB *, db_pgno_t, void *, DBT *));
+int __ham_mswap __P((ENV *, void *));
+int __ham_add_dup __P((DBC *, DBT *, u_int32_t, db_pgno_t *));
+int __ham_dup_convert __P((DBC *));
+int __ham_make_dup __P((ENV *, const DBT *, DBT *d, void **, u_int32_t *));
+void __ham_dsearch __P((DBC *, DBT *, u_int32_t *, int *, u_int32_t));
+u_int32_t __ham_func2 __P((DB *, const void *, u_int32_t));
+u_int32_t __ham_func3 __P((DB *, const void *, u_int32_t));
+u_int32_t __ham_func4 __P((DB *, const void *, u_int32_t));
+u_int32_t __ham_func5 __P((DB *, const void *, u_int32_t));
+u_int32_t __ham_test __P((DB *, const void *, u_int32_t));
+int __ham_get_meta __P((DBC *));
+int __ham_release_meta __P((DBC *));
+int __ham_dirty_meta __P((DBC *, u_int32_t));
+int __ham_return_meta __P((DBC *, u_int32_t, DBMETA **));
+int __ham_db_create __P((DB *));
+int __ham_db_close __P((DB *));
+int __ham_get_h_ffactor __P((DB *, u_int32_t *));
+int __ham_set_h_compare __P((DB *, int (*)(DB *, const DBT *, const DBT *)));
+int __ham_get_h_nelem __P((DB *, u_int32_t *));
+void __ham_copy_config __P((DB *, DB*, u_int32_t));
+int __ham_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char * name, db_pgno_t, u_int32_t));
+int __ham_metachk __P((DB *, const char *, HMETA *));
+int __ham_new_file __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *));
+int __ham_new_subdb __P((DB *, DB *, DB_THREAD_INFO *, DB_TXN *));
+int __ham_item __P((DBC *, db_lockmode_t, db_pgno_t *));
+int __ham_item_reset __P((DBC *));
+int __ham_item_init __P((DBC *));
+int __ham_item_last __P((DBC *, db_lockmode_t, db_pgno_t *));
+int __ham_item_first __P((DBC *, db_lockmode_t, db_pgno_t *));
+int __ham_item_prev __P((DBC *, db_lockmode_t, db_pgno_t *));
+int __ham_item_next __P((DBC *, db_lockmode_t, db_pgno_t *));
+int __ham_insertpair __P((DBC *, PAGE *p, db_indx_t *indxp, const DBT *, const DBT *, u_int32_t, u_int32_t));
+int __ham_getindex __P((DBC *, PAGE *, const DBT *, u_int32_t, int *, db_indx_t *));
+int __ham_verify_sorted_page __P((DBC *, PAGE *));
+int __ham_sort_page_cursor __P((DBC *, PAGE *));
+int __ham_sort_page __P((DBC *,  PAGE **, PAGE *));
+int __ham_del_pair __P((DBC *, int, PAGE *));
+int __ham_replpair __P((DBC *, DBT *, u_int32_t));
+void __ham_onpage_replace __P((DB *, PAGE *, u_int32_t, int32_t, u_int32_t,  int, DBT *));
+int __ham_merge_pages __P((DBC *, u_int32_t, u_int32_t, DB_COMPACT *));
+int __ham_split_page __P((DBC *, u_int32_t, u_int32_t));
+int __ham_add_el __P((DBC *, const DBT *, const DBT *, u_int32_t));
+int __ham_copypair __P((DBC *, PAGE *, u_int32_t, PAGE *, db_indx_t *, int));
+int __ham_add_ovflpage __P((DBC *, PAGE **));
+int __ham_get_cpage __P((DBC *, db_lockmode_t));
+int __ham_next_cpage __P((DBC *, db_pgno_t));
+int __ham_lock_bucket __P((DBC *, db_lockmode_t));
+void __ham_dpair __P((DB *, PAGE *, u_int32_t));
+int __ham_insdel_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_insdel_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_newpage_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_replace_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_replace_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_splitdata_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_copypage_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_metagroup_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_contract_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_groupalloc_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_changeslot_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_curadj_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_chgpg_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_metagroup_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_groupalloc_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_reclaim __P((DB *, DB_THREAD_INFO *, DB_TXN *txn, u_int32_t));
+int __ham_truncate __P((DBC *, u_int32_t *));
+int __ham_stat __P((DBC *, void *, u_int32_t));
+int __ham_stat_print __P((DBC *, u_int32_t));
+void __ham_print_cursor __P((DBC *));
+int __ham_traverse __P((DBC *, db_lockmode_t, int (*)(DBC *, PAGE *, void *, int *), void *, int));
+int __db_no_hash_am __P((ENV *));
+int __ham_30_hashmeta __P((DB *, char *, u_int8_t *));
+int __ham_30_sizefix __P((DB *, DB_FH *, char *, u_int8_t *));
+int __ham_31_hashmeta __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
+int __ham_31_hash __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
+int __ham_46_hashmeta __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
+int __ham_46_hash __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *));
+int __ham_vrfy_meta __P((DB *, VRFY_DBINFO *, HMETA *, db_pgno_t, u_int32_t));
+int __ham_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
+int __ham_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t));
+int __ham_vrfy_hashing __P((DBC *, u_int32_t, HMETA *, u_int32_t, db_pgno_t, u_int32_t, u_int32_t (*) __P((DB *, const void *, u_int32_t))));
+int __ham_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, void *, int (*)(void *, const void *), u_int32_t));
+int __ham_meta2pgset __P((DB *, VRFY_DBINFO *, HMETA *, u_int32_t, DB *));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_hash_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/heap_auto.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,194 @@
+/* Do not edit: automatically built by gen_rec.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__heap_AUTO_H
+#define	__heap_AUTO_H
+#ifdef HAVE_HEAP
+#include "dbinc/log.h"
+#define	DB___heap_addrem	151
+typedef struct ___heap_addrem_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	u_int32_t	indx;
+	u_int32_t	nbytes;
+	DBT	hdr;
+	DBT	dbt;
+	DB_LSN	pagelsn;
+} __heap_addrem_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __heap_addrem_desc[];
+static inline int
+__heap_addrem_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t opcode, db_pgno_t pgno, u_int32_t indx, u_int32_t nbytes,
+    const DBT *hdr, const DBT *dbt, DB_LSN * pagelsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___heap_addrem, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(hdr) +
+	    LOG_DBT_SIZE(dbt) + sizeof(*pagelsn),
+	    __heap_addrem_desc,
+	    opcode, pgno, indx, nbytes, hdr, dbt, pagelsn));
+}
+
+static inline int __heap_addrem_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __heap_addrem_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __heap_addrem_desc, sizeof(__heap_addrem_args), (void**)arg));
+}
+#define	DB___heap_addrem_50	151
+typedef struct ___heap_addrem_50_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	u_int32_t	indx;
+	u_int32_t	nbytes;
+	DBT	hdr;
+	DBT	dbt;
+	DB_LSN	pagelsn;
+} __heap_addrem_50_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __heap_addrem_50_desc[];
+static inline int __heap_addrem_50_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __heap_addrem_50_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __heap_addrem_50_desc, sizeof(__heap_addrem_50_args), (void**)arg));
+}
+#define	DB___heap_pg_alloc	152
+typedef struct ___heap_pg_alloc_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	DB_LSN	meta_lsn;
+	db_pgno_t	meta_pgno;
+	db_pgno_t	pgno;
+	u_int32_t	ptype;
+	db_pgno_t	last_pgno;
+} __heap_pg_alloc_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __heap_pg_alloc_desc[];
+static inline int
+__heap_pg_alloc_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, DB_LSN * meta_lsn, db_pgno_t meta_pgno, db_pgno_t pgno, u_int32_t ptype,
+    db_pgno_t last_pgno)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___heap_pg_alloc, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(*meta_lsn) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __heap_pg_alloc_desc, meta_lsn, meta_pgno, pgno, ptype, last_pgno));
+}
+
+static inline int __heap_pg_alloc_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __heap_pg_alloc_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __heap_pg_alloc_desc, sizeof(__heap_pg_alloc_args), (void**)arg));
+}
+#define	DB___heap_trunc_meta	153
+typedef struct ___heap_trunc_meta_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	u_int32_t	last_pgno;
+	u_int32_t	key_count;
+	u_int32_t	record_count;
+	u_int32_t	curregion;
+	u_int32_t	nregions;
+	DB_LSN	pagelsn;
+} __heap_trunc_meta_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __heap_trunc_meta_desc[];
+static inline int
+__heap_trunc_meta_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, u_int32_t last_pgno, u_int32_t key_count, u_int32_t record_count,
+    u_int32_t curregion, u_int32_t nregions, DB_LSN * pagelsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___heap_trunc_meta, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(*pagelsn),
+	    __heap_trunc_meta_desc, pgno, last_pgno, key_count, record_count, curregion, nregions, pagelsn));
+}
+
+static inline int __heap_trunc_meta_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __heap_trunc_meta_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __heap_trunc_meta_desc, sizeof(__heap_trunc_meta_args), (void**)arg));
+}
+#define	DB___heap_trunc_page	154
+typedef struct ___heap_trunc_page_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_pgno_t	pgno;
+	DBT	old_data;
+	u_int32_t	is_region;
+	DB_LSN	pagelsn;
+} __heap_trunc_page_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __heap_trunc_page_desc[];
+static inline int
+__heap_trunc_page_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_pgno_t pgno, const DBT *old_data, u_int32_t is_region, DB_LSN * pagelsn)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___heap_trunc_page, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(old_data) +
+	    sizeof(u_int32_t) + sizeof(*pagelsn),
+	    __heap_trunc_page_desc, pgno, old_data, is_region, pagelsn));
+}
+
+static inline int __heap_trunc_page_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __heap_trunc_page_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __heap_trunc_page_desc, sizeof(__heap_trunc_page_args), (void**)arg));
+}
+#endif /* HAVE_HEAP */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/heap_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,86 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_heap_ext_h_
+#define	_heap_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __heapc_init __P((DBC *));
+int __heap_ditem __P((DBC *, PAGE *, u_int32_t, u_int32_t));
+int __heap_append __P((DBC *, DBT *, DBT *));
+int __heap_pitem __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *));
+int __heapc_dup __P((DBC *, DBC *));
+int __heapc_gsplit __P((DBC *, DBT *, void **, u_int32_t *));
+int __heapc_refresh __P((DBC *));
+int __heap_init_recover __P((ENV *, DB_DISTAB *));
+int __heap_addrem_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_addrem_50_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_pg_alloc_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_trunc_meta_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_trunc_page_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_init_print __P((ENV *, DB_DISTAB *));
+int __heap_backup __P((DB_ENV *, DB *, DB_THREAD_INFO *, DB_FH *, void *, u_int32_t));
+int __heap_pgin __P((DB *, db_pgno_t, void *, DBT *));
+int __heap_pgout __P((DB *, db_pgno_t, void *, DBT *));
+int __heap_mswap __P((ENV *, PAGE *));
+int __heap_db_create __P((DB *));
+int __heap_db_close __P((DB *));
+int __heap_get_heapsize __P((DB *, u_int32_t *, u_int32_t *));
+int __heap_get_heap_regionsize __P((DB *, u_int32_t *));
+int __heap_set_heapsize __P((DB *, u_int32_t, u_int32_t, u_int32_t));
+int __heap_set_heap_regionsize __P((DB *, u_int32_t));
+int __heap_exist __P((void));
+int __heap_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, db_pgno_t, u_int32_t));
+int __heap_metachk __P((DB *, const char *, HEAPMETA *));
+int __heap_read_meta __P((DB *, DB_THREAD_INFO *, DB_TXN *, db_pgno_t, u_int32_t));
+int __heap_new_file __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *));
+int __heap_create_region __P((DBC *, db_pgno_t));
+int __heap_addrem_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_pg_alloc_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_trunc_meta_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_trunc_page_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_addrem_50_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_truncate __P((DBC *, u_int32_t *));
+int __heap_stat __P((DBC *, void *, u_int32_t));
+int __heap_stat_print __P((DBC *, u_int32_t));
+void __heap_print_cursor __P((DBC *));
+int __heap_stat_callback __P((DBC *, PAGE *, void *, int *));
+int __heap_traverse __P((DBC *, int (*)(DBC *, PAGE *, void *, int *), void *));
+int __db_no_heap_am __P((ENV *));
+int __heap_vrfy_meta __P((DB *, VRFY_DBINFO *, HEAPMETA *, db_pgno_t, u_int32_t));
+int __heap_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t));
+int __heap_vrfy_structure __P((DB *, VRFY_DBINFO *, u_int32_t));
+int __heap_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, void *, int (*)(void *, const void *), u_int32_t));
+int __heap_meta2pgset __P((DB *, VRFY_DBINFO *, HEAPMETA *, DB *));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_heap_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/hmac_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,46 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_hmac_ext_h_
+#define	_hmac_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+void __db_chksum __P((void *, u_int8_t *, size_t, u_int8_t *, u_int8_t *));
+void __db_derive_mac __P((u_int8_t *, size_t, u_int8_t *));
+int __db_check_chksum __P((ENV *, void *, DB_CIPHER *, u_int8_t *, void *, size_t, int));
+void __db_SHA1Transform __P((u_int32_t *, unsigned char *));
+void __db_SHA1Init __P((SHA1_CTX *));
+void __db_SHA1Update __P((SHA1_CTX *, unsigned char *, size_t));
+void __db_SHA1Final __P((unsigned char *, SHA1_CTX *));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_hmac_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/int_def.in	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,2378 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_DB_INT_DEF_IN_
+#define	_DB_INT_DEF_IN_
+
+#define	__crdel_metasub_desc __crdel_metasub_desc@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_create_desc __crdel_inmem_create_desc@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_rename_desc __crdel_inmem_rename_desc@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_remove_desc __crdel_inmem_remove_desc@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_init_recover __crdel_init_recover@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_metasub_print __crdel_metasub_print@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_create_print __crdel_inmem_create_print@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_rename_print __crdel_inmem_rename_print@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_remove_print __crdel_inmem_remove_print@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_init_print __crdel_init_print@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_metasub_recover __crdel_metasub_recover@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_create_recover __crdel_inmem_create_recover@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_rename_recover __crdel_inmem_rename_recover@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_remove_recover __crdel_inmem_remove_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_master_open __db_master_open@DB_VERSION_UNIQUE_NAME@
+#define	__db_master_update __db_master_update@DB_VERSION_UNIQUE_NAME@
+#define	__env_dbreg_setup __env_dbreg_setup@DB_VERSION_UNIQUE_NAME@
+#define	__env_setup __env_setup@DB_VERSION_UNIQUE_NAME@
+#define	__env_mpool __env_mpool@DB_VERSION_UNIQUE_NAME@
+#define	__db_close __db_close@DB_VERSION_UNIQUE_NAME@
+#define	__db_refresh __db_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__db_log_page __db_log_page@DB_VERSION_UNIQUE_NAME@
+#define	__db_walk_cursors __db_walk_cursors@DB_VERSION_UNIQUE_NAME@
+#define	__db_backup_name __db_backup_name@DB_VERSION_UNIQUE_NAME@
+#ifdef CONFIG_TEST
+#define	__db_testcopy __db_testcopy@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__db_testdocopy __db_testdocopy@DB_VERSION_UNIQUE_NAME@
+#define	__db_cursor_int __db_cursor_int@DB_VERSION_UNIQUE_NAME@
+#define	__db_put __db_put@DB_VERSION_UNIQUE_NAME@
+#define	__db_del __db_del@DB_VERSION_UNIQUE_NAME@
+#define	__db_sync __db_sync@DB_VERSION_UNIQUE_NAME@
+#define	__db_associate __db_associate@DB_VERSION_UNIQUE_NAME@
+#define	__db_secondary_close __db_secondary_close@DB_VERSION_UNIQUE_NAME@
+#define	__db_associate_foreign __db_associate_foreign@DB_VERSION_UNIQUE_NAME@
+#define	__db_addrem_desc __db_addrem_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_addrem_42_desc __db_addrem_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_big_desc __db_big_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_big_42_desc __db_big_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_ovref_desc __db_ovref_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_relink_42_desc __db_relink_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_debug_desc __db_debug_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_noop_desc __db_noop_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_alloc_42_desc __db_pg_alloc_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_alloc_desc __db_pg_alloc_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_free_42_desc __db_pg_free_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_free_desc __db_pg_free_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_cksum_desc __db_cksum_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_freedata_42_desc __db_pg_freedata_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_freedata_desc __db_pg_freedata_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_init_desc __db_pg_init_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_sort_44_desc __db_pg_sort_44_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_trunc_desc __db_pg_trunc_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_realloc_desc __db_realloc_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_relink_desc __db_relink_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_merge_desc __db_merge_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pgno_desc __db_pgno_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_init_recover __db_init_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_addrem_print __db_addrem_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_addrem_42_print __db_addrem_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_big_print __db_big_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_big_42_print __db_big_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_ovref_print __db_ovref_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_relink_42_print __db_relink_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_debug_print __db_debug_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_noop_print __db_noop_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_alloc_42_print __db_pg_alloc_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_alloc_print __db_pg_alloc_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_free_42_print __db_pg_free_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_free_print __db_pg_free_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_cksum_print __db_cksum_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_freedata_42_print __db_pg_freedata_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_freedata_print __db_pg_freedata_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_init_print __db_pg_init_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_sort_44_print __db_pg_sort_44_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_trunc_print __db_pg_trunc_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_realloc_print __db_realloc_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_relink_print __db_relink_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_merge_print __db_merge_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_pgno_print __db_pgno_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_init_print __db_init_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbbackup_pp __db_dbbackup_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbbackup __db_dbbackup@DB_VERSION_UNIQUE_NAME@
+#define	__db_backup __db_backup@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_close __dbc_close@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_destroy __dbc_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_cmp __dbc_cmp@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_count __dbc_count@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_del __dbc_del@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_idel __dbc_idel@DB_VERSION_UNIQUE_NAME@
+#ifdef HAVE_COMPRESSION
+#define	__dbc_bulk_del __dbc_bulk_del@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__dbc_dup __dbc_dup@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_idup __dbc_idup@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_newopd __dbc_newopd@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_get __dbc_get@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_iget __dbc_iget@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_put __dbc_put@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_iput __dbc_iput@DB_VERSION_UNIQUE_NAME@
+#define	__db_duperr __db_duperr@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_cleanup __dbc_cleanup@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_secondary_get_pp __dbc_secondary_get_pp@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_pget __dbc_pget@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_del_primary __dbc_del_primary@DB_VERSION_UNIQUE_NAME@
+#define	__db_s_first __db_s_first@DB_VERSION_UNIQUE_NAME@
+#define	__db_s_next __db_s_next@DB_VERSION_UNIQUE_NAME@
+#define	__db_s_done __db_s_done@DB_VERSION_UNIQUE_NAME@
+#define	__db_buildpartial __db_buildpartial@DB_VERSION_UNIQUE_NAME@
+#define	__db_partsize __db_partsize@DB_VERSION_UNIQUE_NAME@
+#define	__db_secondary_corrupt __db_secondary_corrupt@DB_VERSION_UNIQUE_NAME@
+#ifdef DIAGNOSTIC
+#define	__db_check_skeyset __db_check_skeyset@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__cdsgroup_begin __cdsgroup_begin@DB_VERSION_UNIQUE_NAME@
+#define	__cdsgroup_begin_pp __cdsgroup_begin_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_compact_pp __db_compact_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_associate_foreign_pp __db_associate_foreign_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_compact_int __db_compact_int@DB_VERSION_UNIQUE_NAME@
+#define	__db_exchange_page __db_exchange_page@DB_VERSION_UNIQUE_NAME@
+#define	__db_truncate_overflow __db_truncate_overflow@DB_VERSION_UNIQUE_NAME@
+#define	__db_truncate_root __db_truncate_root@DB_VERSION_UNIQUE_NAME@
+#define	__db_find_free __db_find_free@DB_VERSION_UNIQUE_NAME@
+#define	__db_move_metadata __db_move_metadata@DB_VERSION_UNIQUE_NAME@
+#define	__db_pgin __db_pgin@DB_VERSION_UNIQUE_NAME@
+#define	__db_pgout __db_pgout@DB_VERSION_UNIQUE_NAME@
+#define	__db_decrypt_pg __db_decrypt_pg@DB_VERSION_UNIQUE_NAME@
+#define	__db_encrypt_and_checksum_pg __db_encrypt_and_checksum_pg@DB_VERSION_UNIQUE_NAME@
+#define	__db_metaswap __db_metaswap@DB_VERSION_UNIQUE_NAME@
+#define	__db_byteswap __db_byteswap@DB_VERSION_UNIQUE_NAME@
+#define	__db_pageswap __db_pageswap@DB_VERSION_UNIQUE_NAME@
+#define	__db_recordswap __db_recordswap@DB_VERSION_UNIQUE_NAME@
+#define	__db_dispatch __db_dispatch@DB_VERSION_UNIQUE_NAME@
+#define	__db_add_recovery __db_add_recovery@DB_VERSION_UNIQUE_NAME@
+#define	__db_add_recovery_int __db_add_recovery_int@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_init __db_txnlist_init@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_add __db_txnlist_add@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_remove __db_txnlist_remove@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_ckp __db_txnlist_ckp@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_end __db_txnlist_end@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_find __db_txnlist_find@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_update __db_txnlist_update@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_gen __db_txnlist_gen@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_lsnadd __db_txnlist_lsnadd@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_lsnget __db_txnlist_lsnget@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_lsninit __db_txnlist_lsninit@DB_VERSION_UNIQUE_NAME@
+#define	__db_txnlist_print __db_txnlist_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_ditem_nolog __db_ditem_nolog@DB_VERSION_UNIQUE_NAME@
+#define	__db_ditem __db_ditem@DB_VERSION_UNIQUE_NAME@
+#define	__db_pitem_nolog __db_pitem_nolog@DB_VERSION_UNIQUE_NAME@
+#define	__db_pitem __db_pitem@DB_VERSION_UNIQUE_NAME@
+#define	__db_associate_pp __db_associate_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_close_pp __db_close_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_cursor_pp __db_cursor_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_cursor __db_cursor@DB_VERSION_UNIQUE_NAME@
+#define	__db_del_pp __db_del_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_exists __db_exists@DB_VERSION_UNIQUE_NAME@
+#define	__db_fd_pp __db_fd_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_get_pp __db_get_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_get __db_get@DB_VERSION_UNIQUE_NAME@
+#define	__db_key_range_pp __db_key_range_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_open_pp __db_open_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_pget_pp __db_pget_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_pget __db_pget@DB_VERSION_UNIQUE_NAME@
+#define	__db_put_pp __db_put_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_sync_pp __db_sync_pp@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_close_pp __dbc_close_pp@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_cmp_pp __dbc_cmp_pp@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_count_pp __dbc_count_pp@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_del_pp __dbc_del_pp@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_dup_pp __dbc_dup_pp@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_get_pp __dbc_get_pp@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_get_arg __dbc_get_arg@DB_VERSION_UNIQUE_NAME@
+#define	__db_secondary_close_pp __db_secondary_close_pp@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_pget_pp __dbc_pget_pp@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_put_pp __dbc_put_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_txn_auto_init __db_txn_auto_init@DB_VERSION_UNIQUE_NAME@
+#define	__db_txn_auto_resolve __db_txn_auto_resolve@DB_VERSION_UNIQUE_NAME@
+#define	__db_join_pp __db_join_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_join __db_join@DB_VERSION_UNIQUE_NAME@
+#define	__db_join_close __db_join_close@DB_VERSION_UNIQUE_NAME@
+#define	__db_new __db_new@DB_VERSION_UNIQUE_NAME@
+#define	__db_free __db_free@DB_VERSION_UNIQUE_NAME@
+#ifdef HAVE_FTRUNCATE
+#define	__db_freelist_pos __db_freelist_pos@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__db_freelist_sort __db_freelist_sort@DB_VERSION_UNIQUE_NAME@
+#ifdef HAVE_FTRUNCATE
+#define	__db_pg_truncate __db_pg_truncate@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifdef HAVE_FTRUNCATE
+#define	__db_free_truncate __db_free_truncate@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__db_create_internal __db_create_internal@DB_VERSION_UNIQUE_NAME@
+#define	__dbh_am_chk __dbh_am_chk@DB_VERSION_UNIQUE_NAME@
+#define	__db_get_flags __db_get_flags@DB_VERSION_UNIQUE_NAME@
+#define	__db_set_flags __db_set_flags@DB_VERSION_UNIQUE_NAME@
+#define	__db_get_lorder __db_get_lorder@DB_VERSION_UNIQUE_NAME@
+#define	__db_set_lorder __db_set_lorder@DB_VERSION_UNIQUE_NAME@
+#define	__db_set_pagesize __db_set_pagesize@DB_VERSION_UNIQUE_NAME@
+#define	__db_relink __db_relink@DB_VERSION_UNIQUE_NAME@
+#ifdef DIAGNOSTIC
+#define	__db_haslock __db_haslock@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifdef DIAGNOSTIC
+#define	__db_has_pagelock __db_has_pagelock@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__db_open __db_open@DB_VERSION_UNIQUE_NAME@
+#define	__db_get_open_flags __db_get_open_flags@DB_VERSION_UNIQUE_NAME@
+#define	__db_new_file __db_new_file@DB_VERSION_UNIQUE_NAME@
+#define	__db_init_subdb __db_init_subdb@DB_VERSION_UNIQUE_NAME@
+#define	__db_chk_meta __db_chk_meta@DB_VERSION_UNIQUE_NAME@
+#define	__db_meta_setup __db_meta_setup@DB_VERSION_UNIQUE_NAME@
+#define	__db_reopen __db_reopen@DB_VERSION_UNIQUE_NAME@
+#define	__db_goff __db_goff@DB_VERSION_UNIQUE_NAME@
+#define	__db_poff __db_poff@DB_VERSION_UNIQUE_NAME@
+#define	__db_ovref __db_ovref@DB_VERSION_UNIQUE_NAME@
+#define	__db_doff __db_doff@DB_VERSION_UNIQUE_NAME@
+#define	__db_moff __db_moff@DB_VERSION_UNIQUE_NAME@
+#define	__db_coff __db_coff@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_overflow __db_vrfy_overflow@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_ovfl_structure __db_vrfy_ovfl_structure@DB_VERSION_UNIQUE_NAME@
+#define	__db_safe_goff __db_safe_goff@DB_VERSION_UNIQUE_NAME@
+#define	__db_loadme __db_loadme@DB_VERSION_UNIQUE_NAME@
+#define	__db_dumptree __db_dumptree@DB_VERSION_UNIQUE_NAME@
+#define	__db_get_flags_fn __db_get_flags_fn@DB_VERSION_UNIQUE_NAME@
+#define	__db_prnpage __db_prnpage@DB_VERSION_UNIQUE_NAME@
+#define	__db_prpage __db_prpage@DB_VERSION_UNIQUE_NAME@
+#define	__db_lockmode_to_string __db_lockmode_to_string@DB_VERSION_UNIQUE_NAME@
+#define	__db_dumptree __db_dumptree@DB_VERSION_UNIQUE_NAME@
+#define	__db_get_flags_fn __db_get_flags_fn@DB_VERSION_UNIQUE_NAME@
+#define	__db_prpage_int __db_prpage_int@DB_VERSION_UNIQUE_NAME@
+#define	__db_prbytes __db_prbytes@DB_VERSION_UNIQUE_NAME@
+#define	__db_prflags __db_prflags@DB_VERSION_UNIQUE_NAME@
+#define	__db_name_to_val __db_name_to_val@DB_VERSION_UNIQUE_NAME@
+#define	__db_pagetype_to_string __db_pagetype_to_string@DB_VERSION_UNIQUE_NAME@
+#define	__db_dump_pp __db_dump_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_dump __db_dump@DB_VERSION_UNIQUE_NAME@
+#define	__db_prdbt __db_prdbt@DB_VERSION_UNIQUE_NAME@
+#define	__db_prheader __db_prheader@DB_VERSION_UNIQUE_NAME@
+#define	__db_prfooter __db_prfooter@DB_VERSION_UNIQUE_NAME@
+#define	__db_pr_callback __db_pr_callback@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbtype_to_string __db_dbtype_to_string@DB_VERSION_UNIQUE_NAME@
+#define	__db_addrem_recover __db_addrem_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_addrem_42_recover __db_addrem_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_big_recover __db_big_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_big_42_recover __db_big_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_ovref_recover __db_ovref_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_debug_recover __db_debug_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_noop_recover __db_noop_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_alloc_recover __db_pg_alloc_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_free_recover __db_pg_free_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_freedata_recover __db_pg_freedata_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_cksum_recover __db_cksum_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_init_recover __db_pg_init_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_trunc_recover __db_pg_trunc_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_realloc_recover __db_realloc_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_sort_44_recover __db_pg_sort_44_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_alloc_42_recover __db_pg_alloc_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_free_42_recover __db_pg_free_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_freedata_42_recover __db_pg_freedata_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_relink_42_recover __db_relink_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_relink_recover __db_relink_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_merge_recover __db_merge_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_pgno_recover __db_pgno_recover@DB_VERSION_UNIQUE_NAME@
+#define	__db_pglist_swap __db_pglist_swap@DB_VERSION_UNIQUE_NAME@
+#define	__db_pglist_print __db_pglist_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_traverse_big __db_traverse_big@DB_VERSION_UNIQUE_NAME@
+#define	__db_reclaim_callback __db_reclaim_callback@DB_VERSION_UNIQUE_NAME@
+#define	__db_truncate_callback __db_truncate_callback@DB_VERSION_UNIQUE_NAME@
+#define	__env_dbremove_pp __env_dbremove_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_remove_pp __db_remove_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_remove __db_remove@DB_VERSION_UNIQUE_NAME@
+#define	__db_remove_int __db_remove_int@DB_VERSION_UNIQUE_NAME@
+#define	__db_inmem_remove __db_inmem_remove@DB_VERSION_UNIQUE_NAME@
+#define	__env_dbrename_pp __env_dbrename_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_rename_pp __db_rename_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_rename_int __db_rename_int@DB_VERSION_UNIQUE_NAME@
+#define	__db_ret __db_ret@DB_VERSION_UNIQUE_NAME@
+#define	__db_retcopy __db_retcopy@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbt_clone __db_dbt_clone@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbt_clone_free __db_dbt_clone_free@DB_VERSION_UNIQUE_NAME@
+#define	__env_fileid_reset_pp __env_fileid_reset_pp@DB_VERSION_UNIQUE_NAME@
+#define	__env_fileid_reset __env_fileid_reset@DB_VERSION_UNIQUE_NAME@
+#define	__env_lsn_reset_pp __env_lsn_reset_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_lsn_reset __db_lsn_reset@DB_VERSION_UNIQUE_NAME@
+#define	__db_compare_both __db_compare_both@DB_VERSION_UNIQUE_NAME@
+#define	__db_sort_multiple __db_sort_multiple@DB_VERSION_UNIQUE_NAME@
+#define	__db_stat_pp __db_stat_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_stat_print_pp __db_stat_print_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_stat_print __db_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_truncate_pp __db_truncate_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_truncate __db_truncate@DB_VERSION_UNIQUE_NAME@
+#define	__db_upgrade_pp __db_upgrade_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_upgrade __db_upgrade@DB_VERSION_UNIQUE_NAME@
+#define	__db_lastpgno __db_lastpgno@DB_VERSION_UNIQUE_NAME@
+#define	__db_31_offdup __db_31_offdup@DB_VERSION_UNIQUE_NAME@
+#define	__db_verify_pp __db_verify_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_verify_internal __db_verify_internal@DB_VERSION_UNIQUE_NAME@
+#define	__db_verify __db_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_common __db_vrfy_common@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_datapage __db_vrfy_datapage@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_meta __db_vrfy_meta@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_struct_feedback __db_vrfy_struct_feedback@DB_VERSION_UNIQUE_NAME@
+#define	__db_salvage_pg __db_salvage_pg@DB_VERSION_UNIQUE_NAME@
+#define	__db_salvage_leaf __db_salvage_leaf@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_inpitem __db_vrfy_inpitem@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_duptype __db_vrfy_duptype@DB_VERSION_UNIQUE_NAME@
+#define	__db_salvage_duptree __db_salvage_duptree@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_dbinfo_create __db_vrfy_dbinfo_create@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_dbinfo_destroy __db_vrfy_dbinfo_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_getpageinfo __db_vrfy_getpageinfo@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_putpageinfo __db_vrfy_putpageinfo@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_pgset __db_vrfy_pgset@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_pgset_get __db_vrfy_pgset_get@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_pgset_inc __db_vrfy_pgset_inc@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_pgset_next __db_vrfy_pgset_next@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_childcursor __db_vrfy_childcursor@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_childput __db_vrfy_childput@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_ccset __db_vrfy_ccset@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_ccnext __db_vrfy_ccnext@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_ccclose __db_vrfy_ccclose@DB_VERSION_UNIQUE_NAME@
+#define	__db_salvage_init __db_salvage_init@DB_VERSION_UNIQUE_NAME@
+#define	__db_salvage_destroy __db_salvage_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__db_salvage_getnext __db_salvage_getnext@DB_VERSION_UNIQUE_NAME@
+#define	__db_salvage_isdone __db_salvage_isdone@DB_VERSION_UNIQUE_NAME@
+#define	__db_salvage_markdone __db_salvage_markdone@DB_VERSION_UNIQUE_NAME@
+#define	__db_salvage_markneeded __db_salvage_markneeded@DB_VERSION_UNIQUE_NAME@
+#define	__db_vrfy_prdbt __db_vrfy_prdbt@DB_VERSION_UNIQUE_NAME@
+#define	__db_lget __db_lget@DB_VERSION_UNIQUE_NAME@
+#define	__db_lput __db_lput@DB_VERSION_UNIQUE_NAME@
+#define	__db_lprint __db_lprint@DB_VERSION_UNIQUE_NAME@
+#define	__partition_init __partition_init@DB_VERSION_UNIQUE_NAME@
+#define	__partition_set __partition_set@DB_VERSION_UNIQUE_NAME@
+#define	__partition_set_dirs __partition_set_dirs@DB_VERSION_UNIQUE_NAME@
+#define	__partition_open __partition_open@DB_VERSION_UNIQUE_NAME@
+#define	__partition_get_callback __partition_get_callback@DB_VERSION_UNIQUE_NAME@
+#define	__partition_get_keys __partition_get_keys@DB_VERSION_UNIQUE_NAME@
+#define	__partition_get_dirs __partition_get_dirs@DB_VERSION_UNIQUE_NAME@
+#define	__partc_init __partc_init@DB_VERSION_UNIQUE_NAME@
+#define	__partc_get __partc_get@DB_VERSION_UNIQUE_NAME@
+#define	__partition_close __partition_close@DB_VERSION_UNIQUE_NAME@
+#define	__partition_sync __partition_sync@DB_VERSION_UNIQUE_NAME@
+#define	__partition_stat __partition_stat@DB_VERSION_UNIQUE_NAME@
+#define	__part_truncate __part_truncate@DB_VERSION_UNIQUE_NAME@
+#define	__part_compact __part_compact@DB_VERSION_UNIQUE_NAME@
+#define	__part_lsn_reset __part_lsn_reset@DB_VERSION_UNIQUE_NAME@
+#define	__part_fileid_reset __part_fileid_reset@DB_VERSION_UNIQUE_NAME@
+#define	__part_key_range __part_key_range@DB_VERSION_UNIQUE_NAME@
+#define	__part_remove __part_remove@DB_VERSION_UNIQUE_NAME@
+#define	__part_rename __part_rename@DB_VERSION_UNIQUE_NAME@
+#define	__part_verify __part_verify@DB_VERSION_UNIQUE_NAME@
+#define	__part_testdocopy __part_testdocopy@DB_VERSION_UNIQUE_NAME@
+#define	__db_no_partition __db_no_partition@DB_VERSION_UNIQUE_NAME@
+#define	__bam_compact_int __bam_compact_int@DB_VERSION_UNIQUE_NAME@
+#define	__bam_compact_opd __bam_compact_opd@DB_VERSION_UNIQUE_NAME@
+#define	__bam_truncate_ipages __bam_truncate_ipages@DB_VERSION_UNIQUE_NAME@
+#define	__bam_cmp __bam_cmp@DB_VERSION_UNIQUE_NAME@
+#define	__bam_defcmp __bam_defcmp@DB_VERSION_UNIQUE_NAME@
+#define	__bam_defpfx __bam_defpfx@DB_VERSION_UNIQUE_NAME@
+#define	__bam_compress_dupcmp __bam_compress_dupcmp@DB_VERSION_UNIQUE_NAME@
+#define	__bam_defcompress __bam_defcompress@DB_VERSION_UNIQUE_NAME@
+#define	__bam_defdecompress __bam_defdecompress@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_compress_get __bamc_compress_get@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_compress_put __bamc_compress_put@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_compress_del __bamc_compress_del@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_compress_bulk_del __bamc_compress_bulk_del@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_compress_count __bamc_compress_count@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_compress_cmp __bamc_compress_cmp@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_compress_dup __bamc_compress_dup@DB_VERSION_UNIQUE_NAME@
+#define	__bam_compress_salvage __bam_compress_salvage@DB_VERSION_UNIQUE_NAME@
+#define	__bam_compress_count __bam_compress_count@DB_VERSION_UNIQUE_NAME@
+#define	__bam_pgin __bam_pgin@DB_VERSION_UNIQUE_NAME@
+#define	__bam_pgout __bam_pgout@DB_VERSION_UNIQUE_NAME@
+#define	__bam_mswap __bam_mswap@DB_VERSION_UNIQUE_NAME@
+#define	__bam_ca_delete __bam_ca_delete@DB_VERSION_UNIQUE_NAME@
+#define	__ram_ca_delete __ram_ca_delete@DB_VERSION_UNIQUE_NAME@
+#define	__bam_ca_di __bam_ca_di@DB_VERSION_UNIQUE_NAME@
+#define	__bam_ca_dup __bam_ca_dup@DB_VERSION_UNIQUE_NAME@
+#define	__bam_ca_undodup __bam_ca_undodup@DB_VERSION_UNIQUE_NAME@
+#define	__bam_ca_rsplit __bam_ca_rsplit@DB_VERSION_UNIQUE_NAME@
+#define	__bam_ca_split __bam_ca_split@DB_VERSION_UNIQUE_NAME@
+#define	__bam_ca_undosplit __bam_ca_undosplit@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_init __bamc_init@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_refresh __bamc_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_cmp __bamc_cmp@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_count __bamc_count@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_dup __bamc_dup@DB_VERSION_UNIQUE_NAME@
+#define	__bam_bulk_overflow __bam_bulk_overflow@DB_VERSION_UNIQUE_NAME@
+#define	__bam_bulk_duplicates __bam_bulk_duplicates@DB_VERSION_UNIQUE_NAME@
+#define	__bamc_rget __bamc_rget@DB_VERSION_UNIQUE_NAME@
+#define	__bam_opd_exists __bam_opd_exists@DB_VERSION_UNIQUE_NAME@
+#define	__bam_ditem __bam_ditem@DB_VERSION_UNIQUE_NAME@
+#define	__bam_adjindx __bam_adjindx@DB_VERSION_UNIQUE_NAME@
+#define	__bam_dpages __bam_dpages@DB_VERSION_UNIQUE_NAME@
+#define	__bam_pupdate __bam_pupdate@DB_VERSION_UNIQUE_NAME@
+#define	__bam_db_create __bam_db_create@DB_VERSION_UNIQUE_NAME@
+#define	__bam_db_close __bam_db_close@DB_VERSION_UNIQUE_NAME@
+#define	__bam_map_flags __bam_map_flags@DB_VERSION_UNIQUE_NAME@
+#define	__bam_set_flags __bam_set_flags@DB_VERSION_UNIQUE_NAME@
+#define	__bam_set_bt_compare __bam_set_bt_compare@DB_VERSION_UNIQUE_NAME@
+#define	__bam_set_bt_compress __bam_set_bt_compress@DB_VERSION_UNIQUE_NAME@
+#define	__bam_get_bt_minkey __bam_get_bt_minkey@DB_VERSION_UNIQUE_NAME@
+#define	__bam_copy_config __bam_copy_config@DB_VERSION_UNIQUE_NAME@
+#define	__ram_map_flags __ram_map_flags@DB_VERSION_UNIQUE_NAME@
+#define	__ram_set_flags __ram_set_flags@DB_VERSION_UNIQUE_NAME@
+#define	__ram_get_re_len __ram_get_re_len@DB_VERSION_UNIQUE_NAME@
+#define	__ram_get_re_pad __ram_get_re_pad@DB_VERSION_UNIQUE_NAME@
+#define	__bam_open __bam_open@DB_VERSION_UNIQUE_NAME@
+#define	__bam_metachk __bam_metachk@DB_VERSION_UNIQUE_NAME@
+#define	__bam_read_root __bam_read_root@DB_VERSION_UNIQUE_NAME@
+#define	__bam_new_file __bam_new_file@DB_VERSION_UNIQUE_NAME@
+#define	__bam_new_subdb __bam_new_subdb@DB_VERSION_UNIQUE_NAME@
+#define	__bam_iitem __bam_iitem@DB_VERSION_UNIQUE_NAME@
+#define	__bam_ritem __bam_ritem@DB_VERSION_UNIQUE_NAME@
+#define	__bam_ritem_nolog __bam_ritem_nolog@DB_VERSION_UNIQUE_NAME@
+#define	__bam_irep __bam_irep@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_recover __bam_split_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_48_recover __bam_split_48_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_42_recover __bam_split_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_rsplit_recover __bam_rsplit_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_adj_recover __bam_adj_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_cadjust_recover __bam_cadjust_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_cdel_recover __bam_cdel_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_repl_recover __bam_repl_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_irep_recover __bam_irep_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_root_recover __bam_root_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_curadj_recover __bam_curadj_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_rcuradj_recover __bam_rcuradj_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_merge_44_recover __bam_merge_44_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_relink_43_recover __bam_relink_43_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_reclaim __bam_reclaim@DB_VERSION_UNIQUE_NAME@
+#define	__bam_truncate __bam_truncate@DB_VERSION_UNIQUE_NAME@
+#define	__ram_open __ram_open@DB_VERSION_UNIQUE_NAME@
+#define	__ram_append __ram_append@DB_VERSION_UNIQUE_NAME@
+#define	__ramc_del __ramc_del@DB_VERSION_UNIQUE_NAME@
+#define	__ramc_get __ramc_get@DB_VERSION_UNIQUE_NAME@
+#define	__ramc_put __ramc_put@DB_VERSION_UNIQUE_NAME@
+#define	__ram_ca __ram_ca@DB_VERSION_UNIQUE_NAME@
+#define	__ram_getno __ram_getno@DB_VERSION_UNIQUE_NAME@
+#define	__ram_writeback __ram_writeback@DB_VERSION_UNIQUE_NAME@
+#define	__bam_rsearch __bam_rsearch@DB_VERSION_UNIQUE_NAME@
+#define	__bam_adjust __bam_adjust@DB_VERSION_UNIQUE_NAME@
+#define	__bam_nrecs __bam_nrecs@DB_VERSION_UNIQUE_NAME@
+#define	__bam_total __bam_total@DB_VERSION_UNIQUE_NAME@
+#define	__bam_get_root __bam_get_root@DB_VERSION_UNIQUE_NAME@
+#define	__bam_search __bam_search@DB_VERSION_UNIQUE_NAME@
+#define	__bam_stkrel __bam_stkrel@DB_VERSION_UNIQUE_NAME@
+#define	__bam_stkgrow __bam_stkgrow@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split __bam_split@DB_VERSION_UNIQUE_NAME@
+#define	__bam_broot __bam_broot@DB_VERSION_UNIQUE_NAME@
+#define	__ram_root __ram_root@DB_VERSION_UNIQUE_NAME@
+#define	__bam_pinsert __bam_pinsert@DB_VERSION_UNIQUE_NAME@
+#define	__bam_copy __bam_copy@DB_VERSION_UNIQUE_NAME@
+#define	__bam_stat __bam_stat@DB_VERSION_UNIQUE_NAME@
+#define	__bam_stat_print __bam_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_stat_callback __bam_stat_callback@DB_VERSION_UNIQUE_NAME@
+#define	__bam_print_cursor __bam_print_cursor@DB_VERSION_UNIQUE_NAME@
+#define	__bam_key_range __bam_key_range@DB_VERSION_UNIQUE_NAME@
+#define	__bam_traverse __bam_traverse@DB_VERSION_UNIQUE_NAME@
+#define	__bam_30_btreemeta __bam_30_btreemeta@DB_VERSION_UNIQUE_NAME@
+#define	__bam_31_btreemeta __bam_31_btreemeta@DB_VERSION_UNIQUE_NAME@
+#define	__bam_31_lbtree __bam_31_lbtree@DB_VERSION_UNIQUE_NAME@
+#define	__bam_vrfy_meta __bam_vrfy_meta@DB_VERSION_UNIQUE_NAME@
+#define	__ram_vrfy_leaf __ram_vrfy_leaf@DB_VERSION_UNIQUE_NAME@
+#define	__bam_vrfy __bam_vrfy@DB_VERSION_UNIQUE_NAME@
+#define	__bam_vrfy_itemorder __bam_vrfy_itemorder@DB_VERSION_UNIQUE_NAME@
+#define	__bam_vrfy_structure __bam_vrfy_structure@DB_VERSION_UNIQUE_NAME@
+#define	__bam_vrfy_subtree __bam_vrfy_subtree@DB_VERSION_UNIQUE_NAME@
+#define	__bam_salvage __bam_salvage@DB_VERSION_UNIQUE_NAME@
+#define	__bam_salvage_walkdupint __bam_salvage_walkdupint@DB_VERSION_UNIQUE_NAME@
+#define	__bam_meta2pgset __bam_meta2pgset@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_desc __bam_split_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_48_desc __bam_split_48_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_42_desc __bam_split_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_rsplit_desc __bam_rsplit_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_adj_desc __bam_adj_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_cadjust_desc __bam_cadjust_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_cdel_desc __bam_cdel_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_repl_desc __bam_repl_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_irep_desc __bam_irep_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_root_desc __bam_root_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_curadj_desc __bam_curadj_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_rcuradj_desc __bam_rcuradj_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_relink_43_desc __bam_relink_43_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_merge_44_desc __bam_merge_44_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_init_recover __bam_init_recover@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_print __bam_split_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_48_print __bam_split_48_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_42_print __bam_split_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_rsplit_print __bam_rsplit_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_adj_print __bam_adj_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_cadjust_print __bam_cadjust_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_cdel_print __bam_cdel_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_repl_print __bam_repl_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_irep_print __bam_irep_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_root_print __bam_root_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_curadj_print __bam_curadj_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_rcuradj_print __bam_rcuradj_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_relink_43_print __bam_relink_43_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_merge_44_print __bam_merge_44_print@DB_VERSION_UNIQUE_NAME@
+#define	__bam_init_print __bam_init_print@DB_VERSION_UNIQUE_NAME@
+#ifndef HAVE_ATOI
+#define	atoi atoi@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_ATOL
+#define	atol atol@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_BSEARCH
+#define	bsearch bsearch@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_GETCWD
+#define	getcwd getcwd@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_GETOPT
+#define	getopt getopt@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_ISALPHA
+#define	isalpha isalpha@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_ISDIGIT
+#define	isdigit isdigit@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_ISPRINT
+#define	isprint isprint@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_ISSPACE
+#define	isspace isspace@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_MEMCMP
+#define	memcmp memcmp@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_MEMCPY
+#define	memcpy memcpy@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_MEMMOVE
+#define	memmove memmove@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_PRINTF
+#define	printf printf@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_PRINTF
+#define	fprintf fprintf@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_PRINTF
+#define	vfprintf vfprintf@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_QSORT
+#define	qsort qsort@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_RAISE
+#define	raise raise@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_RAND
+#define	rand rand@DB_VERSION_UNIQUE_NAME@
+#define	srand srand@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_SNPRINTF
+#define	snprintf snprintf@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_VSNPRINTF
+#define	vsnprintf vsnprintf@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRCASECMP
+#define	strcasecmp strcasecmp@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRCASECMP
+#define	strncasecmp strncasecmp@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRCAT
+#define	strcat strcat@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRCHR
+#define	strchr strchr@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRDUP
+#define	strdup strdup@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRERROR
+#define	strerror strerror@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRNCAT
+#define	strncat strncat@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRNCMP
+#define	strncmp strncmp@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRRCHR
+#define	strrchr strrchr@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRSEP
+#define	strsep strsep@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRTOL
+#define	strtol strtol@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_STRTOUL
+#define	strtoul strtoul@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_TIME
+#define	time time@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__clock_set_expires __clock_set_expires@DB_VERSION_UNIQUE_NAME@
+#define	__clock_expired __clock_expired@DB_VERSION_UNIQUE_NAME@
+#define	__crypto_region_init __crypto_region_init@DB_VERSION_UNIQUE_NAME@
+#define	__db_isbigendian __db_isbigendian@DB_VERSION_UNIQUE_NAME@
+#define	__db_byteorder __db_byteorder@DB_VERSION_UNIQUE_NAME@
+#define	__db_compress_count_int __db_compress_count_int@DB_VERSION_UNIQUE_NAME@
+#define	__db_compress_int __db_compress_int@DB_VERSION_UNIQUE_NAME@
+#define	__db_decompress_count_int __db_decompress_count_int@DB_VERSION_UNIQUE_NAME@
+#define	__db_decompress_int __db_decompress_int@DB_VERSION_UNIQUE_NAME@
+#define	__db_decompress_int32 __db_decompress_int32@DB_VERSION_UNIQUE_NAME@
+#define	__db_fchk __db_fchk@DB_VERSION_UNIQUE_NAME@
+#define	__db_fcchk __db_fcchk@DB_VERSION_UNIQUE_NAME@
+#define	__db_ferr __db_ferr@DB_VERSION_UNIQUE_NAME@
+#define	__db_fnl __db_fnl@DB_VERSION_UNIQUE_NAME@
+#define	__db_pgerr __db_pgerr@DB_VERSION_UNIQUE_NAME@
+#define	__db_pgfmt __db_pgfmt@DB_VERSION_UNIQUE_NAME@
+#ifdef DIAGNOSTIC
+#define	__db_assert __db_assert@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__env_panic_msg __env_panic_msg@DB_VERSION_UNIQUE_NAME@
+#define	__env_panic __env_panic@DB_VERSION_UNIQUE_NAME@
+#define	__db_unknown_error __db_unknown_error@DB_VERSION_UNIQUE_NAME@
+#define	__db_syserr __db_syserr@DB_VERSION_UNIQUE_NAME@
+#define	__db_err __db_err@DB_VERSION_UNIQUE_NAME@
+#define	__db_errx __db_errx@DB_VERSION_UNIQUE_NAME@
+#define	__db_errcall __db_errcall@DB_VERSION_UNIQUE_NAME@
+#define	__db_errfile __db_errfile@DB_VERSION_UNIQUE_NAME@
+#define	__db_msgadd __db_msgadd@DB_VERSION_UNIQUE_NAME@
+#define	__db_msgadd_ap __db_msgadd_ap@DB_VERSION_UNIQUE_NAME@
+#define	__db_msg __db_msg@DB_VERSION_UNIQUE_NAME@
+#define	__db_repmsg __db_repmsg@DB_VERSION_UNIQUE_NAME@
+#define	__db_unknown_flag __db_unknown_flag@DB_VERSION_UNIQUE_NAME@
+#define	__db_unknown_type __db_unknown_type@DB_VERSION_UNIQUE_NAME@
+#define	__db_unknown_path __db_unknown_path@DB_VERSION_UNIQUE_NAME@
+#define	__db_not_txn_env __db_not_txn_env@DB_VERSION_UNIQUE_NAME@
+#define	__db_rec_toobig __db_rec_toobig@DB_VERSION_UNIQUE_NAME@
+#define	__db_rec_repl __db_rec_repl@DB_VERSION_UNIQUE_NAME@
+#define	__dbc_logging __dbc_logging@DB_VERSION_UNIQUE_NAME@
+#define	__db_check_lsn __db_check_lsn@DB_VERSION_UNIQUE_NAME@
+#define	__db_rdonly __db_rdonly@DB_VERSION_UNIQUE_NAME@
+#define	__db_space_err __db_space_err@DB_VERSION_UNIQUE_NAME@
+#define	__db_failed __db_failed@DB_VERSION_UNIQUE_NAME@
+#define	__db_getlong __db_getlong@DB_VERSION_UNIQUE_NAME@
+#define	__db_getulong __db_getulong@DB_VERSION_UNIQUE_NAME@
+#define	__db_idspace __db_idspace@DB_VERSION_UNIQUE_NAME@
+#define	__db_log2 __db_log2@DB_VERSION_UNIQUE_NAME@
+#define	__db_tablesize __db_tablesize@DB_VERSION_UNIQUE_NAME@
+#define	__db_hashinit __db_hashinit@DB_VERSION_UNIQUE_NAME@
+#define	__dbt_usercopy __dbt_usercopy@DB_VERSION_UNIQUE_NAME@
+#define	__dbt_userfree __dbt_userfree@DB_VERSION_UNIQUE_NAME@
+#define	__db_mkpath __db_mkpath@DB_VERSION_UNIQUE_NAME@
+#define	__db_openflags __db_openflags@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_desc __bam_split_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_48_desc __bam_split_48_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_42_desc __bam_split_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_rsplit_desc __bam_rsplit_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_adj_desc __bam_adj_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_cadjust_desc __bam_cadjust_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_cdel_desc __bam_cdel_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_repl_desc __bam_repl_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_irep_desc __bam_irep_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_root_desc __bam_root_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_curadj_desc __bam_curadj_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_rcuradj_desc __bam_rcuradj_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_relink_43_desc __bam_relink_43_desc@DB_VERSION_UNIQUE_NAME@
+#define	__bam_merge_44_desc __bam_merge_44_desc@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_metasub_desc __crdel_metasub_desc@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_create_desc __crdel_inmem_create_desc@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_rename_desc __crdel_inmem_rename_desc@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_remove_desc __crdel_inmem_remove_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_addrem_desc __db_addrem_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_addrem_42_desc __db_addrem_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_big_desc __db_big_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_big_42_desc __db_big_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_ovref_desc __db_ovref_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_relink_42_desc __db_relink_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_debug_desc __db_debug_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_noop_desc __db_noop_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_alloc_42_desc __db_pg_alloc_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_alloc_desc __db_pg_alloc_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_free_42_desc __db_pg_free_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_free_desc __db_pg_free_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_cksum_desc __db_cksum_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_freedata_42_desc __db_pg_freedata_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_freedata_desc __db_pg_freedata_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_init_desc __db_pg_init_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_sort_44_desc __db_pg_sort_44_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_trunc_desc __db_pg_trunc_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_realloc_desc __db_realloc_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_relink_desc __db_relink_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_merge_desc __db_merge_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_pgno_desc __db_pgno_desc@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_register_desc __dbreg_register_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_create_42_desc __fop_create_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_create_desc __fop_create_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_remove_desc __fop_remove_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_write_42_desc __fop_write_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_write_desc __fop_write_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_42_desc __fop_rename_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_noundo_46_desc __fop_rename_noundo_46_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_desc __fop_rename_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_noundo_desc __fop_rename_noundo_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_file_remove_desc __fop_file_remove_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_insdel_desc __ham_insdel_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_insdel_42_desc __ham_insdel_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_newpage_desc __ham_newpage_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_splitdata_desc __ham_splitdata_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_replace_desc __ham_replace_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_replace_42_desc __ham_replace_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_copypage_desc __ham_copypage_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_metagroup_42_desc __ham_metagroup_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_metagroup_desc __ham_metagroup_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_groupalloc_42_desc __ham_groupalloc_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_groupalloc_desc __ham_groupalloc_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_changeslot_desc __ham_changeslot_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_contract_desc __ham_contract_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_curadj_desc __ham_curadj_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_chgpg_desc __ham_chgpg_desc@DB_VERSION_UNIQUE_NAME@
+#define	__heap_addrem_desc __heap_addrem_desc@DB_VERSION_UNIQUE_NAME@
+#define	__heap_addrem_50_desc __heap_addrem_50_desc@DB_VERSION_UNIQUE_NAME@
+#define	__heap_pg_alloc_desc __heap_pg_alloc_desc@DB_VERSION_UNIQUE_NAME@
+#define	__heap_trunc_meta_desc __heap_trunc_meta_desc@DB_VERSION_UNIQUE_NAME@
+#define	__heap_trunc_page_desc __heap_trunc_page_desc@DB_VERSION_UNIQUE_NAME@
+#define	__qam_incfirst_desc __qam_incfirst_desc@DB_VERSION_UNIQUE_NAME@
+#define	__qam_mvptr_desc __qam_mvptr_desc@DB_VERSION_UNIQUE_NAME@
+#define	__qam_del_desc __qam_del_desc@DB_VERSION_UNIQUE_NAME@
+#define	__qam_add_desc __qam_add_desc@DB_VERSION_UNIQUE_NAME@
+#define	__qam_delext_desc __qam_delext_desc@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_member_desc __repmgr_member_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_regop_42_desc __txn_regop_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_regop_desc __txn_regop_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_ckp_42_desc __txn_ckp_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_ckp_desc __txn_ckp_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_child_desc __txn_child_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_xa_regop_42_desc __txn_xa_regop_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_prepare_desc __txn_prepare_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_recycle_desc __txn_recycle_desc@DB_VERSION_UNIQUE_NAME@
+#define	__db_util_arg __db_util_arg@DB_VERSION_UNIQUE_NAME@
+#define	__db_util_cache __db_util_cache@DB_VERSION_UNIQUE_NAME@
+#define	__db_util_logset __db_util_logset@DB_VERSION_UNIQUE_NAME@
+#define	__db_util_siginit __db_util_siginit@DB_VERSION_UNIQUE_NAME@
+#define	__db_util_interrupted __db_util_interrupted@DB_VERSION_UNIQUE_NAME@
+#define	__db_util_sigresend __db_util_sigresend@DB_VERSION_UNIQUE_NAME@
+#define	__db_zero_fill __db_zero_fill@DB_VERSION_UNIQUE_NAME@
+#define	__db_zero_extend __db_zero_extend@DB_VERSION_UNIQUE_NAME@
+#define	__aes_setup __aes_setup@DB_VERSION_UNIQUE_NAME@
+#define	__aes_adj_size __aes_adj_size@DB_VERSION_UNIQUE_NAME@
+#define	__aes_close __aes_close@DB_VERSION_UNIQUE_NAME@
+#define	__aes_decrypt __aes_decrypt@DB_VERSION_UNIQUE_NAME@
+#define	__aes_encrypt __aes_encrypt@DB_VERSION_UNIQUE_NAME@
+#define	__aes_init __aes_init@DB_VERSION_UNIQUE_NAME@
+#define	__crypto_env_close __crypto_env_close@DB_VERSION_UNIQUE_NAME@
+#define	__crypto_env_refresh __crypto_env_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__crypto_algsetup __crypto_algsetup@DB_VERSION_UNIQUE_NAME@
+#define	__crypto_decrypt_meta __crypto_decrypt_meta@DB_VERSION_UNIQUE_NAME@
+#define	__crypto_set_passwd __crypto_set_passwd@DB_VERSION_UNIQUE_NAME@
+#define	__db_generate_iv __db_generate_iv@DB_VERSION_UNIQUE_NAME@
+#define	__db_rijndaelKeySetupEnc __db_rijndaelKeySetupEnc@DB_VERSION_UNIQUE_NAME@
+#define	__db_rijndaelKeySetupDec __db_rijndaelKeySetupDec@DB_VERSION_UNIQUE_NAME@
+#define	__db_rijndaelEncrypt __db_rijndaelEncrypt@DB_VERSION_UNIQUE_NAME@
+#define	__db_rijndaelDecrypt __db_rijndaelDecrypt@DB_VERSION_UNIQUE_NAME@
+#define	__db_rijndaelEncryptRound __db_rijndaelEncryptRound@DB_VERSION_UNIQUE_NAME@
+#define	__db_rijndaelDecryptRound __db_rijndaelDecryptRound@DB_VERSION_UNIQUE_NAME@
+#define	__db_makeKey __db_makeKey@DB_VERSION_UNIQUE_NAME@
+#define	__db_cipherInit __db_cipherInit@DB_VERSION_UNIQUE_NAME@
+#define	__db_blockEncrypt __db_blockEncrypt@DB_VERSION_UNIQUE_NAME@
+#define	__db_padEncrypt __db_padEncrypt@DB_VERSION_UNIQUE_NAME@
+#define	__db_blockDecrypt __db_blockDecrypt@DB_VERSION_UNIQUE_NAME@
+#define	__db_padDecrypt __db_padDecrypt@DB_VERSION_UNIQUE_NAME@
+#define	__db_cipherUpdateRounds __db_cipherUpdateRounds@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_setup __dbreg_setup@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_teardown __dbreg_teardown@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_teardown_int __dbreg_teardown_int@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_new_id __dbreg_new_id@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_get_id __dbreg_get_id@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_assign_id __dbreg_assign_id@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_revoke_id __dbreg_revoke_id@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_revoke_id_int __dbreg_revoke_id_int@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_close_id __dbreg_close_id@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_close_id_int __dbreg_close_id_int@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_failchk __dbreg_failchk@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_log_close __dbreg_log_close@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_log_id __dbreg_log_id@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_register_desc __dbreg_register_desc@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_init_recover __dbreg_init_recover@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_register_print __dbreg_register_print@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_init_print __dbreg_init_print@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_register_recover __dbreg_register_recover@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_stat_print __dbreg_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_print_fname __dbreg_print_fname@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_add_dbentry __dbreg_add_dbentry@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_rem_dbentry __dbreg_rem_dbentry@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_log_files __dbreg_log_files@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_log_nofiles __dbreg_log_nofiles@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_close_files __dbreg_close_files@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_close_file __dbreg_close_file@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_mark_restored __dbreg_mark_restored@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_invalidate_files __dbreg_invalidate_files@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_id_to_db __dbreg_id_to_db@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_id_to_fname __dbreg_id_to_fname@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_fid_to_fname __dbreg_fid_to_fname@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_get_name __dbreg_get_name@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_do_open __dbreg_do_open@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_lazy_id __dbreg_lazy_id@DB_VERSION_UNIQUE_NAME@
+#define	__env_alloc_init __env_alloc_init@DB_VERSION_UNIQUE_NAME@
+#define	__env_alloc_overhead __env_alloc_overhead@DB_VERSION_UNIQUE_NAME@
+#define	__env_alloc_size __env_alloc_size@DB_VERSION_UNIQUE_NAME@
+#define	__env_alloc __env_alloc@DB_VERSION_UNIQUE_NAME@
+#define	__env_alloc_free __env_alloc_free@DB_VERSION_UNIQUE_NAME@
+#define	__env_alloc_extend __env_alloc_extend@DB_VERSION_UNIQUE_NAME@
+#define	__env_region_extend __env_region_extend@DB_VERSION_UNIQUE_NAME@
+#define	__env_elem_size __env_elem_size@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_chunk __env_get_chunk@DB_VERSION_UNIQUE_NAME@
+#define	__env_alloc_print __env_alloc_print@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_backup_config __env_get_backup_config@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_backup_config __env_set_backup_config@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_backup_callbacks __env_get_backup_callbacks@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_backup_callbacks __env_set_backup_callbacks@DB_VERSION_UNIQUE_NAME@
+#define	__env_read_db_config __env_read_db_config@DB_VERSION_UNIQUE_NAME@
+#define	__env_failchk_pp __env_failchk_pp@DB_VERSION_UNIQUE_NAME@
+#define	__env_failchk_int __env_failchk_int@DB_VERSION_UNIQUE_NAME@
+#define	__env_thread_size __env_thread_size@DB_VERSION_UNIQUE_NAME@
+#define	__env_thread_max __env_thread_max@DB_VERSION_UNIQUE_NAME@
+#define	__env_thread_init __env_thread_init@DB_VERSION_UNIQUE_NAME@
+#define	__env_thread_destroy __env_thread_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_state __env_set_state@DB_VERSION_UNIQUE_NAME@
+#define	__db_file_extend __db_file_extend@DB_VERSION_UNIQUE_NAME@
+#define	__db_file_multi_write __db_file_multi_write@DB_VERSION_UNIQUE_NAME@
+#define	__db_file_write __db_file_write@DB_VERSION_UNIQUE_NAME@
+#define	__db_env_destroy __db_env_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_alloc __env_get_alloc@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_alloc __env_set_alloc@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_memory_init __env_get_memory_init@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_memory_init __env_set_memory_init@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_memory_max __env_get_memory_max@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_memory_max __env_set_memory_max@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_encrypt_flags __env_get_encrypt_flags@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_encrypt __env_set_encrypt@DB_VERSION_UNIQUE_NAME@
+#define	__env_map_flags __env_map_flags@DB_VERSION_UNIQUE_NAME@
+#define	__env_fetch_flags __env_fetch_flags@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_flags __env_set_flags@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_backup __env_set_backup@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_data_dir __env_set_data_dir@DB_VERSION_UNIQUE_NAME@
+#define	__env_add_data_dir __env_add_data_dir@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_create_dir __env_set_create_dir@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_metadata_dir __env_set_metadata_dir@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_data_len __env_set_data_len@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_intermediate_dir_mode __env_set_intermediate_dir_mode@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_errcall __env_get_errcall@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_errcall __env_set_errcall@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_errfile __env_get_errfile@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_errfile __env_set_errfile@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_errpfx __env_get_errpfx@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_errpfx __env_set_errpfx@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_thread_count __env_set_thread_count@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_msgcall __env_get_msgcall@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_msgcall __env_set_msgcall@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_msgfile __env_get_msgfile@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_msgfile __env_set_msgfile@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_paniccall __env_set_paniccall@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_shm_key __env_set_shm_key@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_tmp_dir __env_set_tmp_dir@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_verbose __env_set_verbose@DB_VERSION_UNIQUE_NAME@
+#define	__db_mi_env __db_mi_env@DB_VERSION_UNIQUE_NAME@
+#define	__db_mi_open __db_mi_open@DB_VERSION_UNIQUE_NAME@
+#define	__env_not_config __env_not_config@DB_VERSION_UNIQUE_NAME@
+#define	__env_set_timeout __env_set_timeout@DB_VERSION_UNIQUE_NAME@
+#define	__env_thread_id_string __env_thread_id_string@DB_VERSION_UNIQUE_NAME@
+#define	__db_appname __db_appname@DB_VERSION_UNIQUE_NAME@
+#define	__db_tmp_open __db_tmp_open@DB_VERSION_UNIQUE_NAME@
+#define	__env_open_pp __env_open_pp@DB_VERSION_UNIQUE_NAME@
+#define	__env_open __env_open@DB_VERSION_UNIQUE_NAME@
+#define	__env_remove __env_remove@DB_VERSION_UNIQUE_NAME@
+#define	__env_config __env_config@DB_VERSION_UNIQUE_NAME@
+#define	__env_close_pp __env_close_pp@DB_VERSION_UNIQUE_NAME@
+#define	__env_close __env_close@DB_VERSION_UNIQUE_NAME@
+#define	__env_refresh __env_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__env_get_open_flags __env_get_open_flags@DB_VERSION_UNIQUE_NAME@
+#define	__env_attach_regions __env_attach_regions@DB_VERSION_UNIQUE_NAME@
+#define	__db_apprec __db_apprec@DB_VERSION_UNIQUE_NAME@
+#define	__env_openfiles __env_openfiles@DB_VERSION_UNIQUE_NAME@
+#define	__env_init_rec __env_init_rec@DB_VERSION_UNIQUE_NAME@
+#define	__env_attach __env_attach@DB_VERSION_UNIQUE_NAME@
+#define	__env_turn_on __env_turn_on@DB_VERSION_UNIQUE_NAME@
+#define	__env_turn_off __env_turn_off@DB_VERSION_UNIQUE_NAME@
+#define	__env_panic_set __env_panic_set@DB_VERSION_UNIQUE_NAME@
+#define	__env_ref_increment __env_ref_increment@DB_VERSION_UNIQUE_NAME@
+#define	__env_ref_decrement __env_ref_decrement@DB_VERSION_UNIQUE_NAME@
+#define	__env_ref_get __env_ref_get@DB_VERSION_UNIQUE_NAME@
+#define	__env_detach __env_detach@DB_VERSION_UNIQUE_NAME@
+#define	__env_remove_env __env_remove_env@DB_VERSION_UNIQUE_NAME@
+#define	__env_region_attach __env_region_attach@DB_VERSION_UNIQUE_NAME@
+#define	__env_region_share __env_region_share@DB_VERSION_UNIQUE_NAME@
+#define	__env_region_detach __env_region_detach@DB_VERSION_UNIQUE_NAME@
+#define	__envreg_register __envreg_register@DB_VERSION_UNIQUE_NAME@
+#define	__envreg_unregister __envreg_unregister@DB_VERSION_UNIQUE_NAME@
+#define	__envreg_xunlock __envreg_xunlock@DB_VERSION_UNIQUE_NAME@
+#define	__envreg_isalive __envreg_isalive@DB_VERSION_UNIQUE_NAME@
+#define	__env_struct_sig __env_struct_sig@DB_VERSION_UNIQUE_NAME@
+#define	__env_stat_print_pp __env_stat_print_pp@DB_VERSION_UNIQUE_NAME@
+#define	__db_print_fh __db_print_fh@DB_VERSION_UNIQUE_NAME@
+#define	__db_print_fileid __db_print_fileid@DB_VERSION_UNIQUE_NAME@
+#define	__db_dl __db_dl@DB_VERSION_UNIQUE_NAME@
+#define	__db_dl_pct __db_dl_pct@DB_VERSION_UNIQUE_NAME@
+#define	__db_dlbytes __db_dlbytes@DB_VERSION_UNIQUE_NAME@
+#define	__db_print_reginfo __db_print_reginfo@DB_VERSION_UNIQUE_NAME@
+#define	__db_stat_not_built __db_stat_not_built@DB_VERSION_UNIQUE_NAME@
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_close __repmgr_close@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_get_ack_policy __repmgr_get_ack_policy@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_set_ack_policy __repmgr_set_ack_policy@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_site __repmgr_site@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_site_by_eid __repmgr_site_by_eid@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_local_site __repmgr_local_site@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_site_list __repmgr_site_list@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_start __repmgr_start@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_stat_pp __repmgr_stat_pp@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_stat_print_pp __repmgr_stat_print_pp@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_handle_event __repmgr_handle_event@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_channel __repmgr_channel@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_set_msg_dispatch __repmgr_set_msg_dispatch@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_init_recover __repmgr_init_recover@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__fop_create_42_desc __fop_create_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_create_desc __fop_create_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_remove_desc __fop_remove_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_write_42_desc __fop_write_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_write_desc __fop_write_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_42_desc __fop_rename_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_noundo_46_desc __fop_rename_noundo_46_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_desc __fop_rename_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_noundo_desc __fop_rename_noundo_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_file_remove_desc __fop_file_remove_desc@DB_VERSION_UNIQUE_NAME@
+#define	__fop_init_recover __fop_init_recover@DB_VERSION_UNIQUE_NAME@
+#define	__fop_create_42_print __fop_create_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__fop_create_print __fop_create_print@DB_VERSION_UNIQUE_NAME@
+#define	__fop_remove_print __fop_remove_print@DB_VERSION_UNIQUE_NAME@
+#define	__fop_write_42_print __fop_write_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__fop_write_print __fop_write_print@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_42_print __fop_rename_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_print __fop_rename_print@DB_VERSION_UNIQUE_NAME@
+#define	__fop_file_remove_print __fop_file_remove_print@DB_VERSION_UNIQUE_NAME@
+#define	__fop_init_print __fop_init_print@DB_VERSION_UNIQUE_NAME@
+#define	__fop_create __fop_create@DB_VERSION_UNIQUE_NAME@
+#define	__fop_remove __fop_remove@DB_VERSION_UNIQUE_NAME@
+#define	__fop_write __fop_write@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename __fop_rename@DB_VERSION_UNIQUE_NAME@
+#define	__fop_create_recover __fop_create_recover@DB_VERSION_UNIQUE_NAME@
+#define	__fop_create_42_recover __fop_create_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__fop_remove_recover __fop_remove_recover@DB_VERSION_UNIQUE_NAME@
+#define	__fop_write_recover __fop_write_recover@DB_VERSION_UNIQUE_NAME@
+#define	__fop_write_42_recover __fop_write_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_recover __fop_rename_recover@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_noundo_recover __fop_rename_noundo_recover@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_42_recover __fop_rename_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_noundo_46_recover __fop_rename_noundo_46_recover@DB_VERSION_UNIQUE_NAME@
+#define	__fop_file_remove_recover __fop_file_remove_recover@DB_VERSION_UNIQUE_NAME@
+#define	__fop_lock_handle __fop_lock_handle@DB_VERSION_UNIQUE_NAME@
+#define	__fop_file_setup __fop_file_setup@DB_VERSION_UNIQUE_NAME@
+#define	__fop_subdb_setup __fop_subdb_setup@DB_VERSION_UNIQUE_NAME@
+#define	__fop_remove_setup __fop_remove_setup@DB_VERSION_UNIQUE_NAME@
+#define	__fop_read_meta __fop_read_meta@DB_VERSION_UNIQUE_NAME@
+#define	__fop_dummy __fop_dummy@DB_VERSION_UNIQUE_NAME@
+#define	__fop_dbrename __fop_dbrename@DB_VERSION_UNIQUE_NAME@
+#define	__ham_quick_delete __ham_quick_delete@DB_VERSION_UNIQUE_NAME@
+#define	__hamc_init __hamc_init@DB_VERSION_UNIQUE_NAME@
+#define	__hamc_count __hamc_count@DB_VERSION_UNIQUE_NAME@
+#define	__hamc_cmp __hamc_cmp@DB_VERSION_UNIQUE_NAME@
+#define	__hamc_dup __hamc_dup@DB_VERSION_UNIQUE_NAME@
+#define	__ham_contract_table __ham_contract_table@DB_VERSION_UNIQUE_NAME@
+#define	__ham_call_hash __ham_call_hash@DB_VERSION_UNIQUE_NAME@
+#define	__ham_overwrite __ham_overwrite@DB_VERSION_UNIQUE_NAME@
+#define	__ham_lookup __ham_lookup@DB_VERSION_UNIQUE_NAME@
+#define	__ham_init_dbt __ham_init_dbt@DB_VERSION_UNIQUE_NAME@
+#define	__hamc_update __hamc_update@DB_VERSION_UNIQUE_NAME@
+#define	__ham_get_clist __ham_get_clist@DB_VERSION_UNIQUE_NAME@
+#define	__ham_insdel_desc __ham_insdel_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_insdel_42_desc __ham_insdel_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_newpage_desc __ham_newpage_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_splitdata_desc __ham_splitdata_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_replace_desc __ham_replace_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_replace_42_desc __ham_replace_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_copypage_desc __ham_copypage_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_metagroup_42_desc __ham_metagroup_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_metagroup_desc __ham_metagroup_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_groupalloc_42_desc __ham_groupalloc_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_groupalloc_desc __ham_groupalloc_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_changeslot_desc __ham_changeslot_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_contract_desc __ham_contract_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_curadj_desc __ham_curadj_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_chgpg_desc __ham_chgpg_desc@DB_VERSION_UNIQUE_NAME@
+#define	__ham_init_recover __ham_init_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_insdel_print __ham_insdel_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_insdel_42_print __ham_insdel_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_newpage_print __ham_newpage_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_splitdata_print __ham_splitdata_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_replace_print __ham_replace_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_replace_42_print __ham_replace_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_copypage_print __ham_copypage_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_metagroup_42_print __ham_metagroup_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_metagroup_print __ham_metagroup_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_groupalloc_42_print __ham_groupalloc_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_groupalloc_print __ham_groupalloc_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_changeslot_print __ham_changeslot_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_contract_print __ham_contract_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_curadj_print __ham_curadj_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_chgpg_print __ham_chgpg_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_init_print __ham_init_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_compact_int __ham_compact_int@DB_VERSION_UNIQUE_NAME@
+#define	__ham_compact_bucket __ham_compact_bucket@DB_VERSION_UNIQUE_NAME@
+#define	__ham_compact_hash __ham_compact_hash@DB_VERSION_UNIQUE_NAME@
+#define	__ham_pgin __ham_pgin@DB_VERSION_UNIQUE_NAME@
+#define	__ham_pgout __ham_pgout@DB_VERSION_UNIQUE_NAME@
+#define	__ham_mswap __ham_mswap@DB_VERSION_UNIQUE_NAME@
+#define	__ham_add_dup __ham_add_dup@DB_VERSION_UNIQUE_NAME@
+#define	__ham_dup_convert __ham_dup_convert@DB_VERSION_UNIQUE_NAME@
+#define	__ham_make_dup __ham_make_dup@DB_VERSION_UNIQUE_NAME@
+#define	__ham_dsearch __ham_dsearch@DB_VERSION_UNIQUE_NAME@
+#define	__ham_func2 __ham_func2@DB_VERSION_UNIQUE_NAME@
+#define	__ham_func3 __ham_func3@DB_VERSION_UNIQUE_NAME@
+#define	__ham_func4 __ham_func4@DB_VERSION_UNIQUE_NAME@
+#define	__ham_func5 __ham_func5@DB_VERSION_UNIQUE_NAME@
+#define	__ham_test __ham_test@DB_VERSION_UNIQUE_NAME@
+#define	__ham_get_meta __ham_get_meta@DB_VERSION_UNIQUE_NAME@
+#define	__ham_release_meta __ham_release_meta@DB_VERSION_UNIQUE_NAME@
+#define	__ham_dirty_meta __ham_dirty_meta@DB_VERSION_UNIQUE_NAME@
+#define	__ham_return_meta __ham_return_meta@DB_VERSION_UNIQUE_NAME@
+#define	__ham_db_create __ham_db_create@DB_VERSION_UNIQUE_NAME@
+#define	__ham_db_close __ham_db_close@DB_VERSION_UNIQUE_NAME@
+#define	__ham_get_h_ffactor __ham_get_h_ffactor@DB_VERSION_UNIQUE_NAME@
+#define	__ham_set_h_compare __ham_set_h_compare@DB_VERSION_UNIQUE_NAME@
+#define	__ham_get_h_nelem __ham_get_h_nelem@DB_VERSION_UNIQUE_NAME@
+#define	__ham_copy_config __ham_copy_config@DB_VERSION_UNIQUE_NAME@
+#define	__ham_open __ham_open@DB_VERSION_UNIQUE_NAME@
+#define	__ham_metachk __ham_metachk@DB_VERSION_UNIQUE_NAME@
+#define	__ham_new_file __ham_new_file@DB_VERSION_UNIQUE_NAME@
+#define	__ham_new_subdb __ham_new_subdb@DB_VERSION_UNIQUE_NAME@
+#define	__ham_item __ham_item@DB_VERSION_UNIQUE_NAME@
+#define	__ham_item_reset __ham_item_reset@DB_VERSION_UNIQUE_NAME@
+#define	__ham_item_init __ham_item_init@DB_VERSION_UNIQUE_NAME@
+#define	__ham_item_last __ham_item_last@DB_VERSION_UNIQUE_NAME@
+#define	__ham_item_first __ham_item_first@DB_VERSION_UNIQUE_NAME@
+#define	__ham_item_prev __ham_item_prev@DB_VERSION_UNIQUE_NAME@
+#define	__ham_item_next __ham_item_next@DB_VERSION_UNIQUE_NAME@
+#define	__ham_insertpair __ham_insertpair@DB_VERSION_UNIQUE_NAME@
+#define	__ham_getindex __ham_getindex@DB_VERSION_UNIQUE_NAME@
+#define	__ham_verify_sorted_page __ham_verify_sorted_page@DB_VERSION_UNIQUE_NAME@
+#define	__ham_sort_page_cursor __ham_sort_page_cursor@DB_VERSION_UNIQUE_NAME@
+#define	__ham_sort_page __ham_sort_page@DB_VERSION_UNIQUE_NAME@
+#define	__ham_del_pair __ham_del_pair@DB_VERSION_UNIQUE_NAME@
+#define	__ham_replpair __ham_replpair@DB_VERSION_UNIQUE_NAME@
+#define	__ham_onpage_replace __ham_onpage_replace@DB_VERSION_UNIQUE_NAME@
+#define	__ham_merge_pages __ham_merge_pages@DB_VERSION_UNIQUE_NAME@
+#define	__ham_split_page __ham_split_page@DB_VERSION_UNIQUE_NAME@
+#define	__ham_add_el __ham_add_el@DB_VERSION_UNIQUE_NAME@
+#define	__ham_copypair __ham_copypair@DB_VERSION_UNIQUE_NAME@
+#define	__ham_add_ovflpage __ham_add_ovflpage@DB_VERSION_UNIQUE_NAME@
+#define	__ham_get_cpage __ham_get_cpage@DB_VERSION_UNIQUE_NAME@
+#define	__ham_next_cpage __ham_next_cpage@DB_VERSION_UNIQUE_NAME@
+#define	__ham_lock_bucket __ham_lock_bucket@DB_VERSION_UNIQUE_NAME@
+#define	__ham_dpair __ham_dpair@DB_VERSION_UNIQUE_NAME@
+#define	__ham_insdel_recover __ham_insdel_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_insdel_42_recover __ham_insdel_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_newpage_recover __ham_newpage_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_replace_recover __ham_replace_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_replace_42_recover __ham_replace_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_splitdata_recover __ham_splitdata_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_copypage_recover __ham_copypage_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_metagroup_recover __ham_metagroup_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_contract_recover __ham_contract_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_groupalloc_recover __ham_groupalloc_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_changeslot_recover __ham_changeslot_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_curadj_recover __ham_curadj_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_chgpg_recover __ham_chgpg_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_metagroup_42_recover __ham_metagroup_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_groupalloc_42_recover __ham_groupalloc_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__ham_reclaim __ham_reclaim@DB_VERSION_UNIQUE_NAME@
+#define	__ham_truncate __ham_truncate@DB_VERSION_UNIQUE_NAME@
+#define	__ham_stat __ham_stat@DB_VERSION_UNIQUE_NAME@
+#define	__ham_stat_print __ham_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__ham_print_cursor __ham_print_cursor@DB_VERSION_UNIQUE_NAME@
+#define	__ham_traverse __ham_traverse@DB_VERSION_UNIQUE_NAME@
+#define	__db_no_hash_am __db_no_hash_am@DB_VERSION_UNIQUE_NAME@
+#define	__ham_30_hashmeta __ham_30_hashmeta@DB_VERSION_UNIQUE_NAME@
+#define	__ham_30_sizefix __ham_30_sizefix@DB_VERSION_UNIQUE_NAME@
+#define	__ham_31_hashmeta __ham_31_hashmeta@DB_VERSION_UNIQUE_NAME@
+#define	__ham_31_hash __ham_31_hash@DB_VERSION_UNIQUE_NAME@
+#define	__ham_46_hashmeta __ham_46_hashmeta@DB_VERSION_UNIQUE_NAME@
+#define	__ham_46_hash __ham_46_hash@DB_VERSION_UNIQUE_NAME@
+#define	__ham_vrfy_meta __ham_vrfy_meta@DB_VERSION_UNIQUE_NAME@
+#define	__ham_vrfy __ham_vrfy@DB_VERSION_UNIQUE_NAME@
+#define	__ham_vrfy_structure __ham_vrfy_structure@DB_VERSION_UNIQUE_NAME@
+#define	__ham_vrfy_hashing __ham_vrfy_hashing@DB_VERSION_UNIQUE_NAME@
+#define	__ham_salvage __ham_salvage@DB_VERSION_UNIQUE_NAME@
+#define	__ham_meta2pgset __ham_meta2pgset@DB_VERSION_UNIQUE_NAME@
+#define	__heapc_init __heapc_init@DB_VERSION_UNIQUE_NAME@
+#define	__heap_ditem __heap_ditem@DB_VERSION_UNIQUE_NAME@
+#define	__heap_append __heap_append@DB_VERSION_UNIQUE_NAME@
+#define	__heap_pitem __heap_pitem@DB_VERSION_UNIQUE_NAME@
+#define	__heapc_dup __heapc_dup@DB_VERSION_UNIQUE_NAME@
+#define	__heapc_gsplit __heapc_gsplit@DB_VERSION_UNIQUE_NAME@
+#define	__heapc_refresh __heapc_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__heap_addrem_desc __heap_addrem_desc@DB_VERSION_UNIQUE_NAME@
+#define	__heap_addrem_50_desc __heap_addrem_50_desc@DB_VERSION_UNIQUE_NAME@
+#define	__heap_pg_alloc_desc __heap_pg_alloc_desc@DB_VERSION_UNIQUE_NAME@
+#define	__heap_trunc_meta_desc __heap_trunc_meta_desc@DB_VERSION_UNIQUE_NAME@
+#define	__heap_trunc_page_desc __heap_trunc_page_desc@DB_VERSION_UNIQUE_NAME@
+#define	__heap_init_recover __heap_init_recover@DB_VERSION_UNIQUE_NAME@
+#define	__heap_addrem_print __heap_addrem_print@DB_VERSION_UNIQUE_NAME@
+#define	__heap_addrem_50_print __heap_addrem_50_print@DB_VERSION_UNIQUE_NAME@
+#define	__heap_pg_alloc_print __heap_pg_alloc_print@DB_VERSION_UNIQUE_NAME@
+#define	__heap_trunc_meta_print __heap_trunc_meta_print@DB_VERSION_UNIQUE_NAME@
+#define	__heap_trunc_page_print __heap_trunc_page_print@DB_VERSION_UNIQUE_NAME@
+#define	__heap_init_print __heap_init_print@DB_VERSION_UNIQUE_NAME@
+#define	__heap_backup __heap_backup@DB_VERSION_UNIQUE_NAME@
+#define	__heap_pgin __heap_pgin@DB_VERSION_UNIQUE_NAME@
+#define	__heap_pgout __heap_pgout@DB_VERSION_UNIQUE_NAME@
+#define	__heap_mswap __heap_mswap@DB_VERSION_UNIQUE_NAME@
+#define	__heap_db_create __heap_db_create@DB_VERSION_UNIQUE_NAME@
+#define	__heap_db_close __heap_db_close@DB_VERSION_UNIQUE_NAME@
+#define	__heap_get_heapsize __heap_get_heapsize@DB_VERSION_UNIQUE_NAME@
+#define	__heap_get_heap_regionsize __heap_get_heap_regionsize@DB_VERSION_UNIQUE_NAME@
+#define	__heap_set_heapsize __heap_set_heapsize@DB_VERSION_UNIQUE_NAME@
+#define	__heap_set_heap_regionsize __heap_set_heap_regionsize@DB_VERSION_UNIQUE_NAME@
+#define	__heap_exist __heap_exist@DB_VERSION_UNIQUE_NAME@
+#define	__heap_open __heap_open@DB_VERSION_UNIQUE_NAME@
+#define	__heap_metachk __heap_metachk@DB_VERSION_UNIQUE_NAME@
+#define	__heap_read_meta __heap_read_meta@DB_VERSION_UNIQUE_NAME@
+#define	__heap_new_file __heap_new_file@DB_VERSION_UNIQUE_NAME@
+#define	__heap_create_region __heap_create_region@DB_VERSION_UNIQUE_NAME@
+#define	__heap_addrem_recover __heap_addrem_recover@DB_VERSION_UNIQUE_NAME@
+#define	__heap_pg_alloc_recover __heap_pg_alloc_recover@DB_VERSION_UNIQUE_NAME@
+#define	__heap_trunc_meta_recover __heap_trunc_meta_recover@DB_VERSION_UNIQUE_NAME@
+#define	__heap_trunc_page_recover __heap_trunc_page_recover@DB_VERSION_UNIQUE_NAME@
+#define	__heap_addrem_50_recover __heap_addrem_50_recover@DB_VERSION_UNIQUE_NAME@
+#define	__heap_truncate __heap_truncate@DB_VERSION_UNIQUE_NAME@
+#define	__heap_stat __heap_stat@DB_VERSION_UNIQUE_NAME@
+#define	__heap_stat_print __heap_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__heap_print_cursor __heap_print_cursor@DB_VERSION_UNIQUE_NAME@
+#define	__heap_stat_callback __heap_stat_callback@DB_VERSION_UNIQUE_NAME@
+#define	__heap_traverse __heap_traverse@DB_VERSION_UNIQUE_NAME@
+#define	__db_no_heap_am __db_no_heap_am@DB_VERSION_UNIQUE_NAME@
+#define	__heap_vrfy_meta __heap_vrfy_meta@DB_VERSION_UNIQUE_NAME@
+#define	__heap_vrfy __heap_vrfy@DB_VERSION_UNIQUE_NAME@
+#define	__heap_vrfy_structure __heap_vrfy_structure@DB_VERSION_UNIQUE_NAME@
+#define	__heap_salvage __heap_salvage@DB_VERSION_UNIQUE_NAME@
+#define	__heap_meta2pgset __heap_meta2pgset@DB_VERSION_UNIQUE_NAME@
+#define	__db_chksum __db_chksum@DB_VERSION_UNIQUE_NAME@
+#define	__db_derive_mac __db_derive_mac@DB_VERSION_UNIQUE_NAME@
+#define	__db_check_chksum __db_check_chksum@DB_VERSION_UNIQUE_NAME@
+#define	__db_SHA1Transform __db_SHA1Transform@DB_VERSION_UNIQUE_NAME@
+#define	__db_SHA1Init __db_SHA1Init@DB_VERSION_UNIQUE_NAME@
+#define	__db_SHA1Update __db_SHA1Update@DB_VERSION_UNIQUE_NAME@
+#define	__db_SHA1Final __db_SHA1Final@DB_VERSION_UNIQUE_NAME@
+#define	__db_lget __db_lget@DB_VERSION_UNIQUE_NAME@
+#define	__db_lput __db_lput@DB_VERSION_UNIQUE_NAME@
+#define	__db_lprint __db_lprint@DB_VERSION_UNIQUE_NAME@
+#define	__lock_vec_pp __lock_vec_pp@DB_VERSION_UNIQUE_NAME@
+#define	__lock_vec __lock_vec@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_pp __lock_get_pp@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get __lock_get@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_internal __lock_get_internal@DB_VERSION_UNIQUE_NAME@
+#define	__lock_put_pp __lock_put_pp@DB_VERSION_UNIQUE_NAME@
+#define	__lock_put __lock_put@DB_VERSION_UNIQUE_NAME@
+#define	__lock_downgrade __lock_downgrade@DB_VERSION_UNIQUE_NAME@
+#define	__lock_locker_same_family __lock_locker_same_family@DB_VERSION_UNIQUE_NAME@
+#define	__lock_wakeup __lock_wakeup@DB_VERSION_UNIQUE_NAME@
+#define	__lock_promote __lock_promote@DB_VERSION_UNIQUE_NAME@
+#define	__lock_change __lock_change@DB_VERSION_UNIQUE_NAME@
+#define	__lock_detect_pp __lock_detect_pp@DB_VERSION_UNIQUE_NAME@
+#define	__lock_detect __lock_detect@DB_VERSION_UNIQUE_NAME@
+#define	__lock_failchk __lock_failchk@DB_VERSION_UNIQUE_NAME@
+#define	__lock_id_pp __lock_id_pp@DB_VERSION_UNIQUE_NAME@
+#define	__lock_id __lock_id@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_thread_id __lock_set_thread_id@DB_VERSION_UNIQUE_NAME@
+#define	__lock_id_free_pp __lock_id_free_pp@DB_VERSION_UNIQUE_NAME@
+#define	__lock_id_free __lock_id_free@DB_VERSION_UNIQUE_NAME@
+#define	__lock_id_set __lock_id_set@DB_VERSION_UNIQUE_NAME@
+#define	__lock_getlocker __lock_getlocker@DB_VERSION_UNIQUE_NAME@
+#define	__lock_getlocker_int __lock_getlocker_int@DB_VERSION_UNIQUE_NAME@
+#define	__lock_addfamilylocker __lock_addfamilylocker@DB_VERSION_UNIQUE_NAME@
+#define	__lock_freelocker __lock_freelocker@DB_VERSION_UNIQUE_NAME@
+#define	__lock_familyremove __lock_familyremove@DB_VERSION_UNIQUE_NAME@
+#define	__lock_fix_list __lock_fix_list@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_list __lock_get_list@DB_VERSION_UNIQUE_NAME@
+#define	__lock_list_print __lock_list_print@DB_VERSION_UNIQUE_NAME@
+#define	__lock_env_create __lock_env_create@DB_VERSION_UNIQUE_NAME@
+#define	__lock_env_destroy __lock_env_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_lk_conflicts __lock_get_lk_conflicts@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_lk_conflicts __lock_set_lk_conflicts@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_lk_detect __lock_get_lk_detect@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_lk_detect __lock_set_lk_detect@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_lk_max_locks __lock_get_lk_max_locks@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_lk_max_locks __lock_set_lk_max_locks@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_lk_max_lockers __lock_get_lk_max_lockers@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_lk_max_lockers __lock_set_lk_max_lockers@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_lk_max_objects __lock_get_lk_max_objects@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_lk_max_objects __lock_set_lk_max_objects@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_lk_partitions __lock_get_lk_partitions@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_lk_partitions __lock_set_lk_partitions@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_lk_tablesize __lock_get_lk_tablesize@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_lk_tablesize __lock_set_lk_tablesize@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_lk_priority __lock_set_lk_priority@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_lk_priority __lock_get_lk_priority@DB_VERSION_UNIQUE_NAME@
+#define	__lock_get_env_timeout __lock_get_env_timeout@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_env_timeout __lock_set_env_timeout@DB_VERSION_UNIQUE_NAME@
+#define	__lock_open __lock_open@DB_VERSION_UNIQUE_NAME@
+#define	__lock_env_refresh __lock_env_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__lock_region_mutex_count __lock_region_mutex_count@DB_VERSION_UNIQUE_NAME@
+#define	__lock_region_mutex_max __lock_region_mutex_max@DB_VERSION_UNIQUE_NAME@
+#define	__lock_region_max __lock_region_max@DB_VERSION_UNIQUE_NAME@
+#define	__lock_region_size __lock_region_size@DB_VERSION_UNIQUE_NAME@
+#define	__lock_stat_pp __lock_stat_pp@DB_VERSION_UNIQUE_NAME@
+#define	__lock_stat_print_pp __lock_stat_print_pp@DB_VERSION_UNIQUE_NAME@
+#define	__lock_stat_print __lock_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__lock_printlock __lock_printlock@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_timeout __lock_set_timeout@DB_VERSION_UNIQUE_NAME@
+#define	__lock_set_timeout_internal __lock_set_timeout_internal@DB_VERSION_UNIQUE_NAME@
+#define	__lock_inherit_timeout __lock_inherit_timeout@DB_VERSION_UNIQUE_NAME@
+#define	__lock_ohash __lock_ohash@DB_VERSION_UNIQUE_NAME@
+#define	__lock_lhash __lock_lhash@DB_VERSION_UNIQUE_NAME@
+#define	__lock_nomem __lock_nomem@DB_VERSION_UNIQUE_NAME@
+#define	__log_open __log_open@DB_VERSION_UNIQUE_NAME@
+#define	__log_find __log_find@DB_VERSION_UNIQUE_NAME@
+#define	__log_valid __log_valid@DB_VERSION_UNIQUE_NAME@
+#define	__log_env_refresh __log_env_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__log_get_cached_ckp_lsn __log_get_cached_ckp_lsn@DB_VERSION_UNIQUE_NAME@
+#define	__log_region_mutex_count __log_region_mutex_count@DB_VERSION_UNIQUE_NAME@
+#define	__log_region_mutex_max __log_region_mutex_max@DB_VERSION_UNIQUE_NAME@
+#define	__log_region_size __log_region_size@DB_VERSION_UNIQUE_NAME@
+#define	__log_region_max __log_region_max@DB_VERSION_UNIQUE_NAME@
+#define	__log_vtruncate __log_vtruncate@DB_VERSION_UNIQUE_NAME@
+#define	__log_is_outdated __log_is_outdated@DB_VERSION_UNIQUE_NAME@
+#define	__log_zero __log_zero@DB_VERSION_UNIQUE_NAME@
+#define	__log_inmem_lsnoff __log_inmem_lsnoff@DB_VERSION_UNIQUE_NAME@
+#define	__log_inmem_newfile __log_inmem_newfile@DB_VERSION_UNIQUE_NAME@
+#define	__log_inmem_chkspace __log_inmem_chkspace@DB_VERSION_UNIQUE_NAME@
+#define	__log_inmem_copyout __log_inmem_copyout@DB_VERSION_UNIQUE_NAME@
+#define	__log_inmem_copyin __log_inmem_copyin@DB_VERSION_UNIQUE_NAME@
+#define	__log_set_version __log_set_version@DB_VERSION_UNIQUE_NAME@
+#define	__log_get_oldversion __log_get_oldversion@DB_VERSION_UNIQUE_NAME@
+#define	__log_archive_pp __log_archive_pp@DB_VERSION_UNIQUE_NAME@
+#define	__log_archive __log_archive@DB_VERSION_UNIQUE_NAME@
+#define	__log_get_stable_lsn __log_get_stable_lsn@DB_VERSION_UNIQUE_NAME@
+#define	__log_autoremove __log_autoremove@DB_VERSION_UNIQUE_NAME@
+#define	__log_check_page_lsn __log_check_page_lsn@DB_VERSION_UNIQUE_NAME@
+#define	__log_printf_capi __log_printf_capi@DB_VERSION_UNIQUE_NAME@
+#define	__log_printf_pp __log_printf_pp@DB_VERSION_UNIQUE_NAME@
+#define	__log_printf __log_printf@DB_VERSION_UNIQUE_NAME@
+#define	__log_cursor_pp __log_cursor_pp@DB_VERSION_UNIQUE_NAME@
+#define	__log_cursor __log_cursor@DB_VERSION_UNIQUE_NAME@
+#define	__logc_close __logc_close@DB_VERSION_UNIQUE_NAME@
+#define	__logc_version __logc_version@DB_VERSION_UNIQUE_NAME@
+#define	__logc_get __logc_get@DB_VERSION_UNIQUE_NAME@
+#define	__log_hdrswap __log_hdrswap@DB_VERSION_UNIQUE_NAME@
+#define	__log_persistswap __log_persistswap@DB_VERSION_UNIQUE_NAME@
+#define	__log_read_record_pp __log_read_record_pp@DB_VERSION_UNIQUE_NAME@
+#define	__log_read_record __log_read_record@DB_VERSION_UNIQUE_NAME@
+#define	__log_env_create __log_env_create@DB_VERSION_UNIQUE_NAME@
+#define	__log_env_destroy __log_env_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__log_get_lg_bsize __log_get_lg_bsize@DB_VERSION_UNIQUE_NAME@
+#define	__log_set_lg_bsize __log_set_lg_bsize@DB_VERSION_UNIQUE_NAME@
+#define	__log_get_lg_filemode __log_get_lg_filemode@DB_VERSION_UNIQUE_NAME@
+#define	__log_set_lg_filemode __log_set_lg_filemode@DB_VERSION_UNIQUE_NAME@
+#define	__log_get_lg_max __log_get_lg_max@DB_VERSION_UNIQUE_NAME@
+#define	__log_set_lg_max __log_set_lg_max@DB_VERSION_UNIQUE_NAME@
+#define	__log_get_lg_regionmax __log_get_lg_regionmax@DB_VERSION_UNIQUE_NAME@
+#define	__log_set_lg_regionmax __log_set_lg_regionmax@DB_VERSION_UNIQUE_NAME@
+#define	__log_get_lg_dir __log_get_lg_dir@DB_VERSION_UNIQUE_NAME@
+#define	__log_set_lg_dir __log_set_lg_dir@DB_VERSION_UNIQUE_NAME@
+#define	__log_get_flags __log_get_flags@DB_VERSION_UNIQUE_NAME@
+#define	__log_set_flags __log_set_flags@DB_VERSION_UNIQUE_NAME@
+#define	__log_get_config __log_get_config@DB_VERSION_UNIQUE_NAME@
+#define	__log_set_config __log_set_config@DB_VERSION_UNIQUE_NAME@
+#define	__log_set_config_int __log_set_config_int@DB_VERSION_UNIQUE_NAME@
+#define	__log_check_sizes __log_check_sizes@DB_VERSION_UNIQUE_NAME@
+#define	__log_print_record __log_print_record@DB_VERSION_UNIQUE_NAME@
+#define	__log_put_pp __log_put_pp@DB_VERSION_UNIQUE_NAME@
+#define	__log_put __log_put@DB_VERSION_UNIQUE_NAME@
+#define	__log_current_lsn_int __log_current_lsn_int@DB_VERSION_UNIQUE_NAME@
+#define	__log_current_lsn __log_current_lsn@DB_VERSION_UNIQUE_NAME@
+#define	__log_newfile __log_newfile@DB_VERSION_UNIQUE_NAME@
+#define	__log_flush_pp __log_flush_pp@DB_VERSION_UNIQUE_NAME@
+#define	__log_flush __log_flush@DB_VERSION_UNIQUE_NAME@
+#define	__log_flush_int __log_flush_int@DB_VERSION_UNIQUE_NAME@
+#define	__log_file_pp __log_file_pp@DB_VERSION_UNIQUE_NAME@
+#define	__log_name __log_name@DB_VERSION_UNIQUE_NAME@
+#define	__log_rep_put __log_rep_put@DB_VERSION_UNIQUE_NAME@
+#define	__log_put_record_pp __log_put_record_pp@DB_VERSION_UNIQUE_NAME@
+#define	__log_put_record __log_put_record@DB_VERSION_UNIQUE_NAME@
+#define	__log_stat_pp __log_stat_pp@DB_VERSION_UNIQUE_NAME@
+#define	__log_stat_print_pp __log_stat_print_pp@DB_VERSION_UNIQUE_NAME@
+#define	__log_stat_print __log_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__log_verify_pp __log_verify_pp@DB_VERSION_UNIQUE_NAME@
+#define	__log_verify __log_verify@DB_VERSION_UNIQUE_NAME@
+#define	__log_verify_wrap __log_verify_wrap@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_init_verify __crdel_init_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_init_verify __db_init_verify@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_init_verify __dbreg_init_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_init_verify __bam_init_verify@DB_VERSION_UNIQUE_NAME@
+#define	__fop_init_verify __fop_init_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_init_verify __ham_init_verify@DB_VERSION_UNIQUE_NAME@
+#define	__heap_init_verify __heap_init_verify@DB_VERSION_UNIQUE_NAME@
+#define	__qam_init_verify __qam_init_verify@DB_VERSION_UNIQUE_NAME@
+#define	__txn_init_verify __txn_init_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_log_verify_global_report __db_log_verify_global_report@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_metasub_verify __crdel_metasub_verify@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_create_verify __crdel_inmem_create_verify@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_rename_verify __crdel_inmem_rename_verify@DB_VERSION_UNIQUE_NAME@
+#define	__crdel_inmem_remove_verify __crdel_inmem_remove_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_addrem_verify __db_addrem_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_big_verify __db_big_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_ovref_verify __db_ovref_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_relink_42_verify __db_relink_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_debug_verify __db_debug_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_noop_verify __db_noop_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_alloc_42_verify __db_pg_alloc_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_alloc_verify __db_pg_alloc_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_free_42_verify __db_pg_free_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_free_verify __db_pg_free_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_cksum_verify __db_cksum_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_freedata_42_verify __db_pg_freedata_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_freedata_verify __db_pg_freedata_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_init_verify __db_pg_init_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_sort_44_verify __db_pg_sort_44_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_pg_trunc_verify __db_pg_trunc_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_realloc_verify __db_realloc_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_relink_verify __db_relink_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_merge_verify __db_merge_verify@DB_VERSION_UNIQUE_NAME@
+#define	__db_pgno_verify __db_pgno_verify@DB_VERSION_UNIQUE_NAME@
+#define	__dbreg_register_verify __dbreg_register_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_verify __bam_split_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_split_42_verify __bam_split_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_rsplit_verify __bam_rsplit_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_adj_verify __bam_adj_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_irep_verify __bam_irep_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_cadjust_verify __bam_cadjust_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_cdel_verify __bam_cdel_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_repl_verify __bam_repl_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_root_verify __bam_root_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_curadj_verify __bam_curadj_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_rcuradj_verify __bam_rcuradj_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_relink_43_verify __bam_relink_43_verify@DB_VERSION_UNIQUE_NAME@
+#define	__bam_merge_44_verify __bam_merge_44_verify@DB_VERSION_UNIQUE_NAME@
+#define	__fop_create_42_verify __fop_create_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__fop_create_verify __fop_create_verify@DB_VERSION_UNIQUE_NAME@
+#define	__fop_remove_verify __fop_remove_verify@DB_VERSION_UNIQUE_NAME@
+#define	__fop_write_42_verify __fop_write_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__fop_write_verify __fop_write_verify@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_42_verify __fop_rename_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__fop_rename_verify __fop_rename_verify@DB_VERSION_UNIQUE_NAME@
+#define	__fop_file_remove_verify __fop_file_remove_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_insdel_verify __ham_insdel_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_newpage_verify __ham_newpage_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_splitdata_verify __ham_splitdata_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_replace_verify __ham_replace_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_copypage_verify __ham_copypage_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_metagroup_42_verify __ham_metagroup_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_metagroup_verify __ham_metagroup_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_groupalloc_42_verify __ham_groupalloc_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_groupalloc_verify __ham_groupalloc_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_changeslot_verify __ham_changeslot_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_contract_verify __ham_contract_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_curadj_verify __ham_curadj_verify@DB_VERSION_UNIQUE_NAME@
+#define	__ham_chgpg_verify __ham_chgpg_verify@DB_VERSION_UNIQUE_NAME@
+#define	__heap_addrem_verify __heap_addrem_verify@DB_VERSION_UNIQUE_NAME@
+#define	__heap_pg_alloc_verify __heap_pg_alloc_verify@DB_VERSION_UNIQUE_NAME@
+#define	__heap_trunc_meta_verify __heap_trunc_meta_verify@DB_VERSION_UNIQUE_NAME@
+#define	__heap_trunc_page_verify __heap_trunc_page_verify@DB_VERSION_UNIQUE_NAME@
+#define	__qam_incfirst_verify __qam_incfirst_verify@DB_VERSION_UNIQUE_NAME@
+#define	__qam_mvptr_verify __qam_mvptr_verify@DB_VERSION_UNIQUE_NAME@
+#define	__qam_del_verify __qam_del_verify@DB_VERSION_UNIQUE_NAME@
+#define	__qam_add_verify __qam_add_verify@DB_VERSION_UNIQUE_NAME@
+#define	__qam_delext_verify __qam_delext_verify@DB_VERSION_UNIQUE_NAME@
+#define	__txn_regop_42_verify __txn_regop_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__txn_regop_verify __txn_regop_verify@DB_VERSION_UNIQUE_NAME@
+#define	__txn_ckp_42_verify __txn_ckp_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__txn_ckp_verify __txn_ckp_verify@DB_VERSION_UNIQUE_NAME@
+#define	__txn_child_verify __txn_child_verify@DB_VERSION_UNIQUE_NAME@
+#define	__txn_xa_regop_42_verify __txn_xa_regop_42_verify@DB_VERSION_UNIQUE_NAME@
+#define	__txn_prepare_verify __txn_prepare_verify@DB_VERSION_UNIQUE_NAME@
+#define	__txn_recycle_verify __txn_recycle_verify@DB_VERSION_UNIQUE_NAME@
+#define	__create_log_vrfy_info __create_log_vrfy_info@DB_VERSION_UNIQUE_NAME@
+#define	__destroy_log_vrfy_info __destroy_log_vrfy_info@DB_VERSION_UNIQUE_NAME@
+#define	__put_txn_vrfy_info __put_txn_vrfy_info@DB_VERSION_UNIQUE_NAME@
+#define	__get_txn_vrfy_info __get_txn_vrfy_info@DB_VERSION_UNIQUE_NAME@
+#define	__add_recycle_lsn_range __add_recycle_lsn_range@DB_VERSION_UNIQUE_NAME@
+#define	__iterate_txninfo __iterate_txninfo@DB_VERSION_UNIQUE_NAME@
+#define	__rem_last_recycle_lsn __rem_last_recycle_lsn@DB_VERSION_UNIQUE_NAME@
+#define	__add_file_updated __add_file_updated@DB_VERSION_UNIQUE_NAME@
+#define	__del_file_updated __del_file_updated@DB_VERSION_UNIQUE_NAME@
+#define	__clear_fileups __clear_fileups@DB_VERSION_UNIQUE_NAME@
+#define	__free_txninfo_stack __free_txninfo_stack@DB_VERSION_UNIQUE_NAME@
+#define	__free_txninfo __free_txninfo@DB_VERSION_UNIQUE_NAME@
+#define	__put_filereg_info __put_filereg_info@DB_VERSION_UNIQUE_NAME@
+#define	__del_filelife __del_filelife@DB_VERSION_UNIQUE_NAME@
+#define	__put_filelife __put_filelife@DB_VERSION_UNIQUE_NAME@
+#define	__get_filelife __get_filelife@DB_VERSION_UNIQUE_NAME@
+#define	__get_filereg_by_dbregid __get_filereg_by_dbregid@DB_VERSION_UNIQUE_NAME@
+#define	__add_dbregid __add_dbregid@DB_VERSION_UNIQUE_NAME@
+#define	__get_filereg_info __get_filereg_info@DB_VERSION_UNIQUE_NAME@
+#define	__free_filereg_info __free_filereg_info@DB_VERSION_UNIQUE_NAME@
+#define	__get_ckp_info __get_ckp_info@DB_VERSION_UNIQUE_NAME@
+#define	__get_last_ckp_info __get_last_ckp_info@DB_VERSION_UNIQUE_NAME@
+#define	__put_ckp_info __put_ckp_info@DB_VERSION_UNIQUE_NAME@
+#define	__get_timestamp_info __get_timestamp_info@DB_VERSION_UNIQUE_NAME@
+#define	__get_latest_timestamp_info __get_latest_timestamp_info@DB_VERSION_UNIQUE_NAME@
+#define	__put_timestamp_info __put_timestamp_info@DB_VERSION_UNIQUE_NAME@
+#define	__find_lsnrg_by_timerg __find_lsnrg_by_timerg@DB_VERSION_UNIQUE_NAME@
+#define	__add_txnrange __add_txnrange@DB_VERSION_UNIQUE_NAME@
+#define	__get_aborttxn __get_aborttxn@DB_VERSION_UNIQUE_NAME@
+#define	__txn_started __txn_started@DB_VERSION_UNIQUE_NAME@
+#define	__set_logvrfy_dbfuid __set_logvrfy_dbfuid@DB_VERSION_UNIQUE_NAME@
+#define	__add_page_to_txn __add_page_to_txn@DB_VERSION_UNIQUE_NAME@
+#define	__del_txn_pages __del_txn_pages@DB_VERSION_UNIQUE_NAME@
+#define	__is_ancestor_txn __is_ancestor_txn@DB_VERSION_UNIQUE_NAME@
+#define	__return_txn_pages __return_txn_pages@DB_VERSION_UNIQUE_NAME@
+#define	__memp_alloc __memp_alloc@DB_VERSION_UNIQUE_NAME@
+#define	__memp_free __memp_free@DB_VERSION_UNIQUE_NAME@
+#define	__memp_backup_open __memp_backup_open@DB_VERSION_UNIQUE_NAME@
+#define	__memp_backup_mpf __memp_backup_mpf@DB_VERSION_UNIQUE_NAME@
+#define	__memp_backup_close __memp_backup_close@DB_VERSION_UNIQUE_NAME@
+#define	__memp_failchk __memp_failchk@DB_VERSION_UNIQUE_NAME@
+#define	__memp_bhwrite __memp_bhwrite@DB_VERSION_UNIQUE_NAME@
+#define	__memp_pgread __memp_pgread@DB_VERSION_UNIQUE_NAME@
+#define	__memp_pg __memp_pg@DB_VERSION_UNIQUE_NAME@
+#define	__memp_bhfree __memp_bhfree@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fget_pp __memp_fget_pp@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fget __memp_fget@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fcreate_pp __memp_fcreate_pp@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fcreate __memp_fcreate@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_clear_len __memp_set_clear_len@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_fileid __memp_get_fileid@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_fileid __memp_set_fileid@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_flags __memp_get_flags@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_flags __memp_set_flags@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_ftype __memp_get_ftype@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_ftype __memp_set_ftype@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_lsn_offset __memp_set_lsn_offset@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_pgcookie __memp_get_pgcookie@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_pgcookie __memp_set_pgcookie@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_priority __memp_get_priority@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_last_pgno __memp_get_last_pgno@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fn __memp_fn@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fns __memp_fns@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fopen_pp __memp_fopen_pp@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fopen __memp_fopen@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fclose_pp __memp_fclose_pp@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fclose __memp_fclose@DB_VERSION_UNIQUE_NAME@
+#define	__memp_mf_discard __memp_mf_discard@DB_VERSION_UNIQUE_NAME@
+#define	__memp_inmemlist __memp_inmemlist@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fput_pp __memp_fput_pp@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fput __memp_fput@DB_VERSION_UNIQUE_NAME@
+#define	__memp_unpin_buffers __memp_unpin_buffers@DB_VERSION_UNIQUE_NAME@
+#define	__memp_dirty __memp_dirty@DB_VERSION_UNIQUE_NAME@
+#define	__memp_shared __memp_shared@DB_VERSION_UNIQUE_NAME@
+#define	__memp_env_create __memp_env_create@DB_VERSION_UNIQUE_NAME@
+#define	__memp_env_destroy __memp_env_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_cachesize __memp_get_cachesize@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_cachesize __memp_set_cachesize@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_config __memp_set_config@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_config __memp_get_config@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_mp_max_openfd __memp_get_mp_max_openfd@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_mp_max_openfd __memp_set_mp_max_openfd@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_mp_max_write __memp_get_mp_max_write@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_mp_max_write __memp_set_mp_max_write@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_mp_mmapsize __memp_get_mp_mmapsize@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_mp_mmapsize __memp_set_mp_mmapsize@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_mp_pagesize __memp_get_mp_pagesize@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_mp_pagesize __memp_set_mp_pagesize@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_mp_tablesize __memp_get_mp_tablesize@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_mp_tablesize __memp_set_mp_tablesize@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_mp_mtxcount __memp_get_mp_mtxcount@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_mp_mtxcount __memp_set_mp_mtxcount@DB_VERSION_UNIQUE_NAME@
+#define	__memp_nameop __memp_nameop@DB_VERSION_UNIQUE_NAME@
+#define	__memp_ftruncate __memp_ftruncate@DB_VERSION_UNIQUE_NAME@
+#define	__memp_alloc_freelist __memp_alloc_freelist@DB_VERSION_UNIQUE_NAME@
+#define	__memp_free_freelist __memp_free_freelist@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_freelist __memp_get_freelist@DB_VERSION_UNIQUE_NAME@
+#define	__memp_extend_freelist __memp_extend_freelist@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_last_pgno __memp_set_last_pgno@DB_VERSION_UNIQUE_NAME@
+#define	__memp_bh_settxn __memp_bh_settxn@DB_VERSION_UNIQUE_NAME@
+#define	__memp_skip_curadj __memp_skip_curadj@DB_VERSION_UNIQUE_NAME@
+#define	__memp_bh_freeze __memp_bh_freeze@DB_VERSION_UNIQUE_NAME@
+#define	__memp_bh_thaw __memp_bh_thaw@DB_VERSION_UNIQUE_NAME@
+#define	__memp_open __memp_open@DB_VERSION_UNIQUE_NAME@
+#define	__memp_init __memp_init@DB_VERSION_UNIQUE_NAME@
+#define	__memp_max_regions __memp_max_regions@DB_VERSION_UNIQUE_NAME@
+#define	__memp_region_mutex_count __memp_region_mutex_count@DB_VERSION_UNIQUE_NAME@
+#define	__memp_env_refresh __memp_env_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__memp_register_pp __memp_register_pp@DB_VERSION_UNIQUE_NAME@
+#define	__memp_register __memp_register@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_bucket __memp_get_bucket@DB_VERSION_UNIQUE_NAME@
+#define	__memp_resize __memp_resize@DB_VERSION_UNIQUE_NAME@
+#define	__memp_get_cache_max __memp_get_cache_max@DB_VERSION_UNIQUE_NAME@
+#define	__memp_set_cache_max __memp_set_cache_max@DB_VERSION_UNIQUE_NAME@
+#define	__memp_stat_pp __memp_stat_pp@DB_VERSION_UNIQUE_NAME@
+#define	__memp_stat_print_pp __memp_stat_print_pp@DB_VERSION_UNIQUE_NAME@
+#define	__memp_stat_print __memp_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__memp_stat_hash __memp_stat_hash@DB_VERSION_UNIQUE_NAME@
+#define	__memp_walk_files __memp_walk_files@DB_VERSION_UNIQUE_NAME@
+#define	__memp_discard_all_mpfs __memp_discard_all_mpfs@DB_VERSION_UNIQUE_NAME@
+#define	__memp_sync_pp __memp_sync_pp@DB_VERSION_UNIQUE_NAME@
+#define	__memp_sync __memp_sync@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fsync_pp __memp_fsync_pp@DB_VERSION_UNIQUE_NAME@
+#define	__memp_fsync __memp_fsync@DB_VERSION_UNIQUE_NAME@
+#define	__mp_xxx_fh __mp_xxx_fh@DB_VERSION_UNIQUE_NAME@
+#define	__memp_sync_int __memp_sync_int@DB_VERSION_UNIQUE_NAME@
+#define	__memp_mf_sync __memp_mf_sync@DB_VERSION_UNIQUE_NAME@
+#define	__memp_trickle_pp __memp_trickle_pp@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_alloc __mutex_alloc@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_alloc_int __mutex_alloc_int@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_free __mutex_free@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_free_int __mutex_free_int@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_refresh __mutex_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__mut_failchk __mut_failchk@DB_VERSION_UNIQUE_NAME@
+#define	__db_fcntl_mutex_init __db_fcntl_mutex_init@DB_VERSION_UNIQUE_NAME@
+#define	__db_fcntl_mutex_lock __db_fcntl_mutex_lock@DB_VERSION_UNIQUE_NAME@
+#define	__db_fcntl_mutex_trylock __db_fcntl_mutex_trylock@DB_VERSION_UNIQUE_NAME@
+#define	__db_fcntl_mutex_unlock __db_fcntl_mutex_unlock@DB_VERSION_UNIQUE_NAME@
+#define	__db_fcntl_mutex_destroy __db_fcntl_mutex_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_alloc_pp __mutex_alloc_pp@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_free_pp __mutex_free_pp@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_lock_pp __mutex_lock_pp@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_unlock_pp __mutex_unlock_pp@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_get_align __mutex_get_align@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_set_align __mutex_set_align@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_get_increment __mutex_get_increment@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_set_increment __mutex_set_increment@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_get_init __mutex_get_init@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_set_init __mutex_set_init@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_get_max __mutex_get_max@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_set_max __mutex_set_max@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_get_tas_spins __mutex_get_tas_spins@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_set_tas_spins __mutex_set_tas_spins@DB_VERSION_UNIQUE_NAME@
+#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT)
+#define	__atomic_inc __atomic_inc@DB_VERSION_UNIQUE_NAME@
+#endif
+#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT)
+#define	__atomic_dec __atomic_dec@DB_VERSION_UNIQUE_NAME@
+#endif
+#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT)
+#define	atomic_compare_exchange atomic_compare_exchange@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__db_pthread_mutex_init __db_pthread_mutex_init@DB_VERSION_UNIQUE_NAME@
+#ifndef HAVE_MUTEX_HYBRID
+#define	__db_pthread_mutex_lock __db_pthread_mutex_lock@DB_VERSION_UNIQUE_NAME@
+#endif
+#if defined(HAVE_SHARED_LATCHES)
+#define	__db_pthread_mutex_readlock __db_pthread_mutex_readlock@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifdef HAVE_MUTEX_HYBRID
+#define	__db_hybrid_mutex_suspend __db_hybrid_mutex_suspend@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__db_pthread_mutex_unlock __db_pthread_mutex_unlock@DB_VERSION_UNIQUE_NAME@
+#define	__db_pthread_mutex_destroy __db_pthread_mutex_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_open __mutex_open@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_env_refresh __mutex_env_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_resource_return __mutex_resource_return@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_stat_pp __mutex_stat_pp@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_stat_print_pp __mutex_stat_print_pp@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_stat_print __mutex_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_print_debug_single __mutex_print_debug_single@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_print_debug_stats __mutex_print_debug_stats@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_set_wait_info __mutex_set_wait_info@DB_VERSION_UNIQUE_NAME@
+#define	__mutex_clear __mutex_clear@DB_VERSION_UNIQUE_NAME@
+#define	__db_tas_mutex_init __db_tas_mutex_init@DB_VERSION_UNIQUE_NAME@
+#define	__db_tas_mutex_lock __db_tas_mutex_lock@DB_VERSION_UNIQUE_NAME@
+#define	__db_tas_mutex_trylock __db_tas_mutex_trylock@DB_VERSION_UNIQUE_NAME@
+#if defined(HAVE_SHARED_LATCHES)
+#define	__db_tas_mutex_readlock __db_tas_mutex_readlock@DB_VERSION_UNIQUE_NAME@
+#endif
+#if defined(HAVE_SHARED_LATCHES)
+#define	__db_tas_mutex_tryreadlock __db_tas_mutex_tryreadlock@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__db_tas_mutex_unlock __db_tas_mutex_unlock@DB_VERSION_UNIQUE_NAME@
+#define	__db_tas_mutex_destroy __db_tas_mutex_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__db_win32_mutex_init __db_win32_mutex_init@DB_VERSION_UNIQUE_NAME@
+#define	__db_win32_mutex_lock __db_win32_mutex_lock@DB_VERSION_UNIQUE_NAME@
+#define	__db_win32_mutex_trylock __db_win32_mutex_trylock@DB_VERSION_UNIQUE_NAME@
+#if defined(HAVE_SHARED_LATCHES)
+#define	__db_win32_mutex_readlock __db_win32_mutex_readlock@DB_VERSION_UNIQUE_NAME@
+#endif
+#if defined(HAVE_SHARED_LATCHES)
+#define	__db_win32_mutex_tryreadlock __db_win32_mutex_tryreadlock@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__db_win32_mutex_unlock __db_win32_mutex_unlock@DB_VERSION_UNIQUE_NAME@
+#define	__db_win32_mutex_destroy __db_win32_mutex_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__os_abort __os_abort@DB_VERSION_UNIQUE_NAME@
+#define	__os_abspath __os_abspath@DB_VERSION_UNIQUE_NAME@
+#if defined(HAVE_REPLICATION_THREADS)
+#define	__os_getaddrinfo __os_getaddrinfo@DB_VERSION_UNIQUE_NAME@
+#endif
+#if defined(HAVE_REPLICATION_THREADS)
+#define	__os_freeaddrinfo __os_freeaddrinfo@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__os_umalloc __os_umalloc@DB_VERSION_UNIQUE_NAME@
+#define	__os_urealloc __os_urealloc@DB_VERSION_UNIQUE_NAME@
+#define	__os_ufree __os_ufree@DB_VERSION_UNIQUE_NAME@
+#define	__os_strdup __os_strdup@DB_VERSION_UNIQUE_NAME@
+#define	__os_calloc __os_calloc@DB_VERSION_UNIQUE_NAME@
+#define	__os_malloc __os_malloc@DB_VERSION_UNIQUE_NAME@
+#define	__os_realloc __os_realloc@DB_VERSION_UNIQUE_NAME@
+#define	__os_free __os_free@DB_VERSION_UNIQUE_NAME@
+#define	__ua_memcpy __ua_memcpy@DB_VERSION_UNIQUE_NAME@
+#define	__os_gettime __os_gettime@DB_VERSION_UNIQUE_NAME@
+#define	__os_fs_notzero __os_fs_notzero@DB_VERSION_UNIQUE_NAME@
+#define	__os_support_direct_io __os_support_direct_io@DB_VERSION_UNIQUE_NAME@
+#define	__os_support_db_register __os_support_db_register@DB_VERSION_UNIQUE_NAME@
+#define	__os_support_replication __os_support_replication@DB_VERSION_UNIQUE_NAME@
+#define	__os_cpu_count __os_cpu_count@DB_VERSION_UNIQUE_NAME@
+#define	__os_ctime __os_ctime@DB_VERSION_UNIQUE_NAME@
+#define	__os_dirlist __os_dirlist@DB_VERSION_UNIQUE_NAME@
+#define	__os_dirfree __os_dirfree@DB_VERSION_UNIQUE_NAME@
+#define	__os_get_errno_ret_zero __os_get_errno_ret_zero@DB_VERSION_UNIQUE_NAME@
+#define	__os_get_errno __os_get_errno@DB_VERSION_UNIQUE_NAME@
+#define	__os_get_neterr __os_get_neterr@DB_VERSION_UNIQUE_NAME@
+#define	__os_get_syserr __os_get_syserr@DB_VERSION_UNIQUE_NAME@
+#define	__os_set_errno __os_set_errno@DB_VERSION_UNIQUE_NAME@
+#define	__os_strerror __os_strerror@DB_VERSION_UNIQUE_NAME@
+#define	__os_posix_err __os_posix_err@DB_VERSION_UNIQUE_NAME@
+#define	__os_fileid __os_fileid@DB_VERSION_UNIQUE_NAME@
+#define	__os_fdlock __os_fdlock@DB_VERSION_UNIQUE_NAME@
+#define	__os_fsync __os_fsync@DB_VERSION_UNIQUE_NAME@
+#define	__os_getenv __os_getenv@DB_VERSION_UNIQUE_NAME@
+#define	__os_openhandle __os_openhandle@DB_VERSION_UNIQUE_NAME@
+#define	__os_closehandle __os_closehandle@DB_VERSION_UNIQUE_NAME@
+#define	__os_attach __os_attach@DB_VERSION_UNIQUE_NAME@
+#define	__os_detach __os_detach@DB_VERSION_UNIQUE_NAME@
+#define	__os_mapfile __os_mapfile@DB_VERSION_UNIQUE_NAME@
+#define	__os_unmapfile __os_unmapfile@DB_VERSION_UNIQUE_NAME@
+#define	__os_mkdir __os_mkdir@DB_VERSION_UNIQUE_NAME@
+#define	__os_open __os_open@DB_VERSION_UNIQUE_NAME@
+#define	__os_concat_path __os_concat_path@DB_VERSION_UNIQUE_NAME@
+#define	__os_id __os_id@DB_VERSION_UNIQUE_NAME@
+#define	__os_rename __os_rename@DB_VERSION_UNIQUE_NAME@
+#define	__os_isroot __os_isroot@DB_VERSION_UNIQUE_NAME@
+#define	__db_rpath __db_rpath@DB_VERSION_UNIQUE_NAME@
+#define	__os_io __os_io@DB_VERSION_UNIQUE_NAME@
+#define	__os_read __os_read@DB_VERSION_UNIQUE_NAME@
+#define	__os_write __os_write@DB_VERSION_UNIQUE_NAME@
+#define	__os_physwrite __os_physwrite@DB_VERSION_UNIQUE_NAME@
+#define	__os_seek __os_seek@DB_VERSION_UNIQUE_NAME@
+#define	__os_stack __os_stack@DB_VERSION_UNIQUE_NAME@
+#define	__os_exists __os_exists@DB_VERSION_UNIQUE_NAME@
+#define	__os_ioinfo __os_ioinfo@DB_VERSION_UNIQUE_NAME@
+#define	__os_tmpdir __os_tmpdir@DB_VERSION_UNIQUE_NAME@
+#define	__os_truncate __os_truncate@DB_VERSION_UNIQUE_NAME@
+#define	__os_unique_id __os_unique_id@DB_VERSION_UNIQUE_NAME@
+#define	__os_unlink __os_unlink@DB_VERSION_UNIQUE_NAME@
+#define	__os_yield __os_yield@DB_VERSION_UNIQUE_NAME@
+#ifdef HAVE_QNX
+#define	__os_qnx_region_open __os_qnx_region_open@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__os_is_winnt __os_is_winnt@DB_VERSION_UNIQUE_NAME@
+#define	__os_cpu_count __os_cpu_count@DB_VERSION_UNIQUE_NAME@
+#ifdef HAVE_REPLICATION_THREADS
+#define	__os_get_neterr __os_get_neterr@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__qam_position __qam_position@DB_VERSION_UNIQUE_NAME@
+#define	__qam_pitem __qam_pitem@DB_VERSION_UNIQUE_NAME@
+#define	__qam_append __qam_append@DB_VERSION_UNIQUE_NAME@
+#define	__qamc_dup __qamc_dup@DB_VERSION_UNIQUE_NAME@
+#define	__qamc_init __qamc_init@DB_VERSION_UNIQUE_NAME@
+#define	__qam_truncate __qam_truncate@DB_VERSION_UNIQUE_NAME@
+#define	__qam_delete __qam_delete@DB_VERSION_UNIQUE_NAME@
+#define	__qam_incfirst_desc __qam_incfirst_desc@DB_VERSION_UNIQUE_NAME@
+#define	__qam_mvptr_desc __qam_mvptr_desc@DB_VERSION_UNIQUE_NAME@
+#define	__qam_del_desc __qam_del_desc@DB_VERSION_UNIQUE_NAME@
+#define	__qam_add_desc __qam_add_desc@DB_VERSION_UNIQUE_NAME@
+#define	__qam_delext_desc __qam_delext_desc@DB_VERSION_UNIQUE_NAME@
+#define	__qam_init_recover __qam_init_recover@DB_VERSION_UNIQUE_NAME@
+#define	__qam_incfirst_print __qam_incfirst_print@DB_VERSION_UNIQUE_NAME@
+#define	__qam_mvptr_print __qam_mvptr_print@DB_VERSION_UNIQUE_NAME@
+#define	__qam_del_print __qam_del_print@DB_VERSION_UNIQUE_NAME@
+#define	__qam_add_print __qam_add_print@DB_VERSION_UNIQUE_NAME@
+#define	__qam_delext_print __qam_delext_print@DB_VERSION_UNIQUE_NAME@
+#define	__qam_init_print __qam_init_print@DB_VERSION_UNIQUE_NAME@
+#define	__qam_mswap __qam_mswap@DB_VERSION_UNIQUE_NAME@
+#define	__qam_pgin_out __qam_pgin_out@DB_VERSION_UNIQUE_NAME@
+#define	__qam_fprobe __qam_fprobe@DB_VERSION_UNIQUE_NAME@
+#define	__qam_fclose __qam_fclose@DB_VERSION_UNIQUE_NAME@
+#define	__qam_fremove __qam_fremove@DB_VERSION_UNIQUE_NAME@
+#define	__qam_sync __qam_sync@DB_VERSION_UNIQUE_NAME@
+#define	__qam_gen_filelist __qam_gen_filelist@DB_VERSION_UNIQUE_NAME@
+#define	__qam_extent_names __qam_extent_names@DB_VERSION_UNIQUE_NAME@
+#define	__qam_exid __qam_exid@DB_VERSION_UNIQUE_NAME@
+#define	__qam_nameop __qam_nameop@DB_VERSION_UNIQUE_NAME@
+#define	__qam_lsn_reset __qam_lsn_reset@DB_VERSION_UNIQUE_NAME@
+#define	__qam_backup_extents __qam_backup_extents@DB_VERSION_UNIQUE_NAME@
+#define	__qam_db_create __qam_db_create@DB_VERSION_UNIQUE_NAME@
+#define	__qam_db_close __qam_db_close@DB_VERSION_UNIQUE_NAME@
+#define	__qam_get_extentsize __qam_get_extentsize@DB_VERSION_UNIQUE_NAME@
+#define	__queue_pageinfo __queue_pageinfo@DB_VERSION_UNIQUE_NAME@
+#define	__db_prqueue __db_prqueue@DB_VERSION_UNIQUE_NAME@
+#define	__qam_remove __qam_remove@DB_VERSION_UNIQUE_NAME@
+#define	__qam_rename __qam_rename@DB_VERSION_UNIQUE_NAME@
+#define	__qam_map_flags __qam_map_flags@DB_VERSION_UNIQUE_NAME@
+#define	__qam_set_flags __qam_set_flags@DB_VERSION_UNIQUE_NAME@
+#define	__qam_open __qam_open@DB_VERSION_UNIQUE_NAME@
+#define	__qam_set_ext_data __qam_set_ext_data@DB_VERSION_UNIQUE_NAME@
+#define	__qam_metachk __qam_metachk@DB_VERSION_UNIQUE_NAME@
+#define	__qam_new_file __qam_new_file@DB_VERSION_UNIQUE_NAME@
+#define	__qam_incfirst_recover __qam_incfirst_recover@DB_VERSION_UNIQUE_NAME@
+#define	__qam_mvptr_recover __qam_mvptr_recover@DB_VERSION_UNIQUE_NAME@
+#define	__qam_del_recover __qam_del_recover@DB_VERSION_UNIQUE_NAME@
+#define	__qam_delext_recover __qam_delext_recover@DB_VERSION_UNIQUE_NAME@
+#define	__qam_add_recover __qam_add_recover@DB_VERSION_UNIQUE_NAME@
+#define	__qam_stat __qam_stat@DB_VERSION_UNIQUE_NAME@
+#define	__qam_stat_print __qam_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_no_queue_am __db_no_queue_am@DB_VERSION_UNIQUE_NAME@
+#define	__qam_31_qammeta __qam_31_qammeta@DB_VERSION_UNIQUE_NAME@
+#define	__qam_32_qammeta __qam_32_qammeta@DB_VERSION_UNIQUE_NAME@
+#define	__qam_vrfy_meta __qam_vrfy_meta@DB_VERSION_UNIQUE_NAME@
+#define	__qam_meta2pgset __qam_meta2pgset@DB_VERSION_UNIQUE_NAME@
+#define	__qam_vrfy_data __qam_vrfy_data@DB_VERSION_UNIQUE_NAME@
+#define	__qam_vrfy_structure __qam_vrfy_structure@DB_VERSION_UNIQUE_NAME@
+#define	__qam_vrfy_walkqueue __qam_vrfy_walkqueue@DB_VERSION_UNIQUE_NAME@
+#define	__qam_salvage __qam_salvage@DB_VERSION_UNIQUE_NAME@
+#define	__rep_bulk_marshal __rep_bulk_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_bulk_unmarshal __rep_bulk_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_control_marshal __rep_control_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_control_unmarshal __rep_control_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_egen_marshal __rep_egen_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_egen_unmarshal __rep_egen_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_fileinfo_marshal __rep_fileinfo_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_fileinfo_unmarshal __rep_fileinfo_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_fileinfo_v6_marshal __rep_fileinfo_v6_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_fileinfo_v6_unmarshal __rep_fileinfo_v6_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_grant_info_marshal __rep_grant_info_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_grant_info_unmarshal __rep_grant_info_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_logreq_marshal __rep_logreq_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_logreq_unmarshal __rep_logreq_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_newfile_marshal __rep_newfile_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_newfile_unmarshal __rep_newfile_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_update_marshal __rep_update_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_update_unmarshal __rep_update_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_vote_info_marshal __rep_vote_info_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_vote_info_unmarshal __rep_vote_info_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_vote_info_v5_marshal __rep_vote_info_v5_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_vote_info_v5_unmarshal __rep_vote_info_v5_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lsn_hist_key_marshal __rep_lsn_hist_key_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lsn_hist_key_unmarshal __rep_lsn_hist_key_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lsn_hist_data_marshal __rep_lsn_hist_data_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lsn_hist_data_unmarshal __rep_lsn_hist_data_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_update_req __rep_update_req@DB_VERSION_UNIQUE_NAME@
+#define	__rep_page_req __rep_page_req@DB_VERSION_UNIQUE_NAME@
+#define	__rep_update_setup __rep_update_setup@DB_VERSION_UNIQUE_NAME@
+#define	__rep_bulk_page __rep_bulk_page@DB_VERSION_UNIQUE_NAME@
+#define	__rep_page __rep_page@DB_VERSION_UNIQUE_NAME@
+#define	__rep_init_cleanup __rep_init_cleanup@DB_VERSION_UNIQUE_NAME@
+#define	__rep_pggap_req __rep_pggap_req@DB_VERSION_UNIQUE_NAME@
+#define	__rep_finfo_alloc __rep_finfo_alloc@DB_VERSION_UNIQUE_NAME@
+#define	__rep_remove_init_file __rep_remove_init_file@DB_VERSION_UNIQUE_NAME@
+#define	__rep_reset_init __rep_reset_init@DB_VERSION_UNIQUE_NAME@
+#define	__rep_elect_pp __rep_elect_pp@DB_VERSION_UNIQUE_NAME@
+#define	__rep_elect_int __rep_elect_int@DB_VERSION_UNIQUE_NAME@
+#define	__rep_vote1 __rep_vote1@DB_VERSION_UNIQUE_NAME@
+#define	__rep_vote2 __rep_vote2@DB_VERSION_UNIQUE_NAME@
+#define	__rep_update_grant __rep_update_grant@DB_VERSION_UNIQUE_NAME@
+#define	__rep_islease_granted __rep_islease_granted@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lease_table_alloc __rep_lease_table_alloc@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lease_grant __rep_lease_grant@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lease_check __rep_lease_check@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lease_refresh __rep_lease_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lease_expire __rep_lease_expire@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lease_waittime __rep_lease_waittime@DB_VERSION_UNIQUE_NAME@
+#define	__rep_allreq __rep_allreq@DB_VERSION_UNIQUE_NAME@
+#define	__rep_log __rep_log@DB_VERSION_UNIQUE_NAME@
+#define	__rep_bulk_log __rep_bulk_log@DB_VERSION_UNIQUE_NAME@
+#define	__rep_logreq __rep_logreq@DB_VERSION_UNIQUE_NAME@
+#define	__rep_loggap_req __rep_loggap_req@DB_VERSION_UNIQUE_NAME@
+#define	__rep_logready __rep_logready@DB_VERSION_UNIQUE_NAME@
+#define	__rep_env_create __rep_env_create@DB_VERSION_UNIQUE_NAME@
+#define	__rep_env_destroy __rep_env_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__rep_get_config __rep_get_config@DB_VERSION_UNIQUE_NAME@
+#define	__rep_set_config __rep_set_config@DB_VERSION_UNIQUE_NAME@
+#define	__rep_start_pp __rep_start_pp@DB_VERSION_UNIQUE_NAME@
+#define	__rep_start_int __rep_start_int@DB_VERSION_UNIQUE_NAME@
+#define	__rep_open_sysdb __rep_open_sysdb@DB_VERSION_UNIQUE_NAME@
+#define	__rep_client_dbinit __rep_client_dbinit@DB_VERSION_UNIQUE_NAME@
+#define	__rep_get_limit __rep_get_limit@DB_VERSION_UNIQUE_NAME@
+#define	__rep_set_limit __rep_set_limit@DB_VERSION_UNIQUE_NAME@
+#define	__rep_set_nsites_pp __rep_set_nsites_pp@DB_VERSION_UNIQUE_NAME@
+#define	__rep_set_nsites_int __rep_set_nsites_int@DB_VERSION_UNIQUE_NAME@
+#define	__rep_get_nsites __rep_get_nsites@DB_VERSION_UNIQUE_NAME@
+#define	__rep_set_priority __rep_set_priority@DB_VERSION_UNIQUE_NAME@
+#define	__rep_get_priority __rep_get_priority@DB_VERSION_UNIQUE_NAME@
+#define	__rep_set_timeout __rep_set_timeout@DB_VERSION_UNIQUE_NAME@
+#define	__rep_get_timeout __rep_get_timeout@DB_VERSION_UNIQUE_NAME@
+#define	__rep_get_request __rep_get_request@DB_VERSION_UNIQUE_NAME@
+#define	__rep_set_request __rep_set_request@DB_VERSION_UNIQUE_NAME@
+#define	__rep_set_transport_pp __rep_set_transport_pp@DB_VERSION_UNIQUE_NAME@
+#define	__rep_set_transport_int __rep_set_transport_int@DB_VERSION_UNIQUE_NAME@
+#define	__rep_get_clockskew __rep_get_clockskew@DB_VERSION_UNIQUE_NAME@
+#define	__rep_set_clockskew __rep_set_clockskew@DB_VERSION_UNIQUE_NAME@
+#define	__rep_flush __rep_flush@DB_VERSION_UNIQUE_NAME@
+#define	__rep_sync __rep_sync@DB_VERSION_UNIQUE_NAME@
+#define	__rep_txn_applied __rep_txn_applied@DB_VERSION_UNIQUE_NAME@
+#define	__rep_process_message_pp __rep_process_message_pp@DB_VERSION_UNIQUE_NAME@
+#define	__rep_process_message_int __rep_process_message_int@DB_VERSION_UNIQUE_NAME@
+#define	__rep_apply __rep_apply@DB_VERSION_UNIQUE_NAME@
+#define	__rep_process_txn __rep_process_txn@DB_VERSION_UNIQUE_NAME@
+#define	__rep_resend_req __rep_resend_req@DB_VERSION_UNIQUE_NAME@
+#define	__rep_check_doreq __rep_check_doreq@DB_VERSION_UNIQUE_NAME@
+#define	__rep_check_missing __rep_check_missing@DB_VERSION_UNIQUE_NAME@
+#define	__rep_open __rep_open@DB_VERSION_UNIQUE_NAME@
+#define	__rep_close_diagfiles __rep_close_diagfiles@DB_VERSION_UNIQUE_NAME@
+#define	__rep_env_refresh __rep_env_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__rep_env_close __rep_env_close@DB_VERSION_UNIQUE_NAME@
+#define	__rep_preclose __rep_preclose@DB_VERSION_UNIQUE_NAME@
+#define	__rep_closefiles __rep_closefiles@DB_VERSION_UNIQUE_NAME@
+#define	__rep_write_egen __rep_write_egen@DB_VERSION_UNIQUE_NAME@
+#define	__rep_write_gen __rep_write_gen@DB_VERSION_UNIQUE_NAME@
+#define	__rep_stat_pp __rep_stat_pp@DB_VERSION_UNIQUE_NAME@
+#define	__rep_stat_print_pp __rep_stat_print_pp@DB_VERSION_UNIQUE_NAME@
+#define	__rep_stat_print __rep_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__rep_bulk_message __rep_bulk_message@DB_VERSION_UNIQUE_NAME@
+#define	__rep_send_bulk __rep_send_bulk@DB_VERSION_UNIQUE_NAME@
+#define	__rep_bulk_alloc __rep_bulk_alloc@DB_VERSION_UNIQUE_NAME@
+#define	__rep_bulk_free __rep_bulk_free@DB_VERSION_UNIQUE_NAME@
+#define	__rep_send_message __rep_send_message@DB_VERSION_UNIQUE_NAME@
+#define	__rep_new_master __rep_new_master@DB_VERSION_UNIQUE_NAME@
+#define	__rep_elect_done __rep_elect_done@DB_VERSION_UNIQUE_NAME@
+#define	__env_rep_enter __env_rep_enter@DB_VERSION_UNIQUE_NAME@
+#define	__env_db_rep_exit __env_db_rep_exit@DB_VERSION_UNIQUE_NAME@
+#define	__db_rep_enter __db_rep_enter@DB_VERSION_UNIQUE_NAME@
+#define	__op_handle_enter __op_handle_enter@DB_VERSION_UNIQUE_NAME@
+#define	__op_rep_enter __op_rep_enter@DB_VERSION_UNIQUE_NAME@
+#define	__op_rep_exit __op_rep_exit@DB_VERSION_UNIQUE_NAME@
+#define	__archive_rep_enter __archive_rep_enter@DB_VERSION_UNIQUE_NAME@
+#define	__archive_rep_exit __archive_rep_exit@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lockout_archive __rep_lockout_archive@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lockout_api __rep_lockout_api@DB_VERSION_UNIQUE_NAME@
+#define	__rep_take_apilockout __rep_take_apilockout@DB_VERSION_UNIQUE_NAME@
+#define	__rep_clear_apilockout __rep_clear_apilockout@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lockout_apply __rep_lockout_apply@DB_VERSION_UNIQUE_NAME@
+#define	__rep_lockout_msg __rep_lockout_msg@DB_VERSION_UNIQUE_NAME@
+#define	__rep_send_throttle __rep_send_throttle@DB_VERSION_UNIQUE_NAME@
+#define	__rep_msg_to_old __rep_msg_to_old@DB_VERSION_UNIQUE_NAME@
+#define	__rep_msg_from_old __rep_msg_from_old@DB_VERSION_UNIQUE_NAME@
+#define	__rep_print_system __rep_print_system@DB_VERSION_UNIQUE_NAME@
+#define	__rep_print __rep_print@DB_VERSION_UNIQUE_NAME@
+#define	__rep_print_message __rep_print_message@DB_VERSION_UNIQUE_NAME@
+#define	__rep_fire_event __rep_fire_event@DB_VERSION_UNIQUE_NAME@
+#define	__rep_msg __rep_msg@DB_VERSION_UNIQUE_NAME@
+#define	__rep_notify_threads __rep_notify_threads@DB_VERSION_UNIQUE_NAME@
+#define	__rep_check_goal __rep_check_goal@DB_VERSION_UNIQUE_NAME@
+#define	__rep_log_backup __rep_log_backup@DB_VERSION_UNIQUE_NAME@
+#define	__rep_get_maxpermlsn __rep_get_maxpermlsn@DB_VERSION_UNIQUE_NAME@
+#define	__rep_is_internal_rep_file __rep_is_internal_rep_file@DB_VERSION_UNIQUE_NAME@
+#define	__rep_get_datagen __rep_get_datagen@DB_VERSION_UNIQUE_NAME@
+#define	__rep_verify __rep_verify@DB_VERSION_UNIQUE_NAME@
+#define	__rep_verify_fail __rep_verify_fail@DB_VERSION_UNIQUE_NAME@
+#define	__rep_verify_req __rep_verify_req@DB_VERSION_UNIQUE_NAME@
+#define	__rep_dorecovery __rep_dorecovery@DB_VERSION_UNIQUE_NAME@
+#define	__rep_verify_match __rep_verify_match@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_member_desc __repmgr_member_desc@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_init_recover __repmgr_init_recover@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_handshake_marshal __repmgr_handshake_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_handshake_unmarshal __repmgr_handshake_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_v3handshake_marshal __repmgr_v3handshake_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_v3handshake_unmarshal __repmgr_v3handshake_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_v2handshake_marshal __repmgr_v2handshake_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_v2handshake_unmarshal __repmgr_v2handshake_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_parm_refresh_marshal __repmgr_parm_refresh_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_parm_refresh_unmarshal __repmgr_parm_refresh_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_permlsn_marshal __repmgr_permlsn_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_permlsn_unmarshal __repmgr_permlsn_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_version_proposal_marshal __repmgr_version_proposal_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_version_proposal_unmarshal __repmgr_version_proposal_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_version_confirmation_marshal __repmgr_version_confirmation_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_version_confirmation_unmarshal __repmgr_version_confirmation_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_msg_hdr_marshal __repmgr_msg_hdr_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_msg_hdr_unmarshal __repmgr_msg_hdr_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_msg_metadata_marshal __repmgr_msg_metadata_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_msg_metadata_unmarshal __repmgr_msg_metadata_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_membership_key_marshal __repmgr_membership_key_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_membership_key_unmarshal __repmgr_membership_key_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_membership_data_marshal __repmgr_membership_data_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_membership_data_unmarshal __repmgr_membership_data_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_member_metadata_marshal __repmgr_member_metadata_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_member_metadata_unmarshal __repmgr_member_metadata_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_gm_fwd_marshal __repmgr_gm_fwd_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_gm_fwd_unmarshal __repmgr_gm_fwd_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_membr_vers_marshal __repmgr_membr_vers_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_membr_vers_unmarshal __repmgr_membr_vers_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_site_info_marshal __repmgr_site_info_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_site_info_unmarshal __repmgr_site_info_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_connect_reject_marshal __repmgr_connect_reject_marshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_connect_reject_unmarshal __repmgr_connect_reject_unmarshal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_member_print __repmgr_member_print@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_init_print __repmgr_init_print@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_init_election __repmgr_init_election@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_claim_victory __repmgr_claim_victory@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_turn_on_elections __repmgr_turn_on_elections@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_start __repmgr_start@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_valid_config __repmgr_valid_config@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_autostart __repmgr_autostart@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_start_selector __repmgr_start_selector@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_close __repmgr_close@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_stop __repmgr_stop@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_set_ack_policy __repmgr_set_ack_policy@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_get_ack_policy __repmgr_get_ack_policy@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_env_create __repmgr_env_create@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_env_destroy __repmgr_env_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_stop_threads __repmgr_stop_threads@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_local_site __repmgr_local_site@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_channel __repmgr_channel@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_set_msg_dispatch __repmgr_set_msg_dispatch@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_msg __repmgr_send_msg@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_request __repmgr_send_request@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_response __repmgr_send_response@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_channel_close __repmgr_channel_close@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_channel_timeout __repmgr_channel_timeout@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_request_inval __repmgr_send_request_inval@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_channel_close_inval __repmgr_channel_close_inval@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_channel_timeout_inval __repmgr_channel_timeout_inval@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_join_group __repmgr_join_group@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_site __repmgr_site@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_site_by_eid __repmgr_site_by_eid@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_get_site_address __repmgr_get_site_address@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_get_eid __repmgr_get_eid@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_get_config __repmgr_get_config@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_site_config __repmgr_site_config@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_site_close __repmgr_site_close@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_msg_thread __repmgr_msg_thread@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_err_resp __repmgr_send_err_resp@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_handle_event __repmgr_handle_event@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_update_membership __repmgr_update_membership@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_set_gm_version __repmgr_set_gm_version@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_setup_gmdb_op __repmgr_setup_gmdb_op@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_cleanup_gmdb_op __repmgr_cleanup_gmdb_op@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_hold_master_role __repmgr_hold_master_role@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_rlse_master_role __repmgr_rlse_master_role@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_set_sites __repmgr_set_sites@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_connect __repmgr_connect@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send __repmgr_send@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_sync_siteaddr __repmgr_sync_siteaddr@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_broadcast __repmgr_send_broadcast@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_one __repmgr_send_one@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_many __repmgr_send_many@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_own_msg __repmgr_send_own_msg@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_write_iovecs __repmgr_write_iovecs@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_bust_connection __repmgr_bust_connection@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_disable_connection __repmgr_disable_connection@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_cleanup_defunct __repmgr_cleanup_defunct@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_close_connection __repmgr_close_connection@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_decr_conn_ref __repmgr_decr_conn_ref@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_destroy_conn __repmgr_destroy_conn@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_pack_netaddr __repmgr_pack_netaddr@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_getaddr __repmgr_getaddr@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_listen __repmgr_listen@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_net_close __repmgr_net_close@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_net_destroy __repmgr_net_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_thread_start __repmgr_thread_start@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_thread_join __repmgr_thread_join@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_set_nonblock_conn __repmgr_set_nonblock_conn@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_set_nonblocking __repmgr_set_nonblocking@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_wake_waiters __repmgr_wake_waiters@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_await_cond __repmgr_await_cond@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_await_gmdbop __repmgr_await_gmdbop@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_compute_wait_deadline __repmgr_compute_wait_deadline@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_await_drain __repmgr_await_drain@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_alloc_cond __repmgr_alloc_cond@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_free_cond __repmgr_free_cond@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_env_create_pf __repmgr_env_create_pf@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_create_mutex_pf __repmgr_create_mutex_pf@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_destroy_mutex_pf __repmgr_destroy_mutex_pf@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_init __repmgr_init@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_deinit __repmgr_deinit@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_init_waiters __repmgr_init_waiters@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_destroy_waiters __repmgr_destroy_waiters@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_lock_mutex __repmgr_lock_mutex@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_unlock_mutex __repmgr_unlock_mutex@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_signal __repmgr_signal@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_wake_msngers __repmgr_wake_msngers@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_wake_main_thread __repmgr_wake_main_thread@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_writev __repmgr_writev@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_readv __repmgr_readv@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_select_loop __repmgr_select_loop@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_queue_destroy __repmgr_queue_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_queue_get __repmgr_queue_get@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_queue_put __repmgr_queue_put@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_queue_size __repmgr_queue_size@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_member_recover __repmgr_member_recover@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_select_thread __repmgr_select_thread@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_bow_out __repmgr_bow_out@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_accept __repmgr_accept@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_compute_timeout __repmgr_compute_timeout@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_connected_master __repmgr_connected_master@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_check_timeouts __repmgr_check_timeouts@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_first_try_connections __repmgr_first_try_connections@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_v1_handshake __repmgr_send_v1_handshake@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_read_from_site __repmgr_read_from_site@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_read_conn __repmgr_read_conn@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_prepare_simple_input __repmgr_prepare_simple_input@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_handshake __repmgr_send_handshake@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_find_version_info __repmgr_find_version_info@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_write_some __repmgr_write_some@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_stat_pp __repmgr_stat_pp@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_stat_print_pp __repmgr_stat_print_pp@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_stat_print __repmgr_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_site_list __repmgr_site_list@DB_VERSION_UNIQUE_NAME@
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_close __repmgr_close@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_get_ack_policy __repmgr_get_ack_policy@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_set_ack_policy __repmgr_set_ack_policy@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_site __repmgr_site@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_site_by_eid __repmgr_site_by_eid@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_local_site __repmgr_local_site@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_site_list __repmgr_site_list@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_start __repmgr_start@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_stat_pp __repmgr_stat_pp@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_stat_print_pp __repmgr_stat_print_pp@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_handle_event __repmgr_handle_event@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_channel __repmgr_channel@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_set_msg_dispatch __repmgr_set_msg_dispatch@DB_VERSION_UNIQUE_NAME@
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+#define	__repmgr_init_recover __repmgr_init_recover@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	__repmgr_schedule_connection_attempt __repmgr_schedule_connection_attempt@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_is_server __repmgr_is_server@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_reset_for_reading __repmgr_reset_for_reading@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_new_connection __repmgr_new_connection@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_set_keepalive __repmgr_set_keepalive@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_new_site __repmgr_new_site@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_create_mutex __repmgr_create_mutex@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_destroy_mutex __repmgr_destroy_mutex@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_cleanup_netaddr __repmgr_cleanup_netaddr@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_iovec_init __repmgr_iovec_init@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_add_buffer __repmgr_add_buffer@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_add_dbt __repmgr_add_dbt@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_update_consumed __repmgr_update_consumed@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_prepare_my_addr __repmgr_prepare_my_addr@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_get_nsites __repmgr_get_nsites@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_thread_failure __repmgr_thread_failure@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_format_eid_loc __repmgr_format_eid_loc@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_format_site_loc __repmgr_format_site_loc@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_format_addr_loc __repmgr_format_addr_loc@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_repstart __repmgr_repstart@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_become_master __repmgr_become_master@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_each_connection __repmgr_each_connection@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_open __repmgr_open@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_join __repmgr_join@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_env_refresh __repmgr_env_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_share_netaddrs __repmgr_share_netaddrs@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_copy_in_added_sites __repmgr_copy_in_added_sites@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_init_new_sites __repmgr_init_new_sites@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_failchk __repmgr_failchk@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_master_is_known __repmgr_master_is_known@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_stable_lsn __repmgr_stable_lsn@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_send_sync_msg __repmgr_send_sync_msg@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_marshal_member_list __repmgr_marshal_member_list@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_refresh_membership __repmgr_refresh_membership@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_reload_gmdb __repmgr_reload_gmdb@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_gmdb_version_cmp __repmgr_gmdb_version_cmp@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_init_save __repmgr_init_save@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_init_restore __repmgr_init_restore@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_defer_op __repmgr_defer_op@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_fire_conn_err_event __repmgr_fire_conn_err_event@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_print_conn_err __repmgr_print_conn_err@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_become_client __repmgr_become_client@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_lookup_site __repmgr_lookup_site@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_find_site __repmgr_find_site@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_set_membership __repmgr_set_membership@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_bcast_parm_refresh __repmgr_bcast_parm_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_chg_prio __repmgr_chg_prio@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_bcast_own_msg __repmgr_bcast_own_msg@DB_VERSION_UNIQUE_NAME@
+#define	__seq_stat __seq_stat@DB_VERSION_UNIQUE_NAME@
+#define	__seq_stat_print __seq_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__db_get_seq_flags_fn __db_get_seq_flags_fn@DB_VERSION_UNIQUE_NAME@
+#define	__db_get_seq_flags_fn __db_get_seq_flags_fn@DB_VERSION_UNIQUE_NAME@
+#define	bdb_HCommand bdb_HCommand@DB_VERSION_UNIQUE_NAME@
+#if DB_DBM_HSEARCH != 0
+#define	bdb_NdbmOpen bdb_NdbmOpen@DB_VERSION_UNIQUE_NAME@
+#endif
+#if DB_DBM_HSEARCH != 0
+#define	bdb_DbmCommand bdb_DbmCommand@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	ndbm_Cmd ndbm_Cmd@DB_VERSION_UNIQUE_NAME@
+#define	_DbInfoDelete _DbInfoDelete@DB_VERSION_UNIQUE_NAME@
+#define	db_Cmd db_Cmd@DB_VERSION_UNIQUE_NAME@
+#define	tcl_CompactStat tcl_CompactStat@DB_VERSION_UNIQUE_NAME@
+#define	tcl_rep_send tcl_rep_send@DB_VERSION_UNIQUE_NAME@
+#define	dbc_Cmd dbc_Cmd@DB_VERSION_UNIQUE_NAME@
+#define	env_Cmd env_Cmd@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvRemove tcl_EnvRemove@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvClose tcl_EnvClose@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvAttr tcl_EnvAttr@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvIdReset tcl_EnvIdReset@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvLsnReset tcl_EnvLsnReset@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvVerbose tcl_EnvVerbose@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvSetFlags tcl_EnvSetFlags@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvTest tcl_EnvTest@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvGetEncryptFlags tcl_EnvGetEncryptFlags@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvSetErrfile tcl_EnvSetErrfile@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvSetMsgfile tcl_EnvSetMsgfile@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvSetErrpfx tcl_EnvSetErrpfx@DB_VERSION_UNIQUE_NAME@
+#define	tcl_EnvStatPrint tcl_EnvStatPrint@DB_VERSION_UNIQUE_NAME@
+#define	_NewInfo _NewInfo@DB_VERSION_UNIQUE_NAME@
+#define	_NameToPtr _NameToPtr@DB_VERSION_UNIQUE_NAME@
+#define	_PtrToInfo _PtrToInfo@DB_VERSION_UNIQUE_NAME@
+#define	_NameToInfo _NameToInfo@DB_VERSION_UNIQUE_NAME@
+#define	_SetInfoData _SetInfoData@DB_VERSION_UNIQUE_NAME@
+#define	_DeleteInfo _DeleteInfo@DB_VERSION_UNIQUE_NAME@
+#define	_SetListElem _SetListElem@DB_VERSION_UNIQUE_NAME@
+#define	_SetListElemInt _SetListElemInt@DB_VERSION_UNIQUE_NAME@
+#define	_SetListElemWideInt _SetListElemWideInt@DB_VERSION_UNIQUE_NAME@
+#define	_SetListRecnoElem _SetListRecnoElem@DB_VERSION_UNIQUE_NAME@
+#define	_SetListHeapElem _SetListHeapElem@DB_VERSION_UNIQUE_NAME@
+#define	_Set3DBTList _Set3DBTList@DB_VERSION_UNIQUE_NAME@
+#define	_SetMultiList _SetMultiList@DB_VERSION_UNIQUE_NAME@
+#define	_GetGlobPrefix _GetGlobPrefix@DB_VERSION_UNIQUE_NAME@
+#define	_ReturnSetup _ReturnSetup@DB_VERSION_UNIQUE_NAME@
+#define	_ErrorSetup _ErrorSetup@DB_VERSION_UNIQUE_NAME@
+#define	_ErrorFunc _ErrorFunc@DB_VERSION_UNIQUE_NAME@
+#ifdef CONFIG_TEST 
+#define	_EventFunc _EventFunc@DB_VERSION_UNIQUE_NAME@
+#endif
+#define	_GetLsn _GetLsn@DB_VERSION_UNIQUE_NAME@
+#define	_GetRid _GetRid@DB_VERSION_UNIQUE_NAME@
+#define	_GetUInt32 _GetUInt32@DB_VERSION_UNIQUE_NAME@
+#define	_GetFlagsList _GetFlagsList@DB_VERSION_UNIQUE_NAME@
+#define	_debug_check _debug_check@DB_VERSION_UNIQUE_NAME@
+#define	_CopyObjBytes _CopyObjBytes@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LockDetect tcl_LockDetect@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LockGet tcl_LockGet@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LockStat tcl_LockStat@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LockStatPrint tcl_LockStatPrint@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LockTimeout tcl_LockTimeout@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LockVec tcl_LockVec@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LogArchive tcl_LogArchive@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LogCompare tcl_LogCompare@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LogFile tcl_LogFile@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LogFlush tcl_LogFlush@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LogGet tcl_LogGet@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LogPut tcl_LogPut@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LogStat tcl_LogStat@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LogStatPrint tcl_LogStatPrint@DB_VERSION_UNIQUE_NAME@
+#define	logc_Cmd logc_Cmd@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LogConfig tcl_LogConfig@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LogGetConfig tcl_LogGetConfig@DB_VERSION_UNIQUE_NAME@
+#define	_MpInfoDelete _MpInfoDelete@DB_VERSION_UNIQUE_NAME@
+#define	tcl_MpSync tcl_MpSync@DB_VERSION_UNIQUE_NAME@
+#define	tcl_MpTrickle tcl_MpTrickle@DB_VERSION_UNIQUE_NAME@
+#define	tcl_Mp tcl_Mp@DB_VERSION_UNIQUE_NAME@
+#define	tcl_MpStat tcl_MpStat@DB_VERSION_UNIQUE_NAME@
+#define	tcl_MpStatPrint tcl_MpStatPrint@DB_VERSION_UNIQUE_NAME@
+#define	tcl_Mutex tcl_Mutex@DB_VERSION_UNIQUE_NAME@
+#define	tcl_MutFree tcl_MutFree@DB_VERSION_UNIQUE_NAME@
+#define	tcl_MutGet tcl_MutGet@DB_VERSION_UNIQUE_NAME@
+#define	tcl_MutLock tcl_MutLock@DB_VERSION_UNIQUE_NAME@
+#define	tcl_MutSet tcl_MutSet@DB_VERSION_UNIQUE_NAME@
+#define	tcl_MutStat tcl_MutStat@DB_VERSION_UNIQUE_NAME@
+#define	tcl_MutStatPrint tcl_MutStatPrint@DB_VERSION_UNIQUE_NAME@
+#define	tcl_MutUnlock tcl_MutUnlock@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepConfig tcl_RepConfig@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepGetTwo tcl_RepGetTwo@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepGetConfig tcl_RepGetConfig@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepGetTimeout tcl_RepGetTimeout@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepGetAckPolicy tcl_RepGetAckPolicy@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepGetLocalSite tcl_RepGetLocalSite@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepElect tcl_RepElect@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepFlush tcl_RepFlush@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepSync tcl_RepSync@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepLease tcl_RepLease@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepInmemFiles tcl_RepInmemFiles@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepLimit tcl_RepLimit@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepNSites tcl_RepNSites@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepRequest tcl_RepRequest@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepNoarchiveTimeout tcl_RepNoarchiveTimeout@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepTransport tcl_RepTransport@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepStart tcl_RepStart@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepProcessMessage tcl_RepProcessMessage@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepStat tcl_RepStat@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepStatPrint tcl_RepStatPrint@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepMgr tcl_RepMgr@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepMgrSiteList tcl_RepMgrSiteList@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepMgrStat tcl_RepMgrStat@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepMgrStatPrint tcl_RepMgrStatPrint@DB_VERSION_UNIQUE_NAME@
+#define	tcl_RepApplied tcl_RepApplied@DB_VERSION_UNIQUE_NAME@
+#define	seq_Cmd seq_Cmd@DB_VERSION_UNIQUE_NAME@
+#define	_TxnInfoDelete _TxnInfoDelete@DB_VERSION_UNIQUE_NAME@
+#define	tcl_TxnCheckpoint tcl_TxnCheckpoint@DB_VERSION_UNIQUE_NAME@
+#define	tcl_Txn tcl_Txn@DB_VERSION_UNIQUE_NAME@
+#define	tcl_CDSGroup tcl_CDSGroup@DB_VERSION_UNIQUE_NAME@
+#define	tcl_TxnStat tcl_TxnStat@DB_VERSION_UNIQUE_NAME@
+#define	tcl_TxnStatPrint tcl_TxnStatPrint@DB_VERSION_UNIQUE_NAME@
+#define	tcl_TxnTimeout tcl_TxnTimeout@DB_VERSION_UNIQUE_NAME@
+#define	tcl_TxnRecover tcl_TxnRecover@DB_VERSION_UNIQUE_NAME@
+#define	bdb_RandCommand bdb_RandCommand@DB_VERSION_UNIQUE_NAME@
+#define	tcl_LockMutex tcl_LockMutex@DB_VERSION_UNIQUE_NAME@
+#define	tcl_UnlockMutex tcl_UnlockMutex@DB_VERSION_UNIQUE_NAME@
+#define	__txn_begin_pp __txn_begin_pp@DB_VERSION_UNIQUE_NAME@
+#define	__txn_begin __txn_begin@DB_VERSION_UNIQUE_NAME@
+#define	__txn_recycle_id __txn_recycle_id@DB_VERSION_UNIQUE_NAME@
+#define	__txn_continue __txn_continue@DB_VERSION_UNIQUE_NAME@
+#define	__txn_commit __txn_commit@DB_VERSION_UNIQUE_NAME@
+#define	__txn_abort __txn_abort@DB_VERSION_UNIQUE_NAME@
+#define	__txn_discard_int __txn_discard_int@DB_VERSION_UNIQUE_NAME@
+#define	__txn_prepare __txn_prepare@DB_VERSION_UNIQUE_NAME@
+#define	__txn_id __txn_id@DB_VERSION_UNIQUE_NAME@
+#define	__txn_get_name __txn_get_name@DB_VERSION_UNIQUE_NAME@
+#define	__txn_set_name __txn_set_name@DB_VERSION_UNIQUE_NAME@
+#define	__txn_get_priority __txn_get_priority@DB_VERSION_UNIQUE_NAME@
+#define	__txn_set_priority __txn_set_priority@DB_VERSION_UNIQUE_NAME@
+#define	__txn_set_timeout __txn_set_timeout@DB_VERSION_UNIQUE_NAME@
+#define	__txn_activekids __txn_activekids@DB_VERSION_UNIQUE_NAME@
+#define	__txn_force_abort __txn_force_abort@DB_VERSION_UNIQUE_NAME@
+#define	__txn_preclose __txn_preclose@DB_VERSION_UNIQUE_NAME@
+#define	__txn_reset __txn_reset@DB_VERSION_UNIQUE_NAME@
+#define	__txn_applied_pp __txn_applied_pp@DB_VERSION_UNIQUE_NAME@
+#define	__txn_regop_42_desc __txn_regop_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_regop_desc __txn_regop_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_ckp_42_desc __txn_ckp_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_ckp_desc __txn_ckp_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_child_desc __txn_child_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_xa_regop_42_desc __txn_xa_regop_42_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_prepare_desc __txn_prepare_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_recycle_desc __txn_recycle_desc@DB_VERSION_UNIQUE_NAME@
+#define	__txn_init_recover __txn_init_recover@DB_VERSION_UNIQUE_NAME@
+#define	__txn_regop_42_print __txn_regop_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__txn_regop_print __txn_regop_print@DB_VERSION_UNIQUE_NAME@
+#define	__txn_ckp_42_print __txn_ckp_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__txn_ckp_print __txn_ckp_print@DB_VERSION_UNIQUE_NAME@
+#define	__txn_child_print __txn_child_print@DB_VERSION_UNIQUE_NAME@
+#define	__txn_xa_regop_42_print __txn_xa_regop_42_print@DB_VERSION_UNIQUE_NAME@
+#define	__txn_prepare_print __txn_prepare_print@DB_VERSION_UNIQUE_NAME@
+#define	__txn_recycle_print __txn_recycle_print@DB_VERSION_UNIQUE_NAME@
+#define	__txn_init_print __txn_init_print@DB_VERSION_UNIQUE_NAME@
+#define	__txn_checkpoint_pp __txn_checkpoint_pp@DB_VERSION_UNIQUE_NAME@
+#define	__txn_checkpoint __txn_checkpoint@DB_VERSION_UNIQUE_NAME@
+#define	__txn_getactive __txn_getactive@DB_VERSION_UNIQUE_NAME@
+#define	__txn_getckp __txn_getckp@DB_VERSION_UNIQUE_NAME@
+#define	__txn_updateckp __txn_updateckp@DB_VERSION_UNIQUE_NAME@
+#define	__txn_failchk __txn_failchk@DB_VERSION_UNIQUE_NAME@
+#define	__txn_env_create __txn_env_create@DB_VERSION_UNIQUE_NAME@
+#define	__txn_env_destroy __txn_env_destroy@DB_VERSION_UNIQUE_NAME@
+#define	__txn_get_tx_max __txn_get_tx_max@DB_VERSION_UNIQUE_NAME@
+#define	__txn_set_tx_max __txn_set_tx_max@DB_VERSION_UNIQUE_NAME@
+#define	__txn_get_tx_timestamp __txn_get_tx_timestamp@DB_VERSION_UNIQUE_NAME@
+#define	__txn_set_tx_timestamp __txn_set_tx_timestamp@DB_VERSION_UNIQUE_NAME@
+#define	__db_check_txn __db_check_txn@DB_VERSION_UNIQUE_NAME@
+#define	__db_txn_deadlock_err __db_txn_deadlock_err@DB_VERSION_UNIQUE_NAME@
+#define	__db_dbtxn_remove __db_dbtxn_remove@DB_VERSION_UNIQUE_NAME@
+#define	__txn_regop_recover __txn_regop_recover@DB_VERSION_UNIQUE_NAME@
+#define	__txn_prepare_recover __txn_prepare_recover@DB_VERSION_UNIQUE_NAME@
+#define	__txn_ckp_recover __txn_ckp_recover@DB_VERSION_UNIQUE_NAME@
+#define	__txn_child_recover __txn_child_recover@DB_VERSION_UNIQUE_NAME@
+#define	__txn_restore_txn __txn_restore_txn@DB_VERSION_UNIQUE_NAME@
+#define	__txn_recycle_recover __txn_recycle_recover@DB_VERSION_UNIQUE_NAME@
+#define	__txn_regop_42_recover __txn_regop_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__txn_ckp_42_recover __txn_ckp_42_recover@DB_VERSION_UNIQUE_NAME@
+#define	__txn_recover_pp __txn_recover_pp@DB_VERSION_UNIQUE_NAME@
+#define	__txn_recover __txn_recover@DB_VERSION_UNIQUE_NAME@
+#define	__txn_get_prepared __txn_get_prepared@DB_VERSION_UNIQUE_NAME@
+#define	__txn_openfiles __txn_openfiles@DB_VERSION_UNIQUE_NAME@
+#define	__txn_open __txn_open@DB_VERSION_UNIQUE_NAME@
+#define	__txn_findlastckp __txn_findlastckp@DB_VERSION_UNIQUE_NAME@
+#define	__txn_env_refresh __txn_env_refresh@DB_VERSION_UNIQUE_NAME@
+#define	__txn_region_mutex_count __txn_region_mutex_count@DB_VERSION_UNIQUE_NAME@
+#define	__txn_region_mutex_max __txn_region_mutex_max@DB_VERSION_UNIQUE_NAME@
+#define	__txn_region_size __txn_region_size@DB_VERSION_UNIQUE_NAME@
+#define	__txn_region_max __txn_region_max@DB_VERSION_UNIQUE_NAME@
+#define	__txn_id_set __txn_id_set@DB_VERSION_UNIQUE_NAME@
+#define	__txn_oldest_reader __txn_oldest_reader@DB_VERSION_UNIQUE_NAME@
+#define	__txn_add_buffer __txn_add_buffer@DB_VERSION_UNIQUE_NAME@
+#define	__txn_remove_buffer __txn_remove_buffer@DB_VERSION_UNIQUE_NAME@
+#define	__txn_stat_pp __txn_stat_pp@DB_VERSION_UNIQUE_NAME@
+#define	__txn_stat_print_pp __txn_stat_print_pp@DB_VERSION_UNIQUE_NAME@
+#define	__txn_stat_print __txn_stat_print@DB_VERSION_UNIQUE_NAME@
+#define	__txn_closeevent __txn_closeevent@DB_VERSION_UNIQUE_NAME@
+#define	__txn_remevent __txn_remevent@DB_VERSION_UNIQUE_NAME@
+#define	__txn_remrem __txn_remrem@DB_VERSION_UNIQUE_NAME@
+#define	__txn_lockevent __txn_lockevent@DB_VERSION_UNIQUE_NAME@
+#define	__txn_remlock __txn_remlock@DB_VERSION_UNIQUE_NAME@
+#define	__txn_doevents __txn_doevents@DB_VERSION_UNIQUE_NAME@
+#define	__txn_record_fname __txn_record_fname@DB_VERSION_UNIQUE_NAME@
+#define	__txn_dref_fname __txn_dref_fname@DB_VERSION_UNIQUE_NAME@
+#define	__txn_reset_fe_watermarks __txn_reset_fe_watermarks@DB_VERSION_UNIQUE_NAME@
+#define	__txn_remove_fe_watermark __txn_remove_fe_watermark@DB_VERSION_UNIQUE_NAME@
+#define	__txn_add_fe_watermark __txn_add_fe_watermark@DB_VERSION_UNIQUE_NAME@
+#define	__txn_flush_fe_files __txn_flush_fe_files@DB_VERSION_UNIQUE_NAME@
+#define	__txn_pg_above_fe_watermark __txn_pg_above_fe_watermark@DB_VERSION_UNIQUE_NAME@
+#define	__db_rmid_to_env __db_rmid_to_env@DB_VERSION_UNIQUE_NAME@
+#define	__db_xid_to_txn __db_xid_to_txn@DB_VERSION_UNIQUE_NAME@
+#define	__db_map_rmid __db_map_rmid@DB_VERSION_UNIQUE_NAME@
+#define	__db_unmap_rmid __db_unmap_rmid@DB_VERSION_UNIQUE_NAME@
+#define	__db_unmap_xid __db_unmap_xid@DB_VERSION_UNIQUE_NAME@
+#define	__db_global_values __db_global_values@DB_VERSION_UNIQUE_NAME@
+#define	__repmgr_guesstimated_max __repmgr_guesstimated_max@DB_VERSION_UNIQUE_NAME@
+#define	db_xa_switch db_xa_switch@DB_VERSION_UNIQUE_NAME@
+
+#endif /* !_DB_INT_DEF_IN_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/lock_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,107 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_lock_ext_h_
+#define	_lock_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __db_lget __P((DBC *, int, db_pgno_t, db_lockmode_t, u_int32_t, DB_LOCK *));
+int __db_lput __P((DBC *, DB_LOCK *));
+int __db_lprint __P((DBC *));
+int __lock_vec_pp __P((DB_ENV *, u_int32_t, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **));
+int __lock_vec __P((ENV *, DB_LOCKER *, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **));
+int __lock_get_pp __P((DB_ENV *, u_int32_t, u_int32_t, DBT *, db_lockmode_t, DB_LOCK *));
+int __lock_get __P((ENV *, DB_LOCKER *, u_int32_t, const DBT *, db_lockmode_t, DB_LOCK *));
+int  __lock_get_internal __P((DB_LOCKTAB *, DB_LOCKER *, u_int32_t, const DBT *, db_lockmode_t, db_timeout_t, DB_LOCK *));
+int  __lock_put_pp __P((DB_ENV *, DB_LOCK *));
+int  __lock_put __P((ENV *, DB_LOCK *));
+int __lock_downgrade __P((ENV *, DB_LOCK *, db_lockmode_t, u_int32_t));
+int __lock_locker_same_family __P((ENV *, DB_LOCKER *, DB_LOCKER *, int *));
+int __lock_wakeup __P((ENV *, const DBT *));
+int __lock_promote __P((DB_LOCKTAB *, DB_LOCKOBJ *, int *, u_int32_t));
+int __lock_change __P((ENV *, DB_LOCK *, DB_LOCK *));
+int __lock_detect_pp __P((DB_ENV *, u_int32_t, u_int32_t, int *));
+int __lock_detect __P((ENV *, u_int32_t, int *));
+int __lock_failchk __P((ENV *));
+int __lock_id_pp __P((DB_ENV *, u_int32_t *));
+int  __lock_id __P((ENV *, u_int32_t *, DB_LOCKER **));
+void __lock_set_thread_id __P((void *, pid_t, db_threadid_t));
+int __lock_id_free_pp __P((DB_ENV *, u_int32_t));
+int  __lock_id_free __P((ENV *, DB_LOCKER *));
+int __lock_id_set __P((ENV *, u_int32_t, u_int32_t));
+int __lock_getlocker __P((DB_LOCKTAB *, u_int32_t, int, DB_LOCKER **));
+int __lock_getlocker_int __P((DB_LOCKTAB *, u_int32_t, int, DB_LOCKER **));
+int __lock_addfamilylocker __P((ENV *, u_int32_t, u_int32_t, u_int32_t));
+int __lock_freelocker  __P((DB_LOCKTAB *, DB_LOCKER *));
+int __lock_familyremove  __P((DB_LOCKTAB *, DB_LOCKER *));
+int __lock_fix_list __P((ENV *, DBT *, u_int32_t));
+int __lock_get_list __P((ENV *, DB_LOCKER *, u_int32_t, db_lockmode_t, DBT *));
+void __lock_list_print __P((ENV *, DB_MSGBUF *, DBT *));
+int __lock_env_create __P((DB_ENV *));
+void __lock_env_destroy __P((DB_ENV *));
+int __lock_get_lk_conflicts __P((DB_ENV *, const u_int8_t **, int *));
+int __lock_set_lk_conflicts __P((DB_ENV *, u_int8_t *, int));
+int __lock_get_lk_detect __P((DB_ENV *, u_int32_t *));
+int __lock_set_lk_detect __P((DB_ENV *, u_int32_t));
+int __lock_get_lk_max_locks __P((DB_ENV *, u_int32_t *));
+int __lock_set_lk_max_locks __P((DB_ENV *, u_int32_t));
+int __lock_get_lk_max_lockers __P((DB_ENV *, u_int32_t *));
+int __lock_set_lk_max_lockers __P((DB_ENV *, u_int32_t));
+int __lock_get_lk_max_objects __P((DB_ENV *, u_int32_t *));
+int __lock_set_lk_max_objects __P((DB_ENV *, u_int32_t));
+int __lock_get_lk_partitions __P((DB_ENV *, u_int32_t *));
+int __lock_set_lk_partitions __P((DB_ENV *, u_int32_t));
+int __lock_get_lk_tablesize __P((DB_ENV *, u_int32_t *));
+int __lock_set_lk_tablesize __P((DB_ENV *, u_int32_t));
+int __lock_set_lk_priority __P((DB_ENV *, u_int32_t, u_int32_t));
+int __lock_get_lk_priority __P((DB_ENV *, u_int32_t, u_int32_t *));
+int __lock_get_env_timeout __P((DB_ENV *, db_timeout_t *, u_int32_t));
+int __lock_set_env_timeout __P((DB_ENV *, db_timeout_t, u_int32_t));
+int __lock_open __P((ENV *));
+int __lock_env_refresh __P((ENV *));
+u_int32_t __lock_region_mutex_count __P((ENV *));
+u_int32_t __lock_region_mutex_max __P((ENV *));
+size_t __lock_region_max __P((ENV *));
+size_t __lock_region_size __P((ENV *, size_t));
+int __lock_stat_pp __P((DB_ENV *, DB_LOCK_STAT **, u_int32_t));
+int __lock_stat_print_pp __P((DB_ENV *, u_int32_t));
+int  __lock_stat_print __P((ENV *, u_int32_t));
+void __lock_printlock __P((DB_LOCKTAB *, DB_MSGBUF *mbp, struct __db_lock *, int));
+int __lock_set_timeout __P((ENV *, DB_LOCKER *, db_timeout_t, u_int32_t));
+int __lock_set_timeout_internal __P((ENV *, DB_LOCKER *, db_timeout_t, u_int32_t));
+int __lock_inherit_timeout __P((ENV *, DB_LOCKER *, DB_LOCKER *));
+u_int32_t __lock_ohash __P((const DBT *));
+u_int32_t __lock_lhash __P((DB_LOCKOBJ *));
+int __lock_nomem __P((ENV *, const char *));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_lock_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/log_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,234 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_log_ext_h_
+#define	_log_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __log_open __P((ENV *));
+int __log_find __P((DB_LOG *, int, u_int32_t *, logfile_validity *));
+int __log_valid __P((DB_LOG *, u_int32_t, int, DB_FH **, u_int32_t, logfile_validity *, u_int32_t *));
+int __log_env_refresh __P((ENV *));
+int __log_get_cached_ckp_lsn __P((ENV *, DB_LSN *));
+u_int32_t __log_region_mutex_count __P((ENV *));
+u_int32_t __log_region_mutex_max __P((ENV *));
+size_t	__log_region_size __P((ENV *));
+size_t	__log_region_max __P((ENV *));
+int __log_vtruncate __P((ENV *, DB_LSN *, DB_LSN *, DB_LSN *));
+int __log_is_outdated __P((ENV *, u_int32_t, int *));
+int __log_zero __P((ENV *, DB_LSN *));
+int __log_inmem_lsnoff __P((DB_LOG *, DB_LSN *, size_t *));
+int __log_inmem_newfile __P((DB_LOG *, u_int32_t));
+int __log_inmem_chkspace __P((DB_LOG *, size_t));
+void __log_inmem_copyout __P((DB_LOG *, size_t, void *, size_t));
+void __log_inmem_copyin __P((DB_LOG *, size_t, void *, size_t));
+void __log_set_version __P((ENV *, u_int32_t));
+int __log_get_oldversion __P((ENV *, u_int32_t *));
+int __log_archive_pp __P((DB_ENV *, char **[], u_int32_t));
+int __log_archive __P((ENV *, char **[], u_int32_t));
+int __log_get_stable_lsn __P((ENV *, DB_LSN *, int));
+void __log_autoremove __P((ENV *));
+int __log_check_page_lsn __P((ENV *, DB *, DB_LSN *));
+int __log_printf_capi __P((DB_ENV *, DB_TXN *, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4)));
+int __log_printf_pp __P((DB_ENV *, DB_TXN *, const char *, va_list));
+int __log_printf __P((ENV *, DB_TXN *, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4)));
+int __log_cursor_pp __P((DB_ENV *, DB_LOGC **, u_int32_t));
+int __log_cursor __P((ENV *, DB_LOGC **));
+int __logc_close __P((DB_LOGC *));
+int __logc_version __P((DB_LOGC *, u_int32_t *));
+int __logc_get __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t));
+void __log_hdrswap __P((HDR *, int));
+void __log_persistswap __P((LOGP *));
+int __log_read_record_pp  __P((DB_ENV *, DB **, void *, void *, DB_LOG_RECSPEC *, u_int32_t, void **));
+int __log_read_record  __P((ENV *, DB **, void *, void *, DB_LOG_RECSPEC *, u_int32_t, void **));
+int __log_env_create __P((DB_ENV *));
+void __log_env_destroy __P((DB_ENV *));
+int __log_get_lg_bsize __P((DB_ENV *, u_int32_t *));
+int __log_set_lg_bsize __P((DB_ENV *, u_int32_t));
+int __log_get_lg_filemode __P((DB_ENV *, int *));
+int __log_set_lg_filemode __P((DB_ENV *, int));
+int __log_get_lg_max __P((DB_ENV *, u_int32_t *));
+int __log_set_lg_max __P((DB_ENV *, u_int32_t));
+int __log_get_lg_regionmax __P((DB_ENV *, u_int32_t *));
+int __log_set_lg_regionmax __P((DB_ENV *, u_int32_t));
+int __log_get_lg_dir __P((DB_ENV *, const char **));
+int __log_set_lg_dir __P((DB_ENV *, const char *));
+void __log_get_flags __P((DB_ENV *, u_int32_t *));
+void __log_set_flags __P((ENV *, u_int32_t, int));
+int __log_get_config __P((DB_ENV *, u_int32_t, int *));
+int __log_set_config __P((DB_ENV *, u_int32_t, int));
+int __log_set_config_int __P((DB_ENV *, u_int32_t, int, int));
+int __log_check_sizes __P((ENV *, u_int32_t, u_int32_t));
+int __log_print_record  __P((ENV *, DBT *, DB_LSN *, char *, DB_LOG_RECSPEC *, void *));
+int __log_put_pp __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t));
+int __log_put __P((ENV *, DB_LSN *, const DBT *, u_int32_t));
+int __log_current_lsn_int __P((ENV *, DB_LSN *, u_int32_t *, u_int32_t *));
+int __log_current_lsn __P((ENV *, DB_LSN *, u_int32_t *, u_int32_t *));
+int __log_newfile __P((DB_LOG *, DB_LSN *, u_int32_t, u_int32_t));
+int __log_flush_pp __P((DB_ENV *, const DB_LSN *));
+int __log_flush __P((ENV *, const DB_LSN *));
+int __log_flush_int __P((DB_LOG *, const DB_LSN *, int));
+int __log_file_pp __P((DB_ENV *, const DB_LSN *, char *, size_t));
+int __log_name __P((DB_LOG *, u_int32_t, char **, DB_FH **, u_int32_t));
+int __log_rep_put __P((ENV *, DB_LSN *, const DBT *, u_int32_t));
+int __log_put_record_pp __P((DB_ENV *, DB *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, DB_LOG_RECSPEC *, ...));
+int __log_put_record __P((ENV *, DB *, DB_TXN *, DB_LSN *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, DB_LOG_RECSPEC *, ...));
+int __log_stat_pp __P((DB_ENV *, DB_LOG_STAT **, u_int32_t));
+int __log_stat_print_pp __P((DB_ENV *, u_int32_t));
+int __log_stat_print __P((ENV *, u_int32_t));
+int __log_verify_pp __P((DB_ENV *, const DB_LOG_VERIFY_CONFIG *));
+int __log_verify __P((DB_ENV *, const DB_LOG_VERIFY_CONFIG *, DB_THREAD_INFO *));
+int __log_verify_wrap __P((ENV *, const char *, u_int32_t, const char *, const char *, time_t, time_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, int, int));
+int __crdel_init_verify __P((ENV *, DB_DISTAB *));
+int __db_init_verify __P((ENV *, DB_DISTAB *));
+int __dbreg_init_verify __P((ENV *, DB_DISTAB *));
+int __bam_init_verify __P((ENV *, DB_DISTAB *));
+int __fop_init_verify __P((ENV *, DB_DISTAB *));
+int __ham_init_verify __P((ENV *, DB_DISTAB *));
+int __heap_init_verify __P((ENV *, DB_DISTAB *));
+int __qam_init_verify __P((ENV *, DB_DISTAB *));
+int __txn_init_verify __P((ENV *, DB_DISTAB *));
+void __db_log_verify_global_report __P((const DB_LOG_VRFY_INFO *));
+int __crdel_metasub_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __crdel_inmem_create_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __crdel_inmem_rename_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __crdel_inmem_remove_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_addrem_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_big_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_ovref_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_relink_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_debug_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_noop_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_alloc_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_alloc_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_free_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_free_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_cksum_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_freedata_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_freedata_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_init_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_sort_44_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pg_trunc_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_realloc_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_relink_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_merge_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __db_pgno_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __dbreg_register_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_split_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_split_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_rsplit_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_adj_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_irep_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_cadjust_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_cdel_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_repl_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_root_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_curadj_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_rcuradj_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_relink_43_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __bam_merge_44_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_create_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_create_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_remove_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_write_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_write_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_rename_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_rename_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __fop_file_remove_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_insdel_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_newpage_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_splitdata_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_replace_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_copypage_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_metagroup_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_metagroup_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_groupalloc_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_groupalloc_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_changeslot_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_contract_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_curadj_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __ham_chgpg_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_addrem_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_pg_alloc_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_trunc_meta_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __heap_trunc_page_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_incfirst_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_mvptr_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_del_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_add_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_delext_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_regop_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_regop_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_ckp_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_ckp_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_child_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_xa_regop_42_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_prepare_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_recycle_verify __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __create_log_vrfy_info __P((const DB_LOG_VERIFY_CONFIG *, DB_LOG_VRFY_INFO **, DB_THREAD_INFO *));
+int __destroy_log_vrfy_info __P((DB_LOG_VRFY_INFO *));
+int __put_txn_vrfy_info __P((const DB_LOG_VRFY_INFO *, const VRFY_TXN_INFO *));
+int __get_txn_vrfy_info __P((const DB_LOG_VRFY_INFO *, u_int32_t, VRFY_TXN_INFO **));
+int __add_recycle_lsn_range __P((DB_LOG_VRFY_INFO *, const DB_LSN *, u_int32_t, u_int32_t));
+int __iterate_txninfo __P((DB_LOG_VRFY_INFO *, u_int32_t, u_int32_t, TXNINFO_HANDLER, void *));
+int __rem_last_recycle_lsn __P((VRFY_TXN_INFO *));
+int __add_file_updated __P((VRFY_TXN_INFO *, const DBT *, int32_t));
+int __del_file_updated __P((VRFY_TXN_INFO *, const DBT *));
+int __clear_fileups __P((VRFY_TXN_INFO *));
+int __free_txninfo_stack __P((VRFY_TXN_INFO *));
+int __free_txninfo __P((VRFY_TXN_INFO *));
+int __put_filereg_info __P((const DB_LOG_VRFY_INFO *, const VRFY_FILEREG_INFO *));
+int __del_filelife __P((const DB_LOG_VRFY_INFO *, int32_t));
+int __put_filelife __P((const DB_LOG_VRFY_INFO *, VRFY_FILELIFE *));
+int __get_filelife __P((const DB_LOG_VRFY_INFO *, int32_t, VRFY_FILELIFE **));
+int __get_filereg_by_dbregid __P((const DB_LOG_VRFY_INFO *, int32_t, VRFY_FILEREG_INFO **));
+int __add_dbregid __P((DB_LOG_VRFY_INFO *, VRFY_FILEREG_INFO *, int32_t, u_int32_t, DB_LSN, DBTYPE, db_pgno_t, int *));
+int __get_filereg_info __P((const DB_LOG_VRFY_INFO *, const DBT *, VRFY_FILEREG_INFO **));
+int __free_filereg_info __P((VRFY_FILEREG_INFO *));
+int __get_ckp_info __P((const DB_LOG_VRFY_INFO *, DB_LSN, VRFY_CKP_INFO **));
+int __get_last_ckp_info __P((const DB_LOG_VRFY_INFO *, VRFY_CKP_INFO **));
+int __put_ckp_info __P((const DB_LOG_VRFY_INFO *, const VRFY_CKP_INFO *));
+int __get_timestamp_info __P((const DB_LOG_VRFY_INFO *, DB_LSN, VRFY_TIMESTAMP_INFO **));
+int __get_latest_timestamp_info __P((const DB_LOG_VRFY_INFO *, DB_LSN, VRFY_TIMESTAMP_INFO **));
+int __put_timestamp_info __P((const DB_LOG_VRFY_INFO *, const VRFY_TIMESTAMP_INFO *));
+int __find_lsnrg_by_timerg __P((DB_LOG_VRFY_INFO *, time_t, time_t, DB_LSN *, DB_LSN *));
+int __add_txnrange __P((DB_LOG_VRFY_INFO *, u_int32_t, DB_LSN, int32_t, int));
+int __get_aborttxn __P((DB_LOG_VRFY_INFO *, DB_LSN));
+int __txn_started __P((DB_LOG_VRFY_INFO *, DB_LSN, u_int32_t, int *));
+int __set_logvrfy_dbfuid __P((DB_LOG_VRFY_INFO *));
+int __add_page_to_txn __P((DB_LOG_VRFY_INFO *, int32_t, db_pgno_t, u_int32_t, u_int32_t *, int *));
+int __del_txn_pages __P((DB_LOG_VRFY_INFO *, u_int32_t));
+int __is_ancestor_txn __P((DB_LOG_VRFY_INFO *, u_int32_t, u_int32_t, DB_LSN, int *));
+int __return_txn_pages __P((DB_LOG_VRFY_INFO *, u_int32_t, u_int32_t));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_log_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/mp_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,132 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_mp_ext_h_
+#define	_mp_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __memp_alloc __P((DB_MPOOL *, REGINFO *, MPOOLFILE *, size_t, roff_t *, void *));
+void __memp_free __P((REGINFO *, void *));
+int __memp_backup_open __P((ENV *, DB_MPOOLFILE *, const char *, const char *, u_int32_t, DB_FH **, void**));
+int __memp_backup_mpf __P((ENV *, DB_MPOOLFILE *, DB_THREAD_INFO *, db_pgno_t, db_pgno_t, DB_FH *, void *,  u_int32_t));
+int __memp_backup_close __P((ENV *, DB_MPOOLFILE *, const char *, DB_FH *, void *HANDLE));
+int __memp_failchk __P((ENV *));
+int __memp_bhwrite __P((DB_MPOOL *, DB_MPOOL_HASH *, MPOOLFILE *, BH *, int));
+int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
+int __memp_pg __P((DB_MPOOLFILE *, db_pgno_t, void *, int));
+int __memp_bhfree __P((DB_MPOOL *, REGINFO *, MPOOLFILE *, DB_MPOOL_HASH *, BH *, u_int32_t));
+int __memp_fget_pp __P((DB_MPOOLFILE *, db_pgno_t *, DB_TXN *, u_int32_t, void *));
+int __memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, DB_THREAD_INFO *, DB_TXN *, u_int32_t, void *));
+int __memp_fcreate_pp __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t));
+int __memp_fcreate __P((ENV *, DB_MPOOLFILE **));
+int __memp_set_clear_len __P((DB_MPOOLFILE *, u_int32_t));
+int __memp_get_fileid __P((DB_MPOOLFILE *, u_int8_t *));
+int __memp_set_fileid __P((DB_MPOOLFILE *, u_int8_t *));
+int __memp_get_flags __P((DB_MPOOLFILE *, u_int32_t *));
+int __memp_set_flags __P((DB_MPOOLFILE *, u_int32_t, int));
+int __memp_get_ftype __P((DB_MPOOLFILE *, int *));
+int __memp_set_ftype __P((DB_MPOOLFILE *, int));
+int __memp_set_lsn_offset __P((DB_MPOOLFILE *, int32_t));
+int __memp_get_pgcookie __P((DB_MPOOLFILE *, DBT *));
+int __memp_set_pgcookie __P((DB_MPOOLFILE *, DBT *));
+int __memp_get_priority __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY *));
+int __memp_get_last_pgno __P((DB_MPOOLFILE *, db_pgno_t *));
+char * __memp_fn __P((DB_MPOOLFILE *));
+char * __memp_fns __P((DB_MPOOL *, MPOOLFILE *));
+int __memp_fopen_pp __P((DB_MPOOLFILE *, const char *, u_int32_t, int, size_t));
+int __memp_fopen __P((DB_MPOOLFILE *, MPOOLFILE *, const char *, const char **, u_int32_t, int, size_t));
+int __memp_fclose_pp __P((DB_MPOOLFILE *, u_int32_t));
+int __memp_fclose __P((DB_MPOOLFILE *, u_int32_t));
+int __memp_mf_discard __P((DB_MPOOL *, MPOOLFILE *, int));
+int __memp_inmemlist __P((ENV *, char ***, int *));
+int __memp_fput_pp __P((DB_MPOOLFILE *, void *, DB_CACHE_PRIORITY, u_int32_t));
+int __memp_fput __P((DB_MPOOLFILE *, DB_THREAD_INFO *, void *, DB_CACHE_PRIORITY));
+int __memp_unpin_buffers __P((ENV *, DB_THREAD_INFO *));
+int __memp_dirty __P((DB_MPOOLFILE *, void *, DB_THREAD_INFO *, DB_TXN *, DB_CACHE_PRIORITY, u_int32_t));
+int __memp_shared __P((DB_MPOOLFILE *, void *));
+int __memp_env_create __P((DB_ENV *));
+void __memp_env_destroy __P((DB_ENV *));
+int __memp_get_cachesize __P((DB_ENV *, u_int32_t *, u_int32_t *, int *));
+int __memp_set_cachesize __P((DB_ENV *, u_int32_t, u_int32_t, int));
+int __memp_set_config __P((DB_ENV *, u_int32_t, int));
+int __memp_get_config __P((DB_ENV *, u_int32_t, int *));
+int __memp_get_mp_max_openfd __P((DB_ENV *, int *));
+int __memp_set_mp_max_openfd __P((DB_ENV *, int));
+int __memp_get_mp_max_write __P((DB_ENV *, int *, db_timeout_t *));
+int __memp_set_mp_max_write __P((DB_ENV *, int, db_timeout_t));
+int __memp_get_mp_mmapsize __P((DB_ENV *, size_t *));
+int __memp_set_mp_mmapsize __P((DB_ENV *, size_t));
+int __memp_get_mp_pagesize __P((DB_ENV *, u_int32_t *));
+int __memp_set_mp_pagesize __P((DB_ENV *, u_int32_t));
+int __memp_get_mp_tablesize __P((DB_ENV *, u_int32_t *));
+int __memp_set_mp_tablesize __P((DB_ENV *, u_int32_t));
+int __memp_get_mp_mtxcount __P((DB_ENV *, u_int32_t *));
+int __memp_set_mp_mtxcount __P((DB_ENV *, u_int32_t));
+int __memp_nameop __P((ENV *, u_int8_t *, const char *, const char *, const char *, int));
+int __memp_ftruncate __P((DB_MPOOLFILE *, DB_TXN *, DB_THREAD_INFO *, db_pgno_t, u_int32_t));
+int __memp_alloc_freelist __P((DB_MPOOLFILE *, u_int32_t, db_pgno_t **));
+int __memp_free_freelist __P((DB_MPOOLFILE *));
+int __memp_get_freelist __P(( DB_MPOOLFILE *, u_int32_t *, db_pgno_t **));
+int __memp_extend_freelist __P(( DB_MPOOLFILE *, u_int32_t , db_pgno_t **));
+int __memp_set_last_pgno __P((DB_MPOOLFILE *, db_pgno_t));
+int __memp_bh_settxn __P((DB_MPOOL *, MPOOLFILE *mfp, BH *, void *));
+int __memp_skip_curadj __P((DBC *, db_pgno_t));
+int __memp_bh_freeze __P((DB_MPOOL *, REGINFO *, DB_MPOOL_HASH *, BH *, int *));
+int __memp_bh_thaw __P((DB_MPOOL *, REGINFO *, DB_MPOOL_HASH *, BH *, BH *));
+int __memp_open __P((ENV *, int));
+int	__memp_init __P((ENV *, DB_MPOOL *, u_int, u_int32_t, u_int));
+u_int32_t __memp_max_regions __P((ENV *));
+u_int32_t __memp_region_mutex_count __P((ENV *));
+int __memp_env_refresh __P((ENV *));
+int __memp_register_pp __P((DB_ENV *, int, int (*)(DB_ENV *, db_pgno_t, void *, DBT *), int (*)(DB_ENV *, db_pgno_t, void *, DBT *)));
+int __memp_register __P((ENV *, int, int (*)(DB_ENV *, db_pgno_t, void *, DBT *), int (*)(DB_ENV *, db_pgno_t, void *, DBT *)));
+int __memp_get_bucket __P((ENV *, MPOOLFILE *, db_pgno_t, REGINFO **, DB_MPOOL_HASH **, u_int32_t *));
+int __memp_resize __P((DB_MPOOL *, u_int32_t, u_int32_t));
+int __memp_get_cache_max __P((DB_ENV *, u_int32_t *, u_int32_t *));
+int __memp_set_cache_max __P((DB_ENV *, u_int32_t, u_int32_t));
+int __memp_stat_pp __P((DB_ENV *, DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t));
+int __memp_stat_print_pp __P((DB_ENV *, u_int32_t));
+int  __memp_stat_print __P((ENV *, u_int32_t));
+void __memp_stat_hash __P((REGINFO *, MPOOL *, u_int32_t *));
+int __memp_walk_files __P((ENV *, MPOOL *, int (*) __P((ENV *, MPOOLFILE *, void *, u_int32_t *, u_int32_t)), void *, u_int32_t *, u_int32_t));
+int __memp_discard_all_mpfs __P((ENV *, MPOOL *));
+int __memp_sync_pp __P((DB_ENV *, DB_LSN *));
+int __memp_sync __P((ENV *, u_int32_t, DB_LSN *));
+int __memp_fsync_pp __P((DB_MPOOLFILE *));
+int __memp_fsync __P((DB_MPOOLFILE *));
+int __mp_xxx_fh __P((DB_MPOOLFILE *, DB_FH **));
+int __memp_sync_int __P((ENV *, DB_MPOOLFILE *, u_int32_t, u_int32_t, u_int32_t *, int *));
+int __memp_mf_sync __P((DB_MPOOL *, MPOOLFILE *, int));
+int __memp_trickle_pp __P((DB_ENV *, int, int *));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_mp_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/mutex_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,117 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_mutex_ext_h_
+#define	_mutex_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __mutex_alloc __P((ENV *, int, u_int32_t, db_mutex_t *));
+int __mutex_alloc_int __P((ENV *, int, int, u_int32_t, db_mutex_t *));
+int __mutex_free __P((ENV *, db_mutex_t *));
+int __mutex_free_int __P((ENV *, int, db_mutex_t *));
+int __mutex_refresh __P((ENV *, db_mutex_t));
+int __mut_failchk __P((ENV *));
+int __db_fcntl_mutex_init __P((ENV *, db_mutex_t, u_int32_t));
+int __db_fcntl_mutex_lock __P((ENV *, db_mutex_t, db_timeout_t));
+int __db_fcntl_mutex_trylock __P((ENV *, db_mutex_t));
+int __db_fcntl_mutex_unlock __P((ENV *, db_mutex_t));
+int __db_fcntl_mutex_destroy __P((ENV *, db_mutex_t));
+int __mutex_alloc_pp __P((DB_ENV *, u_int32_t, db_mutex_t *));
+int __mutex_free_pp __P((DB_ENV *, db_mutex_t));
+int __mutex_lock_pp __P((DB_ENV *, db_mutex_t));
+int __mutex_unlock_pp __P((DB_ENV *, db_mutex_t));
+int __mutex_get_align __P((DB_ENV *, u_int32_t *));
+int __mutex_set_align __P((DB_ENV *, u_int32_t));
+int __mutex_get_increment __P((DB_ENV *, u_int32_t *));
+int __mutex_set_increment __P((DB_ENV *, u_int32_t));
+int __mutex_get_init __P((DB_ENV *, u_int32_t *));
+int __mutex_set_init __P((DB_ENV *, u_int32_t));
+int __mutex_get_max __P((DB_ENV *, u_int32_t *));
+int __mutex_set_max __P((DB_ENV *, u_int32_t));
+int __mutex_get_tas_spins __P((DB_ENV *, u_int32_t *));
+int __mutex_set_tas_spins __P((DB_ENV *, u_int32_t));
+#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT)
+atomic_value_t __atomic_inc __P((ENV *, db_atomic_t *));
+#endif
+#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT)
+atomic_value_t __atomic_dec __P((ENV *, db_atomic_t *));
+#endif
+#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT)
+int atomic_compare_exchange __P((ENV *, db_atomic_t *, atomic_value_t, atomic_value_t));
+#endif
+int __db_pthread_mutex_init __P((ENV *, db_mutex_t, u_int32_t));
+#ifndef HAVE_MUTEX_HYBRID
+int __db_pthread_mutex_lock __P((ENV *, db_mutex_t, db_timeout_t));
+#endif
+#if defined(HAVE_SHARED_LATCHES)
+int __db_pthread_mutex_readlock __P((ENV *, db_mutex_t));
+#endif
+#ifdef HAVE_MUTEX_HYBRID
+int __db_hybrid_mutex_suspend __P((ENV *, db_mutex_t, db_timespec *, int));
+#endif
+int __db_pthread_mutex_unlock __P((ENV *, db_mutex_t));
+int __db_pthread_mutex_destroy __P((ENV *, db_mutex_t));
+int __mutex_open __P((ENV *, int));
+int __mutex_env_refresh __P((ENV *));
+void __mutex_resource_return __P((ENV *, REGINFO *));
+int __mutex_stat_pp __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t));
+int __mutex_stat_print_pp __P((DB_ENV *, u_int32_t));
+int __mutex_stat_print __P((ENV *, u_int32_t));
+void __mutex_print_debug_single __P((ENV *, const char *, db_mutex_t, u_int32_t));
+void __mutex_print_debug_stats __P((ENV *, DB_MSGBUF *, db_mutex_t, u_int32_t));
+void __mutex_set_wait_info __P((ENV *, db_mutex_t, uintmax_t *, uintmax_t *));
+void __mutex_clear __P((ENV *, db_mutex_t));
+int __db_tas_mutex_init __P((ENV *, db_mutex_t, u_int32_t));
+int __db_tas_mutex_lock __P((ENV *, db_mutex_t, db_timeout_t));
+int __db_tas_mutex_trylock __P((ENV *, db_mutex_t));
+#if defined(HAVE_SHARED_LATCHES)
+int __db_tas_mutex_readlock __P((ENV *, db_mutex_t));
+#endif
+#if defined(HAVE_SHARED_LATCHES)
+int __db_tas_mutex_tryreadlock __P((ENV *, db_mutex_t));
+#endif
+int __db_tas_mutex_unlock __P((ENV *, db_mutex_t));
+int __db_tas_mutex_destroy __P((ENV *, db_mutex_t));
+int __db_win32_mutex_init __P((ENV *, db_mutex_t, u_int32_t));
+int __db_win32_mutex_lock __P((ENV *, db_mutex_t, db_timeout_t));
+int __db_win32_mutex_trylock __P((ENV *, db_mutex_t));
+#if defined(HAVE_SHARED_LATCHES)
+int __db_win32_mutex_readlock __P((ENV *, db_mutex_t));
+#endif
+#if defined(HAVE_SHARED_LATCHES)
+int __db_win32_mutex_tryreadlock __P((ENV *, db_mutex_t));
+#endif
+int __db_win32_mutex_unlock __P((ENV *, db_mutex_t));
+int __db_win32_mutex_destroy __P((ENV *, db_mutex_t));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_mutex_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/os_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,110 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_os_ext_h_
+#define	_os_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+void __os_abort __P((ENV *));
+int __os_abspath __P((const char *));
+#if defined(HAVE_REPLICATION_THREADS)
+int __os_getaddrinfo __P((ENV *, const char *, u_int, const char *, const ADDRINFO *, ADDRINFO **));
+#endif
+#if defined(HAVE_REPLICATION_THREADS)
+void __os_freeaddrinfo __P((ENV *, ADDRINFO *));
+#endif
+int __os_umalloc __P((ENV *, size_t, void *));
+int __os_urealloc __P((ENV *, size_t, void *));
+void __os_ufree __P((ENV *, void *));
+int __os_strdup __P((ENV *, const char *, void *));
+int __os_calloc __P((ENV *, size_t, size_t, void *));
+int __os_malloc __P((ENV *, size_t, void *));
+int __os_realloc __P((ENV *, size_t, void *));
+void __os_free __P((ENV *, void *));
+void *__ua_memcpy __P((void *, const void *, size_t));
+void __os_gettime __P((ENV *, db_timespec *, int));
+int __os_fs_notzero __P((void));
+int __os_support_direct_io __P((void));
+int __os_support_db_register __P((void));
+int __os_support_replication __P((void));
+u_int32_t __os_cpu_count __P((void));
+char *__os_ctime __P((const time_t *, char *));
+int __os_dirlist __P((ENV *, const char *, int, char ***, int *));
+void __os_dirfree __P((ENV *, char **, int));
+int __os_get_errno_ret_zero __P((void));
+int __os_get_errno __P((void));
+int __os_get_neterr __P((void));
+int __os_get_syserr __P((void));
+void __os_set_errno __P((int));
+char *__os_strerror __P((int, char *, size_t));
+int __os_posix_err __P((int));
+int __os_fileid __P((ENV *, const char *, int, u_int8_t *));
+int __os_fdlock __P((ENV *, DB_FH *, off_t, int, int));
+int __os_fsync __P((ENV *, DB_FH *));
+int __os_getenv __P((ENV *, const char *, char **, size_t));
+int __os_openhandle __P((ENV *, const char *, int, int, DB_FH **));
+int __os_closehandle __P((ENV *, DB_FH *));
+int __os_attach __P((ENV *, REGINFO *, REGION *));
+int __os_detach __P((ENV *, REGINFO *, int));
+int __os_mapfile __P((ENV *, char *, DB_FH *, size_t, int, void **));
+int __os_unmapfile __P((ENV *, void *, size_t));
+int __os_mkdir __P((ENV *, const char *, int));
+int __os_open __P((ENV *, const char *, u_int32_t, u_int32_t, int, DB_FH **));
+int __os_concat_path __P((char *, size_t, const char *, const char *));
+void __os_id __P((DB_ENV *, pid_t *, db_threadid_t*));
+int __os_rename __P((ENV *, const char *, const char *, u_int32_t));
+int __os_isroot __P((void));
+char *__db_rpath __P((const char *));
+int __os_io __P((ENV *, int, DB_FH *, db_pgno_t, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, size_t *));
+int __os_read __P((ENV *, DB_FH *, void *, size_t, size_t *));
+int __os_write __P((ENV *, DB_FH *, void *, size_t, size_t *));
+int __os_physwrite __P((ENV *, DB_FH *, void *, size_t, size_t *));
+int __os_seek __P((ENV *, DB_FH *, db_pgno_t, u_int32_t, off_t));
+void __os_stack __P((ENV *));
+int __os_exists __P((ENV *, const char *, int *));
+int __os_ioinfo __P((ENV *, const char *, DB_FH *, u_int32_t *, u_int32_t *, u_int32_t *));
+int __os_tmpdir __P((ENV *, u_int32_t));
+int __os_truncate __P((ENV *, DB_FH *, db_pgno_t, u_int32_t));
+void __os_unique_id __P((ENV *, u_int32_t *));
+int __os_unlink __P((ENV *, const char *, int));
+void __os_yield __P((ENV *, u_long, u_long));
+#ifdef HAVE_QNX
+int __os_qnx_region_open __P((ENV *, const char *, int, int, DB_FH **));
+#endif
+int __os_is_winnt __P((void));
+u_int32_t __os_cpu_count __P((void));
+#ifdef HAVE_REPLICATION_THREADS
+int __os_get_neterr __P((void));
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_os_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/qam_auto.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,199 @@
+/* Do not edit: automatically built by gen_rec.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__qam_AUTO_H
+#define	__qam_AUTO_H
+#ifdef HAVE_QUEUE
+#include "dbinc/log.h"
+#define	DB___qam_incfirst	84
+typedef struct ___qam_incfirst_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	db_recno_t	recno;
+	db_pgno_t	meta_pgno;
+} __qam_incfirst_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __qam_incfirst_desc[];
+static inline int
+__qam_incfirst_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, db_recno_t recno, db_pgno_t meta_pgno)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___qam_incfirst, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __qam_incfirst_desc, recno, meta_pgno));
+}
+
+static inline int __qam_incfirst_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __qam_incfirst_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __qam_incfirst_desc, sizeof(__qam_incfirst_args), (void**)arg));
+}
+#define	DB___qam_mvptr	85
+typedef struct ___qam_mvptr_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	fileid;
+	db_recno_t	old_first;
+	db_recno_t	new_first;
+	db_recno_t	old_cur;
+	db_recno_t	new_cur;
+	DB_LSN	metalsn;
+	db_pgno_t	meta_pgno;
+} __qam_mvptr_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __qam_mvptr_desc[];
+static inline int
+__qam_mvptr_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t opcode, db_recno_t old_first, db_recno_t new_first, db_recno_t old_cur,
+    db_recno_t new_cur, DB_LSN * metalsn, db_pgno_t meta_pgno)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___qam_mvptr, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    sizeof(*metalsn) + sizeof(u_int32_t),
+	    __qam_mvptr_desc,
+	    opcode, old_first, new_first, old_cur, new_cur, metalsn, meta_pgno));
+}
+
+static inline int __qam_mvptr_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __qam_mvptr_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __qam_mvptr_desc, sizeof(__qam_mvptr_args), (void**)arg));
+}
+#define	DB___qam_del	79
+typedef struct ___qam_del_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	DB_LSN	lsn;
+	db_pgno_t	pgno;
+	u_int32_t	indx;
+	db_recno_t	recno;
+} __qam_del_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __qam_del_desc[];
+static inline int
+__qam_del_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, DB_LSN * lsn, db_pgno_t pgno, u_int32_t indx, db_recno_t recno)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___qam_del, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(*lsn) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __qam_del_desc, lsn, pgno, indx, recno));
+}
+
+static inline int __qam_del_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __qam_del_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __qam_del_desc, sizeof(__qam_del_args), (void**)arg));
+}
+#define	DB___qam_add	80
+typedef struct ___qam_add_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	DB_LSN	lsn;
+	db_pgno_t	pgno;
+	u_int32_t	indx;
+	db_recno_t	recno;
+	DBT	data;
+	u_int32_t	vflag;
+	DBT	olddata;
+} __qam_add_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __qam_add_desc[];
+static inline int
+__qam_add_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, DB_LSN * lsn, db_pgno_t pgno, u_int32_t indx, db_recno_t recno,
+    const DBT *data, u_int32_t vflag, const DBT *olddata)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___qam_add, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(*lsn) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(data) +
+	    sizeof(u_int32_t) + LOG_DBT_SIZE(olddata),
+	    __qam_add_desc, lsn, pgno, indx, recno, data, vflag, olddata));
+}
+
+static inline int __qam_add_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __qam_add_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __qam_add_desc, sizeof(__qam_add_args), (void**)arg));
+}
+#define	DB___qam_delext	83
+typedef struct ___qam_delext_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	int32_t	fileid;
+	DB_LSN	lsn;
+	db_pgno_t	pgno;
+	u_int32_t	indx;
+	db_recno_t	recno;
+	DBT	data;
+} __qam_delext_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __qam_delext_desc[];
+static inline int
+__qam_delext_log(DB *dbp, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags, DB_LSN * lsn, db_pgno_t pgno, u_int32_t indx, db_recno_t recno,
+    const DBT *data)
+{
+	return (__log_put_record((dbp)->env, dbp, txnp, ret_lsnp,
+	    flags, DB___qam_delext, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(*lsn) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + LOG_DBT_SIZE(data),
+	    __qam_delext_desc, lsn, pgno, indx, recno, data));
+}
+
+static inline int __qam_delext_read(ENV *env, 
+    DB **dbpp, void *td, void *data, __qam_delext_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    dbpp, td, data, __qam_delext_desc, sizeof(__qam_delext_args), (void**)arg));
+}
+#endif /* HAVE_QUEUE */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/qam_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,94 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_qam_ext_h_
+#define	_qam_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __qam_position __P((DBC *, db_recno_t *, u_int32_t, int *));
+int __qam_pitem __P((DBC *,  QPAGE *, u_int32_t, db_recno_t, DBT *));
+int __qam_append __P((DBC *, DBT *, DBT *));
+int __qamc_dup __P((DBC *, DBC *));
+int __qamc_init __P((DBC *));
+int __qam_truncate __P((DBC *, u_int32_t *));
+int __qam_delete __P((DBC *,  DBT *, u_int32_t));
+int __qam_init_recover __P((ENV *, DB_DISTAB *));
+int __qam_incfirst_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_mvptr_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_del_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_add_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_delext_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_init_print __P((ENV *, DB_DISTAB *));
+int __qam_mswap __P((ENV *, PAGE *));
+int __qam_pgin_out __P((ENV *, db_pgno_t, void *, DBT *));
+int __qam_fprobe __P((DBC *, db_pgno_t, void *, qam_probe_mode, DB_CACHE_PRIORITY, u_int32_t));
+int __qam_fclose __P((DB *, db_pgno_t));
+int __qam_fremove __P((DB *, db_pgno_t));
+int __qam_sync __P((DB *));
+int __qam_gen_filelist __P((DB *, DB_THREAD_INFO *, QUEUE_FILELIST **));
+int __qam_extent_names __P((ENV *, char *, char ***));
+void __qam_exid __P((DB *, u_int8_t *, u_int32_t));
+int __qam_nameop __P((DB *, DB_TXN *, const char *, qam_name_op));
+int __qam_lsn_reset __P((DB *, DB_THREAD_INFO *));
+int __qam_backup_extents __P((DB *, DB_THREAD_INFO *, const char *, u_int32_t));
+int __qam_db_create __P((DB *));
+int __qam_db_close __P((DB *, u_int32_t));
+int __qam_get_extentsize __P((DB *, u_int32_t *));
+int __queue_pageinfo __P((DB *, db_pgno_t *, db_pgno_t *, int *, int, u_int32_t));
+int __db_prqueue __P((DB *, u_int32_t));
+int __qam_remove __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, u_int32_t));
+int __qam_rename __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *, const char *));
+void __qam_map_flags __P((DB *, u_int32_t *, u_int32_t *));
+int __qam_set_flags __P((DB *, u_int32_t *flagsp));
+int __qam_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, db_pgno_t, int, u_int32_t));
+int __qam_set_ext_data __P((DB*, const char *));
+int __qam_metachk __P((DB *, const char *, QMETA *));
+int __qam_new_file __P((DB *, DB_THREAD_INFO *, DB_TXN *, DB_FH *, const char *));
+int __qam_incfirst_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_mvptr_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_del_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_delext_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_add_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __qam_stat __P((DBC *, void *, u_int32_t));
+int __qam_stat_print __P((DBC *, u_int32_t));
+int __db_no_queue_am __P((ENV *));
+int __qam_31_qammeta __P((DB *, char *, u_int8_t *));
+int __qam_32_qammeta __P((DB *, char *, u_int8_t *));
+int __qam_vrfy_meta __P((DB *, VRFY_DBINFO *, QMETA *, db_pgno_t, u_int32_t));
+int __qam_meta2pgset __P((DB *, VRFY_DBINFO *, DB *));
+int __qam_vrfy_data __P((DB *, VRFY_DBINFO *, QPAGE *, db_pgno_t, u_int32_t));
+int __qam_vrfy_structure __P((DB *, VRFY_DBINFO *, u_int32_t));
+int __qam_vrfy_walkqueue __P((DB *, VRFY_DBINFO *, void *, int (*)(void *, const void *), u_int32_t));
+int __qam_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, void *, int (*)(void *, const void *), u_int32_t));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_qam_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/rep_automsg.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,145 @@
+/* Do not edit: automatically built by gen_msg.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__rep_AUTOMSG_H
+#define	__rep_AUTOMSG_H
+
+/*
+ * Message sizes are simply the sum of field sizes (not
+ * counting variable size parts, when DBTs are present),
+ * and may be different from struct sizes due to padding.
+ */
+#define	__REP_BULK_SIZE	16
+typedef struct ___rep_bulk_args {
+	u_int32_t	len;
+	DB_LSN		lsn;
+	DBT		bulkdata;
+} __rep_bulk_args;
+
+#define	__REP_CONTROL_SIZE	36
+typedef struct ___rep_control_args {
+	u_int32_t	rep_version;
+	u_int32_t	log_version;
+	DB_LSN		lsn;
+	u_int32_t	rectype;
+	u_int32_t	gen;
+	u_int32_t	msg_sec;
+	u_int32_t	msg_nsec;
+	u_int32_t	flags;
+} __rep_control_args;
+
+#define	__REP_EGEN_SIZE	4
+typedef struct ___rep_egen_args {
+	u_int32_t	egen;
+} __rep_egen_args;
+
+#define	__REP_FILEINFO_SIZE	40
+typedef struct ___rep_fileinfo_args {
+	u_int32_t	pgsize;
+	db_pgno_t	pgno;
+	db_pgno_t	max_pgno;
+	u_int32_t	filenum;
+	u_int32_t	finfo_flags;
+	u_int32_t	type;
+	u_int32_t	db_flags;
+	DBT		uid;
+	DBT		info;
+	DBT		dir;
+} __rep_fileinfo_args;
+
+#define	__REP_FILEINFO_V6_SIZE	36
+typedef struct ___rep_fileinfo_v6_args {
+	u_int32_t	pgsize;
+	db_pgno_t	pgno;
+	db_pgno_t	max_pgno;
+	u_int32_t	filenum;
+	u_int32_t	finfo_flags;
+	u_int32_t	type;
+	u_int32_t	db_flags;
+	DBT		uid;
+	DBT		info;
+} __rep_fileinfo_v6_args;
+
+#define	__REP_GRANT_INFO_SIZE	8
+typedef struct ___rep_grant_info_args {
+	u_int32_t	msg_sec;
+	u_int32_t	msg_nsec;
+} __rep_grant_info_args;
+
+#define	__REP_LOGREQ_SIZE	8
+typedef struct ___rep_logreq_args {
+	DB_LSN		endlsn;
+} __rep_logreq_args;
+
+#define	__REP_NEWFILE_SIZE	4
+typedef struct ___rep_newfile_args {
+	u_int32_t	version;
+} __rep_newfile_args;
+
+#define	__REP_UPDATE_SIZE	16
+typedef struct ___rep_update_args {
+	DB_LSN		first_lsn;
+	u_int32_t	first_vers;
+	u_int32_t	num_files;
+} __rep_update_args;
+
+#define	__REP_VOTE_INFO_SIZE	28
+typedef struct ___rep_vote_info_args {
+	u_int32_t	egen;
+	u_int32_t	nsites;
+	u_int32_t	nvotes;
+	u_int32_t	priority;
+	u_int32_t	spare_pri;
+	u_int32_t	tiebreaker;
+	u_int32_t	data_gen;
+} __rep_vote_info_args;
+
+#define	__REP_VOTE_INFO_V5_SIZE	20
+typedef struct ___rep_vote_info_v5_args {
+	u_int32_t	egen;
+	u_int32_t	nsites;
+	u_int32_t	nvotes;
+	u_int32_t	priority;
+	u_int32_t	tiebreaker;
+} __rep_vote_info_v5_args;
+
+#define	__REP_LSN_HIST_KEY_SIZE	8
+typedef struct ___rep_lsn_hist_key_args {
+	u_int32_t	version;
+	u_int32_t	gen;
+} __rep_lsn_hist_key_args;
+
+#define	__REP_LSN_HIST_DATA_SIZE	20
+typedef struct ___rep_lsn_hist_data_args {
+	u_int32_t	envid;
+	DB_LSN		lsn;
+	u_int32_t	hist_sec;
+	u_int32_t	hist_nsec;
+} __rep_lsn_hist_data_args;
+
+#define	__REP_MAXMSG_SIZE	40
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/rep_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,177 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_rep_ext_h_
+#define	_rep_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __rep_bulk_marshal __P((ENV *, __rep_bulk_args *, u_int8_t *, size_t, size_t *));
+int __rep_bulk_unmarshal __P((ENV *, __rep_bulk_args *, u_int8_t *, size_t, u_int8_t **));
+int __rep_control_marshal __P((ENV *, __rep_control_args *, u_int8_t *, size_t, size_t *));
+int __rep_control_unmarshal __P((ENV *, __rep_control_args *, u_int8_t *, size_t, u_int8_t **));
+int __rep_egen_marshal __P((ENV *, __rep_egen_args *, u_int8_t *, size_t, size_t *));
+int __rep_egen_unmarshal __P((ENV *, __rep_egen_args *, u_int8_t *, size_t, u_int8_t **));
+int __rep_fileinfo_marshal __P((ENV *, u_int32_t, __rep_fileinfo_args *, u_int8_t *, size_t, size_t *));
+int __rep_fileinfo_unmarshal __P((ENV *, u_int32_t, __rep_fileinfo_args **, u_int8_t *, size_t, u_int8_t **));
+int __rep_fileinfo_v6_marshal __P((ENV *, u_int32_t, __rep_fileinfo_v6_args *, u_int8_t *, size_t, size_t *));
+int __rep_fileinfo_v6_unmarshal __P((ENV *, u_int32_t, __rep_fileinfo_v6_args **, u_int8_t *, size_t, u_int8_t **));
+int __rep_grant_info_marshal __P((ENV *, __rep_grant_info_args *, u_int8_t *, size_t, size_t *));
+int __rep_grant_info_unmarshal __P((ENV *, __rep_grant_info_args *, u_int8_t *, size_t, u_int8_t **));
+int __rep_logreq_marshal __P((ENV *, __rep_logreq_args *, u_int8_t *, size_t, size_t *));
+int __rep_logreq_unmarshal __P((ENV *, __rep_logreq_args *, u_int8_t *, size_t, u_int8_t **));
+int __rep_newfile_marshal __P((ENV *, __rep_newfile_args *, u_int8_t *, size_t, size_t *));
+int __rep_newfile_unmarshal __P((ENV *, __rep_newfile_args *, u_int8_t *, size_t, u_int8_t **));
+int __rep_update_marshal __P((ENV *, u_int32_t, __rep_update_args *, u_int8_t *, size_t, size_t *));
+int __rep_update_unmarshal __P((ENV *, u_int32_t, __rep_update_args **, u_int8_t *, size_t, u_int8_t **));
+int __rep_vote_info_marshal __P((ENV *, __rep_vote_info_args *, u_int8_t *, size_t, size_t *));
+int __rep_vote_info_unmarshal __P((ENV *, __rep_vote_info_args *, u_int8_t *, size_t, u_int8_t **));
+int __rep_vote_info_v5_marshal __P((ENV *, __rep_vote_info_v5_args *, u_int8_t *, size_t, size_t *));
+int __rep_vote_info_v5_unmarshal __P((ENV *, __rep_vote_info_v5_args *, u_int8_t *, size_t, u_int8_t **));
+void __rep_lsn_hist_key_marshal __P((ENV *, __rep_lsn_hist_key_args *, u_int8_t *));
+int __rep_lsn_hist_key_unmarshal __P((ENV *, __rep_lsn_hist_key_args *, u_int8_t *, size_t, u_int8_t **));
+void __rep_lsn_hist_data_marshal __P((ENV *, __rep_lsn_hist_data_args *, u_int8_t *));
+int __rep_lsn_hist_data_unmarshal __P((ENV *, __rep_lsn_hist_data_args *, u_int8_t *, size_t, u_int8_t **));
+int __rep_update_req __P((ENV *, __rep_control_args *));
+int __rep_page_req __P((ENV *, DB_THREAD_INFO *, int, __rep_control_args *, DBT *));
+int __rep_update_setup __P((ENV *, int, __rep_control_args *, DBT *, time_t, DB_LSN *));
+int __rep_bulk_page __P((ENV *, DB_THREAD_INFO *, int, __rep_control_args *, DBT *));
+int __rep_page __P((ENV *, DB_THREAD_INFO *, int, __rep_control_args *, DBT *));
+int __rep_init_cleanup __P((ENV *, REP *, int));
+int __rep_pggap_req __P((ENV *, REP *, __rep_fileinfo_args *, u_int32_t));
+int __rep_finfo_alloc __P((ENV *, __rep_fileinfo_args *, __rep_fileinfo_args **));
+int __rep_remove_init_file __P((ENV *));
+int __rep_reset_init __P((ENV *));
+int __rep_elect_pp __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t));
+int __rep_elect_int __P((ENV *, u_int32_t, u_int32_t, u_int32_t));
+int __rep_vote1 __P((ENV *, __rep_control_args *, DBT *, int));
+int __rep_vote2 __P((ENV *, __rep_control_args *, DBT *, int));
+int __rep_update_grant __P((ENV *, db_timespec *));
+int __rep_islease_granted __P((ENV *));
+int __rep_lease_table_alloc __P((ENV *, u_int32_t));
+int __rep_lease_grant __P((ENV *, __rep_control_args *, DBT *, int));
+int __rep_lease_check __P((ENV *, int));
+int __rep_lease_refresh __P((ENV *));
+int __rep_lease_expire __P((ENV *));
+db_timeout_t __rep_lease_waittime __P((ENV *));
+int __rep_allreq __P((ENV *, __rep_control_args *, int));
+int __rep_log __P((ENV *, DB_THREAD_INFO *, __rep_control_args *, DBT *, int, time_t, DB_LSN *));
+int __rep_bulk_log __P((ENV *, DB_THREAD_INFO *, __rep_control_args *, DBT *, time_t, DB_LSN *));
+int __rep_logreq __P((ENV *, __rep_control_args *, DBT *, int));
+int __rep_loggap_req __P((ENV *, REP *, DB_LSN *, u_int32_t));
+int __rep_logready __P((ENV *, REP *, time_t, DB_LSN *));
+int __rep_env_create __P((DB_ENV *));
+void __rep_env_destroy __P((DB_ENV *));
+int __rep_get_config __P((DB_ENV *, u_int32_t, int *));
+int __rep_set_config __P((DB_ENV *, u_int32_t, int));
+int __rep_start_pp __P((DB_ENV *, DBT *, u_int32_t));
+int __rep_start_int __P((ENV *, DBT *, u_int32_t));
+int __rep_open_sysdb __P((ENV *, DB_THREAD_INFO *, DB_TXN *, const char *, u_int32_t, DB **));
+int __rep_client_dbinit __P((ENV *, int, repdb_t));
+int __rep_get_limit __P((DB_ENV *, u_int32_t *, u_int32_t *));
+int __rep_set_limit __P((DB_ENV *, u_int32_t, u_int32_t));
+int __rep_set_nsites_pp __P((DB_ENV *, u_int32_t));
+int __rep_set_nsites_int __P((ENV *, u_int32_t));
+int __rep_get_nsites __P((DB_ENV *, u_int32_t *));
+int __rep_set_priority __P((DB_ENV *, u_int32_t));
+int __rep_get_priority __P((DB_ENV *, u_int32_t *));
+int __rep_set_timeout __P((DB_ENV *, int, db_timeout_t));
+int __rep_get_timeout __P((DB_ENV *, int, db_timeout_t *));
+int __rep_get_request __P((DB_ENV *, db_timeout_t *, db_timeout_t *));
+int __rep_set_request __P((DB_ENV *, db_timeout_t, db_timeout_t));
+int __rep_set_transport_pp __P((DB_ENV *, int, int (*)(DB_ENV *, const DBT *, const DBT *, const DB_LSN *, int, u_int32_t)));
+int __rep_set_transport_int __P((ENV *, int, int (*)(DB_ENV *, const DBT *, const DBT *, const DB_LSN *, int, u_int32_t)));
+int __rep_get_clockskew __P((DB_ENV *, u_int32_t *, u_int32_t *));
+int __rep_set_clockskew __P((DB_ENV *, u_int32_t, u_int32_t));
+int __rep_flush __P((DB_ENV *));
+int __rep_sync __P((DB_ENV *, u_int32_t));
+int __rep_txn_applied __P((ENV *, DB_THREAD_INFO *, DB_COMMIT_INFO *, db_timeout_t));
+int __rep_process_message_pp __P((DB_ENV *, DBT *, DBT *, int, DB_LSN *));
+int __rep_process_message_int __P((ENV *, DBT *, DBT *, int, DB_LSN *));
+int __rep_apply __P((ENV *, DB_THREAD_INFO *, __rep_control_args *, DBT *, DB_LSN *, int *, DB_LSN *));
+int __rep_process_txn __P((ENV *, DBT *));
+int __rep_resend_req __P((ENV *, int));
+int __rep_check_doreq __P((ENV *, REP *));
+int __rep_check_missing __P((ENV *, u_int32_t, DB_LSN *));
+int __rep_open __P((ENV *));
+int __rep_close_diagfiles __P((ENV *));
+int __rep_env_refresh __P((ENV *));
+int __rep_env_close __P((ENV *));
+int __rep_preclose __P((ENV *));
+int __rep_closefiles __P((ENV *));
+int __rep_write_egen __P((ENV *, REP *, u_int32_t));
+int __rep_write_gen __P((ENV *, REP *, u_int32_t));
+int __rep_stat_pp __P((DB_ENV *, DB_REP_STAT **, u_int32_t));
+int __rep_stat_print_pp __P((DB_ENV *, u_int32_t));
+int __rep_stat_print __P((ENV *, u_int32_t));
+int __rep_bulk_message __P((ENV *, REP_BULK *, REP_THROTTLE *, DB_LSN *, const DBT *, u_int32_t));
+int __rep_send_bulk __P((ENV *, REP_BULK *, u_int32_t));
+int __rep_bulk_alloc __P((ENV *, REP_BULK *, int, uintptr_t *, u_int32_t *, u_int32_t));
+int __rep_bulk_free __P((ENV *, REP_BULK *, u_int32_t));
+int __rep_send_message __P((ENV *, int, u_int32_t, DB_LSN *, const DBT *, u_int32_t, u_int32_t));
+int __rep_new_master __P((ENV *, __rep_control_args *, int));
+void __rep_elect_done __P((ENV *, REP *));
+int __env_rep_enter __P((ENV *, int));
+int __env_db_rep_exit __P((ENV *));
+int __db_rep_enter __P((DB *, int, int, int));
+int __op_handle_enter __P((ENV *));
+int __op_rep_enter __P((ENV *, int, int));
+int __op_rep_exit __P((ENV *));
+int __archive_rep_enter __P((ENV *));
+int __archive_rep_exit __P((ENV *));
+int __rep_lockout_archive __P((ENV *, REP *));
+int __rep_lockout_api __P((ENV *, REP *));
+int __rep_take_apilockout __P((ENV *));
+int __rep_clear_apilockout __P((ENV *));
+int __rep_lockout_apply __P((ENV *, REP *, u_int32_t));
+int __rep_lockout_msg __P((ENV *, REP *, u_int32_t));
+int __rep_send_throttle __P((ENV *, int, REP_THROTTLE *, u_int32_t, u_int32_t));
+u_int32_t __rep_msg_to_old __P((u_int32_t, u_int32_t));
+u_int32_t __rep_msg_from_old __P((u_int32_t, u_int32_t));
+int __rep_print_system __P((ENV *, u_int32_t, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4)));
+int __rep_print __P((ENV *, u_int32_t, const char *, ...)) __attribute__ ((__format__ (__printf__, 3, 4)));
+void __rep_print_message __P((ENV *, int, __rep_control_args *, char *, u_int32_t));
+void __rep_fire_event __P((ENV *, u_int32_t, void *));
+void __rep_msg __P((const ENV *, const char *));
+int __rep_notify_threads __P((ENV *, rep_waitreason_t));
+int __rep_check_goal __P((ENV *, struct rep_waitgoal *));
+int __rep_log_backup __P((ENV *, DB_LOGC *, DB_LSN *, u_int32_t));
+int __rep_get_maxpermlsn __P((ENV *, DB_LSN *));
+int __rep_is_internal_rep_file __P((char *));
+int __rep_get_datagen __P((ENV *, u_int32_t *));
+int __rep_verify __P((ENV *, __rep_control_args *, DBT *, int, time_t));
+int __rep_verify_fail __P((ENV *, __rep_control_args *));
+int __rep_verify_req __P((ENV *, __rep_control_args *, int));
+int __rep_dorecovery __P((ENV *, DB_LSN *, DB_LSN *));
+int __rep_verify_match __P((ENV *, DB_LSN *, time_t));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_rep_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/repmgr_auto.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,66 @@
+/* Do not edit: automatically built by gen_rec.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__repmgr_AUTO_H
+#define	__repmgr_AUTO_H
+#ifdef HAVE_REPLICATION_THREADS
+#include "dbinc/log.h"
+#define	DB___repmgr_member	200
+typedef struct ___repmgr_member_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	version;
+	u_int32_t	prev_status;
+	u_int32_t	status;
+	DBT	host;
+	u_int32_t	port;
+} __repmgr_member_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __repmgr_member_desc[];
+static inline int
+__repmgr_member_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t version, u_int32_t prev_status, u_int32_t status, const DBT *host, u_int32_t port)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___repmgr_member, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    LOG_DBT_SIZE(host) + sizeof(u_int32_t),
+	    __repmgr_member_desc,
+	    version, prev_status, status, host, port));
+}
+
+static inline int __repmgr_member_read(ENV *env, 
+    void *data, __repmgr_member_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __repmgr_member_desc, sizeof(__repmgr_member_args), (void**)arg));
+}
+#endif /* HAVE_REPLICATION_THREADS */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/repmgr_automsg.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,138 @@
+/* Do not edit: automatically built by gen_msg.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__repmgr_AUTOMSG_H
+#define	__repmgr_AUTOMSG_H
+
+/*
+ * Message sizes are simply the sum of field sizes (not
+ * counting variable size parts, when DBTs are present),
+ * and may be different from struct sizes due to padding.
+ */
+#define	__REPMGR_HANDSHAKE_SIZE	12
+typedef struct ___repmgr_handshake_args {
+	u_int16_t	port;
+	u_int16_t	alignment;
+	u_int32_t	ack_policy;
+	u_int32_t	flags;
+} __repmgr_handshake_args;
+
+#define	__REPMGR_V3HANDSHAKE_SIZE	10
+typedef struct ___repmgr_v3handshake_args {
+	u_int16_t	port;
+	u_int32_t	priority;
+	u_int32_t	flags;
+} __repmgr_v3handshake_args;
+
+#define	__REPMGR_V2HANDSHAKE_SIZE	6
+typedef struct ___repmgr_v2handshake_args {
+	u_int16_t	port;
+	u_int32_t	priority;
+} __repmgr_v2handshake_args;
+
+#define	__REPMGR_PARM_REFRESH_SIZE	8
+typedef struct ___repmgr_parm_refresh_args {
+	u_int32_t	ack_policy;
+	u_int32_t	flags;
+} __repmgr_parm_refresh_args;
+
+#define	__REPMGR_PERMLSN_SIZE	12
+typedef struct ___repmgr_permlsn_args {
+	u_int32_t	generation;
+	DB_LSN		lsn;
+} __repmgr_permlsn_args;
+
+#define	__REPMGR_VERSION_PROPOSAL_SIZE	8
+typedef struct ___repmgr_version_proposal_args {
+	u_int32_t	min;
+	u_int32_t	max;
+} __repmgr_version_proposal_args;
+
+#define	__REPMGR_VERSION_CONFIRMATION_SIZE	4
+typedef struct ___repmgr_version_confirmation_args {
+	u_int32_t	version;
+} __repmgr_version_confirmation_args;
+
+#define	__REPMGR_MSG_HDR_SIZE	9
+typedef struct ___repmgr_msg_hdr_args {
+	u_int8_t	type;
+	u_int32_t	word1;
+	u_int32_t	word2;
+} __repmgr_msg_hdr_args;
+
+#define	__REPMGR_MSG_METADATA_SIZE	12
+typedef struct ___repmgr_msg_metadata_args {
+	u_int32_t	tag;
+	u_int32_t	limit;
+	u_int32_t	flags;
+} __repmgr_msg_metadata_args;
+
+#define	__REPMGR_MEMBERSHIP_KEY_SIZE	6
+typedef struct ___repmgr_membership_key_args {
+	DBT		host;
+	u_int16_t	port;
+} __repmgr_membership_key_args;
+
+#define	__REPMGR_MEMBERSHIP_DATA_SIZE	4
+typedef struct ___repmgr_membership_data_args {
+	u_int32_t	flags;
+} __repmgr_membership_data_args;
+
+#define	__REPMGR_MEMBER_METADATA_SIZE	8
+typedef struct ___repmgr_member_metadata_args {
+	u_int32_t	format;
+	u_int32_t	version;
+} __repmgr_member_metadata_args;
+
+#define	__REPMGR_GM_FWD_SIZE	10
+typedef struct ___repmgr_gm_fwd_args {
+	DBT		host;
+	u_int16_t	port;
+	u_int32_t	gen;
+} __repmgr_gm_fwd_args;
+
+#define	__REPMGR_MEMBR_VERS_SIZE	8
+typedef struct ___repmgr_membr_vers_args {
+	u_int32_t	version;
+	u_int32_t	gen;
+} __repmgr_membr_vers_args;
+
+#define	__REPMGR_SITE_INFO_SIZE	10
+typedef struct ___repmgr_site_info_args {
+	DBT		host;
+	u_int16_t	port;
+	u_int32_t	flags;
+} __repmgr_site_info_args;
+
+#define	__REPMGR_CONNECT_REJECT_SIZE	8
+typedef struct ___repmgr_connect_reject_args {
+	u_int32_t	version;
+	u_int32_t	gen;
+} __repmgr_connect_reject_args;
+
+#define	__REPMGR_MAXMSG_SIZE	12
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/repmgr_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,275 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_repmgr_ext_h_
+#define	_repmgr_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __repmgr_init_recover __P((ENV *, DB_DISTAB *));
+void __repmgr_handshake_marshal __P((ENV *, __repmgr_handshake_args *, u_int8_t *));
+int __repmgr_handshake_unmarshal __P((ENV *, __repmgr_handshake_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_v3handshake_marshal __P((ENV *, __repmgr_v3handshake_args *, u_int8_t *));
+int __repmgr_v3handshake_unmarshal __P((ENV *, __repmgr_v3handshake_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_v2handshake_marshal __P((ENV *, __repmgr_v2handshake_args *, u_int8_t *));
+int __repmgr_v2handshake_unmarshal __P((ENV *, __repmgr_v2handshake_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_parm_refresh_marshal __P((ENV *, __repmgr_parm_refresh_args *, u_int8_t *));
+int __repmgr_parm_refresh_unmarshal __P((ENV *, __repmgr_parm_refresh_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_permlsn_marshal __P((ENV *, __repmgr_permlsn_args *, u_int8_t *));
+int __repmgr_permlsn_unmarshal __P((ENV *, __repmgr_permlsn_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_version_proposal_marshal __P((ENV *, __repmgr_version_proposal_args *, u_int8_t *));
+int __repmgr_version_proposal_unmarshal __P((ENV *, __repmgr_version_proposal_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_version_confirmation_marshal __P((ENV *, __repmgr_version_confirmation_args *, u_int8_t *));
+int __repmgr_version_confirmation_unmarshal __P((ENV *, __repmgr_version_confirmation_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_msg_hdr_marshal __P((ENV *, __repmgr_msg_hdr_args *, u_int8_t *));
+int __repmgr_msg_hdr_unmarshal __P((ENV *, __repmgr_msg_hdr_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_msg_metadata_marshal __P((ENV *, __repmgr_msg_metadata_args *, u_int8_t *));
+int __repmgr_msg_metadata_unmarshal __P((ENV *, __repmgr_msg_metadata_args *, u_int8_t *, size_t, u_int8_t **));
+int __repmgr_membership_key_marshal __P((ENV *, __repmgr_membership_key_args *, u_int8_t *, size_t, size_t *));
+int __repmgr_membership_key_unmarshal __P((ENV *, __repmgr_membership_key_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_membership_data_marshal __P((ENV *, __repmgr_membership_data_args *, u_int8_t *));
+int __repmgr_membership_data_unmarshal __P((ENV *, __repmgr_membership_data_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_member_metadata_marshal __P((ENV *, __repmgr_member_metadata_args *, u_int8_t *));
+int __repmgr_member_metadata_unmarshal __P((ENV *, __repmgr_member_metadata_args *, u_int8_t *, size_t, u_int8_t **));
+int __repmgr_gm_fwd_marshal __P((ENV *, __repmgr_gm_fwd_args *, u_int8_t *, size_t, size_t *));
+int __repmgr_gm_fwd_unmarshal __P((ENV *, __repmgr_gm_fwd_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_membr_vers_marshal __P((ENV *, __repmgr_membr_vers_args *, u_int8_t *));
+int __repmgr_membr_vers_unmarshal __P((ENV *, __repmgr_membr_vers_args *, u_int8_t *, size_t, u_int8_t **));
+int __repmgr_site_info_marshal __P((ENV *, __repmgr_site_info_args *, u_int8_t *, size_t, size_t *));
+int __repmgr_site_info_unmarshal __P((ENV *, __repmgr_site_info_args *, u_int8_t *, size_t, u_int8_t **));
+void __repmgr_connect_reject_marshal __P((ENV *, __repmgr_connect_reject_args *, u_int8_t *));
+int __repmgr_connect_reject_unmarshal __P((ENV *, __repmgr_connect_reject_args *, u_int8_t *, size_t, u_int8_t **));
+int __repmgr_member_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __repmgr_init_print __P((ENV *, DB_DISTAB *));
+int __repmgr_init_election __P((ENV *, u_int32_t));
+int __repmgr_claim_victory __P((ENV *));
+int __repmgr_turn_on_elections __P((ENV *));
+int __repmgr_start __P((DB_ENV *, int, u_int32_t));
+int __repmgr_valid_config __P((ENV *, u_int32_t));
+int __repmgr_autostart __P((ENV *));
+int __repmgr_start_selector __P((ENV *));
+int __repmgr_close __P((ENV *));
+int __repmgr_stop __P((ENV *));
+int __repmgr_set_ack_policy __P((DB_ENV *, int));
+int __repmgr_get_ack_policy __P((DB_ENV *, int *));
+int __repmgr_env_create __P((ENV *, DB_REP *));
+void __repmgr_env_destroy __P((ENV *, DB_REP *));
+int __repmgr_stop_threads __P((ENV *));
+int __repmgr_local_site __P((DB_ENV *, DB_SITE **));
+int __repmgr_channel __P((DB_ENV *, int, DB_CHANNEL **, u_int32_t));
+int __repmgr_set_msg_dispatch __P((DB_ENV *, void (*)(DB_ENV *, DB_CHANNEL *, DBT *, u_int32_t, u_int32_t), u_int32_t));
+int __repmgr_send_msg __P((DB_CHANNEL *, DBT *, u_int32_t, u_int32_t));
+int __repmgr_send_request __P((DB_CHANNEL *, DBT *, u_int32_t, DBT *, db_timeout_t, u_int32_t));
+int __repmgr_send_response __P((DB_CHANNEL *, DBT *, u_int32_t, u_int32_t));
+int __repmgr_channel_close __P((DB_CHANNEL *, u_int32_t));
+int __repmgr_channel_timeout __P((DB_CHANNEL *, db_timeout_t));
+int __repmgr_send_request_inval __P((DB_CHANNEL *, DBT *, u_int32_t, DBT *, db_timeout_t, u_int32_t));
+int __repmgr_channel_close_inval __P((DB_CHANNEL *, u_int32_t));
+int __repmgr_channel_timeout_inval __P((DB_CHANNEL *, db_timeout_t));
+int __repmgr_join_group __P((ENV *));
+int __repmgr_site __P((DB_ENV *, const char *, u_int, DB_SITE **, u_int32_t));
+int __repmgr_site_by_eid __P((DB_ENV *, int, DB_SITE **));
+int __repmgr_get_site_address __P((DB_SITE *, const char **, u_int *));
+int __repmgr_get_eid __P((DB_SITE *, int *));
+int __repmgr_get_config __P((DB_SITE *, u_int32_t, u_int32_t *));
+int __repmgr_site_config __P((DB_SITE *, u_int32_t, u_int32_t));
+int __repmgr_site_close __P((DB_SITE *));
+void *__repmgr_msg_thread __P((void *));
+int __repmgr_send_err_resp __P((ENV *, CHANNEL *, int));
+int __repmgr_handle_event __P((ENV *, u_int32_t, void *));
+int __repmgr_update_membership __P((ENV *, DB_THREAD_INFO *, int, u_int32_t));
+int __repmgr_set_gm_version __P((ENV *, DB_THREAD_INFO *, DB_TXN *, u_int32_t));
+int __repmgr_setup_gmdb_op __P((ENV *, DB_THREAD_INFO *, DB_TXN **, u_int32_t));
+int __repmgr_cleanup_gmdb_op __P((ENV *, int));
+int __repmgr_hold_master_role __P((ENV *, REPMGR_CONNECTION *));
+int __repmgr_rlse_master_role __P((ENV *));
+void __repmgr_set_sites __P((ENV *));
+int __repmgr_connect __P((ENV *, repmgr_netaddr_t *, REPMGR_CONNECTION **, int *));
+int __repmgr_send __P((DB_ENV *, const DBT *, const DBT *, const DB_LSN *, int, u_int32_t));
+int __repmgr_sync_siteaddr __P((ENV *));
+int __repmgr_send_broadcast __P((ENV *, u_int, const DBT *, const DBT *, u_int *, u_int *, int *));
+int __repmgr_send_one __P((ENV *, REPMGR_CONNECTION *, u_int, const DBT *, const DBT *, db_timeout_t));
+int __repmgr_send_many __P((ENV *, REPMGR_CONNECTION *, REPMGR_IOVECS *, db_timeout_t));
+int __repmgr_send_own_msg __P((ENV *, REPMGR_CONNECTION *, u_int32_t, u_int8_t *, u_int32_t));
+int __repmgr_write_iovecs __P((ENV *, REPMGR_CONNECTION *, REPMGR_IOVECS *, size_t *));
+int __repmgr_bust_connection __P((ENV *, REPMGR_CONNECTION *));
+int __repmgr_disable_connection __P((ENV *, REPMGR_CONNECTION *));
+int __repmgr_cleanup_defunct __P((ENV *, REPMGR_CONNECTION *));
+int __repmgr_close_connection __P((ENV *, REPMGR_CONNECTION *));
+int __repmgr_decr_conn_ref __P((ENV *, REPMGR_CONNECTION *));
+int __repmgr_destroy_conn __P((ENV *, REPMGR_CONNECTION *));
+int __repmgr_pack_netaddr __P((ENV *, const char *, u_int, repmgr_netaddr_t *));
+int __repmgr_getaddr __P((ENV *, const char *, u_int, int, ADDRINFO **));
+int __repmgr_listen __P((ENV *));
+int __repmgr_net_close __P((ENV *));
+void __repmgr_net_destroy __P((ENV *, DB_REP *));
+int __repmgr_thread_start __P((ENV *, REPMGR_RUNNABLE *));
+int __repmgr_thread_join __P((REPMGR_RUNNABLE *));
+int __repmgr_set_nonblock_conn __P((REPMGR_CONNECTION *));
+int __repmgr_set_nonblocking __P((socket_t));
+int __repmgr_wake_waiters __P((ENV *, waiter_t *));
+int __repmgr_await_cond __P((ENV *, PREDICATE, void *, db_timeout_t, waiter_t *));
+int __repmgr_await_gmdbop __P((ENV *));
+void __repmgr_compute_wait_deadline __P((ENV*, struct timespec *, db_timeout_t));
+int __repmgr_await_drain __P((ENV *, REPMGR_CONNECTION *, db_timeout_t));
+int __repmgr_alloc_cond __P((cond_var_t *));
+int __repmgr_free_cond __P((cond_var_t *));
+void __repmgr_env_create_pf __P((DB_REP *));
+int __repmgr_create_mutex_pf __P((mgr_mutex_t *));
+int __repmgr_destroy_mutex_pf __P((mgr_mutex_t *));
+int __repmgr_init __P((ENV *));
+int __repmgr_deinit __P((ENV *));
+int __repmgr_init_waiters __P((ENV *, waiter_t *));
+int __repmgr_destroy_waiters __P((ENV *, waiter_t *));
+int __repmgr_lock_mutex __P((mgr_mutex_t *));
+int __repmgr_unlock_mutex __P((mgr_mutex_t *));
+int __repmgr_signal __P((cond_var_t *));
+int __repmgr_wake_msngers __P((ENV*, u_int));
+int __repmgr_wake_main_thread __P((ENV*));
+int __repmgr_writev __P((socket_t, db_iovec_t *, int, size_t *));
+int __repmgr_readv __P((socket_t, db_iovec_t *, int, size_t *));
+int __repmgr_select_loop __P((ENV *));
+int __repmgr_queue_destroy __P((ENV *));
+int __repmgr_queue_get __P((ENV *, REPMGR_MESSAGE **, REPMGR_RUNNABLE *));
+int __repmgr_queue_put __P((ENV *, REPMGR_MESSAGE *));
+int __repmgr_queue_size __P((ENV *));
+int __repmgr_member_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+void *__repmgr_select_thread __P((void *));
+int __repmgr_bow_out __P((ENV *));
+int __repmgr_accept __P((ENV *));
+int __repmgr_compute_timeout __P((ENV *, db_timespec *));
+REPMGR_SITE *__repmgr_connected_master __P((ENV *));
+int __repmgr_check_timeouts __P((ENV *));
+int __repmgr_first_try_connections __P((ENV *));
+int __repmgr_send_v1_handshake __P((ENV *, REPMGR_CONNECTION *, void *, size_t));
+int __repmgr_read_from_site __P((ENV *, REPMGR_CONNECTION *));
+int __repmgr_read_conn __P((REPMGR_CONNECTION *));
+int __repmgr_prepare_simple_input __P((ENV *, REPMGR_CONNECTION *, __repmgr_msg_hdr_args *));
+int __repmgr_send_handshake __P((ENV *, REPMGR_CONNECTION *, void *, size_t, u_int32_t));
+int __repmgr_find_version_info __P((ENV *, REPMGR_CONNECTION *, DBT *));
+int __repmgr_write_some __P((ENV *, REPMGR_CONNECTION *));
+int __repmgr_stat_pp __P((DB_ENV *, DB_REPMGR_STAT **, u_int32_t));
+int __repmgr_stat_print_pp __P((DB_ENV *, u_int32_t));
+int __repmgr_stat_print __P((ENV *, u_int32_t));
+int __repmgr_site_list __P((DB_ENV *, u_int *, DB_REPMGR_SITE **));
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_close __P((ENV *));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_get_ack_policy __P((DB_ENV *, int *));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_set_ack_policy __P((DB_ENV *, int));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_site __P((DB_ENV *, const char *, u_int, DB_SITE **, u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_site_by_eid __P((DB_ENV *, int, DB_SITE **));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_local_site __P((DB_ENV *, DB_SITE **));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_site_list __P((DB_ENV *, u_int *, DB_REPMGR_SITE **));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_start __P((DB_ENV *, int, u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_stat_pp __P((DB_ENV *, DB_REPMGR_STAT **, u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_stat_print_pp __P((DB_ENV *, u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_handle_event __P((ENV *, u_int32_t, void *));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_channel __P((DB_ENV *, int, DB_CHANNEL **, u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_set_msg_dispatch __P((DB_ENV *, void (*)(DB_ENV *, DB_CHANNEL *, DBT *, u_int32_t, u_int32_t), u_int32_t));
+#endif
+#ifndef HAVE_REPLICATION_THREADS
+int __repmgr_init_recover __P((ENV *, DB_DISTAB *));
+#endif
+int __repmgr_schedule_connection_attempt __P((ENV *, int, int));
+int __repmgr_is_server __P((ENV *, REPMGR_SITE *));
+void __repmgr_reset_for_reading __P((REPMGR_CONNECTION *));
+int __repmgr_new_connection __P((ENV *, REPMGR_CONNECTION **, socket_t, int));
+int __repmgr_set_keepalive __P((ENV *, REPMGR_CONNECTION *));
+int __repmgr_new_site __P((ENV *, REPMGR_SITE**, const char *, u_int));
+int __repmgr_create_mutex __P((ENV *, mgr_mutex_t **));
+int __repmgr_destroy_mutex __P((ENV *, mgr_mutex_t *));
+void __repmgr_cleanup_netaddr __P((ENV *, repmgr_netaddr_t *));
+void __repmgr_iovec_init __P((REPMGR_IOVECS *));
+void __repmgr_add_buffer __P((REPMGR_IOVECS *, void *, size_t));
+void __repmgr_add_dbt __P((REPMGR_IOVECS *, const DBT *));
+int __repmgr_update_consumed __P((REPMGR_IOVECS *, size_t));
+int __repmgr_prepare_my_addr __P((ENV *, DBT *));
+int __repmgr_get_nsites __P((ENV *, u_int32_t *));
+int __repmgr_thread_failure __P((ENV *, int));
+char *__repmgr_format_eid_loc __P((DB_REP *, REPMGR_CONNECTION *, char *));
+char *__repmgr_format_site_loc __P((REPMGR_SITE *, char *));
+char *__repmgr_format_addr_loc __P((repmgr_netaddr_t *, char *));
+int __repmgr_repstart __P((ENV *, u_int32_t));
+int __repmgr_become_master __P((ENV *));
+int __repmgr_each_connection __P((ENV *, CONNECTION_ACTION, void *, int));
+int __repmgr_open __P((ENV *, void *));
+int __repmgr_join __P((ENV *, void *));
+int __repmgr_env_refresh __P((ENV *env));
+int __repmgr_share_netaddrs __P((ENV *, void *, u_int, u_int));
+int __repmgr_copy_in_added_sites __P((ENV *));
+int __repmgr_init_new_sites __P((ENV *, int, int));
+int __repmgr_failchk __P((ENV *));
+int __repmgr_master_is_known __P((ENV *));
+int __repmgr_stable_lsn __P((ENV *, DB_LSN *));
+int __repmgr_send_sync_msg __P((ENV *, REPMGR_CONNECTION *, u_int32_t, u_int8_t *, u_int32_t));
+int __repmgr_marshal_member_list __P((ENV *, u_int8_t **, size_t *));
+int __repmgr_refresh_membership __P((ENV *, u_int8_t *, size_t));
+int __repmgr_reload_gmdb __P((ENV *));
+int __repmgr_gmdb_version_cmp __P((ENV *, u_int32_t, u_int32_t));
+int __repmgr_init_save __P((ENV *, DBT *));
+int __repmgr_init_restore __P((ENV *, DBT *));
+int __repmgr_defer_op __P((ENV *, u_int32_t));
+void __repmgr_fire_conn_err_event __P((ENV *, REPMGR_CONNECTION *, int));
+void __repmgr_print_conn_err __P((ENV *, repmgr_netaddr_t *, int));
+int __repmgr_become_client __P((ENV *));
+REPMGR_SITE *__repmgr_lookup_site __P((ENV *, const char *, u_int));
+int __repmgr_find_site __P((ENV *, const char *, u_int, int *));
+int __repmgr_set_membership __P((ENV *, const char *, u_int, u_int32_t));
+int __repmgr_bcast_parm_refresh __P((ENV *));
+int __repmgr_chg_prio __P((ENV *, u_int32_t, u_int32_t));
+int __repmgr_bcast_own_msg __P((ENV *, u_int32_t, u_int8_t *, size_t));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_repmgr_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/sequence_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,43 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_sequence_ext_h_
+#define	_sequence_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __seq_stat __P((DB_SEQUENCE *, DB_SEQUENCE_STAT **, u_int32_t));
+int __seq_stat_print __P((DB_SEQUENCE *, u_int32_t));
+const FN * __db_get_seq_flags_fn __P((void));
+const FN * __db_get_seq_flags_fn __P((void));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_sequence_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/tcl_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,160 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_tcl_ext_h_
+#define	_tcl_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int bdb_HCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
+#if DB_DBM_HSEARCH != 0
+int bdb_NdbmOpen __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DBM **));
+#endif
+#if DB_DBM_HSEARCH != 0
+int bdb_DbmCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*, int, DBM *));
+#endif
+int ndbm_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
+void _DbInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
+int db_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
+int tcl_CompactStat __P((Tcl_Interp *, DBTCL_INFO *));
+int tcl_rep_send __P((DB_ENV *, const DBT *, const DBT *, const DB_LSN *, int, u_int32_t));
+int dbc_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
+int env_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
+int tcl_EnvRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
+int tcl_EnvClose __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
+int tcl_EnvAttr __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_EnvIdReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_EnvLsnReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_EnvVerbose __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *, Tcl_Obj *));
+int tcl_EnvSetFlags __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *, Tcl_Obj *));
+int tcl_EnvTest __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_EnvGetEncryptFlags __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+void tcl_EnvSetErrfile __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *, char *));
+void tcl_EnvSetMsgfile __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *, char *));
+int tcl_EnvSetErrpfx __P((Tcl_Interp *, DB_ENV *, DBTCL_INFO *, char *));
+int tcl_EnvStatPrint __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+DBTCL_INFO *_NewInfo __P((Tcl_Interp *, void *, char *, enum INFOTYPE));
+void *_NameToPtr __P((CONST char *));
+DBTCL_INFO *_PtrToInfo __P((CONST void *));
+DBTCL_INFO *_NameToInfo __P((CONST char *));
+void  _SetInfoData __P((DBTCL_INFO *, void *));
+void  _DeleteInfo __P((DBTCL_INFO *));
+int _SetListElem __P((Tcl_Interp *, Tcl_Obj *, void *, u_int32_t, void *, u_int32_t));
+int _SetListElemInt __P((Tcl_Interp *, Tcl_Obj *, void *, long));
+int _SetListElemWideInt __P((Tcl_Interp *, Tcl_Obj *, void *, int64_t));
+int _SetListRecnoElem __P((Tcl_Interp *, Tcl_Obj *, db_recno_t, u_char *, u_int32_t));
+int _SetListHeapElem __P((Tcl_Interp *, Tcl_Obj *, DB_HEAP_RID, u_char *, u_int32_t));
+int _Set3DBTList __P((Tcl_Interp *, Tcl_Obj *, DBT *, int, DBT *, int, DBT *));
+int _SetMultiList __P((Tcl_Interp *, Tcl_Obj *, DBT *, DBT*, DBTYPE, u_int32_t, DBC*));
+int _GetGlobPrefix __P((char *, char **));
+int _ReturnSetup __P((Tcl_Interp *, int, int, char *));
+int _ErrorSetup __P((Tcl_Interp *, int, char *));
+void _ErrorFunc __P((const DB_ENV *, CONST char *, const char *));
+#ifdef CONFIG_TEST 
+void _EventFunc __P((DB_ENV *, u_int32_t, void *));
+#endif
+int _GetLsn __P((Tcl_Interp *, Tcl_Obj *, DB_LSN *));
+int _GetRid __P((Tcl_Interp *, Tcl_Obj *, DB_HEAP_RID *));
+int _GetUInt32 __P((Tcl_Interp *, Tcl_Obj *, u_int32_t *));
+Tcl_Obj *_GetFlagsList __P((Tcl_Interp *, u_int32_t, const FN *));
+void _debug_check  __P((void));
+int _CopyObjBytes  __P((Tcl_Interp *, Tcl_Obj *obj, void *, u_int32_t *, int *));
+int tcl_LockDetect __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LockGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LockStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LockStatPrint __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LockTimeout __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LockVec __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LogArchive __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LogCompare __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
+int tcl_LogFile __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LogFlush __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LogGet __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LogPut __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LogStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_LogStatPrint __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int logc_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
+int tcl_LogConfig __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *, Tcl_Obj *));
+int tcl_LogGetConfig __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *));
+void _MpInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
+int tcl_MpSync __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_MpTrickle __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_Mp __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
+int tcl_MpStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_MpStatPrint __P((Tcl_Interp *, int,  Tcl_Obj * CONST*, DB_ENV *));
+int tcl_Mutex __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_MutFree __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_MutGet __P((Tcl_Interp *, DB_ENV *, int));
+int tcl_MutLock __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_MutSet __P((Tcl_Interp *, Tcl_Obj *, DB_ENV *, int));
+int tcl_MutStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_MutStatPrint __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_MutUnlock __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_RepConfig __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *));
+int tcl_RepGetTwo __P((Tcl_Interp *, DB_ENV *, int));
+int tcl_RepGetConfig __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *));
+int tcl_RepGetTimeout __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *));
+int tcl_RepGetAckPolicy __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepGetLocalSite __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepElect __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepFlush __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepSync __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepLease  __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepInmemFiles  __P((Tcl_Interp *, DB_ENV *));
+int tcl_RepLimit __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepNSites __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepRequest __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepNoarchiveTimeout __P((Tcl_Interp *, DB_ENV *));
+int tcl_RepTransport  __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *, DBTCL_INFO *));
+int tcl_RepStart __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepProcessMessage __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepStat __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepStatPrint __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_RepMgr __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepMgrSiteList __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepMgrStat __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int tcl_RepMgrStatPrint __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_RepApplied __P((Tcl_Interp *, int, Tcl_Obj * CONST *, DB_ENV *));
+int seq_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*));
+void _TxnInfoDelete __P((Tcl_Interp *, DBTCL_INFO *));
+int tcl_TxnCheckpoint __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_Txn __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
+int tcl_CDSGroup __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
+int tcl_TxnStat __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_TxnStatPrint __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_TxnTimeout __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *));
+int tcl_TxnRecover __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *));
+int bdb_RandCommand __P((Tcl_Interp *, int, Tcl_Obj * CONST*));
+int tcl_LockMutex __P((DB_ENV *, db_mutex_t));
+int tcl_UnlockMutex __P((DB_ENV *, db_mutex_t));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_tcl_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/txn_auto.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,245 @@
+/* Do not edit: automatically built by gen_rec.awk.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved. *
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef	__txn_AUTO_H
+#define	__txn_AUTO_H
+#include "dbinc/log.h"
+#define	DB___txn_regop_42	10
+typedef struct ___txn_regop_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	timestamp;
+	DBT	locks;
+} __txn_regop_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __txn_regop_42_desc[];
+static inline int __txn_regop_42_read(ENV *env, 
+    void *data, __txn_regop_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __txn_regop_42_desc, sizeof(__txn_regop_42_args), (void**)arg));
+}
+#define	DB___txn_regop	10
+typedef struct ___txn_regop_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	int32_t	timestamp;
+	u_int32_t	envid;
+	DBT	locks;
+} __txn_regop_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __txn_regop_desc[];
+static inline int
+__txn_regop_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t opcode, int32_t timestamp, u_int32_t envid, const DBT *locks)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___txn_regop, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_int32_t) +
+	    LOG_DBT_SIZE(locks),
+	    __txn_regop_desc,
+	    opcode, timestamp, envid, locks));
+}
+
+static inline int __txn_regop_read(ENV *env, 
+    void *data, __txn_regop_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __txn_regop_desc, sizeof(__txn_regop_args), (void**)arg));
+}
+#define	DB___txn_ckp_42	11
+typedef struct ___txn_ckp_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DB_LSN	ckp_lsn;
+	DB_LSN	last_ckp;
+	int32_t	timestamp;
+	u_int32_t	rep_gen;
+} __txn_ckp_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __txn_ckp_42_desc[];
+static inline int __txn_ckp_42_read(ENV *env, 
+    void *data, __txn_ckp_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __txn_ckp_42_desc, sizeof(__txn_ckp_42_args), (void**)arg));
+}
+#define	DB___txn_ckp	11
+typedef struct ___txn_ckp_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	DB_LSN	ckp_lsn;
+	DB_LSN	last_ckp;
+	int32_t	timestamp;
+	u_int32_t	envid;
+	u_int32_t	spare;
+} __txn_ckp_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __txn_ckp_desc[];
+static inline int
+__txn_ckp_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    DB_LSN * ckp_lsn, DB_LSN * last_ckp, int32_t timestamp, u_int32_t envid, u_int32_t spare)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___txn_ckp, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(*ckp_lsn) + sizeof(*last_ckp) + sizeof(u_int32_t) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __txn_ckp_desc,
+	    ckp_lsn, last_ckp, timestamp, envid, spare));
+}
+
+static inline int __txn_ckp_read(ENV *env, 
+    void *data, __txn_ckp_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __txn_ckp_desc, sizeof(__txn_ckp_args), (void**)arg));
+}
+#define	DB___txn_child	12
+typedef struct ___txn_child_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	child;
+	DB_LSN	c_lsn;
+} __txn_child_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __txn_child_desc[];
+static inline int
+__txn_child_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t child, DB_LSN * c_lsn)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___txn_child, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(*c_lsn),
+	    __txn_child_desc,
+	    child, c_lsn));
+}
+
+static inline int __txn_child_read(ENV *env, 
+    void *data, __txn_child_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __txn_child_desc, sizeof(__txn_child_args), (void**)arg));
+}
+#define	DB___txn_xa_regop_42	13
+typedef struct ___txn_xa_regop_42_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	DBT	xid;
+	int32_t	formatID;
+	u_int32_t	gtrid;
+	u_int32_t	bqual;
+	DB_LSN	begin_lsn;
+	DBT	locks;
+} __txn_xa_regop_42_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __txn_xa_regop_42_desc[];
+static inline int __txn_xa_regop_42_read(ENV *env, 
+    void *data, __txn_xa_regop_42_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __txn_xa_regop_42_desc, sizeof(__txn_xa_regop_42_args), (void**)arg));
+}
+#define	DB___txn_prepare	13
+typedef struct ___txn_prepare_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	opcode;
+	DBT	gid;
+	DB_LSN	begin_lsn;
+	DBT	locks;
+} __txn_prepare_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __txn_prepare_desc[];
+static inline int
+__txn_prepare_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t opcode, const DBT *gid, DB_LSN * begin_lsn, const DBT *locks)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___txn_prepare, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + LOG_DBT_SIZE(gid) + sizeof(*begin_lsn) +
+	    LOG_DBT_SIZE(locks),
+	    __txn_prepare_desc,
+	    opcode, gid, begin_lsn, locks));
+}
+
+static inline int __txn_prepare_read(ENV *env, 
+    void *data, __txn_prepare_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __txn_prepare_desc, sizeof(__txn_prepare_args), (void**)arg));
+}
+#define	DB___txn_recycle	14
+typedef struct ___txn_recycle_args {
+	u_int32_t type;
+	DB_TXN *txnp;
+	DB_LSN prev_lsn;
+	u_int32_t	min;
+	u_int32_t	max;
+} __txn_recycle_args;
+
+extern __DB_IMPORT DB_LOG_RECSPEC __txn_recycle_desc[];
+static inline int
+__txn_recycle_log(ENV *env, DB_TXN *txnp, DB_LSN *ret_lsnp, u_int32_t flags,
+    u_int32_t min, u_int32_t max)
+{
+	return (__log_put_record(env, NULL, txnp, ret_lsnp,
+	    flags, DB___txn_recycle, 0,
+	    sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN) +
+	    sizeof(u_int32_t) + sizeof(u_int32_t),
+	    __txn_recycle_desc,
+	    min, max));
+}
+
+static inline int __txn_recycle_read(ENV *env, 
+    void *data, __txn_recycle_args **arg)
+{
+	*arg = NULL;
+	return (__log_read_record(env, 
+	    NULL, NULL, data, __txn_recycle_desc, sizeof(__txn_recycle_args), (void**)arg));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/txn_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,122 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_txn_ext_h_
+#define	_txn_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __txn_begin_pp __P((DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t));
+int __txn_begin __P((ENV *, DB_THREAD_INFO *, DB_TXN *, DB_TXN **, u_int32_t));
+int __txn_recycle_id __P((ENV *, int));
+int __txn_continue __P((ENV *, DB_TXN *, TXN_DETAIL *, DB_THREAD_INFO *, int));
+int __txn_commit __P((DB_TXN *, u_int32_t));
+int __txn_abort __P((DB_TXN *));
+int __txn_discard_int __P((DB_TXN *, u_int32_t flags));
+int __txn_prepare __P((DB_TXN *, u_int8_t *));
+u_int32_t __txn_id __P((DB_TXN *));
+int __txn_get_name __P((DB_TXN *, const char **));
+int __txn_set_name __P((DB_TXN *, const char *));
+int __txn_get_priority __P((DB_TXN *, u_int32_t *));
+int __txn_set_priority __P((DB_TXN *, u_int32_t));
+int  __txn_set_timeout __P((DB_TXN *, db_timeout_t, u_int32_t));
+int __txn_activekids __P((ENV *, u_int32_t, DB_TXN *));
+int __txn_force_abort __P((ENV *, u_int8_t *));
+int __txn_preclose __P((ENV *));
+int __txn_reset __P((ENV *));
+int __txn_applied_pp __P((DB_ENV *, DB_TXN_TOKEN *, db_timeout_t, u_int32_t));
+int __txn_init_recover __P((ENV *, DB_DISTAB *));
+int __txn_regop_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_regop_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_ckp_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_ckp_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_child_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_xa_regop_42_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_prepare_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_recycle_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_init_print __P((ENV *, DB_DISTAB *));
+int __txn_checkpoint_pp __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t));
+int __txn_checkpoint __P((ENV *, u_int32_t, u_int32_t, u_int32_t));
+int __txn_getactive __P((ENV *, DB_LSN *));
+int __txn_getckp __P((ENV *, DB_LSN *));
+int __txn_updateckp __P((ENV *, DB_LSN *));
+int __txn_failchk __P((ENV *));
+int __txn_env_create __P((DB_ENV *));
+void __txn_env_destroy __P((DB_ENV *));
+int __txn_get_tx_max __P((DB_ENV *, u_int32_t *));
+int __txn_set_tx_max __P((DB_ENV *, u_int32_t));
+int __txn_get_tx_timestamp __P((DB_ENV *, time_t *));
+int __txn_set_tx_timestamp __P((DB_ENV *, time_t *));
+int __db_check_txn __P((DB *, DB_TXN *, DB_LOCKER *, int));
+int __db_txn_deadlock_err __P((ENV *, DB_TXN *));
+int __db_dbtxn_remove __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, const char *));
+int __txn_regop_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_prepare_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_ckp_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_child_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_restore_txn __P((ENV *, DB_LSN *, __txn_prepare_args *));
+int __txn_recycle_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_regop_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_ckp_42_recover __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+int __txn_recover_pp __P((DB_ENV *, DB_PREPLIST *, long, long *, u_int32_t));
+int __txn_recover __P((ENV *, DB_PREPLIST *, long, long *, u_int32_t));
+int __txn_get_prepared __P((ENV *, XID *, DB_PREPLIST *, long, long *, u_int32_t));
+int __txn_openfiles __P((ENV *, DB_THREAD_INFO *, DB_LSN *, int));
+int __txn_open __P((ENV *));
+int __txn_findlastckp __P((ENV *, DB_LSN *, DB_LSN *));
+int __txn_env_refresh __P((ENV *));
+u_int32_t __txn_region_mutex_count __P((ENV *));
+u_int32_t __txn_region_mutex_max __P((ENV *));
+size_t __txn_region_size __P((ENV *));
+size_t __txn_region_max __P((ENV *));
+int __txn_id_set __P((ENV *, u_int32_t, u_int32_t));
+int __txn_oldest_reader __P((ENV *, DB_LSN *));
+int __txn_add_buffer __P((ENV *, TXN_DETAIL *));
+int __txn_remove_buffer __P((ENV *, TXN_DETAIL *, db_mutex_t));
+int __txn_stat_pp __P((DB_ENV *, DB_TXN_STAT **, u_int32_t));
+int __txn_stat_print_pp __P((DB_ENV *, u_int32_t));
+int  __txn_stat_print __P((ENV *, u_int32_t));
+int __txn_closeevent __P((ENV *, DB_TXN *, DB *));
+int __txn_remevent __P((ENV *, DB_TXN *, const char *, u_int8_t *, int));
+void __txn_remrem __P((ENV *, DB_TXN *, const char *));
+int __txn_lockevent __P((ENV *, DB_TXN *, DB *, DB_LOCK *, DB_LOCKER *));
+void __txn_remlock __P((ENV *, DB_TXN *, DB_LOCK *, DB_LOCKER *));
+int __txn_doevents __P((ENV *, DB_TXN *, int, int));
+int __txn_record_fname __P((ENV *, DB_TXN *, FNAME *));
+int __txn_dref_fname __P((ENV *, DB_TXN *));
+void __txn_reset_fe_watermarks __P((DB_TXN *));
+void __txn_remove_fe_watermark __P((DB_TXN *,DB *));
+void __txn_add_fe_watermark __P((DB_TXN *, DB *, db_pgno_t));
+int __txn_flush_fe_files __P((DB_TXN *));
+int __txn_pg_above_fe_watermark __P((DB_TXN*, MPOOLFILE*, db_pgno_t));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_txn_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbinc_auto/xa_ext.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,44 @@
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_xa_ext_h_
+#define	_xa_ext_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int __db_rmid_to_env __P((int, ENV **));
+int __db_xid_to_txn __P((ENV *, XID *, TXN_DETAIL **));
+void __db_map_rmid __P((int, ENV *));
+int __db_unmap_rmid __P((int));
+void __db_unmap_xid __P((ENV *, XID *, size_t));
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_xa_ext_h_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/env/env_alloc.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,781 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * Implement shared memory region allocation.  The initial list is a single
+ * memory "chunk" which is carved up as memory is requested.  Chunks are
+ * coalesced when free'd.  We maintain two types of linked-lists: a list of
+ * all chunks sorted by address, and a set of lists with free chunks sorted
+ * by size.
+ *
+ * The ALLOC_LAYOUT structure is the governing structure for the allocator.
+ *
+ * The ALLOC_ELEMENT structure is the structure that describes any single
+ * chunk of memory, and is immediately followed by the user's memory.
+ *
+ * The internal memory chunks are always aligned to a uintmax_t boundary so
+ * we don't drop core accessing the fields of the ALLOC_ELEMENT structure.
+ *
+ * The memory chunks returned to the user are aligned to a uintmax_t boundary.
+ * This is enforced by terminating the ALLOC_ELEMENT structure with a uintmax_t
+ * field as that immediately precedes the user's memory.  Any caller needing
+ * more than uintmax_t alignment is responsible for doing alignment themselves.
+ */
+
+typedef SH_TAILQ_HEAD(__sizeq) SIZEQ_HEAD;
+
+typedef struct __alloc_layout {
+	SH_TAILQ_HEAD(__addrq) addrq;		/* Sorted by address */
+
+	/*
+	 * A perfect Berkeley DB application does little allocation because
+	 * most things are allocated on startup and never free'd.  This is
+	 * true even for the cache, because we don't free and re-allocate
+	 * the memory associated with a cache buffer when swapping a page
+	 * in memory for a page on disk -- unless the page is changing size.
+	 * The latter problem is why we have multiple size queues.  If the
+	 * application's working set fits in cache, it's not a problem.  If
+	 * the application's working set doesn't fit in cache, but all of
+	 * the databases have the same size pages, it's still not a problem.
+	 * If the application's working set doesn't fit in cache, and its
+	 * databases have different page sizes, we can end up walking a lot
+	 * of 512B chunk allocations looking for an available 64KB chunk.
+	 *
+	 * So, we keep a set of queues, where we expect to find a chunk of
+	 * roughly the right size at the front of the list.  The first queue
+	 * is chunks <= 1024, the second is <= 2048, and so on.  With 11
+	 * queues, we have separate queues for chunks up to 1MB.
+	 */
+#define	DB_SIZE_Q_COUNT	11
+	SIZEQ_HEAD	sizeq[DB_SIZE_Q_COUNT];	/* Sorted by size */
+#ifdef HAVE_STATISTICS
+	u_int32_t	pow2_size[DB_SIZE_Q_COUNT];
+#endif
+
+#ifdef HAVE_STATISTICS
+	u_int32_t success;			/* Successful allocations */
+	u_int32_t failure;			/* Failed allocations */
+	u_int32_t freed;			/* Free calls */
+	u_int32_t longest;			/* Longest chain walked */
+#endif
+	uintmax_t  unused;			/* Guarantee alignment */
+} ALLOC_LAYOUT;
+
+typedef struct __alloc_element {
+	SH_TAILQ_ENTRY addrq;			/* List by address */
+	SH_TAILQ_ENTRY sizeq;			/* List by size */
+
+	/*
+	 * The "len" field is the total length of the chunk, not the size
+	 * available to the caller.  Use a uintmax_t to guarantee that the
+	 * size of this struct will be aligned correctly.
+	 */
+	uintmax_t len;				/* Chunk length */
+
+	/*
+	 * The "ulen" field is the length returned to the caller.
+	 *
+	 * Set to 0 if the chunk is not currently in use.
+	 */
+	uintmax_t ulen;				/* User's length */
+} ALLOC_ELEMENT;
+
+/*
+ * If the chunk can be split into two pieces, with the fragment holding at
+ * least 64 bytes of memory, we divide the chunk into two parts.
+ */
+#define	SHALLOC_FRAGMENT	(sizeof(ALLOC_ELEMENT) + 64)
+
+/* Macro to find the appropriate queue for a specific size chunk. */
+#undef	SET_QUEUE_FOR_SIZE
+#define	SET_QUEUE_FOR_SIZE(head, q, i, len) do {			\
+	for (i = 0; i < DB_SIZE_Q_COUNT; ++i) {				\
+		q = &(head)->sizeq[i];					\
+		if ((len) <= (u_int64_t)1024 << i)			\
+			break;						\
+	}								\
+} while (0)
+
+static void __env_size_insert __P((ALLOC_LAYOUT *, ALLOC_ELEMENT *));
+
+/*
+ * __env_alloc_init --
+ *	Initialize the area as one large chunk.
+ *
+ * PUBLIC: void __env_alloc_init __P((REGINFO *, size_t));
+ */
+void
+__env_alloc_init(infop, size)
+	REGINFO *infop;
+	size_t size;
+{
+	ALLOC_ELEMENT *elp;
+	ALLOC_LAYOUT *head;
+	ENV *env;
+	u_int i;
+
+	env = infop->env;
+
+	/* No initialization needed for heap memory regions. */
+	if (F_ISSET(env, ENV_PRIVATE))
+		return;
+
+	/*
+	 * The first chunk of memory is the ALLOC_LAYOUT structure.
+	 */
+	head = infop->head;
+	memset(head, 0, sizeof(*head));
+	SH_TAILQ_INIT(&head->addrq);
+	for (i = 0; i < DB_SIZE_Q_COUNT; ++i)
+		SH_TAILQ_INIT(&head->sizeq[i]);
+	COMPQUIET(head->unused, 0);
+
+	/*
+	 * The rest of the memory is the first available chunk.
+	 */
+	elp = (ALLOC_ELEMENT *)((u_int8_t *)head + sizeof(ALLOC_LAYOUT));
+	elp->len = size - sizeof(ALLOC_LAYOUT);
+	elp->ulen = 0;
+
+	SH_TAILQ_INSERT_HEAD(&head->addrq, elp, addrq, __alloc_element);
+	SH_TAILQ_INSERT_HEAD(
+	    &head->sizeq[DB_SIZE_Q_COUNT - 1], elp, sizeq, __alloc_element);
+}
+
+/*
+ * The length, the ALLOC_ELEMENT structure and an optional guard byte,
+ * rounded up to standard alignment.
+ */
+#ifdef DIAGNOSTIC
+#define	DB_ALLOC_SIZE(len)						\
+	(size_t)DB_ALIGN((len) + sizeof(ALLOC_ELEMENT) + 1, sizeof(uintmax_t))
+#else
+#define	DB_ALLOC_SIZE(len)						\
+	(size_t)DB_ALIGN((len) + sizeof(ALLOC_ELEMENT), sizeof(uintmax_t))
+#endif
+
+/*
+ * __env_alloc_overhead --
+ *	Return the overhead needed for an allocation.
+ *
+ * PUBLIC: size_t __env_alloc_overhead __P((void));
+ */
+size_t
+__env_alloc_overhead()
+{
+	return (sizeof(ALLOC_ELEMENT));
+}
+
+/*
+ * __env_alloc_size --
+ *	Return the space needed for an allocation, including alignment.
+ *
+ * PUBLIC: size_t __env_alloc_size __P((size_t));
+ */
+size_t
+__env_alloc_size(len)
+	size_t len;
+{
+	return (DB_ALLOC_SIZE(len));
+}
+
+/*
+ * __env_alloc --
+ *	Allocate space from the shared region.
+ *
+ * PUBLIC: int __env_alloc __P((REGINFO *, size_t, void *));
+ */
+int
+__env_alloc(infop, len, retp)
+	REGINFO *infop;
+	size_t len;
+	void *retp;
+{
+	SIZEQ_HEAD *q;
+	ALLOC_ELEMENT *elp, *frag, *elp_tmp;
+	ALLOC_LAYOUT *head;
+	ENV *env;
+	REGION_MEM *mem;
+	REGINFO *envinfop;
+	size_t total_len;
+	u_int8_t *p;
+	u_int i;
+	int ret;
+#ifdef HAVE_STATISTICS
+	u_int32_t st_search;
+#endif
+	env = infop->env;
+	*(void **)retp = NULL;
+#ifdef HAVE_MUTEX_SUPPORT
+	MUTEX_REQUIRED(env, infop->mtx_alloc);
+#endif
+
+	PERFMON3(env, mpool, env_alloc, len, infop->id, infop->type);
+	/*
+	 * In a heap-backed environment, we call malloc for additional space.
+	 * (Malloc must return memory correctly aligned for our use.)
+	 *
+	 * In a heap-backed environment, memory is laid out as follows:
+	 *
+	 * { uintmax_t total-length } { user-memory } { guard-byte }
+	 */
+	if (F_ISSET(env, ENV_PRIVATE)) {
+		/*
+		 * If we are shared then we must track the allocation
+		 * in the main environment region.
+		 */
+		if (F_ISSET(infop, REGION_SHARED))
+			envinfop = env->reginfo;
+		else
+			envinfop = infop;
+		/*
+		 * We need an additional uintmax_t to hold the length (and
+		 * keep the buffer aligned on 32-bit systems).
+		 */
+		len += sizeof(uintmax_t);
+		if (F_ISSET(infop, REGION_TRACKED))
+			len += sizeof(REGION_MEM);
+
+#ifdef DIAGNOSTIC
+		/* Plus one byte for the guard byte. */
+		++len;
+#endif
+		/* Check if we're over the limit. */
+		if (envinfop->max_alloc != 0 &&
+		     envinfop->allocated + len > envinfop->max_alloc)
+			return (ENOMEM);
+
+		/* Allocate the space. */
+		if ((ret = __os_malloc(env, len, &p)) != 0)
+			return (ret);
+		infop->allocated += len;
+		if (infop != envinfop)
+			envinfop->allocated += len;
+
+		*(uintmax_t *)p = len;
+#ifdef DIAGNOSTIC
+		p[len - 1] = GUARD_BYTE;
+#endif
+		if (F_ISSET(infop, REGION_TRACKED)) {
+			mem = (REGION_MEM *)(p + sizeof(uintmax_t));
+			mem->next = infop->mem;
+			infop->mem = mem;
+			p += sizeof(mem);
+		}
+		*(void **)retp = p + sizeof(uintmax_t);
+		return (0);
+	}
+
+	head = infop->head;
+	total_len = DB_ALLOC_SIZE(len);
+
+	/* Find the first size queue that could satisfy the request. */
+	COMPQUIET(q, NULL);
+#ifdef HAVE_MMAP_EXTEND
+retry:
+#endif
+	SET_QUEUE_FOR_SIZE(head, q, i, total_len);
+
+#ifdef HAVE_STATISTICS
+	if (i >= DB_SIZE_Q_COUNT)
+		i = DB_SIZE_Q_COUNT - 1;
+	++head->pow2_size[i];		/* Note the size of the request. */
+#endif
+
+	/*
+	 * Search this queue, and, if necessary, queues larger than this queue,
+	 * looking for a chunk we can use.
+	 */
+	STAT(st_search = 0);
+	for (elp = NULL;; ++q) {
+		SH_TAILQ_FOREACH(elp_tmp, q, sizeq, __alloc_element) {
+			STAT(++st_search);
+
+			/*
+			 * Chunks are sorted from largest to smallest -- if
+			 * this chunk is less than what we need, no chunk
+			 * further down the list will be large enough.
+			 */
+			if (elp_tmp->len < total_len)
+				break;
+
+			/*
+			 * This chunk will do... maybe there's a better one,
+			 * but this one will do.
+			 */
+			elp = elp_tmp;
+
+			/*
+			 * We might have many chunks of the same size.  Stop
+			 * looking if we won't fragment memory by picking the
+			 * current one.
+			 */
+			if (elp_tmp->len - total_len <= SHALLOC_FRAGMENT)
+				break;
+		}
+		if (elp != NULL || ++i >= DB_SIZE_Q_COUNT)
+			break;
+	}
+
+#ifdef HAVE_STATISTICS
+	if (head->longest < st_search) {
+		head->longest = st_search;
+		STAT_PERFMON3(env,
+		    mpool, longest_search, len, infop->id, st_search);
+	}
+#endif
+
+	/*
+	 * If we don't find an element of the right size, try to extend
+	 * the region, if not then we are done.
+	 */
+	if (elp == NULL) {
+		ret = ENOMEM;
+#ifdef HAVE_MMAP_EXTEND
+		if (infop->rp->size < infop->rp->max &&
+		     (ret = __env_region_extend(env, infop)) == 0)
+			goto retry;
+#endif
+		STAT_INC_VERB(env, mpool, fail, head->failure, len, infop->id);
+		return (ret);
+	}
+	STAT_INC_VERB(env, mpool, alloc, head->success, len, infop->id);
+
+	/* Pull the chunk off of the size queue. */
+	SH_TAILQ_REMOVE(q, elp, sizeq, __alloc_element);
+
+	if (elp->len - total_len > SHALLOC_FRAGMENT) {
+		frag = (ALLOC_ELEMENT *)((u_int8_t *)elp + total_len);
+		frag->len = elp->len - total_len;
+		frag->ulen = 0;
+
+		elp->len = total_len;
+
+		/* The fragment follows the chunk on the address queue. */
+		SH_TAILQ_INSERT_AFTER(
+		    &head->addrq, elp, frag, addrq, __alloc_element);
+
+		/* Insert the frag into the correct size queue. */
+		__env_size_insert(head, frag);
+	}
+
+	p = (u_int8_t *)elp + sizeof(ALLOC_ELEMENT);
+	elp->ulen = len;
+#ifdef DIAGNOSTIC
+	p[len] = GUARD_BYTE;
+#endif
+	*(void **)retp = p;
+
+	return (0);
+}
+
+/*
+ * __env_alloc_free --
+ *	Free space into the shared region.
+ *
+ * PUBLIC: void __env_alloc_free __P((REGINFO *, void *));
+ */
+void
+__env_alloc_free(infop, ptr)
+	REGINFO *infop;
+	void *ptr;
+{
+	ALLOC_ELEMENT *elp, *elp_tmp;
+	ALLOC_LAYOUT *head;
+	ENV *env;
+	SIZEQ_HEAD *q;
+	size_t len;
+	u_int8_t i, *p;
+
+	env = infop->env;
+
+	/* In a private region, we call free. */
+	if (F_ISSET(env, ENV_PRIVATE)) {
+		/* Find the start of the memory chunk and its length. */
+		p = (u_int8_t *)((uintmax_t *)ptr - 1);
+		len = (size_t)*(uintmax_t *)p;
+
+		infop->allocated -= len;
+		if (F_ISSET(infop, REGION_SHARED))
+			env->reginfo->allocated -= len;
+
+#ifdef DIAGNOSTIC
+		/* Check the guard byte. */
+		DB_ASSERT(env, p[len - 1] == GUARD_BYTE);
+
+		/* Trash the memory chunk. */
+		memset(p, CLEAR_BYTE, len);
+#endif
+		__os_free(env, p);
+		return;
+	}
+
+#ifdef HAVE_MUTEX_SUPPORT
+	MUTEX_REQUIRED(env, infop->mtx_alloc);
+#endif
+
+	head = infop->head;
+
+	p = ptr;
+	elp = (ALLOC_ELEMENT *)(p - sizeof(ALLOC_ELEMENT));
+
+	STAT_INC_VERB(env, mpool, free, head->freed, elp->ulen, infop->id);
+
+#ifdef DIAGNOSTIC
+	/* Check the guard byte. */
+	DB_ASSERT(env, p[elp->ulen] == GUARD_BYTE);
+
+	/* Trash the memory chunk. */
+	memset(p, CLEAR_BYTE, (size_t)elp->len - sizeof(ALLOC_ELEMENT));
+#endif
+
+	/* Mark the memory as no longer in use. */
+	elp->ulen = 0;
+
+	/*
+	 * Try and merge this chunk with chunks on either side of it.  Two
+	 * chunks can be merged if they're contiguous and not in use.
+	 */
+	if ((elp_tmp =
+	    SH_TAILQ_PREV(&head->addrq, elp, addrq, __alloc_element)) != NULL &&
+	    elp_tmp->ulen == 0 &&
+	    (u_int8_t *)elp_tmp + elp_tmp->len == (u_int8_t *)elp) {
+		/*
+		 * If we're merging the entry into a previous entry, remove the
+		 * current entry from the addr queue and the previous entry from
+		 * its size queue, and merge.
+		 */
+		SH_TAILQ_REMOVE(&head->addrq, elp, addrq, __alloc_element);
+		SET_QUEUE_FOR_SIZE(head, q, i, elp_tmp->len);
+		SH_TAILQ_REMOVE(q, elp_tmp, sizeq, __alloc_element);
+
+		elp_tmp->len += elp->len;
+		elp = elp_tmp;
+	}
+	if ((elp_tmp = SH_TAILQ_NEXT(elp, addrq, __alloc_element)) != NULL &&
+	    elp_tmp->ulen == 0 &&
+	    (u_int8_t *)elp + elp->len == (u_int8_t *)elp_tmp) {
+		/*
+		 * If we're merging the current entry into a subsequent entry,
+		 * remove the subsequent entry from the addr and size queues
+		 * and merge.
+		 */
+		SH_TAILQ_REMOVE(&head->addrq, elp_tmp, addrq, __alloc_element);
+		SET_QUEUE_FOR_SIZE(head, q, i, elp_tmp->len);
+		SH_TAILQ_REMOVE(q, elp_tmp, sizeq, __alloc_element);
+
+		elp->len += elp_tmp->len;
+	}
+
+	/* Insert in the correct place in the size queues. */
+	__env_size_insert(head, elp);
+}
+
+/*
+ * __env_alloc_extend --
+ *	Extend a previously allocated chunk at the end of a region.
+ *
+ * PUBLIC: int __env_alloc_extend __P((REGINFO *, void *, size_t *));
+ */
+int
+__env_alloc_extend(infop, ptr, lenp)
+	REGINFO *infop;
+	void *ptr;
+	size_t *lenp;
+{
+	ALLOC_ELEMENT *elp, *elp_tmp;
+	ALLOC_LAYOUT *head;
+	ENV *env;
+	SIZEQ_HEAD *q;
+	size_t len, tlen;
+	u_int8_t i, *p;
+	int ret;
+
+	env = infop->env;
+
+	DB_ASSERT(env, !F_ISSET(env, ENV_PRIVATE));
+
+#ifdef HAVE_MUTEX_SUPPORT
+	MUTEX_REQUIRED(env, infop->mtx_alloc);
+#endif
+
+	head = infop->head;
+
+	p = ptr;
+	len = *lenp;
+	elp = (ALLOC_ELEMENT *)(p - sizeof(ALLOC_ELEMENT));
+#ifdef DIAGNOSTIC
+	/* Check the guard byte. */
+	DB_ASSERT(env, p[elp->ulen] == GUARD_BYTE);
+#endif
+
+	/* See if there is anything left in the region. */
+again:	if ((elp_tmp = SH_TAILQ_NEXT(elp, addrq, __alloc_element)) != NULL &&
+	    elp_tmp->ulen == 0 &&
+	    (u_int8_t *)elp + elp->len == (u_int8_t *)elp_tmp) {
+		/*
+		 * If we're merging the current entry into a subsequent entry,
+		 * remove the subsequent entry from the addr and size queues
+		 * and merge.
+		 */
+		SH_TAILQ_REMOVE(&head->addrq, elp_tmp, addrq, __alloc_element);
+		SET_QUEUE_FOR_SIZE(head, q, i, elp_tmp->len);
+		SH_TAILQ_REMOVE(q, elp_tmp, sizeq, __alloc_element);
+		if (elp_tmp->len < len + SHALLOC_FRAGMENT) {
+			elp->len += elp_tmp->len;
+			if (elp_tmp->len < len)
+				len -= (size_t)elp_tmp->len;
+			else
+				len = 0;
+		} else {
+			tlen = (size_t)elp_tmp->len;
+			elp_tmp = (ALLOC_ELEMENT *) ((u_int8_t *)elp_tmp + len);
+			elp_tmp->len = tlen - len;
+			elp_tmp->ulen = 0;
+			elp->len += len;
+			len = 0;
+
+			/* The fragment follows the on the address queue. */
+			SH_TAILQ_INSERT_AFTER(
+			    &head->addrq, elp, elp_tmp, addrq, __alloc_element);
+
+			/* Insert the frag into the correct size queue. */
+			__env_size_insert(head, elp_tmp);
+		}
+	} else if (elp_tmp != NULL) {
+		__db_errx(env, DB_STR("1583", "block not at end of region"));
+		return (__env_panic(env, EINVAL));
+	}
+	if (len == 0)
+		goto done;
+
+	if ((ret = __env_region_extend(env, infop)) != 0) {
+		if (ret != ENOMEM)
+			return (ret);
+		goto done;
+	}
+	goto again;
+
+done:	elp->ulen = elp->len - sizeof(ALLOC_ELEMENT);
+#ifdef DIAGNOSTIC
+	elp->ulen -= sizeof(uintmax_t);
+	/* There was room for the guard byte in the chunk that came in. */
+	p[elp->ulen] = GUARD_BYTE;
+#endif
+	*lenp -= len;
+	infop->allocated += *lenp;
+	if (F_ISSET(infop, REGION_SHARED))
+		env->reginfo->allocated += *lenp;
+	return (0);
+}
+
+/*
+ * __env_size_insert --
+ *	Insert into the correct place in the size queues.
+ */
+static void
+__env_size_insert(head, elp)
+	ALLOC_LAYOUT *head;
+	ALLOC_ELEMENT *elp;
+{
+	SIZEQ_HEAD *q;
+	ALLOC_ELEMENT *elp_tmp;
+	u_int i;
+
+	/* Find the appropriate queue for the chunk. */
+	SET_QUEUE_FOR_SIZE(head, q, i, elp->len);
+
+	/* Find the correct slot in the size queue. */
+	SH_TAILQ_FOREACH(elp_tmp, q, sizeq, __alloc_element)
+		if (elp->len >= elp_tmp->len)
+			break;
+	if (elp_tmp == NULL)
+		SH_TAILQ_INSERT_TAIL(q, elp, sizeq);
+	else
+		SH_TAILQ_INSERT_BEFORE(q, elp_tmp, elp, sizeq, __alloc_element);
+}
+
+/*
+ * __env_region_extend --
+ *	Extend a region.
+ *
+ * PUBLIC: int __env_region_extend __P((ENV *, REGINFO *));
+ */
+int
+__env_region_extend(env, infop)
+	ENV *env;
+	REGINFO *infop;
+{
+	ALLOC_ELEMENT *elp;
+	REGION *rp;
+	int ret;
+
+	DB_ASSERT(env, !F_ISSET(env, ENV_PRIVATE));
+
+	ret = 0;
+	rp = infop->rp;
+	if (rp->size >= rp->max)
+		return (ENOMEM);
+	elp = (ALLOC_ELEMENT *)((u_int8_t *)infop->addr + rp->size);
+	if (rp->size + rp->alloc > rp->max)
+		rp->alloc = rp->max - rp->size;
+	rp->size += rp->alloc;
+	rp->size = (size_t)ALIGNP_INC(rp->size, sizeof(size_t));
+	if (rp->max - rp->size <= SHALLOC_FRAGMENT)
+		rp->size = rp->max;
+	if (infop->fhp &&
+	    (ret = __db_file_extend(env, infop->fhp, rp->size)) != 0)
+		return (ret);
+	elp->len = rp->alloc;
+	elp->ulen = 0;
+#ifdef DIAGNOSTIC
+	*(u_int8_t *)(elp+1) = GUARD_BYTE;
+#endif
+
+	SH_TAILQ_INSERT_TAIL(&((ALLOC_LAYOUT *)infop->head)->addrq, elp, addrq);
+	__env_alloc_free(infop, elp + 1);
+	if (rp->alloc < MEGABYTE)
+		rp->alloc += rp->size;
+	if (rp->alloc > MEGABYTE)
+		rp->alloc = MEGABYTE;
+	return (ret);
+}
+
+/*
+ * __env_elem_size --
+ *	Return the size of an allocated element.
+ * PUBLIC: uintmax_t __env_elem_size __P((ENV *, void *));
+ */
+uintmax_t
+__env_elem_size(env, p)
+	ENV *env;
+	void *p;
+{
+	ALLOC_ELEMENT *elp;
+	uintmax_t size;
+
+	if (F_ISSET(env, ENV_PRIVATE)) {
+		size = *((uintmax_t *)p - 1);
+		size -= sizeof(uintmax_t);
+	} else {
+		elp = (ALLOC_ELEMENT *)((u_int8_t *)p - sizeof(ALLOC_ELEMENT));
+		size = elp->ulen;
+	}
+	return (size);
+}
+
+/*
+ * __env_get_chunk --
+ *	Return the next chunk allocated in a private region.
+ * PUBLIC: void * __env_get_chunk __P((REGINFO *, void **, uintmax_t *));
+ */
+void *
+__env_get_chunk(infop, nextp, sizep)
+	REGINFO *infop;
+	void **nextp;
+	uintmax_t *sizep;
+{
+	REGION_MEM *mem;
+
+	if (infop->mem == NULL)
+		return (NULL);
+	if (*nextp == NULL)
+		*nextp = infop->mem;
+	mem = *(REGION_MEM **)nextp;
+	*nextp = mem->next;
+
+	*sizep = __env_elem_size(infop->env, mem);
+	*sizep -= sizeof(*mem);
+
+	return ((void *)(mem + 1));
+}
+
+#ifdef HAVE_STATISTICS
+/*
+ * __env_alloc_print --
+ *	Display the lists of memory chunks.
+ *
+ * PUBLIC: void __env_alloc_print __P((REGINFO *, u_int32_t));
+ */
+void
+__env_alloc_print(infop, flags)
+	REGINFO *infop;
+	u_int32_t flags;
+{
+	ALLOC_ELEMENT *elp;
+	ALLOC_LAYOUT *head;
+	ENV *env;
+	u_int i;
+
+	env = infop->env;
+	head = infop->head;
+
+	if (F_ISSET(env, ENV_PRIVATE))
+		return;
+
+	__db_msg(env,
+    "Region allocations: %lu allocations, %lu failures, %lu frees, %lu longest",
+	    (u_long)head->success, (u_long)head->failure, (u_long)head->freed,
+	    (u_long)head->longest);
+
+	if (!LF_ISSET(DB_STAT_ALL))
+		return;
+
+	__db_msg(env, "%s", "Allocations by power-of-two sizes:");
+	for (i = 0; i < DB_SIZE_Q_COUNT; ++i)
+		__db_msg(env, "%3dKB\t%lu",
+		    (1024 << i) / 1024, (u_long)head->pow2_size[i]);
+
+	if (!LF_ISSET(DB_STAT_ALLOC))
+		return;
+	/*
+	 * We don't normally display the list of address/chunk pairs, a few
+	 * thousand lines of output is too voluminous for even DB_STAT_ALL.
+	 */
+	__db_msg(env,
+	    "Allocation list by address, offset: {chunk length, user length}");
+	SH_TAILQ_FOREACH(elp, &head->addrq, addrq, __alloc_element)
+		__db_msg(env, "\t%#lx, %lu {%lu, %lu}",
+		    P_TO_ULONG(elp), (u_long)R_OFFSET(infop, elp),
+		    (u_long)elp->len, (u_long)elp->ulen);
+
+	__db_msg(env, "Allocation free list by size: KB {chunk length}");
+	for (i = 0; i < DB_SIZE_Q_COUNT; ++i) {
+		__db_msg(env, "%3dKB", (1024 << i) / 1024);
+		SH_TAILQ_FOREACH(elp, &head->sizeq[i], sizeq, __alloc_element)
+			__db_msg(env,
+			    "\t%#lx {%lu}", P_TO_ULONG(elp), (u_long)elp->len);
+	}
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/env/env_config.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,759 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/lock.h"
+#include "dbinc/log.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+#include "dbinc/db_page.h"
+#include "dbinc_auto/db_ext.h"
+
+/*
+ * DB_CONFIG lines are processed primarily by interpreting the command
+ * description tables initialized below.
+ *
+ * Most DB_CONFIG commands consist of a single token name followed by one or two
+ * integer or string arguments. These commands are described by entries in the
+ * config_descs[] array.
+ *
+ * The remaining, usually more complex, DB_CONFIG commands are handled by small
+ * code blocks in __config_parse().  Many of those commands need to translate
+ * option names to the integer values needed by the API configuration functions.
+ * Below the __config_descs[] initialization there are many FN array
+ * initializations which provide the mapping between user-specifiable strings
+ * and internally-used integer values. Typically there is one of these mappings
+ * defined for each complex DB_CONFIG command. Use __db_name_to_val()
+ * to translate a string to its integer value.
+ */
+typedef enum {
+	CFG_INT,	/* The argument is 1 signed integer. */
+	CFG_LONG,	/* The argument is 1 signed long int. */
+	CFG_UINT,	/* The argument is 1 unsigned integer. */
+	CFG_2INT,	/* The arguments are 2 signed integers. */
+	CFG_2UINT,	/* The arguments are 2 unsigned integers. */
+	CFG_STRING	/* The rest of the line is a string. */
+} __db_config_type;
+
+typedef struct __db_config_desc {
+	char *name;		/* The name of a simple DB_CONFIG command. */
+	__db_config_type type;	/* The enum describing its argument type(s). */
+	int (*func)();		/* The function to call with the argument(s). */
+} CFG_DESC;
+
+/* These typedefs help eliminate lint warnings where "func" above is used. */
+typedef int (*CFG_FUNC_STRING) __P((DB_ENV *, const char *));
+typedef int (*CFG_FUNC_INT) __P((DB_ENV *, int));
+typedef int (*CFG_FUNC_LONG) __P((DB_ENV *, long));
+typedef int (*CFG_FUNC_UINT) __P((DB_ENV *, u_int32_t));
+typedef int (*CFG_FUNC_2INT) __P((DB_ENV *, int, int));
+typedef int (*CFG_FUNC_2UINT) __P((DB_ENV *, u_int32_t, u_int32_t));
+
+/*
+ * This table lists the simple DB_CONFIG configuration commands. It is sorted by
+ * the command name, so that __config_scan() can bsearch() it.  After making an
+ * addition to this table, please be sure that it remains sorted.  With vi or
+ * vim, the following command line will do it:
+ *	:/^static const CFG_DESC config_descs/+1, /^}/-1 ! sort
+ *
+ * This table can contain aliases.  Aliases have different names with identical
+ * types and functions. At this time there are four aliases:
+ *	Outdated Name		Current Name
+ *	db_data_dir		set_data_dir
+ *	db_log_dir		set_lg_dir
+ *	db_tmp_dir		set_tmp_dir
+ *	set_tas_spins		mutex_set_tas_spins
+ */
+static const CFG_DESC config_descs[] = {
+    { "add_data_dir",		CFG_STRING,	__env_add_data_dir	},
+    { "db_data_dir",		CFG_STRING,	__env_set_data_dir	},
+    { "db_log_dir",		CFG_STRING,	__log_set_lg_dir	},
+    { "db_tmp_dir",		CFG_STRING,	__env_set_tmp_dir	},
+    { "mutex_set_align",	CFG_UINT,	__mutex_set_align	},
+    { "mutex_set_increment",	CFG_UINT,	__mutex_set_increment	},
+    { "mutex_set_init",		CFG_UINT,	__mutex_set_init	},
+    { "mutex_set_max",		CFG_UINT,	__mutex_set_max		},
+    { "mutex_set_tas_spins",	CFG_UINT,	__mutex_set_tas_spins	},
+    { "rep_set_clockskew",	CFG_2UINT,	__rep_set_clockskew	},
+    { "rep_set_limit",		CFG_2UINT,	__rep_set_limit		},
+    { "rep_set_nsites",		CFG_UINT,	__rep_set_nsites_pp	},
+    { "rep_set_priority",	CFG_UINT,	__rep_set_priority	},
+    { "rep_set_request",	CFG_2UINT,	__rep_set_request	},
+    { "set_cache_max",		CFG_2UINT,	__memp_set_cache_max	},
+    { "set_create_dir",		CFG_STRING,	__env_set_create_dir	},
+    { "set_data_dir",		CFG_STRING,	__env_set_data_dir	},
+    { "set_data_len",		CFG_UINT,	__env_set_data_len	},
+    { "set_intermediate_dir_mode",CFG_STRING, __env_set_intermediate_dir_mode },
+    { "set_lg_bsize",		CFG_UINT,	__log_set_lg_bsize	},
+    { "set_lg_dir",		CFG_STRING,	__log_set_lg_dir	},
+    { "set_lg_filemode",	CFG_INT,	__log_set_lg_filemode	},
+    { "set_lg_max",		CFG_UINT,	__log_set_lg_max	},
+    { "set_lg_regionmax",	CFG_UINT,	__log_set_lg_regionmax	},
+    { "set_lk_max_lockers",	CFG_UINT,	__lock_set_lk_max_lockers },
+    { "set_lk_max_locks",	CFG_UINT,	__lock_set_lk_max_locks },
+    { "set_lk_max_objects",	CFG_UINT,	__lock_set_lk_max_objects },
+    { "set_lk_partitions",	CFG_UINT,	__lock_set_lk_partitions },
+    { "set_lk_tablesize",	CFG_UINT,	__lock_set_lk_tablesize },
+    { "set_memory_max",		CFG_2UINT,	__env_set_memory_max	},
+    { "set_metadata_dir",	CFG_STRING,	__env_set_metadata_dir	},
+    { "set_mp_max_openfd",	CFG_INT,	__memp_set_mp_max_openfd },
+    { "set_mp_max_write",	CFG_2INT,	__memp_set_mp_max_write },
+    { "set_mp_mmapsize",	CFG_UINT,	__memp_set_mp_mmapsize	},
+    { "set_mp_mtxcount",	CFG_UINT,	__memp_set_mp_mtxcount	},
+    { "set_mp_pagesize",	CFG_UINT,	__memp_set_mp_pagesize	},
+    { "set_shm_key",		CFG_LONG,	__env_set_shm_key	},
+    { "set_tas_spins",		CFG_UINT,	__mutex_set_tas_spins	},
+    { "set_thread_count",	CFG_UINT,	__env_set_thread_count },
+    { "set_tmp_dir",		CFG_STRING,	__env_set_tmp_dir	},
+    { "set_tx_max",		CFG_UINT,	__txn_set_tx_max	}
+};
+
+/*
+ * Here are the option-name to option-value mappings used by complex commands.
+ */
+static const FN config_mem_init[] = {
+	{ (u_int32_t) DB_MEM_LOCK,		"DB_MEM_LOCK" },
+	{ (u_int32_t) DB_MEM_LOCKER,		"DB_MEM_LOCKER" },
+	{ (u_int32_t) DB_MEM_LOCKOBJECT,	"DB_MEM_LOCKOBJECT" },
+	{ (u_int32_t) DB_MEM_TRANSACTION,	"DB_MEM_TRANSACTION" },
+	{ (u_int32_t) DB_MEM_THREAD,		"DB_MEM_THREAD" },
+	{ (u_int32_t) DB_MEM_LOGID,		"DB_MEM_LOGID" },
+	{ 0, NULL }
+};
+
+static const FN config_rep_config[] = {
+	{ DB_REP_CONF_AUTOINIT,		"db_rep_conf_autoinit" },
+	{ DB_REP_CONF_AUTOROLLBACK,	"db_rep_conf_autorollback" },
+	{ DB_REP_CONF_BULK,		"db_rep_conf_bulk" },
+	{ DB_REP_CONF_DELAYCLIENT,	"db_rep_conf_delayclient" },
+	{ DB_REP_CONF_INMEM,		"db_rep_conf_inmem" },
+	{ DB_REP_CONF_LEASE,		"db_rep_conf_lease" },
+	{ DB_REP_CONF_NOWAIT,		"db_rep_conf_nowait" },
+	{ DB_REPMGR_CONF_2SITE_STRICT,	"db_repmgr_conf_2site_strict" },
+	{ DB_REPMGR_CONF_ELECTIONS,	"db_repmgr_conf_elections" },
+	{ 0, NULL }
+};
+
+static const FN config_rep_timeout[] = {
+	{ DB_REP_ACK_TIMEOUT,		"db_rep_ack_timeout" },
+	{ DB_REP_CHECKPOINT_DELAY,	"db_rep_checkpoint_delay" },
+	{ DB_REP_CONNECTION_RETRY,	"db_rep_connection_retry" },
+	{ DB_REP_ELECTION_TIMEOUT,	"db_rep_election_timeout" },
+	{ DB_REP_ELECTION_RETRY,	"db_rep_election_retry" },
+	{ DB_REP_FULL_ELECTION_TIMEOUT,	"db_rep_full_election_timeout" },
+	{ DB_REP_HEARTBEAT_MONITOR,	"db_rep_heartbeat_monitor" },
+	{ DB_REP_HEARTBEAT_SEND,	"db_rep_heartbeat_send" },
+	{ DB_REP_LEASE_TIMEOUT,		"db_rep_lease_timeout" },
+	{ 0, NULL }
+};
+
+static const FN config_repmgr_ack_policy[] = {
+	{ DB_REPMGR_ACKS_ALL,		"db_repmgr_acks_all" },
+	{ DB_REPMGR_ACKS_ALL_AVAILABLE,	"db_repmgr_acks_all_available" },
+	{ DB_REPMGR_ACKS_ALL_PEERS,	"db_repmgr_acks_all_peers" },
+	{ DB_REPMGR_ACKS_NONE,		"db_repmgr_acks_none" },
+	{ DB_REPMGR_ACKS_ONE,		"db_repmgr_acks_one" },
+	{ DB_REPMGR_ACKS_ONE_PEER,	"db_repmgr_acks_one_peer" },
+	{ DB_REPMGR_ACKS_QUORUM,	"db_repmgr_acks_quorum" },
+	{ 0, NULL }
+};
+
+static const FN config_repmgr_site[] = {
+	{ DB_BOOTSTRAP_HELPER,	"db_bootstrap_helper" },
+	{ DB_GROUP_CREATOR,	"db_group_creator" },
+	{ DB_LEGACY,		"db_legacy" },
+	{ DB_LOCAL_SITE,	"db_local_site" },
+	{ DB_REPMGR_PEER,	"db_repmgr_peer" },
+	{ 0, NULL }
+};
+
+static const FN config_set_flags[] = {
+	{ DB_AUTO_COMMIT,	"db_auto_commit" },
+	{ DB_CDB_ALLDB,		"db_cdb_alldb" },
+	{ DB_DIRECT_DB,		"db_direct_db" },
+	{ DB_DSYNC_DB,		"db_dsync_db" },
+	{ DB_MULTIVERSION,	"db_multiversion" },
+	{ DB_NOLOCKING,		"db_nolocking" },
+	{ DB_NOMMAP,		"db_nommap" },
+	{ DB_NOPANIC,		"db_nopanic" },
+	{ DB_OVERWRITE,		"db_overwrite" },
+	{ DB_REGION_INIT,	"db_region_init" },
+	{ DB_TIME_NOTGRANTED,	"db_time_notgranted" },
+	{ DB_TXN_NOSYNC,	"db_txn_nosync" },
+	{ DB_TXN_NOWAIT,	"db_txn_nowait" },
+	{ DB_TXN_SNAPSHOT,	"db_txn_snapshot" },
+	{ DB_TXN_WRITE_NOSYNC,	"db_txn_write_nosync" },
+	{ DB_YIELDCPU,		"db_yieldcpu" },
+	{ 0, NULL }
+};
+
+static const FN config_set_flags_forlog[] = {
+	{ DB_LOG_DIRECT,	"db_direct_log" },
+	{ DB_LOG_DSYNC,		"db_dsync_log" },
+	{ DB_LOG_AUTO_REMOVE,	"db_log_autoremove" },
+	{ DB_LOG_IN_MEMORY,	"db_log_inmemory" },
+	{ 0, NULL }
+};
+
+static const FN config_log_set_config[] = {
+	{ DB_LOG_DIRECT,	"db_log_direct" },
+	{ DB_LOG_DSYNC,		"db_log_dsync" },
+	{ DB_LOG_AUTO_REMOVE,	"db_log_auto_remove" },
+	{ DB_LOG_IN_MEMORY,	"db_log_in_memory" },
+	{ DB_LOG_ZERO,		"db_log_zero" },
+	{ 0, NULL }
+};
+
+static const FN config_set_lk_detect[] = {
+	{ DB_LOCK_DEFAULT,	"db_lock_default" },
+	{ DB_LOCK_EXPIRE,	"db_lock_expire" },
+	{ DB_LOCK_MAXLOCKS,	"db_lock_maxlocks" },
+	{ DB_LOCK_MAXWRITE,	"db_lock_maxwrite" },
+	{ DB_LOCK_MINLOCKS,	"db_lock_minlocks" },
+	{ DB_LOCK_MINWRITE,	"db_lock_minwrite" },
+	{ DB_LOCK_OLDEST,	"db_lock_oldest" },
+	{ DB_LOCK_RANDOM,	"db_lock_random" },
+	{ DB_LOCK_YOUNGEST,	"db_lock_youngest" },
+	{ 0, NULL }
+};
+
+static const FN config_set_open_flags[] = {
+	{ DB_INIT_REP,	"db_init_rep" },
+	{ DB_PRIVATE,	"db_private" },
+	{ DB_REGISTER,	"db_register" },
+	{ DB_THREAD,	"db_thread" },
+	{ 0, NULL }
+};
+
+static const FN config_set_verbose[] = {
+	{ DB_VERB_BACKUP,	"db_verb_backup" },
+	{ DB_VERB_DEADLOCK,	"db_verb_deadlock" },
+	{ DB_VERB_FILEOPS,	"db_verb_fileops" },
+	{ DB_VERB_FILEOPS_ALL,	"db_verb_fileops_all" },
+	{ DB_VERB_RECOVERY,	"db_verb_recovery" },
+	{ DB_VERB_REGISTER,	"db_verb_register" },
+	{ DB_VERB_REPLICATION,	"db_verb_replication" },
+	{ DB_VERB_REP_ELECT,	"db_verb_rep_elect" },
+	{ DB_VERB_REP_LEASE,	"db_verb_rep_lease" },
+	{ DB_VERB_REP_MISC,	"db_verb_rep_misc" },
+	{ DB_VERB_REP_MSGS,	"db_verb_rep_msgs" },
+	{ DB_VERB_REP_SYNC,	"db_verb_rep_sync" },
+	{ DB_VERB_REP_SYSTEM,	"db_verb_rep_system" },
+	{ DB_VERB_REP_TEST,	"db_verb_rep_test" },
+	{ DB_VERB_REPMGR_CONNFAIL,	"db_verb_repmgr_connfail" },
+	{ DB_VERB_REPMGR_MISC,	"db_verb_repmgr_misc" },
+	{ DB_VERB_WAITSFOR,	"db_verb_waitsfor" },
+	{ 0, NULL}
+};
+
+static int __config_parse __P((ENV *, char *, int));
+static int __config_scan __P((char *, char **, const CFG_DESC **));
+static int cmp_cfg_name __P((const void *, const void *element));
+
+/*
+ * __env_read_db_config --
+ *	Read the DB_CONFIG file.
+ *
+ * PUBLIC: int __env_read_db_config __P((ENV *));
+ */
+int
+__env_read_db_config(env)
+	ENV *env;
+{
+	FILE *fp;
+	int lc, ret;
+	char *p, buf[256];
+
+	/* Parse the config file. */
+	p = NULL;
+	if ((ret = __db_appname(env,
+	    DB_APP_NONE, "DB_CONFIG", NULL, &p)) != 0)
+		return (ret);
+	if (p == NULL)
+		fp = NULL;
+	else {
+		fp = fopen(p, "r");
+		__os_free(env, p);
+	}
+
+	if (fp == NULL)
+		return (0);
+
+	for (lc = 1; fgets(buf, sizeof(buf), fp) != NULL; ++lc) {
+		if ((p = strchr(buf, '\n')) == NULL)
+			p = buf + strlen(buf);
+		if (p > buf && p[-1] == '\r')
+			--p;
+		*p = '\0';
+		for (p = buf; *p != '\0' && isspace((int)*p); ++p)
+			;
+		if (*p == '\0' || *p == '#')
+			continue;
+
+		if ((ret = __config_parse(env, p, lc)) != 0)
+			break;
+	}
+	(void)fclose(fp);
+
+	return (ret);
+}
+
+#undef	CFG_GET_INT
+#define	CFG_GET_INT(s, vp) do {					\
+	int __ret;							\
+	if ((__ret =							\
+	    __db_getlong(env->dbenv, NULL, s, 0, INT_MAX, vp)) != 0)	\
+		return (__ret);						\
+} while (0)
+#undef	CFG_GET_LONG
+#define	CFG_GET_LONG(s, vp) do {					\
+	int __ret;							\
+	if ((__ret =							\
+	    __db_getlong(env->dbenv, NULL, s, 0, LONG_MAX, vp)) != 0)	\
+		return (__ret);						\
+} while (0)
+#undef	CFG_GET_UINT
+#define	CFG_GET_UINT(s, vp) do {					\
+	int __ret;							\
+	if ((__ret =							\
+	    __db_getulong(env->dbenv, NULL, s, 0, UINT_MAX, vp)) != 0)	\
+		return (__ret);						\
+} while (0)
+#undef	CFG_GET_UINT32
+#define	CFG_GET_UINT32(s, vp) do {					\
+	if (__db_getulong(env->dbenv, NULL, s, 0, UINT32_MAX, vp) != 0)	\
+		return (EINVAL);					\
+} while (0)
+
+/* This is the maximum number of tokens in a DB_CONFIG line. */
+#undef	CFG_SLOTS
+#define	CFG_SLOTS	10
+
+/*
+ * __config_parse --
+ *	Parse a single NAME VALUE pair.
+ */
+static int
+__config_parse(env, s, lc)
+	ENV *env;
+	char *s;
+	int lc;
+{
+	DB_ENV *dbenv;
+	DB_SITE *site;
+	u_long uv1, uv2;
+	long lv1, lv2;
+	u_int port;
+	int i, nf, onoff, bad, ret, t_ret;
+	char *argv[CFG_SLOTS];
+	const CFG_DESC *desc;
+
+	bad = 0;
+	dbenv = env->dbenv;
+
+	/*
+	 * Split the input line in 's' into its argv-like components, returning
+	 * the number of fields. If the command is one of the "simple" ones in
+	 * config_descs, also return its command descriptor.
+	 */
+	if ((nf = __config_scan(s, argv, &desc)) < 2) {
+format:		__db_errx(env, DB_STR_A("1584",
+		    "line %d: %s: incorrect name-value pair", "%d %s"),
+			    lc, argv[0]);
+		return (EINVAL);
+	}
+
+	/* Handle simple configuration lines here. */
+	if (desc != NULL) {
+		ret = 0;
+		switch (desc->type) {
+		  case CFG_INT:		/* <command> <int> */
+			if (nf != 2)
+				goto format;
+			CFG_GET_INT(argv[1], &lv1);
+			ret = ((CFG_FUNC_INT)desc->func)(dbenv, (int) lv1);
+			break;
+
+		  case CFG_LONG:	/* <command> <long int> */
+			if (nf != 2)
+				goto format;
+			CFG_GET_LONG(argv[1], &lv1);
+			ret = ((CFG_FUNC_LONG)desc->func)(dbenv, lv1);
+			break;
+
+		  case CFG_UINT:	/* <command> <uint> */
+			if (nf != 2)
+				goto format;
+			CFG_GET_UINT(argv[1], &uv1);
+			ret = ((CFG_FUNC_UINT)desc->func)
+			    (dbenv, (u_int32_t) uv1);
+			break;
+
+		  case CFG_2INT:	/* <command> <int1> <int2> */
+			if (nf != 3)
+				goto format;
+			CFG_GET_INT(argv[1], &lv1);
+			CFG_GET_INT(argv[2], &lv2);
+			ret = ((CFG_FUNC_2INT)desc->func)
+			    (dbenv, (int) lv1, (int) lv2);
+			break;
+
+		  case CFG_2UINT:	/* <command> <uint1> <uint2> */
+			if (nf != 3)
+				goto format;
+			CFG_GET_UINT(argv[1], &uv1);
+			CFG_GET_UINT(argv[2], &uv2);
+			ret = ((CFG_FUNC_2UINT)desc->func)
+			    (dbenv, (u_int32_t) uv1, (u_int32_t) uv2);
+			break;
+
+		  case CFG_STRING:	/* <command> <rest of line as string> */
+			ret = ((CFG_FUNC_STRING) desc->func)(dbenv, argv[1]);
+			break;
+		}
+		return (ret);
+	}
+
+	/*
+	 * The commands not covered in config_descs are handled below, each
+	 * with their own command-specific block of code. Most of them are
+	 * fairly similar to each other, but not quite enough to warrant
+	 * that they all be table-driven too.
+	 */
+
+	/* set_memory_init db_mem_XXX <unsigned> */
+	if (strcasecmp(argv[0], "set_memory_init") == 0) {
+		if (nf != 3)
+			goto format;
+		if ((lv1 = __db_name_to_val(config_mem_init, argv[1])) == -1)
+			goto format;
+		CFG_GET_UINT32(argv[2], &uv2);
+		return (__env_set_memory_init(dbenv,
+		    (DB_MEM_CONFIG) lv1, (u_int32_t)uv2));
+	}
+
+	/* rep_set_config { db_rep_conf_XXX | db_repmgr_conf_XXX }  [on|off] */
+	if (strcasecmp(argv[0], "rep_set_config") == 0) {
+		if (nf != 2 && nf != 3)
+			goto format;
+		onoff = 1;
+		if (nf == 3) {
+			if (strcasecmp(argv[2], "off") == 0)
+				onoff = 0;
+			else if (strcasecmp(argv[2], "on") != 0)
+				goto format;
+		}
+		if ((lv1 = __db_name_to_val(config_rep_config, argv[1])) == -1)
+			goto format;
+		return (__rep_set_config(dbenv, (u_int32_t)lv1, onoff));
+	}
+
+	/* rep_set_timeout db_rep_XXX <unsigned> */
+	if (strcasecmp(argv[0], "rep_set_timeout") == 0) {
+		if (nf != 3)
+			goto format;
+		if ((lv1 = __db_name_to_val(config_rep_timeout, argv[1])) == -1)
+			goto format;
+		CFG_GET_UINT32(argv[2], &uv2);
+		return (__rep_set_timeout(dbenv, lv1, (db_timeout_t)uv2));
+	}
+
+	/* repmgr_set_ack_policy db_repmgr_acks_XXX */
+	if (strcasecmp(argv[0], "repmgr_set_ack_policy") == 0) {
+		if (nf != 2)
+			goto format;
+		if ((lv1 =
+		    __db_name_to_val(config_repmgr_ack_policy, argv[1])) == -1)
+			goto format;
+		return (__repmgr_set_ack_policy(dbenv, lv1));
+	}
+
+	/*
+	 * Configure name/value pairs of config information for a site (local or
+	 * remote).
+	 *
+	 * repmgr_site host port [which value(on | off | unsigned)}] ...
+	 */
+	if (strcasecmp(argv[0], "repmgr_site") == 0) {
+		if (nf < 3 || (nf % 2) == 0)
+			goto format;
+		CFG_GET_UINT(argv[2], &uv2);
+		port = (u_int)uv2;
+
+		if ((ret = __repmgr_site(dbenv, argv[1], port, &site, 0)) != 0)
+			return (ret);
+#ifdef HAVE_REPLICATION_THREADS
+		for (i = 3; i < nf; i += 2) {
+			if ((lv1 = __db_name_to_val(
+			    config_repmgr_site, argv[i])) == -1) {
+				bad = 1;
+				break;
+			}
+
+			if (strcasecmp(argv[i + 1], "on") == 0)
+				uv2 = 1;
+			else if (strcasecmp(argv[i + 1], "off") == 0)
+				uv2 = 0;
+			else
+				CFG_GET_UINT32(argv[i + 1], &uv2);
+			if ((ret = __repmgr_site_config(site,
+			    (u_int32_t)lv1, (u_int32_t)uv2)) != 0)
+				break;
+		}
+		if ((t_ret = __repmgr_site_close(site)) != 0 && ret == 0)
+			ret = t_ret;
+		if (bad)
+			goto format;
+#else
+		/* If repmgr not built, __repmgr_site() returns DB_OPNOTSUP. */
+		COMPQUIET(i, 0);
+		COMPQUIET(t_ret, 0);
+		DB_ASSERT(env, 0);
+#endif
+		return (ret);
+	}
+
+	/* set_cachesize <unsigned gbytes> <unsigned bytes> <int ncaches> */
+	if (strcasecmp(argv[0], "set_cachesize") == 0) {
+		if (nf != 4)
+			goto format;
+		CFG_GET_UINT32(argv[1], &uv1);
+		CFG_GET_UINT32(argv[2], &uv2);
+		CFG_GET_INT(argv[3], &lv1);
+		return (__memp_set_cachesize(
+		    dbenv, (u_int32_t)uv1, (u_int32_t)uv2, (int)lv1));
+	}
+
+	/* set_intermediate_dir <integer dir permission> */
+	if (strcasecmp(argv[0], "set_intermediate_dir") == 0) {
+		if (nf != 2)
+			goto format;
+		CFG_GET_INT(argv[1], &lv1);
+		if (lv1 <= 0)
+			goto format;
+		env->dir_mode = (int)lv1;
+		return (0);
+	}
+
+	/* set_flags <env or log flag name> [on | off] */
+	if (strcasecmp(argv[0], "set_flags") == 0) {
+		if (nf != 2 && nf != 3)
+			goto format;
+		onoff = 1;
+		if (nf == 3) {
+			if (strcasecmp(argv[2], "off") == 0)
+				onoff = 0;
+			else if (strcasecmp(argv[2], "on") != 0)
+				goto format;
+		}
+		/* First see whether it is an env flag, then a log flag. */
+		if ((lv1 = __db_name_to_val(config_set_flags, argv[1])) != -1)
+			return (__env_set_flags(dbenv, (u_int32_t)lv1, onoff));
+		else if ((lv1 =
+		    __db_name_to_val(config_set_flags_forlog, argv[1])) != -1)
+			return (__log_set_config(dbenv, (u_int32_t)lv1, onoff));
+		goto format;
+	}
+
+	/* log_set_config <log flag name> [on | off] */
+	if (strcasecmp(argv[0], "log_set_config") == 0) {
+		if (nf != 2 && nf != 3)
+			goto format;
+		onoff = 1;
+		if (nf == 3) {
+			if (strcasecmp(argv[2], "off") == 0)
+				onoff = 0;
+			else if (strcasecmp(argv[2], "on") != 0)
+				goto format;
+		}
+		if ((lv1 =
+		    __db_name_to_val(config_log_set_config, argv[1])) == -1)
+			goto format;
+		return (__log_set_config(dbenv, (u_int32_t)lv1, onoff));
+	}
+
+	/* set_lk_detect db_lock_xxx */
+	if (strcasecmp(argv[0], "set_lk_detect") == 0) {
+		if (nf != 2)
+			goto format;
+		if ((lv1 =
+		    __db_name_to_val(config_set_lk_detect, argv[1])) == -1)
+			goto format;
+		return (__lock_set_lk_detect(dbenv, (u_int32_t)lv1));
+	}
+
+	/* set_lock_timeout <unsigned lock timeout> */
+	if (strcasecmp(argv[0], "set_lock_timeout") == 0) {
+		if (nf != 2)
+			goto format;
+		CFG_GET_UINT32(argv[1], &uv1);
+		return (__lock_set_env_timeout(
+		    dbenv, (u_int32_t)uv1, DB_SET_LOCK_TIMEOUT));
+	}
+
+	/* set_open_flags <env open flag name> [on | off] */
+	if (strcasecmp(argv[0], "set_open_flags") == 0) {
+		if (nf != 2 && nf != 3)
+			goto format;
+		onoff = 1;
+		if (nf == 3) {
+			if (strcasecmp(argv[2], "off") == 0)
+				onoff = 0;
+			else if (strcasecmp(argv[2], "on") != 0)
+				goto format;
+		}
+		if ((lv1 =
+		    __db_name_to_val(config_set_open_flags, argv[1])) == -1)
+			goto format;
+		if (onoff == 1)
+			FLD_SET(env->open_flags, (u_int32_t)lv1);
+		else
+			FLD_CLR(env->open_flags, (u_int32_t)lv1);
+		return (0);
+	}
+
+	/* set_region_init <0 or 1> */
+	if (strcasecmp(argv[0], "set_region_init") == 0) {
+		if (nf != 2)
+			goto format;
+		CFG_GET_INT(argv[1], &lv1);
+		if (lv1 != 0 && lv1 != 1)
+			goto format;
+		return (__env_set_flags(
+		    dbenv, DB_REGION_INIT, lv1 == 0 ? 0 : 1));
+	}
+
+	/* set_reg_timeout <unsigned timeout> */
+	if (strcasecmp(argv[0], "set_reg_timeout") == 0) {
+		if (nf != 2)
+			goto format;
+		CFG_GET_UINT32(argv[1], &uv1);
+		return (__env_set_timeout(
+		    dbenv, (u_int32_t)uv1, DB_SET_REG_TIMEOUT));
+	}
+
+	/* set_txn_timeout <unsigned timeout> */
+	if (strcasecmp(argv[0], "set_txn_timeout") == 0) {
+		if (nf != 2)
+			goto format;
+		CFG_GET_UINT32(argv[1], &uv1);
+		return (__lock_set_env_timeout(
+		    dbenv, (u_int32_t)uv1, DB_SET_TXN_TIMEOUT));
+	}
+
+	/* set_verbose db_verb_XXX [on | off] */
+	if (strcasecmp(argv[0], "set_verbose") == 0) {
+		if (nf != 2 && nf != 3)
+			goto format;
+		onoff = 1;
+		if (nf == 3) {
+			if (strcasecmp(argv[2], "off") == 0)
+				onoff = 0;
+			else if (strcasecmp(argv[2], "on") != 0)
+				goto format;
+		}
+		if ((lv1 = __db_name_to_val(config_set_verbose, argv[1])) == -1)
+			goto format;
+		return (__env_set_verbose(dbenv, (u_int32_t)lv1, onoff));
+	}
+
+	__db_errx(env,
+	    DB_STR_A("1585", "unrecognized name-value pair: %s", "%s"), s);
+	return (EINVAL);
+}
+
+/* cmp_cfg_name --
+ *	Bsearch comparison function for CFG_DESC.name, for looking up
+ *	the names of simple commmands.
+ */
+static int
+cmp_cfg_name(sought, element)
+	const void *sought;
+	const void *element;
+{
+	return
+	    (strcmp((const char *) sought, ((const CFG_DESC *) element)->name));
+}
+
+/*
+ * __config_scan --
+ *      Split DB_CONFIG lines into fields. Usually each whitespace separated
+ *	field is scanned as a distinct argument. However, if the command is
+ *	recognized as one needing a single string value, then the rest of the
+ *	line is returned as the one argument. That supports strings which
+ *	contain whitespaces, such as some directory paths.
+ *
+ *	This returns the number of fields. It sets *descptr to the command
+ *	descriptor (if it is recognized), or NULL.
+ */
+static int
+__config_scan(input, argv, descptr)
+	char *input, *argv[CFG_SLOTS];
+	const CFG_DESC **descptr;
+{
+	size_t tablecount;
+	int count;
+	char **ap;
+
+	tablecount = sizeof(config_descs) / sizeof(config_descs[0]);
+	*descptr = NULL;
+	for (count = 0, ap = argv; (*ap = strsep(&input, " \t\n")) != NULL;) {
+		/* Empty tokens are adjacent whitespaces; skip them. */
+		if (**ap == '\0')
+			continue;
+		/* Accept a non-empty token as the next field. */
+		count++;
+		ap++;
+		/*
+		 * If that was the first token, look it up in the simple command
+		 * table. If it is there and takes a single string value, then
+		 * return the remainder of the line (after skipping over any
+		 * leading whitespaces) without splitting it further.
+		 */
+		if (count == 1) {
+			*descptr = bsearch(argv[0], config_descs,
+			    tablecount, sizeof(config_descs[0]), cmp_cfg_name);
+			if (*descptr != NULL &&
+			    (*descptr)->type == CFG_STRING) {
+				count++;
+				while (isspace(*input))
+					input++;
+				*ap++ = input;
+				break;
+			}
+		}
+		/* Stop scanning if the line has too many tokens. */
+		if (count >= CFG_SLOTS)
+			break;
+	}
+	return (count);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/env/env_file.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,150 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2002, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __db_file_extend --
+ *	Initialize a regular file by writing the last page of the file.
+ *
+ * PUBLIC: int __db_file_extend __P((ENV *, DB_FH *, size_t));
+ */
+int
+__db_file_extend(env, fhp, size)
+	ENV *env;
+	DB_FH *fhp;
+	size_t size;
+{
+	db_pgno_t pages;
+	size_t nw;
+	u_int32_t relative;
+	int ret;
+	char buf;
+
+	buf = '\0';
+	/*
+	 * Extend the file by writing the last page.  If the region is >4Gb,
+	 * increment may be larger than the maximum possible seek "relative"
+	 * argument, as it's an unsigned 32-bit value.  Break the offset into
+	 * pages of 1MB each so we don't overflow -- (2^20 * 2^32 is bigger
+	 * than any memory I expect to see for awhile).
+	 */
+	pages = (db_pgno_t)((size - sizeof(buf)) / MEGABYTE);
+	relative = (u_int32_t)((size - sizeof(buf)) % MEGABYTE);
+	if ((ret = __os_seek(env, fhp, pages, MEGABYTE, relative)) == 0)
+		ret = __os_write(env, fhp, &buf, sizeof(buf), &nw);
+
+	return (ret);
+}
+
+/*
+ * __db_file_multi_write  --
+ *	Overwrite a file with multiple passes to corrupt the data.
+ *
+ * PUBLIC: int __db_file_multi_write __P((ENV *, const char *));
+ */
+int
+__db_file_multi_write(env, path)
+	ENV *env;
+	const char *path;
+{
+	DB_FH *fhp;
+	u_int32_t mbytes, bytes;
+	int ret;
+
+	if ((ret = __os_open(env, path, 0, DB_OSO_REGION, 0, &fhp)) == 0 &&
+	    (ret = __os_ioinfo(env, path, fhp, &mbytes, &bytes, NULL)) == 0) {
+		/*
+		 * !!!
+		 * Overwrite a regular file with alternating 0xff, 0x00 and 0xff
+		 * byte patterns.  Implies a fixed-block filesystem, journaling
+		 * or logging filesystems will require operating system support.
+		 */
+		if ((ret =
+		    __db_file_write(env, fhp, mbytes, bytes, 255)) != 0)
+			goto err;
+		if ((ret =
+		    __db_file_write(env, fhp, mbytes, bytes, 0)) != 0)
+			goto err;
+		if ((ret =
+		    __db_file_write(env, fhp, mbytes, bytes, 255)) != 0)
+			goto err;
+	} else
+		__db_err(env, ret, "%s", path);
+
+err:	if (fhp != NULL)
+		(void)__os_closehandle(env, fhp);
+	return (ret);
+}
+
+/*
+ * __db_file_write --
+ *	A single pass over the file, writing the specified byte pattern.
+ *
+ * PUBLIC: int __db_file_write __P((ENV *,
+ * PUBLIC:     DB_FH *, u_int32_t, u_int32_t, int));
+ */
+int
+__db_file_write(env, fhp, mbytes, bytes, pattern)
+	ENV *env;
+	DB_FH *fhp;
+	int pattern;
+	u_int32_t mbytes, bytes;
+{
+	size_t len, nw;
+	int i, ret;
+	char *buf;
+
+#undef	FILE_WRITE_IO_SIZE
+#define	FILE_WRITE_IO_SIZE	(64 * 1024)
+	if ((ret = __os_malloc(env, FILE_WRITE_IO_SIZE, &buf)) != 0)
+		return (ret);
+	memset(buf, pattern, FILE_WRITE_IO_SIZE);
+
+	if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0)
+		goto err;
+	for (; mbytes > 0; --mbytes)
+		for (i = MEGABYTE / FILE_WRITE_IO_SIZE; i > 0; --i)
+			if ((ret = __os_write(
+			    env, fhp, buf, FILE_WRITE_IO_SIZE, &nw)) != 0)
+				goto err;
+	for (; bytes > 0; bytes -= (u_int32_t)len) {
+		len = bytes < FILE_WRITE_IO_SIZE ? bytes : FILE_WRITE_IO_SIZE;
+		if ((ret = __os_write(env, fhp, buf, len, &nw)) != 0)
+			goto err;
+	}
+
+	ret = __os_fsync(env, fhp);
+
+err:	__os_free(env, buf);
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/env/env_globals.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,88 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * A structure with static initialization values for all of the global fields
+ * used by Berkeley DB.
+ * See dbinc/globals.h for the structure definition.
+ */
+DB_GLOBALS __db_global_values = {
+#ifdef HAVE_VXWORKS
+	0,				/* VxWorks: db_global_init */
+	NULL,				/* VxWorks: db_global_lock */
+#endif
+#ifdef DB_WIN32
+#ifndef DB_WINCE
+	{ 0 },			/* SECURITY_DESCRIPTOR win_default_sec_desc */
+	{ 0 },			/* SECURITY_ATTRIBUTES win_default_sec_attr */
+#endif
+	NULL,				/* SECURITY_ATTRIBUTES *win_sec_attr */
+#endif
+	{ NULL, NULL },			/* XA env list */
+
+	"=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=", /* db_line */
+	{ 0 },				/* error_buf */
+	0,				/* uid_init */
+	0,				/* rand_next */
+	0,				/* fid_serial */
+	0,				/* db_errno */
+	0,				/* num_active_pids */
+	0,				/* size_active_pids */
+	NULL,                           /* active_pids */
+	NULL,                           /* saved_errstr */
+	NULL,				/* j_assert */
+	NULL,				/* j_close */
+	NULL,				/* j_dirfree */
+	NULL,				/* j_dirlist */
+	NULL,				/* j_exists*/
+	NULL,				/* j_free */
+	NULL,				/* j_fsync */
+	NULL,				/* j_ftruncate */
+	NULL,				/* j_ioinfo */
+	NULL,				/* j_malloc */
+	NULL,				/* j_file_map */
+	NULL,				/* j_file_unmap */
+	NULL,				/* j_open */
+	NULL,				/* j_pread */
+	NULL,				/* j_pwrite */
+	NULL,				/* j_read */
+	NULL,				/* j_realloc */
+	NULL,				/* j_region_map */
+	NULL,				/* j_region_unmap */
+	NULL,				/* j_rename */
+	NULL,				/* j_seek */
+	NULL,				/* j_unlink */
+	NULL,				/* j_write */
+	NULL				/* j_yield */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/env/env_method.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1782 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id: env_method.c,v dabaaeb7d839 2010/08/03 17:28:53 mike $
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/crypto.h"
+#include "dbinc/hmac.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+static int  __db_env_init __P((DB_ENV *));
+static void __env_err __P((const DB_ENV *, int, const char *, ...));
+static void __env_errx __P((const DB_ENV *, const char *, ...));
+static int  __env_get_create_dir __P((DB_ENV *, const char **));
+static int  __env_get_data_dirs __P((DB_ENV *, const char ***));
+static int  __env_get_data_len __P((DB_ENV *, u_int32_t *));
+static int  __env_get_flags __P((DB_ENV *, u_int32_t *));
+static int  __env_get_home __P((DB_ENV *, const char **));
+static int  __env_get_intermediate_dir_mode __P((DB_ENV *, const char **));
+static int  __env_get_metadata_dir __P((DB_ENV *, const char **));
+static int  __env_get_shm_key __P((DB_ENV *, long *));
+static int  __env_get_thread_count __P((DB_ENV *, u_int32_t *));
+static int  __env_get_thread_id_fn __P((DB_ENV *,
+		void (**)(DB_ENV *, pid_t *, db_threadid_t *)));
+static int  __env_get_thread_id_string_fn __P((DB_ENV *,
+		char * (**)(DB_ENV *, pid_t, db_threadid_t, char *)));
+static int  __env_get_timeout __P((DB_ENV *, db_timeout_t *, u_int32_t));
+static int  __env_get_tmp_dir __P((DB_ENV *, const char **));
+static int  __env_get_verbose __P((DB_ENV *, u_int32_t, int *));
+static int __env_set_event_notify
+		__P((DB_ENV *, void (*)(DB_ENV *, u_int32_t, void *)));
+static int  __env_get_feedback __P((DB_ENV *, void (**)(DB_ENV *, int, int)));
+static int  __env_set_feedback __P((DB_ENV *, void (*)(DB_ENV *, int, int)));
+static int  __env_set_thread_id __P((DB_ENV *, void (*)(DB_ENV *,
+		pid_t *, db_threadid_t *)));
+static int  __env_set_thread_id_string __P((DB_ENV *,
+		char * (*)(DB_ENV *, pid_t, db_threadid_t, char *)));
+
+/*
+ * db_env_create --
+ *	DB_ENV constructor.
+ *
+ * EXTERN: int db_env_create __P((DB_ENV **, u_int32_t));
+ */
+int
+db_env_create(dbenvpp, flags)
+	DB_ENV **dbenvpp;
+	u_int32_t flags;
+{
+	DB_ENV *dbenv;
+	ENV *env;
+	int ret;
+
+	/*
+	 * !!!
+	 * Our caller has not yet had the opportunity to reset the panic
+	 * state or turn off mutex locking, and so we can neither check
+	 * the panic state or acquire a mutex in the DB_ENV create path.
+	 *
+	 * !!!
+	 * We can't call the flags-checking routines, we don't have an
+	 * environment yet.
+	 */
+	if (flags != 0)
+		return (EINVAL);
+
+	/* Allocate the DB_ENV and ENV structures -- we always have both. */
+	if ((ret = __os_calloc(NULL, 1, sizeof(DB_ENV), &dbenv)) != 0)
+		return (ret);
+	if ((ret = __os_calloc(NULL, 1, sizeof(ENV), &env)) != 0)
+		goto err;
+	dbenv->env = env;
+	env->dbenv = dbenv;
+
+	if ((ret = __db_env_init(dbenv)) != 0 ||
+	    (ret = __lock_env_create(dbenv)) != 0 ||
+	    (ret = __log_env_create(dbenv)) != 0 ||
+	    (ret = __memp_env_create(dbenv)) != 0 ||
+#ifdef HAVE_REPLICATION
+	    (ret = __rep_env_create(dbenv)) != 0 ||
+#endif
+	    (ret = __txn_env_create(dbenv)))
+		goto err;
+
+	*dbenvpp = dbenv;
+	return (0);
+
+err:	__db_env_destroy(dbenv);
+	return (ret);
+}
+
+/*
+ * __db_env_destroy --
+ *	DB_ENV destructor.
+ *
+ * PUBLIC: void __db_env_destroy __P((DB_ENV *));
+ */
+void
+__db_env_destroy(dbenv)
+	DB_ENV *dbenv;
+{
+	__lock_env_destroy(dbenv);
+	__log_env_destroy(dbenv);
+	__memp_env_destroy(dbenv);
+#ifdef HAVE_REPLICATION
+	__rep_env_destroy(dbenv);
+#endif
+	__txn_env_destroy(dbenv);
+
+	/*
+	 * Discard the underlying ENV structure.
+	 *
+	 * XXX
+	 * This is wrong, but can't be fixed until we finish the work of
+	 * splitting up the DB_ENV and ENV structures so that we don't
+	 * touch anything in the ENV as part of the above calls to subsystem
+	 * DB_ENV cleanup routines.
+	 */
+	memset(dbenv->env, CLEAR_BYTE, sizeof(ENV));
+	__os_free(NULL, dbenv->env);
+
+	memset(dbenv, CLEAR_BYTE, sizeof(DB_ENV));
+	__os_free(NULL, dbenv);
+}
+
+/*
+ * __db_env_init --
+ *	Initialize a DB_ENV structure.
+ */
+static int
+__db_env_init(dbenv)
+	DB_ENV *dbenv;
+{
+	ENV *env;
+	/*
+	 * !!!
+	 * Our caller has not yet had the opportunity to reset the panic
+	 * state or turn off mutex locking, and so we can neither check
+	 * the panic state or acquire a mutex in the DB_ENV create path.
+	 *
+	 * Initialize the method handles.
+	 */
+	/* DB_ENV PUBLIC HANDLE LIST BEGIN */
+	dbenv->add_data_dir = __env_add_data_dir;
+	dbenv->close = __env_close_pp;
+	dbenv->err = __env_err;
+	dbenv->errx = __env_errx;
+	dbenv->get_alloc = __env_get_alloc;
+	dbenv->get_cache_max = __memp_get_cache_max;
+	dbenv->get_cachesize = __memp_get_cachesize;
+	dbenv->get_create_dir = __env_get_create_dir;
+	dbenv->get_data_dirs = __env_get_data_dirs;
+	dbenv->get_data_len = __env_get_data_len;
+	dbenv->get_errcall = __env_get_errcall;
+	dbenv->get_errfile = __env_get_errfile;
+	dbenv->get_errpfx = __env_get_errpfx;
+	dbenv->get_feedback = __env_get_feedback;
+	dbenv->get_flags = __env_get_flags;
+	dbenv->get_home = __env_get_home;
+	dbenv->get_intermediate_dir_mode = __env_get_intermediate_dir_mode;
+	dbenv->get_memory_init = __env_get_memory_init;
+	dbenv->get_memory_max = __env_get_memory_max;
+	dbenv->get_metadata_dir = __env_get_metadata_dir;
+	dbenv->get_mp_max_openfd = __memp_get_mp_max_openfd;
+	dbenv->get_mp_max_write = __memp_get_mp_max_write;
+	dbenv->get_mp_mmapsize = __memp_get_mp_mmapsize;
+	dbenv->get_mp_mtxcount = __memp_get_mp_mtxcount;
+	dbenv->get_mp_pagesize = __memp_get_mp_pagesize;
+	dbenv->get_mp_tablesize = __memp_get_mp_tablesize;
+	dbenv->get_msgcall = __env_get_msgcall;
+	dbenv->get_msgfile = __env_get_msgfile;
+	dbenv->get_open_flags = __env_get_open_flags;
+	dbenv->get_shm_key = __env_get_shm_key;
+	dbenv->get_thread_count = __env_get_thread_count;
+	dbenv->get_thread_id_fn = __env_get_thread_id_fn;
+	dbenv->get_thread_id_string_fn = __env_get_thread_id_string_fn;
+	dbenv->get_timeout = __env_get_timeout;
+	dbenv->get_tmp_dir = __env_get_tmp_dir;
+	dbenv->get_verbose = __env_get_verbose;
+	dbenv->is_bigendian = __db_isbigendian;
+	dbenv->memp_fcreate = __memp_fcreate_pp;
+	dbenv->memp_register = __memp_register_pp;
+	dbenv->memp_stat = __memp_stat_pp;
+	dbenv->memp_stat_print = __memp_stat_print_pp;
+	dbenv->memp_sync = __memp_sync_pp;
+	dbenv->memp_trickle = __memp_trickle_pp;
+	dbenv->mutex_alloc = __mutex_alloc_pp;
+	dbenv->mutex_free = __mutex_free_pp;
+	dbenv->mutex_get_align = __mutex_get_align;
+	dbenv->mutex_get_increment = __mutex_get_increment;
+	dbenv->mutex_get_init = __mutex_get_init;
+	dbenv->mutex_get_max = __mutex_get_max;
+	dbenv->mutex_get_tas_spins = __mutex_get_tas_spins;
+	dbenv->mutex_lock = __mutex_lock_pp;
+	dbenv->mutex_set_align = __mutex_set_align;
+	dbenv->mutex_set_increment = __mutex_set_increment;
+	dbenv->mutex_set_init = __mutex_set_init;
+	dbenv->mutex_set_max = __mutex_set_max;
+	dbenv->mutex_set_tas_spins = __mutex_set_tas_spins;
+	dbenv->mutex_stat = __mutex_stat_pp;
+	dbenv->mutex_stat_print = __mutex_stat_print_pp;
+	dbenv->mutex_unlock = __mutex_unlock_pp;
+	dbenv->open = __env_open_pp;
+	dbenv->remove = __env_remove;
+	dbenv->set_alloc = __env_set_alloc;
+	dbenv->set_cache_max = __memp_set_cache_max;
+	dbenv->set_cachesize = __memp_set_cachesize;
+	dbenv->set_create_dir = __env_set_create_dir;
+	dbenv->set_data_dir = __env_set_data_dir;
+	dbenv->set_data_len = __env_set_data_len;
+	dbenv->set_encrypt = __env_set_encrypt;
+	dbenv->set_errcall = __env_set_errcall;
+	dbenv->set_errfile = __env_set_errfile;
+	dbenv->set_errpfx = __env_set_errpfx;
+	dbenv->set_event_notify = __env_set_event_notify;
+	dbenv->set_feedback = __env_set_feedback;
+	dbenv->set_flags = __env_set_flags;
+	dbenv->set_intermediate_dir_mode = __env_set_intermediate_dir_mode;
+	dbenv->set_memory_init = __env_set_memory_init;
+	dbenv->set_memory_max = __env_set_memory_max;
+	dbenv->set_metadata_dir = __env_set_metadata_dir;
+	dbenv->set_mp_max_openfd = __memp_set_mp_max_openfd;
+	dbenv->set_mp_max_write = __memp_set_mp_max_write;
+	dbenv->set_mp_mmapsize = __memp_set_mp_mmapsize;
+	dbenv->set_mp_mtxcount = __memp_set_mp_mtxcount;
+	dbenv->set_mp_pagesize = __memp_set_mp_pagesize;
+	dbenv->set_mp_tablesize = __memp_set_mp_tablesize;
+	dbenv->set_msgcall = __env_set_msgcall;
+	dbenv->set_msgfile = __env_set_msgfile;
+	dbenv->set_paniccall = __env_set_paniccall;
+	dbenv->set_shm_key = __env_set_shm_key;
+	dbenv->set_thread_count = __env_set_thread_count;
+	dbenv->set_thread_id = __env_set_thread_id;
+	dbenv->set_thread_id_string = __env_set_thread_id_string;
+	dbenv->set_timeout = __env_set_timeout;
+	dbenv->set_tmp_dir = __env_set_tmp_dir;
+	dbenv->set_verbose = __env_set_verbose;
+	dbenv->stat_print = __env_stat_print_pp;
+	/* DB_ENV PUBLIC HANDLE LIST END */
+
+	/* DB_ENV PRIVATE HANDLE LIST BEGIN */
+	dbenv->prdbt = __db_prdbt;
+	/* DB_ENV PRIVATE HANDLE LIST END */
+
+	dbenv->shm_key = INVALID_REGION_SEGID;
+	dbenv->thread_id = __os_id;
+	dbenv->thread_id_string = __env_thread_id_string;
+
+	env = dbenv->env;
+	__os_id(NULL, &env->pid_cache, NULL);
+
+	env->db_ref = 0;
+	env->log_verify_wrap = __log_verify_wrap;
+	env->data_len = ENV_DEF_DATA_LEN;
+	TAILQ_INIT(&env->fdlist);
+
+	if (!__db_isbigendian())
+		F_SET(env, ENV_LITTLEENDIAN);
+	F_SET(env, ENV_NO_OUTPUT_SET);
+
+	return (0);
+}
+
+/*
+ * __env_err --
+ *	DbEnv.err method.
+ */
+static void
+#ifdef STDC_HEADERS
+__env_err(const DB_ENV *dbenv, int error, const char *fmt, ...)
+#else
+__env_err(dbenv, error, fmt, va_alist)
+	const DB_ENV *dbenv;
+	int error;
+	const char *fmt;
+	va_dcl
+#endif
+{
+	/* Message with error string, to stderr by default. */
+	DB_REAL_ERR(dbenv, error, DB_ERROR_SET, 1, fmt);
+}
+
+/*
+ * __env_errx --
+ *	DbEnv.errx method.
+ */
+static void
+#ifdef STDC_HEADERS
+__env_errx(const DB_ENV *dbenv, const char *fmt, ...)
+#else
+__env_errx(dbenv, fmt, va_alist)
+	const DB_ENV *dbenv;
+	const char *fmt;
+	va_dcl
+#endif
+{
+	/* Message without error string, to stderr by default. */
+	DB_REAL_ERR(dbenv, 0, DB_ERROR_NOT_SET, 1, fmt);
+}
+
+static int
+__env_get_home(dbenv, homep)
+	DB_ENV *dbenv;
+	const char **homep;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->get_home");
+	*homep = env->db_home;
+
+	return (0);
+}
+
+/*
+ * __env_get_alloc --
+ *	{DB_ENV,DB}->get_alloc.
+ *
+ * PUBLIC: int  __env_get_alloc __P((DB_ENV *, void *(**)(size_t),
+ * PUBLIC:          void *(**)(void *, size_t), void (**)(void *)));
+ */
+int
+__env_get_alloc(dbenv, mal_funcp, real_funcp, free_funcp)
+	DB_ENV *dbenv;
+	void *(**mal_funcp) __P((size_t));
+	void *(**real_funcp) __P((void *, size_t));
+	void (**free_funcp) __P((void *));
+{
+
+	if (mal_funcp != NULL)
+		*mal_funcp = dbenv->db_malloc;
+	if (real_funcp != NULL)
+		*real_funcp = dbenv->db_realloc;
+	if (free_funcp != NULL)
+		*free_funcp = dbenv->db_free;
+	return (0);
+}
+
+/*
+ * __env_set_alloc --
+ *	{DB_ENV,DB}->set_alloc.
+ *
+ * PUBLIC: int  __env_set_alloc __P((DB_ENV *, void *(*)(size_t),
+ * PUBLIC:          void *(*)(void *, size_t), void (*)(void *)));
+ */
+int
+__env_set_alloc(dbenv, mal_func, real_func, free_func)
+	DB_ENV *dbenv;
+	void *(*mal_func) __P((size_t));
+	void *(*real_func) __P((void *, size_t));
+	void (*free_func) __P((void *));
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_alloc");
+
+	dbenv->db_malloc = mal_func;
+	dbenv->db_realloc = real_func;
+	dbenv->db_free = free_func;
+	return (0);
+}
+/*
+ * __env_get_memory_init --
+ *	DB_ENV->get_memory_init.
+ *
+ * PUBLIC: int  __env_get_memory_init __P((DB_ENV *,
+ * PUBLIC:	    DB_MEM_CONFIG, u_int32_t *));
+ */
+int
+__env_get_memory_init(dbenv, type, countp)
+	DB_ENV *dbenv;
+	DB_MEM_CONFIG type;
+	u_int32_t *countp;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	switch (type) {
+	case DB_MEM_LOCK:
+		ENV_NOT_CONFIGURED(env,
+		    env->lk_handle, "DB_ENV->get_memory_init", DB_INIT_LOCK);
+		if (LOCKING_ON(env))
+			*countp = ((DB_LOCKREGION *)
+			    env->lk_handle->reginfo.primary)->stat.st_initlocks;
+		else
+			*countp = dbenv->lk_init;
+		break;
+	case DB_MEM_LOCKOBJECT:
+		ENV_NOT_CONFIGURED(env,
+		    env->lk_handle, "DB_ENV->get_memory_init", DB_INIT_LOCK);
+		if (LOCKING_ON(env))
+			*countp = ((DB_LOCKREGION *) env->
+			    lk_handle->reginfo.primary)->stat.st_initobjects;
+		else
+			*countp = dbenv->lk_init_objects;
+		break;
+	case DB_MEM_LOCKER:
+		ENV_NOT_CONFIGURED(env,
+		    env->lk_handle, "DB_ENV->get_memory_init", DB_INIT_LOCK);
+		if (LOCKING_ON(env))
+			*countp = ((DB_LOCKREGION *) env->
+			    lk_handle->reginfo.primary)->stat.st_initlockers;
+		else
+			*countp = dbenv->lk_init_lockers;
+		break;
+	case DB_MEM_LOGID:
+		ENV_NOT_CONFIGURED(env,
+		    env->lg_handle, "DB_ENV->get_memory_init", DB_INIT_LOG);
+
+		if (LOGGING_ON(env))
+			*countp = ((LOG *)env->lg_handle->
+			    reginfo.primary)->stat.st_fileid_init;
+		else
+			*countp = dbenv->lg_fileid_init;
+		break;
+	case DB_MEM_TRANSACTION:
+		ENV_NOT_CONFIGURED(env,
+		    env->tx_handle, "DB_ENV->get_memory_init", DB_INIT_TXN);
+
+		if (TXN_ON(env))
+			*countp = ((DB_TXNREGION *)
+			    env->tx_handle->reginfo.primary)->inittxns;
+		else
+			*countp = dbenv->tx_init;
+		break;
+	case DB_MEM_THREAD:
+		/* We always update thr_init when joining an env. */
+		*countp = dbenv->thr_init;
+		break;
+	}
+
+	return (0);
+}
+
+/*
+ * __env_set_memory_init --
+ *	DB_ENV->set_memory_init.
+ *
+ * PUBLIC: int  __env_set_memory_init __P((DB_ENV *, DB_MEM_CONFIG, u_int32_t));
+ */
+int
+__env_set_memory_init(dbenv, type, count)
+	DB_ENV *dbenv;
+	DB_MEM_CONFIG type;
+	u_int32_t count;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_memory_init");
+	switch (type) {
+	case DB_MEM_LOCK:
+		dbenv->lk_init = count;
+		break;
+	case DB_MEM_LOCKOBJECT:
+		dbenv->lk_init_objects = count;
+		break;
+	case DB_MEM_LOCKER:
+		dbenv->lk_init_lockers = count;
+		break;
+	case DB_MEM_LOGID:
+		dbenv->lg_fileid_init = count;
+		break;
+	case DB_MEM_TRANSACTION:
+		dbenv->tx_init = count;
+		break;
+	case DB_MEM_THREAD:
+		dbenv->thr_init = count;
+		break;
+	}
+
+	return (0);
+}
+/*
+ * __env_get_memory_max --
+ *	DB_ENV->get_memory_max.
+ *
+ * PUBLIC: int  __env_get_memory_max __P((DB_ENV *, u_int32_t *, u_int32_t *));
+ */
+int
+__env_get_memory_max(dbenv, gbytes, bytes)
+	DB_ENV *dbenv;
+	u_int32_t *gbytes, *bytes;
+{
+	ENV *env;
+	env = dbenv->env;
+
+	if (F_ISSET(env, ENV_OPEN_CALLED)) {
+		*gbytes = (u_int32_t)(env->reginfo->rp->max / GIGABYTE);
+		*bytes = (u_int32_t)(env->reginfo->rp->max % GIGABYTE);
+	} else {
+		*gbytes = (u_int32_t)(dbenv->memory_max / GIGABYTE);
+		*bytes = (u_int32_t)(dbenv->memory_max % GIGABYTE);
+	}
+	return (0);
+}
+
+/*
+ * __env_set_memory_max --
+ *	DB_ENV->set_memory_max.
+ *
+ * PUBLIC: int  __env_set_memory_max __P((DB_ENV *, u_int32_t, u_int32_t));
+ */
+int
+__env_set_memory_max(dbenv, gbytes, bytes)
+	DB_ENV *dbenv;
+	u_int32_t gbytes, bytes;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_memory_max");
+
+	/*
+	 * If they are asking for 4GB exactly on a 32 bit platform, they
+	 * really meant 4GB - 1. Give it to them.
+	 */
+	if (sizeof(roff_t) == 4 && gbytes == 4 && bytes == 0) {
+		--gbytes;
+		bytes = GIGABYTE - 1;
+	}
+	/*
+	 * Make sure they wouldn't overflow the memory_max field on a
+	 * 32 bit architecture.
+	 */
+	if (sizeof(roff_t) == 4 && gbytes >= 4) {
+		__db_errx(env, DB_STR("1588",
+	    "Maximum memory size too large: maximum is 4GB"));
+		return (EINVAL);
+	}
+	dbenv->memory_max = ((roff_t)gbytes * GIGABYTE) + bytes;
+	return (0);
+}
+
+/*
+ * __env_get_encrypt_flags --
+ *	{DB_ENV,DB}->get_encrypt_flags.
+ *
+ * PUBLIC: int __env_get_encrypt_flags __P((DB_ENV *, u_int32_t *));
+ */
+int
+__env_get_encrypt_flags(dbenv, flagsp)
+	DB_ENV *dbenv;
+	u_int32_t *flagsp;
+{
+#ifdef HAVE_CRYPTO
+	DB_CIPHER *db_cipher;
+#endif
+	ENV *env;
+
+	env = dbenv->env;
+
+#ifdef HAVE_CRYPTO
+	db_cipher = env->crypto_handle;
+	if (db_cipher != NULL && db_cipher->alg == CIPHER_AES)
+		*flagsp = DB_ENCRYPT_AES;
+	else
+		*flagsp = 0;
+	return (0);
+#else
+	COMPQUIET(flagsp, 0);
+	__db_errx(env, DB_STR("1555",
+	    "library build did not include support for cryptography"));
+	return (DB_OPNOTSUP);
+#endif
+}
+
+/*
+ * __env_set_encrypt --
+ *	DB_ENV->set_encrypt.
+ *
+ * PUBLIC: int __env_set_encrypt __P((DB_ENV *, const char *, u_int32_t));
+ */
+int
+__env_set_encrypt(dbenv, passwd, flags)
+	DB_ENV *dbenv;
+	const char *passwd;
+	u_int32_t flags;
+{
+#ifdef HAVE_CRYPTO
+	DB_THREAD_INFO *ip;
+	DB_CIPHER *db_cipher;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_encrypt");
+#define	OK_CRYPTO_FLAGS	(DB_ENCRYPT_AES)
+
+	if (flags != 0 && LF_ISSET(~OK_CRYPTO_FLAGS))
+		return (__db_ferr(env, "DB_ENV->set_encrypt", 0));
+
+	if (passwd == NULL || strlen(passwd) == 0) {
+		__db_errx(env, DB_STR("1556",
+		    "Empty password specified to set_encrypt"));
+		return (EINVAL);
+	}
+	ENV_ENTER(env, ip);
+	if (!CRYPTO_ON(env)) {
+		if ((ret = __os_calloc(env, 1, sizeof(DB_CIPHER), &db_cipher))
+		    != 0)
+			goto err;
+		env->crypto_handle = db_cipher;
+	} else
+		db_cipher = env->crypto_handle;
+
+	if (dbenv->passwd != NULL)
+		__os_free(env, dbenv->passwd);
+	if ((ret = __os_strdup(env, passwd, &dbenv->passwd)) != 0) {
+		__os_free(env, db_cipher);
+		goto err;
+	}
+	/*
+	 * We're going to need this often enough to keep around
+	 */
+	dbenv->passwd_len = strlen(dbenv->passwd) + 1;
+	/*
+	 * The MAC key is for checksumming, and is separate from
+	 * the algorithm.  So initialize it here, even if they
+	 * are using CIPHER_ANY.
+	 */
+	__db_derive_mac(
+	    (u_int8_t *)dbenv->passwd, dbenv->passwd_len, db_cipher->mac_key);
+	switch (flags) {
+	case 0:
+		F_SET(db_cipher, CIPHER_ANY);
+		break;
+	case DB_ENCRYPT_AES:
+		if ((ret =
+		    __crypto_algsetup(env, db_cipher, CIPHER_AES, 0)) != 0)
+			goto err1;
+		break;
+	default:				/* Impossible. */
+		break;
+	}
+	ENV_LEAVE(env, ip);
+	return (0);
+
+err1:
+	__os_free(env, dbenv->passwd);
+	__os_free(env, db_cipher);
+	env->crypto_handle = NULL;
+err:
+	ENV_LEAVE(env, ip);
+	return (ret);
+#else
+	COMPQUIET(passwd, NULL);
+	COMPQUIET(flags, 0);
+
+	__db_errx(dbenv->env, DB_STR("1557",
+	    "library build did not include support for cryptography"));
+	return (DB_OPNOTSUP);
+#endif
+}
+#ifndef HAVE_BREW
+static
+#endif
+const FLAG_MAP EnvMap[] = {
+	{ DB_AUTO_COMMIT,	DB_ENV_AUTO_COMMIT },
+	{ DB_CDB_ALLDB,		DB_ENV_CDB_ALLDB },
+	{ DB_DATABASE_LOCKING,	DB_ENV_DATABASE_LOCKING },
+	{ DB_DIRECT_DB,		DB_ENV_DIRECT_DB },
+	{ DB_DSYNC_DB,		DB_ENV_DSYNC_DB },
+	{ DB_HOTBACKUP_IN_PROGRESS, DB_ENV_HOTBACKUP },
+	{ DB_MULTIVERSION,	DB_ENV_MULTIVERSION },
+	{ DB_NOFLUSH,		DB_ENV_NOFLUSH },
+	{ DB_NOLOCKING,		DB_ENV_NOLOCKING },
+	{ DB_NOMMAP,		DB_ENV_NOMMAP },
+	{ DB_NOPANIC,		DB_ENV_NOPANIC },
+	{ DB_OVERWRITE,		DB_ENV_OVERWRITE },
+	{ DB_REGION_INIT,	DB_ENV_REGION_INIT },
+	{ DB_TIME_NOTGRANTED,	DB_ENV_TIME_NOTGRANTED },
+	{ DB_TXN_NOSYNC,	DB_ENV_TXN_NOSYNC },
+	{ DB_TXN_NOWAIT,	DB_ENV_TXN_NOWAIT },
+	{ DB_TXN_SNAPSHOT,	DB_ENV_TXN_SNAPSHOT },
+	{ DB_TXN_WRITE_NOSYNC,	DB_ENV_TXN_WRITE_NOSYNC },
+	{ DB_YIELDCPU,		DB_ENV_YIELDCPU }
+};
+
+/*
+ * __env_map_flags -- map from external to internal flags.
+ * PUBLIC: void __env_map_flags __P((const FLAG_MAP *,
+ * PUBLIC:       u_int, u_int32_t *, u_int32_t *));
+ */
+void
+__env_map_flags(flagmap, mapsize, inflagsp, outflagsp)
+	const FLAG_MAP *flagmap;
+	u_int mapsize;
+	u_int32_t *inflagsp, *outflagsp;
+{
+
+	const FLAG_MAP *fmp;
+	u_int i;
+
+	for (i = 0, fmp = flagmap;
+	    i < mapsize / sizeof(flagmap[0]); ++i, ++fmp)
+		if (FLD_ISSET(*inflagsp, fmp->inflag)) {
+			FLD_SET(*outflagsp, fmp->outflag);
+			FLD_CLR(*inflagsp, fmp->inflag);
+			if (*inflagsp == 0)
+				break;
+		}
+}
+
+/*
+ * __env_fetch_flags -- map from internal to external flags.
+ * PUBLIC: void __env_fetch_flags __P((const FLAG_MAP *,
+ * PUBLIC:       u_int, u_int32_t *, u_int32_t *));
+ */
+void
+__env_fetch_flags(flagmap, mapsize, inflagsp, outflagsp)
+	const FLAG_MAP *flagmap;
+	u_int mapsize;
+	u_int32_t *inflagsp, *outflagsp;
+{
+	const FLAG_MAP *fmp;
+	u_int32_t i;
+
+	*outflagsp = 0;
+	for (i = 0, fmp = flagmap;
+	    i < mapsize / sizeof(flagmap[0]); ++i, ++fmp)
+		if (FLD_ISSET(*inflagsp, fmp->outflag))
+			FLD_SET(*outflagsp, fmp->inflag);
+}
+
+static int
+__env_get_flags(dbenv, flagsp)
+	DB_ENV *dbenv;
+	u_int32_t *flagsp;
+{
+	ENV *env;
+	DB_THREAD_INFO *ip;
+
+	__env_fetch_flags(EnvMap, sizeof(EnvMap), &dbenv->flags, flagsp);
+
+	env = dbenv->env;
+	/* Some flags are persisted in the regions. */
+	if (env->reginfo != NULL &&
+	    ((REGENV *)env->reginfo->primary)->panic != 0)
+		FLD_SET(*flagsp, DB_PANIC_ENVIRONMENT);
+
+	/* If the hotbackup counter is positive, set the flag indicating so. */
+	if (TXN_ON(env)) {
+		ENV_ENTER(env, ip);
+		TXN_SYSTEM_LOCK(env);
+		if (((DB_TXNREGION *)
+		    env->tx_handle->reginfo.primary)->n_hotbackup > 0)
+			FLD_SET(*flagsp, DB_HOTBACKUP_IN_PROGRESS);
+		TXN_SYSTEM_UNLOCK(env);
+		ENV_LEAVE(env, ip);
+	}
+
+	return (0);
+}
+
+/*
+ * __env_set_flags --
+ *	DB_ENV->set_flags.
+ *
+ * PUBLIC: int  __env_set_flags __P((DB_ENV *, u_int32_t, int));
+ */
+int
+__env_set_flags(dbenv, flags, on)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+	int on;
+{
+	ENV *env;
+	DB_THREAD_INFO *ip;
+	u_int32_t mapped_flags;
+	int mem_on, ret;
+
+	env = dbenv->env;
+
+#define	OK_FLAGS							\
+	(DB_AUTO_COMMIT | DB_CDB_ALLDB | DB_DATABASE_LOCKING |		\
+	    DB_DIRECT_DB | DB_DSYNC_DB |  DB_MULTIVERSION |		\
+	    DB_NOLOCKING | DB_NOMMAP | DB_NOPANIC | DB_OVERWRITE |	\
+	    DB_PANIC_ENVIRONMENT | DB_REGION_INIT |			\
+	    DB_TIME_NOTGRANTED | DB_TXN_NOSYNC | DB_TXN_NOWAIT |	\
+	    DB_TXN_SNAPSHOT | DB_TXN_WRITE_NOSYNC | DB_YIELDCPU |	\
+	    DB_HOTBACKUP_IN_PROGRESS | DB_NOFLUSH)
+
+	if (LF_ISSET(~OK_FLAGS))
+		return (__db_ferr(env, "DB_ENV->set_flags", 0));
+	if (on) {
+		if ((ret = __db_fcchk(env, "DB_ENV->set_flags",
+		    flags, DB_TXN_NOSYNC, DB_TXN_WRITE_NOSYNC)) != 0)
+			return (ret);
+		if (LF_ISSET(DB_DIRECT_DB) && __os_support_direct_io() == 0) {
+			__db_errx(env,
+	"DB_ENV->set_flags: direct I/O either not configured or not supported");
+			return (EINVAL);
+		}
+	}
+
+	if (LF_ISSET(DB_CDB_ALLDB))
+		ENV_ILLEGAL_AFTER_OPEN(env,
+		    "DB_ENV->set_flags: DB_CDB_ALLDB");
+	if (LF_ISSET(DB_PANIC_ENVIRONMENT)) {
+		ENV_ILLEGAL_BEFORE_OPEN(env,
+		    "DB_ENV->set_flags: DB_PANIC_ENVIRONMENT");
+		if (on) {
+			__db_errx(env, DB_STR("1558",
+			    "Environment panic set"));
+			(void)__env_panic(env, DB_RUNRECOVERY);
+		} else
+			__env_panic_set(env, 0);
+	}
+	if (LF_ISSET(DB_REGION_INIT))
+		ENV_ILLEGAL_AFTER_OPEN(env,
+		    "DB_ENV->set_flags: DB_REGION_INIT");
+
+	/*
+	 * DB_LOG_IN_MEMORY, DB_TXN_NOSYNC and DB_TXN_WRITE_NOSYNC are
+	 * mutually incompatible.  If we're setting one of them, clear all
+	 * current settings.  If the environment is open, check to see that
+	 * logging is not in memory.
+	 */
+	if (on && LF_ISSET(DB_TXN_NOSYNC | DB_TXN_WRITE_NOSYNC)) {
+		F_CLR(dbenv, DB_ENV_TXN_NOSYNC | DB_ENV_TXN_WRITE_NOSYNC);
+		if (!F_ISSET(env, ENV_OPEN_CALLED)) {
+		    if ((ret =
+			__log_set_config(dbenv, DB_LOG_IN_MEMORY, 0)) != 0)
+				return (ret);
+		} else if (LOGGING_ON(env)) {
+			if ((ret = __log_get_config(dbenv,
+			    DB_LOG_IN_MEMORY, &mem_on)) != 0)
+				return (ret);
+			if (mem_on == 1) {
+				__db_errx(env, DB_STR("1559",
+				    "DB_TXN_NOSYNC and DB_TXN_WRITE_NOSYNC"
+				    " may not be used with DB_LOG_IN_MEMORY"));
+				return (EINVAL);
+			}
+		}
+	}
+
+	/*
+	 * Settings of DB_HOTBACKUP_IN_PROGRESS are reference-counted
+	 * in REGENV.
+	 */
+	if (LF_ISSET(DB_HOTBACKUP_IN_PROGRESS)) {
+		/* You can't take a hot backup without transactions. */
+		ENV_REQUIRES_CONFIG(env, env->tx_handle,
+		    "DB_ENV->set_flags: DB_HOTBACKUP_IN_PROGRESS", DB_INIT_TXN);
+
+		COMPQUIET(ip, NULL);
+	}
+
+	mapped_flags = 0;
+	__env_map_flags(EnvMap, sizeof(EnvMap), &flags, &mapped_flags);
+	if (on)
+		F_SET(dbenv, mapped_flags);
+	else
+		F_CLR(dbenv, mapped_flags);
+
+	return (0);
+}
+
+/*
+ * __env_set_backup --
+ * PUBLIC: int __env_set_backup __P((ENV *, int));
+ */
+int
+__env_set_backup(env, on)
+	ENV *env;
+	int on;
+{
+	DB_TXNREGION *tenv;
+	int needs_checkpoint, ret;
+
+	tenv = (DB_TXNREGION *)env->tx_handle->reginfo.primary;
+	needs_checkpoint = 0;
+
+	TXN_SYSTEM_LOCK(env);
+	if (on) {
+		tenv->n_hotbackup++;
+		if (tenv->n_bulk_txn > 0)
+			needs_checkpoint = 1;
+	} else {
+		if (tenv->n_hotbackup == 0)
+			needs_checkpoint = -1; /* signal count error */
+		else
+			tenv->n_hotbackup--;
+	}
+	TXN_SYSTEM_UNLOCK(env);
+
+	if (needs_checkpoint == -1) {
+		__db_errx(env, DB_STR("1560",
+	    "Attempt to decrement hotbackup counter past zero"));
+		return (EINVAL);
+	}
+
+	if (needs_checkpoint && (ret = __txn_checkpoint(env, 0, 0, 0)))
+		return (ret);
+	return (0);
+}
+
+static int
+__env_get_data_dirs(dbenv, dirpp)
+	DB_ENV *dbenv;
+	const char ***dirpp;
+{
+	*dirpp = (const char **)dbenv->db_data_dir;
+	return (0);
+}
+
+/*
+ * __env_set_data_dir --
+ *	DB_ENV->set_data_dir.
+ *
+ * PUBLIC: int  __env_set_data_dir __P((DB_ENV *, const char *));
+ */
+int
+__env_set_data_dir(dbenv, dir)
+	DB_ENV *dbenv;
+	const char *dir;
+{
+	int ret;
+
+	if ((ret = __env_add_data_dir(dbenv, dir)) != 0)
+		return (ret);
+
+	if (dbenv->data_next == 1)
+		return (__env_set_create_dir(dbenv, dir));
+
+	return (0);
+}
+
+/*
+ * __env_add_data_dir --
+ *	DB_ENV->add_data_dir.
+ *
+ * PUBLIC: int  __env_add_data_dir __P((DB_ENV *, const char *));
+ */
+int
+__env_add_data_dir(dbenv, dir)
+	DB_ENV *dbenv;
+	const char *dir;
+{
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->add_data_dir");
+
+	/*
+	 * The array is NULL-terminated so it can be returned by get_data_dirs
+	 * without a length.
+	 */
+
+#define	DATA_INIT_CNT	20			/* Start with 20 data slots. */
+	if (dbenv->db_data_dir == NULL) {
+		if ((ret = __os_calloc(env, DATA_INIT_CNT,
+		    sizeof(char **), &dbenv->db_data_dir)) != 0)
+			return (ret);
+		dbenv->data_cnt = DATA_INIT_CNT;
+	} else if (dbenv->data_next == dbenv->data_cnt - 2) {
+		dbenv->data_cnt *= 2;
+		if ((ret = __os_realloc(env,
+		    (u_int)dbenv->data_cnt * sizeof(char **),
+		    &dbenv->db_data_dir)) != 0)
+			return (ret);
+	}
+
+	ret = __os_strdup(env,
+	    dir, &dbenv->db_data_dir[dbenv->data_next++]);
+	dbenv->db_data_dir[dbenv->data_next] = NULL;
+	return (ret);
+}
+
+/*
+ * __env_set_create_dir --
+ *	DB_ENV->set_create_dir.
+ * The list of directories cannot change after opening the env and setting
+ * a pointer must be atomic so we do not need to mutex here even if multiple
+ * threads are using the DB_ENV handle.
+ *
+ * PUBLIC: int  __env_set_create_dir __P((DB_ENV *, const char *));
+ */
+int
+__env_set_create_dir(dbenv, dir)
+	DB_ENV *dbenv;
+	const char *dir;
+{
+	ENV *env;
+	int i;
+
+	env = dbenv->env;
+
+	for (i = 0; i < dbenv->data_next; i++)
+		if (strcmp(dir, dbenv->db_data_dir[i]) == 0)
+			break;
+
+	if (i == dbenv->data_next) {
+		__db_errx(env, DB_STR_A("1561",
+		    "Directory %s not in environment list.", "%s"), dir);
+		return (EINVAL);
+	}
+
+	dbenv->db_create_dir = dbenv->db_data_dir[i];
+	return (0);
+}
+
+static int
+__env_get_create_dir(dbenv, dirp)
+	DB_ENV *dbenv;
+	const char **dirp;
+{
+	*dirp = dbenv->db_create_dir;
+	return (0);
+}
+
+static int
+__env_get_intermediate_dir_mode(dbenv, modep)
+	DB_ENV *dbenv;
+	const char **modep;
+{
+	*modep = dbenv->intermediate_dir_mode;
+	return (0);
+}
+
+/*
+ * __env_set_metadata_dir --
+ *	DB_ENV->set_metadata_dir.
+ *
+ * PUBLIC: int  __env_set_metadata_dir __P((DB_ENV *, const char *));
+ */
+int
+__env_set_metadata_dir(dbenv, dir)
+	DB_ENV *dbenv;
+	const char *dir;
+{
+	ENV *env;
+	int i, ret;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_metadata_dir");
+
+	/* If metadata_dir is not already on data_dir list, add it. */
+	for (i = 0; i < dbenv->data_next; i++)
+		if (strcmp(dir, dbenv->db_data_dir[i]) == 0)
+			break;
+	if (i == dbenv->data_next &&
+	    (ret = __env_add_data_dir(dbenv, dir)) != 0) {
+		__db_errx(env, DB_STR_A("1590",
+		    "Could not add %s to environment list.", "%s"), dir);
+		return (ret);
+	}
+
+	if (dbenv->db_md_dir != NULL)
+		__os_free(env, dbenv->db_md_dir);
+	return (__os_strdup(env, dir, &dbenv->db_md_dir));
+}
+
+static int
+__env_get_metadata_dir(dbenv, dirp)
+	DB_ENV *dbenv;
+	const char **dirp;
+{
+	*dirp = dbenv->db_md_dir;
+	return (0);
+}
+
+/*
+ * __env_set_data_len --
+ *	DB_ENV->set_data_len.
+ *
+ * PUBLIC: int  __env_set_data_len __P((DB_ENV *, u_int32_t));
+ */
+int
+__env_set_data_len(dbenv, data_len)
+	DB_ENV *dbenv;
+	u_int32_t data_len;
+{
+
+	dbenv->env->data_len = data_len;
+	return (0);
+}
+
+static int
+__env_get_data_len(dbenv, data_lenp)
+	DB_ENV *dbenv;
+	u_int32_t *data_lenp;
+{
+	*data_lenp = dbenv->env->data_len;
+	return (0);
+}
+
+/*
+ * __env_set_intermediate_dir_mode --
+ *	DB_ENV->set_intermediate_dir_mode.
+ *
+ * PUBLIC: int  __env_set_intermediate_dir_mode __P((DB_ENV *, const char *));
+ */
+int
+__env_set_intermediate_dir_mode(dbenv, mode)
+	DB_ENV *dbenv;
+	const char *mode;
+{
+	ENV *env;
+	u_int t;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_intermediate_dir_mode");
+
+#define	__SETMODE(offset, valid_ch, mask) {				\
+	if (mode[offset] == (valid_ch))					\
+		t |= (mask);						\
+	else if (mode[offset] != '-')					\
+		goto format_err;					\
+}
+	t = 0;
+	__SETMODE(0, 'r', S_IRUSR);
+	__SETMODE(1, 'w', S_IWUSR);
+	__SETMODE(2, 'x', S_IXUSR);
+	__SETMODE(3, 'r', S_IRGRP);
+	__SETMODE(4, 'w', S_IWGRP);
+	__SETMODE(5, 'x', S_IXGRP);
+	__SETMODE(6, 'r', S_IROTH);
+	__SETMODE(7, 'w', S_IWOTH);
+	__SETMODE(8, 'x', S_IXOTH);
+	if (mode[9] != '\0' || t == 0) {
+		/*
+		 * We disallow modes of 0 -- we use 0 to decide the application
+		 * never configured intermediate directory permissions, and we
+		 * shouldn't create intermediate directories.  Besides, setting
+		 * the permissions to 0 makes no sense.
+		 */
+format_err:	__db_errx(env,
+	    "DB_ENV->set_intermediate_dir_mode: illegal mode \"%s\"", mode);
+		return (EINVAL);
+	}
+
+	if (dbenv->intermediate_dir_mode != NULL)
+		__os_free(env, dbenv->intermediate_dir_mode);
+	if ((ret = __os_strdup(env, mode, &dbenv->intermediate_dir_mode)) != 0)
+		return (ret);
+
+	env->dir_mode = (int)t;
+	return (0);
+}
+
+/*
+ * __env_get_errcall --
+ *	{DB_ENV,DB}->get_errcall.
+ *
+ * PUBLIC: void __env_get_errcall __P((DB_ENV *,
+ * PUBLIC:		void (**)(const DB_ENV *, const char *, const char *)));
+ */
+void
+__env_get_errcall(dbenv, errcallp)
+	DB_ENV *dbenv;
+	void (**errcallp) __P((const DB_ENV *, const char *, const char *));
+{
+	*errcallp = dbenv->db_errcall;
+}
+
+/*
+ * __env_set_errcall --
+ *	{DB_ENV,DB}->set_errcall.
+ *
+ * PUBLIC: void __env_set_errcall __P((DB_ENV *,
+ * PUBLIC:		void (*)(const DB_ENV *, const char *, const char *)));
+ */
+void
+__env_set_errcall(dbenv, errcall)
+	DB_ENV *dbenv;
+	void (*errcall) __P((const DB_ENV *, const char *, const char *));
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	F_CLR(env, ENV_NO_OUTPUT_SET);
+	dbenv->db_errcall = errcall;
+}
+
+/*
+ * __env_get_errfile --
+ *	{DB_ENV,DB}->get_errfile.
+ *
+ * PUBLIC: void __env_get_errfile __P((DB_ENV *, FILE **));
+ */
+void
+__env_get_errfile(dbenv, errfilep)
+	DB_ENV *dbenv;
+	FILE **errfilep;
+{
+	*errfilep = dbenv->db_errfile;
+}
+
+/*
+ * __env_set_errfile --
+ *	{DB_ENV,DB}->set_errfile.
+ *
+ * PUBLIC: void __env_set_errfile __P((DB_ENV *, FILE *));
+ */
+void
+__env_set_errfile(dbenv, errfile)
+	DB_ENV *dbenv;
+	FILE *errfile;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	F_CLR(env, ENV_NO_OUTPUT_SET);
+	dbenv->db_errfile = errfile;
+}
+
+/*
+ * __env_get_errpfx --
+ *	{DB_ENV,DB}->get_errpfx.
+ *
+ * PUBLIC: void __env_get_errpfx __P((DB_ENV *, const char **));
+ */
+void
+__env_get_errpfx(dbenv, errpfxp)
+	DB_ENV *dbenv;
+	const char **errpfxp;
+{
+	*errpfxp = dbenv->db_errpfx;
+}
+
+/*
+ * __env_set_errpfx --
+ *	{DB_ENV,DB}->set_errpfx.
+ *
+ * PUBLIC: void __env_set_errpfx __P((DB_ENV *, const char *));
+ */
+void
+__env_set_errpfx(dbenv, errpfx)
+	DB_ENV *dbenv;
+	const char *errpfx;
+{
+	dbenv->db_errpfx = errpfx;
+}
+
+static int
+__env_get_feedback(dbenv, feedbackp)
+	DB_ENV *dbenv;
+	void (**feedbackp) __P((DB_ENV *, int, int));
+{
+	if (feedbackp != NULL)
+		*feedbackp = dbenv->db_feedback;
+	return (0);
+}
+
+static int
+__env_set_feedback(dbenv, feedback)
+	DB_ENV *dbenv;
+	void (*feedback) __P((DB_ENV *, int, int));
+{
+	dbenv->db_feedback = feedback;
+	return (0);
+}
+
+/*
+ * __env_get_thread_id_fn --
+ *	DB_ENV->get_thread_id_fn
+ */
+static int
+__env_get_thread_id_fn(dbenv, idp)
+	DB_ENV *dbenv;
+	void (**idp) __P((DB_ENV *, pid_t *, db_threadid_t *));
+{
+	if (idp != NULL)
+		*idp = dbenv->thread_id;
+	return (0);
+}
+
+/*
+ * __env_set_thread_id --
+ *	DB_ENV->set_thread_id
+ */
+static int
+__env_set_thread_id(dbenv, id)
+	DB_ENV *dbenv;
+	void (*id) __P((DB_ENV *, pid_t *, db_threadid_t *));
+{
+	dbenv->thread_id = id;
+	return (0);
+}
+
+/*
+ * __env_get_threadid_string_fn --
+ *	DB_ENV->get_threadid_string_fn
+ */
+static int
+__env_get_thread_id_string_fn(dbenv, thread_id_stringp)
+	DB_ENV *dbenv;
+	char *(**thread_id_stringp)
+	    __P((DB_ENV *, pid_t, db_threadid_t, char *));
+{
+	if (thread_id_stringp != NULL)
+		*thread_id_stringp = dbenv->thread_id_string;
+	return (0);
+}
+
+/*
+ * __env_set_threadid_string --
+ *	DB_ENV->set_threadid_string
+ */
+static int
+__env_set_thread_id_string(dbenv, thread_id_string)
+	DB_ENV *dbenv;
+	char *(*thread_id_string) __P((DB_ENV *, pid_t, db_threadid_t, char *));
+{
+	dbenv->thread_id_string = thread_id_string;
+	return (0);
+}
+
+/*
+ * __env_get_thread_count --
+ *	DB_ENV->get_thread_count
+ */
+static int
+__env_get_thread_count(dbenv, countp)
+	DB_ENV *dbenv;
+	u_int32_t *countp;
+{
+	*countp = dbenv->thr_max;
+	return (0);
+}
+
+/*
+ * __env_set_thread_count --
+ *	DB_ENV->set_thread_count
+ *
+ * PUBLIC: int  __env_set_thread_count __P((DB_ENV *, u_int32_t));
+ */
+int
+__env_set_thread_count(dbenv, count)
+	DB_ENV *dbenv;
+	u_int32_t count;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_thread_count");
+	dbenv->thr_max = count;
+
+	return (0);
+}
+
+/*
+ * __env_get_msgcall --
+ *	{DB_ENV,DB}->get_msgcall.
+ *
+ * PUBLIC: void __env_get_msgcall
+ * PUBLIC:     __P((DB_ENV *, void (**)(const DB_ENV *, const char *)));
+ */
+void
+__env_get_msgcall(dbenv, msgcallp)
+	DB_ENV *dbenv;
+	void (**msgcallp) __P((const DB_ENV *, const char *));
+{
+	if (msgcallp != NULL)
+		*msgcallp = dbenv->db_msgcall;
+}
+
+/*
+ * __env_set_msgcall --
+ *	{DB_ENV,DB}->set_msgcall.
+ *
+ * PUBLIC: void __env_set_msgcall
+ * PUBLIC:     __P((DB_ENV *, void (*)(const DB_ENV *, const char *)));
+ */
+void
+__env_set_msgcall(dbenv, msgcall)
+	DB_ENV *dbenv;
+	void (*msgcall) __P((const DB_ENV *, const char *));
+{
+	dbenv->db_msgcall = msgcall;
+}
+
+/*
+ * __env_get_msgfile --
+ *	{DB_ENV,DB}->get_msgfile.
+ *
+ * PUBLIC: void __env_get_msgfile __P((DB_ENV *, FILE **));
+ */
+void
+__env_get_msgfile(dbenv, msgfilep)
+	DB_ENV *dbenv;
+	FILE **msgfilep;
+{
+	*msgfilep = dbenv->db_msgfile;
+}
+
+/*
+ * __env_set_msgfile --
+ *	{DB_ENV,DB}->set_msgfile.
+ *
+ * PUBLIC: void __env_set_msgfile __P((DB_ENV *, FILE *));
+ */
+void
+__env_set_msgfile(dbenv, msgfile)
+	DB_ENV *dbenv;
+	FILE *msgfile;
+{
+	dbenv->db_msgfile = msgfile;
+}
+
+/*
+ * __env_set_paniccall --
+ *	{DB_ENV,DB}->set_paniccall.
+ *
+ * PUBLIC: int  __env_set_paniccall __P((DB_ENV *, void (*)(DB_ENV *, int)));
+ */
+int
+__env_set_paniccall(dbenv, paniccall)
+	DB_ENV *dbenv;
+	void (*paniccall) __P((DB_ENV *, int));
+{
+	dbenv->db_paniccall = paniccall;
+	return (0);
+}
+
+/*
+ * __env_set_event_notify --
+ *	DB_ENV->set_event_notify.
+ */
+static int
+__env_set_event_notify(dbenv, event_func)
+	DB_ENV *dbenv;
+	void (*event_func) __P((DB_ENV *, u_int32_t, void *));
+{
+	dbenv->db_event_func = event_func;
+	return (0);
+}
+
+static int
+__env_get_shm_key(dbenv, shm_keyp)
+	DB_ENV *dbenv;
+	long *shm_keyp;			/* !!!: really a key_t *. */
+{
+	*shm_keyp = dbenv->shm_key;
+	return (0);
+}
+
+/*
+ * __env_set_shm_key --
+ *	DB_ENV->set_shm_key.
+ *
+ * PUBLIC: int  __env_set_shm_key __P((DB_ENV *, long));
+ */
+int
+__env_set_shm_key(dbenv, shm_key)
+	DB_ENV *dbenv;
+	long shm_key;			/* !!!: really a key_t. */
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_shm_key");
+
+	dbenv->shm_key = shm_key;
+	return (0);
+}
+
+static int
+__env_get_tmp_dir(dbenv, dirp)
+	DB_ENV *dbenv;
+	const char **dirp;
+{
+	*dirp = dbenv->db_tmp_dir;
+	return (0);
+}
+
+/*
+ * __env_set_tmp_dir --
+ *	DB_ENV->set_tmp_dir.
+ *
+ * PUBLIC: int  __env_set_tmp_dir __P((DB_ENV *, const char *));
+ */
+int
+__env_set_tmp_dir(dbenv, dir)
+	DB_ENV *dbenv;
+	const char *dir;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	if (dbenv->db_tmp_dir != NULL)
+		__os_free(env, dbenv->db_tmp_dir);
+	return (__os_strdup(env, dir, &dbenv->db_tmp_dir));
+}
+
+static int
+__env_get_verbose(dbenv, which, onoffp)
+	DB_ENV *dbenv;
+	u_int32_t which;
+	int *onoffp;
+{
+	switch (which) {
+	case DB_VERB_BACKUP:
+	case DB_VERB_DEADLOCK:
+	case DB_VERB_FILEOPS:
+	case DB_VERB_FILEOPS_ALL:
+	case DB_VERB_RECOVERY:
+	case DB_VERB_REGISTER:
+	case DB_VERB_REPLICATION:
+	case DB_VERB_REP_ELECT:
+	case DB_VERB_REP_LEASE:
+	case DB_VERB_REP_MISC:
+	case DB_VERB_REP_MSGS:
+	case DB_VERB_REP_SYNC:
+	case DB_VERB_REP_SYSTEM:
+	case DB_VERB_REP_TEST:
+	case DB_VERB_REPMGR_CONNFAIL:
+	case DB_VERB_REPMGR_MISC:
+	case DB_VERB_WAITSFOR:
+		*onoffp = FLD_ISSET(dbenv->verbose, which) ? 1 : 0;
+		break;
+	default:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+/*
+ * __env_set_verbose --
+ *	DB_ENV->set_verbose.
+ *
+ * PUBLIC: int  __env_set_verbose __P((DB_ENV *, u_int32_t, int));
+ */
+int
+__env_set_verbose(dbenv, which, on)
+	DB_ENV *dbenv;
+	u_int32_t which;
+	int on;
+{
+	switch (which) {
+	case DB_VERB_BACKUP:
+	case DB_VERB_DEADLOCK:
+	case DB_VERB_FILEOPS:
+	case DB_VERB_FILEOPS_ALL:
+	case DB_VERB_RECOVERY:
+	case DB_VERB_REGISTER:
+	case DB_VERB_REPLICATION:
+	case DB_VERB_REP_ELECT:
+	case DB_VERB_REP_LEASE:
+	case DB_VERB_REP_MISC:
+	case DB_VERB_REP_MSGS:
+	case DB_VERB_REP_SYNC:
+	case DB_VERB_REP_SYSTEM:
+	case DB_VERB_REP_TEST:
+	case DB_VERB_REPMGR_CONNFAIL:
+	case DB_VERB_REPMGR_MISC:
+	case DB_VERB_WAITSFOR:
+		if (on)
+			FLD_SET(dbenv->verbose, which);
+		else
+			FLD_CLR(dbenv->verbose, which);
+		break;
+	default:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+/*
+ * __db_mi_env --
+ *	Method illegally called with public environment.
+ *
+ * PUBLIC: int __db_mi_env __P((ENV *, const char *));
+ */
+int
+__db_mi_env(env, name)
+	ENV *env;
+	const char *name;
+{
+	__db_errx(env, DB_STR_A("1564",
+	    "%s: method not permitted when environment specified", "%s"),
+	    name);
+	return (EINVAL);
+}
+
+/*
+ * __db_mi_open --
+ *	Method illegally called after open.
+ *
+ * PUBLIC: int __db_mi_open __P((ENV *, const char *, int));
+ */
+int
+__db_mi_open(env, name, after)
+	ENV *env;
+	const char *name;
+	int after;
+{
+	__db_errx(env, DB_STR_A("1565",
+	    "%s: method not permitted %s handle's open method", "%s %s"),
+	    name, after ? DB_STR_P("after") : DB_STR_P("before"));
+	return (EINVAL);
+}
+
+/*
+ * __env_not_config --
+ *	Method or function called without required configuration.
+ *
+ * PUBLIC: int __env_not_config __P((ENV *, char *, u_int32_t));
+ */
+int
+__env_not_config(env, i, flags)
+	ENV *env;
+	char *i;
+	u_int32_t flags;
+{
+	char *sub;
+	int is_sub;
+
+	is_sub = 1;
+
+	switch (flags) {
+	case DB_INIT_CDB:
+		sub = "DB_INIT_CDB";
+		is_sub = 0;
+		break;
+	case DB_INIT_LOCK:
+		sub = "locking";
+		break;
+	case DB_INIT_LOG:
+		sub = "logging";
+		break;
+	case DB_INIT_MPOOL:
+		sub = "memory pool";
+		break;
+	case DB_INIT_MUTEX:
+		sub = "mutex";
+		break;
+	case DB_INIT_REP:
+		sub = "replication";
+		break;
+	case DB_INIT_TXN:
+		sub = "transaction";
+		break;
+	default:
+		sub = "<unspecified>";
+		break;
+	}
+
+	if (is_sub) {
+		__db_errx(env, DB_STR_A("1566",
+    "%s interface requires an environment configured for the %s subsystem",
+	    "%s %s"), i, sub);
+	} else {
+		__db_errx(env, DB_STR_A("1587",
+	"%s interface requires an environment configured with %s",
+	    "%s %s"), i, sub);
+	}
+
+	return (EINVAL);
+}
+
+/*
+ * __env_get_timeout --
+ *	DB_ENV->get_timeout
+ */
+static int
+__env_get_timeout(dbenv, timeoutp, flags)
+	DB_ENV *dbenv;
+	db_timeout_t *timeoutp;
+	u_int32_t flags;
+{
+	int ret;
+
+	ret = 0;
+	if (flags == DB_SET_REG_TIMEOUT) {
+		*timeoutp = dbenv->envreg_timeout;
+	} else
+		ret = __lock_get_env_timeout(dbenv, timeoutp, flags);
+	return (ret);
+}
+
+/*
+ * __env_set_timeout --
+ *	DB_ENV->set_timeout
+ *
+ * PUBLIC: int __env_set_timeout __P((DB_ENV *, db_timeout_t, u_int32_t));
+ */
+int
+__env_set_timeout(dbenv, timeout, flags)
+	DB_ENV *dbenv;
+	db_timeout_t timeout;
+	u_int32_t flags;
+{
+	int ret;
+
+	ret = 0;
+	if (flags == DB_SET_REG_TIMEOUT)
+		dbenv->envreg_timeout = timeout;
+	else
+		ret = __lock_set_env_timeout(dbenv, timeout, flags);
+	return (ret);
+}
+
+/*
+ * __env_thread_id_string --
+ *	Convert a thread id to a string.
+ *
+ * PUBLIC: char *__env_thread_id_string
+ * PUBLIC:     __P((DB_ENV *, pid_t, db_threadid_t, char *));
+ */
+char *
+__env_thread_id_string(dbenv, pid, tid, buf)
+	DB_ENV *dbenv;
+	pid_t pid;
+	db_threadid_t tid;
+	char *buf;
+{
+#ifdef HAVE_SIMPLE_THREAD_TYPE
+#ifdef UINT64_FMT
+	char fmt[20];
+
+	snprintf(fmt, sizeof(fmt), "%s/%s", UINT64_FMT, UINT64_FMT);
+	snprintf(buf,
+	    DB_THREADID_STRLEN, fmt, (u_int64_t)pid, (u_int64_t)(uintptr_t)tid);
+#else
+	snprintf(buf, DB_THREADID_STRLEN, "%lu/%lu", (u_long)pid, (u_long)tid);
+#endif
+#else
+#ifdef UINT64_FMT
+	char fmt[20];
+
+	snprintf(fmt, sizeof(fmt), "%s/TID", UINT64_FMT);
+	snprintf(buf, DB_THREADID_STRLEN, fmt, (u_int64_t)pid);
+#else
+	snprintf(buf, DB_THREADID_STRLEN, "%lu/TID", (u_long)pid);
+#endif
+#endif
+	COMPQUIET(dbenv, NULL);
+	COMPQUIET(*(u_int8_t *)&tid, 0);
+
+	return (buf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/env/env_name.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,307 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+static int __db_fullpath
+    __P((ENV *, const char *, const char *, int, int, char **));
+
+#define	DB_ADDSTR(add) {						\
+	/*								\
+	 * The string might be NULL or zero-length, and the p[-1]	\
+	 * might indirect to before the beginning of our buffer.	\
+	 */								\
+	if ((add) != NULL && (add)[0] != '\0') {			\
+		/* If leading slash, start over. */			\
+		if (__os_abspath(add)) {				\
+			p = str;					\
+			slash = 0;					\
+		}							\
+		/* Append to the current string. */			\
+		len = strlen(add);					\
+		if (slash)						\
+			*p++ = PATH_SEPARATOR[0];			\
+		memcpy(p, add, len);					\
+		p += len;						\
+		slash = strchr(PATH_SEPARATOR, p[-1]) == NULL;		\
+	}								\
+}
+
+/*
+ * __db_fullpath --
+ *	Constructs a path name relative to the environment home, and optionally
+ *	checks whether the file or directory exist.
+ */
+static int
+__db_fullpath(env, dir, file, check_file, check_dir, namep)
+	ENV *env;
+	const char *dir;
+	const char *file;
+	int check_file;
+	int check_dir;
+	char **namep;
+{
+	size_t len;
+	const char *home;
+	char *p, *str;
+	int isdir, ret, slash;
+
+	/* All paths are relative to the environment home. */
+	home = (env == NULL) ? NULL : env->db_home;
+
+	len =
+	    (home == NULL ? 0 : strlen(home) + 1) +
+	    (dir == NULL ? 0 : strlen(dir) + 1) +
+	    (file == NULL ? 0 : strlen(file) + 1);
+
+	if ((ret = __os_malloc(env, len, &str)) != 0)
+		return (ret);
+
+	slash = 0;
+	p = str;
+	DB_ADDSTR(home);
+	DB_ADDSTR(dir);
+	*p = '\0';
+	if (check_dir && (__os_exists(env, str, &isdir) != 0 || !isdir)) {
+		__os_free(env, str);
+		return (ENOENT);
+	}
+	DB_ADDSTR(file);
+	*p = '\0';
+
+	/*
+	 * If we're opening a data file, see if it exists.  If not, keep
+	 * trying.
+	 */
+	if (check_file && __os_exists(env, str, NULL) != 0) {
+		__os_free(env, str);
+		return (ENOENT);
+	}
+
+	if (namep == NULL)
+		__os_free(env, str);
+	else
+		*namep = str;
+	return (0);
+}
+
+#define	DB_CHECKFILE(file, dir, check_file, check_dir, namep, ret_dir) do { \
+	ret = __db_fullpath(env, dir, file,				\
+			check_file, check_dir, namep);			\
+	if (ret == 0 && (ret_dir) != NULL)				\
+		*(ret_dir) = (dir);					\
+	if (ret != ENOENT)						\
+		return (ret);						\
+} while (0)
+
+/*
+ * __db_appname --
+ *	Given an optional DB environment, directory and file name and type
+ *	of call, build a path based on the ENV->open rules, and return
+ *	it in allocated space.  Dirp can be used to specify a data directory
+ *	to use.  If not and one is used then drip will contain a pointer
+ *	to the directory name.
+ *
+ * PUBLIC: int __db_appname __P((ENV *, APPNAME,
+ * PUBLIC:    const char *, const char **, char **));
+ */
+int
+__db_appname(env, appname, file, dirp, namep)
+	ENV *env;
+	APPNAME appname;
+	const char *file;
+	const char **dirp;
+	char **namep;
+{
+	DB_ENV *dbenv;
+	char **ddp;
+	const char *dir;
+	int ret;
+
+	dbenv = env->dbenv;
+	dir = NULL;
+
+	if (namep != NULL)
+		*namep = NULL;
+
+	/*
+	 * Absolute path names are never modified.  If the file is an absolute
+	 * path, we're done.
+	 */
+	if (file != NULL && __os_abspath(file))
+		return (__os_strdup(env, file, namep));
+
+	/*
+	 * DB_APP_NONE:
+	 *      DB_HOME/file
+	 * DB_APP_DATA:
+	 *      DB_HOME/DB_DATA_DIR/file
+	 * DB_APP_LOG:
+	 *      DB_HOME/DB_LOG_DIR/file
+	 * DB_APP_TMP:
+	 *      DB_HOME/DB_TMP_DIR/<create>
+	 */
+	switch (appname) {
+	case DB_APP_NONE:
+		break;
+	case DB_APP_RECOVER:
+	case DB_APP_DATA:
+		/*
+		 * First, step through the data_dir entries, if any, looking
+		 * for the file.
+		 */
+		if (dbenv != NULL && dbenv->db_data_dir != NULL)
+			for (ddp = dbenv->db_data_dir; *ddp != NULL; ddp++)
+				DB_CHECKFILE(file, *ddp, 1, 0, namep, dirp);
+
+		/* Second, look in the environment home directory. */
+		DB_CHECKFILE(file, NULL, 1, 0, namep, dirp);
+
+		/*
+		 * Otherwise, we're going to create.  Use the specified
+		 * directory unless we're in recovery and it doesn't exist.
+		 */
+		if (dirp != NULL && *dirp != NULL)
+			DB_CHECKFILE(file, *dirp, 0,
+			    appname == DB_APP_RECOVER, namep, dirp);
+
+		/* Finally, use the create directory, if set. */
+		if (dbenv != NULL && dbenv->db_create_dir != NULL)
+			dir = dbenv->db_create_dir;
+		break;
+	case DB_APP_LOG:
+		if (dbenv != NULL)
+			dir = dbenv->db_log_dir;
+		break;
+	case DB_APP_TMP:
+		if (dbenv != NULL)
+			dir = dbenv->db_tmp_dir;
+		break;
+	case DB_APP_META:
+		if (dbenv != NULL)
+			dir = dbenv->db_md_dir;
+		break;
+	}
+
+	/*
+	 * Construct the full path.  For temporary files, it is an error if the
+	 * directory does not exist: if it doesn't, checking whether millions
+	 * of temporary files exist inside it takes a *very* long time.
+	 */
+	DB_CHECKFILE(file, dir, 0, appname == DB_APP_TMP, namep, dirp);
+
+	return (ret);
+}
+
+/*
+ * __db_tmp_open --
+ *	Create a temporary file.
+ *
+ * PUBLIC: int __db_tmp_open __P((ENV *, u_int32_t, DB_FH **));
+ */
+int
+__db_tmp_open(env, oflags, fhpp)
+	ENV *env;
+	u_int32_t oflags;
+	DB_FH **fhpp;
+{
+	pid_t pid;
+	int filenum, i, ipid, ret;
+	char *path;
+	char *firstx, *trv;
+
+	DB_ASSERT(env, fhpp != NULL);
+	*fhpp = NULL;
+
+#define	DB_TRAIL	"BDBXXXXX"
+	if ((ret = __db_appname(env, DB_APP_TMP, DB_TRAIL, NULL, &path)) != 0)
+		goto done;
+
+	/* Replace the X's with the process ID (in decimal). */
+	__os_id(env->dbenv, &pid, NULL);
+	ipid = (int)pid;
+	if (ipid < 0)
+		ipid = -ipid;
+	for (trv = path + strlen(path); *--trv == 'X'; ipid /= 10)
+		*trv = '0' + (u_char)(ipid % 10);
+	firstx = trv + 1;
+
+	/* Loop, trying to open a file. */
+	for (filenum = 1;; filenum++) {
+		if ((ret = __os_open(env, path, 0,
+		    oflags | DB_OSO_CREATE | DB_OSO_EXCL | DB_OSO_TEMP,
+		    DB_MODE_600, fhpp)) == 0) {
+			ret = 0;
+			goto done;
+		}
+
+		/*
+		 * !!!:
+		 * If we don't get an EEXIST error, then there's something
+		 * seriously wrong.  Unfortunately, if the implementation
+		 * doesn't return EEXIST for O_CREAT and O_EXCL regardless
+		 * of other possible errors, we've lost.
+		 */
+		if (ret != EEXIST) {
+			__db_err(env, ret, DB_STR_A("1586",
+			    "temporary open: %s", "%s"), path);
+			goto done;
+		}
+
+		/*
+		 * Generate temporary file names in a backwards-compatible way.
+		 * If pid == 12345, the result is:
+		 *   <path>/DB12345 (tried above, the first time through).
+		 *   <path>/DBa2345 ...  <path>/DBz2345
+		 *   <path>/DBaa345 ...  <path>/DBaz345
+		 *   <path>/DBba345, and so on.
+		 *
+		 * XXX
+		 * This algorithm is O(n**2) -- that is, creating 100 temporary
+		 * files requires 5,000 opens, creating 1000 files requires
+		 * 500,000.  If applications open a lot of temporary files, we
+		 * could improve performance by switching to timestamp-based
+		 * file names.
+		 */
+		for (i = filenum, trv = firstx; i > 0; i = (i - 1) / 26)
+			if (*trv++ == '\0') {
+				ret = EINVAL;
+				goto done;
+			}
+
+		for (i = filenum; i > 0; i = (i - 1) / 26)
+			*--trv = 'a' + ((i - 1) % 26);
+	}
+done:
+	__os_free(env, path);
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/env/env_open.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1286 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/crypto.h"
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+static int __env_open_arg __P((DB_ENV *, u_int32_t));
+static int __file_handle_cleanup __P((ENV *));
+
+/*
+ * db_version --
+ *	Return legacy version information, including DB Major Version,
+ *	DB Minor Version, and DB Patch/Build numbers.
+ *
+ * EXTERN: char *db_version __P((int *, int *, int *));
+ */
+char *
+db_version(majverp, minverp, patchp)
+	int *majverp, *minverp, *patchp;
+{
+	if (majverp != NULL)
+		*majverp = DB_VERSION_MAJOR;
+	if (minverp != NULL)
+		*minverp = DB_VERSION_MINOR;
+	if (patchp != NULL)
+		*patchp = DB_VERSION_PATCH;
+	return ((char *)DB_VERSION_STRING);
+}
+
+/*
+ * db_full_version --
+ *	Return complete version information, including Oracle Family,
+ *	Oracle Release, DB Major Version, DB Minor Version, and DB
+ *	Patch/Build numbers.
+ *
+ * EXTERN: char *db_full_version __P((int *, int *, int *, int *, int *));
+ */
+char *
+db_full_version(familyp, releasep, majverp, minverp, patchp)
+	int *familyp, *releasep, *majverp, *minverp, *patchp;
+{
+	if (familyp != NULL)
+		*familyp = DB_VERSION_FAMILY;
+	if (releasep != NULL)
+		*releasep = DB_VERSION_RELEASE;
+	if (majverp != NULL)
+		*majverp = DB_VERSION_MAJOR;
+	if (minverp != NULL)
+		*minverp = DB_VERSION_MINOR;
+	if (patchp != NULL)
+		*patchp = DB_VERSION_PATCH;
+	return ((char *)DB_VERSION_FULL_STRING);
+}
+
+/*
+ * __env_open_pp --
+ *	DB_ENV->open pre/post processing.
+ *
+ * PUBLIC: int __env_open_pp __P((DB_ENV *, const char *, u_int32_t, int));
+ */
+int
+__env_open_pp(dbenv, db_home, flags, mode)
+	DB_ENV *dbenv;
+	const char *db_home;
+	u_int32_t flags;
+	int mode;
+{
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->open");
+
+#undef	OKFLAGS
+#define	OKFLAGS								\
+	(DB_CREATE | DB_FAILCHK | DB_FAILCHK_ISALIVE | DB_INIT_CDB |	\
+	DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_REP |	\
+	DB_INIT_TXN | DB_LOCKDOWN | DB_NO_CHECKPOINT | DB_PRIVATE |	\
+	DB_RECOVER | DB_RECOVER_FATAL | DB_REGISTER | DB_SYSTEM_MEM |	\
+	DB_THREAD | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)
+#undef	OKFLAGS_CDB
+#define	OKFLAGS_CDB							\
+	(DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL | DB_LOCKDOWN |	\
+	DB_PRIVATE | DB_SYSTEM_MEM | DB_THREAD |			\
+	DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)
+
+	if ((ret = __db_fchk(env, "DB_ENV->open", flags, OKFLAGS)) != 0)
+		return (ret);
+	if ((ret = __db_fcchk(
+	    env, "DB_ENV->open", flags, DB_INIT_CDB, ~OKFLAGS_CDB)) != 0)
+		return (ret);
+
+#if defined(HAVE_MIXED_SIZE_ADDRESSING) && (SIZEOF_CHAR_P == 8)
+	if (F_ISSET(env, DB_PRIVATE)) {
+		__db_errx(env, DB_STR("1589", "DB_PRIVATE is not "
+			    "supported by 64-bit applications in "
+			    "mixed-size-addressing mode"));
+			return (EINVAL);
+		}
+#endif
+
+	return (__env_open(dbenv, db_home, flags, mode));
+}
+
+/*
+ * __env_open --
+ *	DB_ENV->open.
+ *
+ * PUBLIC: int __env_open __P((DB_ENV *, const char *, u_int32_t, int));
+ */
+int
+__env_open(dbenv, db_home, flags, mode)
+	DB_ENV *dbenv;
+	const char *db_home;
+	u_int32_t flags;
+	int mode;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	u_int32_t orig_flags;
+	int register_recovery, ret, t_ret;
+
+	ip = NULL;
+	env = dbenv->env;
+	register_recovery = 0;
+
+	/* Initial configuration. */
+	if ((ret = __env_config(dbenv, db_home, &flags, mode)) != 0)
+		return (ret);
+
+	/*
+	 * Save the DB_ENV handle's configuration flags as set by user-called
+	 * configuration methods and the environment directory's DB_CONFIG
+	 * file.  If we use this DB_ENV structure to recover the existing
+	 * environment or to remove an environment we created after failure,
+	 * we'll restore the DB_ENV flags to these values.
+	 */
+	orig_flags = dbenv->flags;
+
+	/* Check open flags. */
+	if ((ret = __env_open_arg(dbenv, flags)) != 0)
+		return (ret);
+
+	/*
+	 * If we're going to register with the environment, that's the first
+	 * thing we do.
+	 */
+	if (LF_ISSET(DB_REGISTER)) {
+		/*
+		 * Through the SQL interface (btree.c) we set
+		 * DB_FAILCHK_ISALIVE.  When set, we want to run failchk
+		 * if a recovery is needed. Set up the infrastructure to run
+		 * it.   SQL applications have no way to specify the thread
+		 * count or an isalive, so force it here. Failchk is run
+		 * inside of register code.
+		 */
+		if (LF_ISSET(DB_FAILCHK_ISALIVE)) {
+			(void)__env_set_thread_count(dbenv, 50);
+			dbenv->is_alive = __envreg_isalive;
+		}
+
+		if ((ret =
+		    __envreg_register(env, &register_recovery, flags)) != 0)
+			goto err;
+		if (register_recovery) {
+			if (!LF_ISSET(DB_RECOVER)) {
+				__db_errx(env, DB_STR("1567",
+	    "The DB_RECOVER flag was not specified, and recovery is needed"));
+				ret = DB_RUNRECOVERY;
+				goto err;
+			}
+		} else
+			LF_CLR(DB_RECOVER);
+	}
+
+	/*
+	 * If we're doing recovery, destroy the environment so that we create
+	 * all the regions from scratch.  The major concern I have is if the
+	 * application stomps the environment with a rogue pointer.  We have
+	 * no way of detecting that, and we could be forced into a situation
+	 * where we start up and then crash, repeatedly.
+	 *
+	 * We do not check any flags like DB_PRIVATE before calling remove.
+	 * We don't care if the current environment was private or not, we
+	 * want to remove files left over for any reason, from any session.
+	 */
+retry:	if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL))
+#ifdef HAVE_REPLICATION
+		if ((ret = __rep_reset_init(env)) != 0 ||
+		    (ret = __env_remove_env(env)) != 0 ||
+#else
+		if ((ret = __env_remove_env(env)) != 0 ||
+#endif
+		    (ret = __env_refresh(dbenv, orig_flags, 0)) != 0)
+			goto err;
+
+	if ((ret = __env_attach_regions(dbenv, flags, orig_flags, 1)) != 0)
+		goto err;
+
+	/*
+	 * After attached to env, run failchk if not doing register
+	 * recovery.  Not providing this option with the DB_FAILCHK_ISALIVE
+	 * flag.
+	 */
+	if (LF_ISSET(DB_FAILCHK) && !register_recovery) {
+		ENV_ENTER(env, ip);
+		if ((ret = __env_failchk_int(dbenv)) != 0)
+			goto err;
+		ENV_LEAVE(env, ip);
+	}
+
+err:	if (ret != 0)
+		(void)__env_refresh(dbenv, orig_flags, 0);
+
+	if (register_recovery) {
+		/*
+		 * If recovery succeeded, release our exclusive lock, other
+		 * processes can now proceed.
+		 *
+		 * If recovery failed, unregister now and let another process
+		 * clean up.
+		 */
+		if (ret == 0 && (t_ret = __envreg_xunlock(env)) != 0)
+			ret = t_ret;
+		if (ret != 0)
+			(void)__envreg_unregister(env, 1);
+	}
+
+	/*
+	 * If the open is called with DB_REGISTER we can potentially skip
+	 * running recovery on a panicked environment. We can't check the panic
+	 * bit earlier since checking requires opening the environment.
+	 * Only retry if DB_RECOVER was specified - the register_recovery flag
+	 * indicates that.
+	 */
+	if (ret == DB_RUNRECOVERY && !register_recovery &&
+	    !LF_ISSET(DB_RECOVER) && LF_ISSET(DB_REGISTER)) {
+		LF_SET(DB_RECOVER);
+		goto retry;
+	}
+
+	return (ret);
+}
+
+/*
+ * __env_open_arg --
+ *	DB_ENV->open flags checking.
+ */
+static int
+__env_open_arg(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+	ret = 0;
+
+	if (LF_ISSET(DB_REGISTER)) {
+		if (!__os_support_db_register()) {
+			__db_errx(env, DB_STR("1568",
+	    "Berkeley DB library does not support DB_REGISTER on this system"));
+			return (EINVAL);
+		}
+		if ((ret = __db_fcchk(env, "DB_ENV->open", flags,
+		    DB_PRIVATE, DB_REGISTER | DB_SYSTEM_MEM)) != 0)
+			return (ret);
+		if (LF_ISSET(DB_CREATE) && !LF_ISSET(DB_INIT_TXN)) {
+			__db_errx(env, DB_STR("1569",
+			    "registration requires transaction support"));
+			return (EINVAL);
+		}
+	}
+	/*
+	 * Only check for flags compatible with DB_INIT_REP when creating
+	 * since otherwise it'll be ignored anyway.
+	 */
+	if (LF_ISSET(DB_INIT_REP) && LF_ISSET(DB_CREATE)) {
+		if (!__os_support_replication()) {
+			__db_errx(env, DB_STR("1570",
+	    "Berkeley DB library does not support replication on this system"));
+			return (EINVAL);
+		}
+		if (!LF_ISSET(DB_INIT_LOCK)) {
+			__db_errx(env, DB_STR("1571",
+			    "replication requires locking support"));
+			return (EINVAL);
+		}
+		if (!LF_ISSET(DB_INIT_TXN)) {
+			__db_errx(env, DB_STR("1572",
+			    "replication requires transaction support"));
+			return (EINVAL);
+		}
+	}
+	if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL)) {
+		if ((ret = __db_fcchk(env,
+		    "DB_ENV->open", flags, DB_RECOVER, DB_RECOVER_FATAL)) != 0)
+			return (ret);
+		if ((ret = __db_fcchk(env,
+		    "DB_ENV->open", flags, DB_REGISTER, DB_RECOVER_FATAL)) != 0)
+			return (ret);
+		if (!LF_ISSET(DB_CREATE)) {
+			__db_errx(env, DB_STR("1573",
+			    "recovery requires the create flag"));
+			return (EINVAL);
+		}
+		if (!LF_ISSET(DB_INIT_TXN)) {
+			__db_errx(env, DB_STR("1574",
+			    "recovery requires transaction support"));
+			return (EINVAL);
+		}
+	}
+	if (LF_ISSET(DB_FAILCHK)) {
+		if (!ALIVE_ON(env)) {
+			__db_errx(env, DB_STR("1575",
+		    "DB_FAILCHK requires DB_ENV->is_alive be configured"));
+			return (EINVAL);
+		}
+		if (dbenv->thr_max == 0) {
+			__db_errx(env, DB_STR("1576",
+	    "DB_FAILCHK requires DB_ENV->set_thread_count be configured"));
+			return (EINVAL);
+		}
+	}
+
+#ifdef HAVE_MUTEX_THREAD_ONLY
+	/*
+	 * Currently we support one kind of mutex that is intra-process only,
+	 * POSIX 1003.1 pthreads, because a variety of systems don't support
+	 * the full pthreads API, and our only alternative is test-and-set.
+	 */
+	if (!LF_ISSET(DB_PRIVATE)) {
+		__db_errx(env, DB_STR("1577",
+    "Berkeley DB library configured to support only private environments"));
+		return (EINVAL);
+	}
+#endif
+
+#ifdef HAVE_MUTEX_FCNTL
+	/*
+	 * !!!
+	 * We need a file descriptor for fcntl(2) locking.  We use the file
+	 * handle from the REGENV file for this purpose.
+	 *
+	 * Since we may be using shared memory regions, e.g., shmget(2), and
+	 * not a mapped-in regular file, the backing file may be only a few
+	 * bytes in length.  So, this depends on the ability to call fcntl to
+	 * lock file offsets much larger than the actual physical file.  I
+	 * think that's safe -- besides, very few systems actually need this
+	 * kind of support, SunOS is the only one still in wide use of which
+	 * I'm aware.
+	 *
+	 * The error case is if an application lacks spinlocks and wants to be
+	 * threaded.  That doesn't work because fcntl will lock the underlying
+	 * process, including all its threads.
+	 */
+	if (F_ISSET(env, ENV_THREAD)) {
+		__db_errx(env, DB_STR("1578",
+    "architecture lacks fast mutexes: applications cannot be threaded"));
+		return (EINVAL);
+	}
+#endif
+	return (ret);
+}
+
+/*
+ * __env_remove --
+ *	DB_ENV->remove.
+ *
+ * PUBLIC: int __env_remove __P((DB_ENV *, const char *, u_int32_t));
+ */
+int
+__env_remove(dbenv, db_home, flags)
+	DB_ENV *dbenv;
+	const char *db_home;
+	u_int32_t flags;
+{
+	ENV *env;
+	int ret, t_ret;
+
+	env = dbenv->env;
+
+#undef	OKFLAGS
+#define	OKFLAGS								\
+	(DB_FORCE | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)
+
+	/* Validate arguments. */
+	if ((ret = __db_fchk(env, "DB_ENV->remove", flags, OKFLAGS)) != 0)
+		return (ret);
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->remove");
+
+	if ((ret = __env_config(dbenv, db_home, &flags, 0)) != 0)
+		return (ret);
+
+	/*
+	 * Turn the environment off -- if the environment is corrupted, this
+	 * could fail.  Ignore any error if we're forcing the question.
+	 */
+	if ((ret = __env_turn_off(env, flags)) == 0 || LF_ISSET(DB_FORCE))
+		ret = __env_remove_env(env);
+
+	if ((t_ret = __env_close(dbenv, 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __env_config --
+ *	Argument-based initialization.
+ *
+ * PUBLIC: int __env_config __P((DB_ENV *, const char *, u_int32_t *, int));
+ */
+int
+__env_config(dbenv, db_home, flagsp, mode)
+	DB_ENV *dbenv;
+	const char *db_home;
+	u_int32_t *flagsp;
+	int mode;
+{
+	ENV *env;
+	int ret;
+	u_int32_t flags;
+	char *home, home_buf[DB_MAXPATHLEN];
+
+	env = dbenv->env;
+	flags = *flagsp;
+
+	/*
+	 * Set the database home.
+	 *
+	 * Use db_home by default, this allows utilities to reasonably
+	 * override the environment either explicitly or by using a -h
+	 * option.  Otherwise, use the environment if it's permitted
+	 * and initialized.
+	 */
+	home = (char *)db_home;
+	if (home == NULL && (LF_ISSET(DB_USE_ENVIRON) ||
+	    (LF_ISSET(DB_USE_ENVIRON_ROOT) && __os_isroot()))) {
+		home = home_buf;
+		if ((ret = __os_getenv(
+		    env, "DB_HOME", &home, sizeof(home_buf))) != 0)
+			return (ret);
+		/*
+		 * home set to NULL if __os_getenv failed to find DB_HOME.
+		 */
+	}
+	if (home != NULL) {
+		if (env->db_home != NULL)
+			__os_free(env, env->db_home);
+		if ((ret = __os_strdup(env, home, &env->db_home)) != 0)
+			return (ret);
+	}
+
+	/* Save a copy of the DB_ENV->open method flags. */
+	env->open_flags = flags;
+
+	/* Default permissions are read-write for both owner and group. */
+	env->db_mode = mode == 0 ? DB_MODE_660 : mode;
+
+	/* Read the DB_CONFIG file. */
+	if ((ret = __env_read_db_config(env)) != 0)
+		return (ret);
+
+	/*
+	 * Update the DB_ENV->open method flags. The copy of the flags might
+	 * have been changed during reading DB_CONFIG file.
+	 */
+	flags = env->open_flags;
+
+	/*
+	 * If no temporary directory path was specified in the config file,
+	 * choose one.
+	 */
+	if (dbenv->db_tmp_dir == NULL && (ret = __os_tmpdir(env, flags)) != 0)
+		return (ret);
+
+	*flagsp = flags;
+	return (0);
+}
+
+/*
+ * __env_close_pp --
+ *	DB_ENV->close pre/post processor.
+ *
+ * PUBLIC: int __env_close_pp __P((DB_ENV *, u_int32_t));
+ */
+int
+__env_close_pp(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int rep_check, ret, t_ret;
+	u_int32_t close_flags, flags_orig;
+
+	env = dbenv->env;
+	ret = 0;
+	close_flags = flags_orig = 0;
+
+	/*
+	 * Validate arguments, but as a DB_ENV handle destructor, we can't
+	 * fail.
+	 */
+	if (flags != 0 && flags != DB_FORCESYNC &&
+	    (t_ret = __db_ferr(env, "DB_ENV->close", 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+#define	DBENV_FORCESYNC		0x00000001
+#define	DBENV_CLOSE_REPCHECK	0x00000010
+	if (flags == DB_FORCESYNC)
+		close_flags |= DBENV_FORCESYNC;
+
+	/*
+	 * If the environment has panic'd, all we do is try and discard
+	 * the important resources.
+	 */
+	if (PANIC_ISSET(env)) {
+		/* clean up from registry file */
+		if (dbenv->registry != NULL) {
+			/*
+			 * Temporarily set no panic so we do not trigger the
+			 * LAST_PANIC_CHECK_BEFORE_IO check in __os_physwr
+			 * thus allowing the unregister to happen correctly.
+			 */
+			flags_orig = F_ISSET(dbenv, DB_ENV_NOPANIC);
+			F_SET(dbenv, DB_ENV_NOPANIC);
+			(void)__envreg_unregister(env, 0);
+			dbenv->registry = NULL;
+			if (!flags_orig)
+				F_CLR(dbenv, DB_ENV_NOPANIC);
+		}
+
+		/* Close all underlying threads and sockets. */
+		if (IS_ENV_REPLICATED(env))
+			(void)__repmgr_close(env);
+
+		/* Close all underlying file handles. */
+		(void)__file_handle_cleanup(env);
+
+		PANIC_CHECK(env);
+	}
+
+	ENV_ENTER(env, ip);
+
+	rep_check = IS_ENV_REPLICATED(env) ? 1 : 0;
+	if (rep_check) {
+#ifdef HAVE_REPLICATION_THREADS
+		/*
+		 * Shut down Replication Manager threads first of all.  This
+		 * must be done before __env_rep_enter to avoid a deadlock that
+		 * could occur if repmgr's background threads try to do a rep
+		 * operation that needs __rep_lockout.
+		 */
+		if ((t_ret = __repmgr_close(env)) != 0 && ret == 0)
+			ret = t_ret;
+#endif
+		if ((t_ret = __env_rep_enter(env, 0)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+
+	if (rep_check)
+		close_flags |= DBENV_CLOSE_REPCHECK;
+	if ((t_ret = __env_close(dbenv, close_flags)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Don't ENV_LEAVE as we have already detached from the region. */
+	return (ret);
+}
+
+/*
+ * __env_close --
+ *	DB_ENV->close.
+ *
+ * PUBLIC: int __env_close __P((DB_ENV *, u_int32_t));
+ */
+int
+__env_close(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	DB *dbp;
+	ENV *env;
+	int ret, rep_check, t_ret;
+	char **p;
+	u_int32_t close_flags;
+
+	env = dbenv->env;
+	ret = 0;
+	close_flags = LF_ISSET(DBENV_FORCESYNC) ? 0 : DB_NOSYNC;
+	rep_check = LF_ISSET(DBENV_CLOSE_REPCHECK);
+
+	/*
+	 * Check to see if we were in the middle of restoring transactions and
+	 * need to close the open files.
+	 */
+	if (TXN_ON(env) && (t_ret = __txn_preclose(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+#ifdef HAVE_REPLICATION
+	if ((t_ret = __rep_env_close(env)) != 0 && ret == 0)
+		ret = t_ret;
+#endif
+
+	/*
+	 * Close all databases opened in this environment after the rep region
+	 * is closed. Rep region's internal database is already closed now.
+	 */
+	while ((dbp = TAILQ_FIRST(&env->dblist)) != NULL) {
+		/*
+		 * Do not close the handle on a database partition, since it
+		 * will be closed when closing the handle on the main database.
+		 */
+		while (dbp != NULL && F_ISSET(dbp, DB_AM_PARTDB))
+			dbp = TAILQ_NEXT(dbp, dblistlinks);
+		DB_ASSERT(env, dbp != NULL);
+		/*
+		 * Note down and ignore the error code. Since we can't do
+		 * anything about the dbp handle anyway if the close
+		 * operation fails. But we want to return the error to the
+		 * caller. This is how this function takes care of various
+		 * close operation errors.
+		 */
+		if (dbp->alt_close != NULL)
+			t_ret = dbp->alt_close(dbp, close_flags);
+		else
+			t_ret = __db_close(dbp, NULL, close_flags);
+		if (t_ret != 0 && ret == 0)
+			ret = t_ret;
+	}
+
+	/*
+	 * Detach from the regions and undo the allocations done by
+	 * DB_ENV->open.
+	 */
+	if ((t_ret = __env_refresh(dbenv, 0, rep_check)) != 0 && ret == 0)
+		ret = t_ret;
+
+#ifdef HAVE_CRYPTO
+	/*
+	 * Crypto comes last, because higher level close functions need
+	 * cryptography.
+	 */
+	if ((t_ret = __crypto_env_close(env)) != 0 && ret == 0)
+		ret = t_ret;
+#endif
+
+	/* If we're registered, clean up. */
+	if (dbenv->registry != NULL) {
+		(void)__envreg_unregister(env, 0);
+		dbenv->registry = NULL;
+	}
+
+	/* Check we've closed all underlying file handles. */
+	if ((t_ret = __file_handle_cleanup(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/* Release any string-based configuration parameters we've copied. */
+	if (dbenv->db_log_dir != NULL)
+		__os_free(env, dbenv->db_log_dir);
+	dbenv->db_log_dir = NULL;
+	if (dbenv->db_tmp_dir != NULL)
+		__os_free(env, dbenv->db_tmp_dir);
+	dbenv->db_tmp_dir = NULL;
+	if (dbenv->db_md_dir != NULL)
+		__os_free(env, dbenv->db_md_dir);
+	dbenv->db_md_dir = NULL;
+	if (dbenv->db_data_dir != NULL) {
+		for (p = dbenv->db_data_dir; *p != NULL; ++p)
+			__os_free(env, *p);
+		__os_free(env, dbenv->db_data_dir);
+		dbenv->db_data_dir = NULL;
+		dbenv->data_next = 0;
+	}
+	if (dbenv->intermediate_dir_mode != NULL)
+		__os_free(env, dbenv->intermediate_dir_mode);
+	if (env->db_home != NULL) {
+		__os_free(env, env->db_home);
+		env->db_home = NULL;
+	}
+
+	if (env->backup_handle != NULL) {
+		__os_free(env, env->backup_handle);
+		env->backup_handle = NULL;
+	}
+
+	/* Discard the structure. */
+	__db_env_destroy(dbenv);
+
+	return (ret);
+}
+
+/*
+ * __env_refresh --
+ *	Refresh the DB_ENV structure.
+ * PUBLIC: int __env_refresh __P((DB_ENV *, u_int32_t, int));
+ */
+int
+__env_refresh(dbenv, orig_flags, rep_check)
+	DB_ENV *dbenv;
+	u_int32_t orig_flags;
+	int rep_check;
+{
+	DB *ldbp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret, t_ret;
+
+	env = dbenv->env;
+	ret = 0;
+
+	/*
+	 * Release resources allocated by DB_ENV->open, and return it to the
+	 * state it was in just before __env_open was called.  (This means
+	 * state set by pre-open configuration functions must be preserved.)
+	 *
+	 * Refresh subsystems, in the reverse order they were opened (txn
+	 * must be first, it may want to discard locks and flush the log).
+	 *
+	 * !!!
+	 * Note that these functions, like all of __env_refresh, only undo
+	 * the effects of __env_open.  Functions that undo work done by
+	 * db_env_create or by a configuration function should go in
+	 * __env_close.
+	 */
+	if (TXN_ON(env) &&
+	    (t_ret = __txn_env_refresh(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (LOGGING_ON(env) &&
+	    (t_ret = __log_env_refresh(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * Locking should come after logging, because closing log results
+	 * in files closing which may require locks being released.
+	 */
+	if (LOCKING_ON(env)) {
+		if (!F_ISSET(env, ENV_THREAD) &&
+		    env->env_lref != NULL && (t_ret =
+		    __lock_id_free(env, env->env_lref)) != 0 && ret == 0)
+			ret = t_ret;
+		env->env_lref = NULL;
+
+		if ((t_ret = __lock_env_refresh(env)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+
+	/* Discard the DB_ENV, ENV handle mutexes. */
+	if ((t_ret = __mutex_free(env, &dbenv->mtx_db_env)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __mutex_free(env, &env->mtx_env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * Discard DB list and its mutex.
+	 * Discard the MT mutex.
+	 *
+	 * !!!
+	 * This must be done after we close the log region, because we close
+	 * database handles and so acquire this mutex when we close log file
+	 * handles.
+	 */
+	if (env->db_ref != 0) {
+		__db_errx(env, DB_STR("1579",
+		    "Database handles still open at environment close"));
+		TAILQ_FOREACH(ldbp, &env->dblist, dblistlinks)
+			__db_errx(env, DB_STR_A("1580",
+			    "Open database handle: %s%s%s", "%s %s %s"),
+			    ldbp->fname == NULL ? "unnamed" : ldbp->fname,
+			    ldbp->dname == NULL ? "" : "/",
+			    ldbp->dname == NULL ? "" : ldbp->dname);
+		if (ret == 0)
+			ret = EINVAL;
+	}
+	TAILQ_INIT(&env->dblist);
+	if ((t_ret = __mutex_free(env, &env->mtx_dblist)) != 0 && ret == 0)
+		ret = t_ret;
+	if ((t_ret = __mutex_free(env, &env->mtx_mt)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (env->mt != NULL) {
+		__os_free(env, env->mt);
+		env->mt = NULL;
+	}
+
+	if (MPOOL_ON(env)) {
+		/*
+		 * If it's a private environment, flush the contents to disk.
+		 * Recovery would have put everything back together, but it's
+		 * faster and cleaner to flush instead.
+		 *
+		 * Ignore application max-write configuration, we're shutting
+		 * down.
+		 */
+		if (F_ISSET(env, ENV_PRIVATE) &&
+		    !F_ISSET(dbenv, DB_ENV_NOFLUSH) &&
+		    (t_ret = __memp_sync_int(env, NULL, 0,
+		    DB_SYNC_CACHE | DB_SYNC_SUPPRESS_WRITE, NULL, NULL)) != 0 &&
+		    ret == 0)
+			ret = t_ret;
+
+		if ((t_ret = __memp_env_refresh(env)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+
+	/*
+	 * If we're included in a shared replication handle count, this
+	 * is our last chance to decrement that count.
+	 *
+	 * !!!
+	 * We can't afford to do anything dangerous after we decrement the
+	 * handle count, of course, as replication may be proceeding with
+	 * client recovery.  However, since we're discarding the regions
+	 * as soon as we drop the handle count, there's little opportunity
+	 * to do harm.
+	 */
+	if (rep_check && (t_ret = __env_db_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * Refresh the replication region.
+	 *
+	 * Must come after we call __env_db_rep_exit above.
+	 */
+	if (REP_ON(env) && (t_ret = __rep_env_refresh(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+#ifdef HAVE_CRYPTO
+	/*
+	 * Crypto comes last, because higher level close functions need
+	 * cryptography.
+	 */
+	if (env->reginfo != NULL &&
+	    (t_ret = __crypto_env_refresh(env)) != 0 && ret == 0)
+		ret = t_ret;
+#endif
+
+	/*
+	 * Mark the thread as out of the env before we get rid of the handles
+	 * needed to do so.
+	 */
+	if (env->thr_hashtab != NULL &&
+	    (t_ret = __env_set_state(env, &ip, THREAD_OUT)) != 0 && ret == 0)
+		ret = t_ret;
+
+	/*
+	 * We are about to detach from the mutex region.  This is the last
+	 * chance we have to acquire/destroy a mutex -- acquire/destroy the
+	 * mutex and release our reference.
+	 *
+	 * !!!
+	 * There are two DbEnv methods that care about environment reference
+	 * counts: DbEnv.close and DbEnv.remove.  The DbEnv.close method is
+	 * not a problem because it only decrements the reference count and
+	 * no actual resources are discarded -- lots of threads of control
+	 * can call DbEnv.close at the same time, and regardless of racing
+	 * on the reference count mutex, we wouldn't have a problem.  Since
+	 * the DbEnv.remove method actually discards resources, we can have
+	 * a problem.
+	 *
+	 * If we decrement the reference count to 0 here, go to sleep, and
+	 * the DbEnv.remove method is called, by the time we run again, the
+	 * underlying shared regions could have been removed.  That's fine,
+	 * except we might actually need the regions to resolve outstanding
+	 * operations in the various subsystems, and if we don't have hard
+	 * OS references to the regions, we could get screwed.  Of course,
+	 * we should have hard OS references to everything we need, but just
+	 * in case, we put off decrementing the reference count as long as
+	 * possible.
+	 */
+	if ((t_ret = __env_ref_decrement(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+#ifdef HAVE_MUTEX_SUPPORT
+	if (MUTEX_ON(env) &&
+	    (t_ret = __mutex_env_refresh(env)) != 0 && ret == 0)
+		ret = t_ret;
+#endif
+	/* Free memory for thread tracking. */
+	if (env->reginfo != NULL) {
+		if (F_ISSET(env, ENV_PRIVATE)) {
+			__env_thread_destroy(env);
+			t_ret = __env_detach(env, 1);
+		} else
+			t_ret = __env_detach(env, 0);
+
+		if (t_ret != 0 && ret == 0)
+			ret = t_ret;
+
+		/*
+		 * !!!
+		 * Don't free env->reginfo or set the reference to NULL,
+		 * that was done by __env_detach().
+		 */
+	}
+
+	if (env->recover_dtab.int_dispatch != NULL) {
+		__os_free(env, env->recover_dtab.int_dispatch);
+		env->recover_dtab.int_size = 0;
+		env->recover_dtab.int_dispatch = NULL;
+	}
+	if (env->recover_dtab.ext_dispatch != NULL) {
+		__os_free(env, env->recover_dtab.ext_dispatch);
+		env->recover_dtab.ext_size = 0;
+		env->recover_dtab.ext_dispatch = NULL;
+	}
+
+	dbenv->flags = orig_flags;
+
+	return (ret);
+}
+
+/*
+ * __file_handle_cleanup --
+ *	Close any underlying open file handles so we don't leak system
+ *	resources.
+ */
+static int
+__file_handle_cleanup(env)
+	ENV *env;
+{
+	DB_FH *fhp;
+
+	if (TAILQ_FIRST(&env->fdlist) == NULL)
+		return (0);
+
+	__db_errx(env, DB_STR("1581",
+	    "File handles still open at environment close"));
+	while ((fhp = TAILQ_FIRST(&env->fdlist)) != NULL) {
+		__db_errx(env, DB_STR_A("1582", "Open file handle: %s", "%s"),
+		    fhp->name);
+		(void)__os_closehandle(env, fhp);
+	}
+	return (EINVAL);
+}
+
+/*
+ * __env_get_open_flags
+ *	DbEnv.get_open_flags method.
+ *
+ * PUBLIC: int __env_get_open_flags __P((DB_ENV *, u_int32_t *));
+ */
+int
+__env_get_open_flags(dbenv, flagsp)
+	DB_ENV *dbenv;
+	u_int32_t *flagsp;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->get_open_flags");
+
+	*flagsp = env->open_flags;
+	return (0);
+}
+/*
+ * __env_attach_regions --
+ *	Perform attaches to env and required regions (subsystems)
+ *
+ * PUBLIC: int __env_attach_regions __P((DB_ENV *,  u_int32_t, u_int32_t, int));
+ */
+int
+__env_attach_regions(dbenv, flags, orig_flags, retry_ok)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+	u_int32_t orig_flags;
+	int retry_ok;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	REGINFO *infop;
+	u_int32_t init_flags;
+	int create_ok, rep_check, ret;
+
+	ip = NULL;
+	env = dbenv->env;
+	rep_check = 0;
+
+	/* Convert the DB_ENV->open flags to internal flags. */
+	create_ok = LF_ISSET(DB_CREATE) ? 1 : 0;
+	if (LF_ISSET(DB_LOCKDOWN))
+		F_SET(env, ENV_LOCKDOWN);
+	if (LF_ISSET(DB_PRIVATE))
+		F_SET(env, ENV_PRIVATE);
+	if (LF_ISSET(DB_RECOVER_FATAL))
+		F_SET(env, ENV_RECOVER_FATAL);
+	if (LF_ISSET(DB_SYSTEM_MEM))
+		F_SET(env, ENV_SYSTEM_MEM);
+	if (LF_ISSET(DB_THREAD))
+		F_SET(env, ENV_THREAD);
+
+	/*
+	 * Create/join the environment.  We pass in the flags of interest to
+	 * a thread subsequently joining an environment we create.  If we're
+	 * not the ones to create the environment, our flags will be updated
+	 * to match the existing environment.
+	 */
+	init_flags = 0;
+	if (LF_ISSET(DB_INIT_CDB))
+		FLD_SET(init_flags, DB_INITENV_CDB);
+	if (F_ISSET(dbenv, DB_ENV_CDB_ALLDB))
+		FLD_SET(init_flags, DB_INITENV_CDB_ALLDB);
+	if (LF_ISSET(DB_INIT_LOCK))
+		FLD_SET(init_flags, DB_INITENV_LOCK);
+	if (LF_ISSET(DB_INIT_LOG))
+		FLD_SET(init_flags, DB_INITENV_LOG);
+	if (LF_ISSET(DB_INIT_MPOOL))
+		FLD_SET(init_flags, DB_INITENV_MPOOL);
+	if (LF_ISSET(DB_INIT_REP))
+		FLD_SET(init_flags, DB_INITENV_REP);
+	if (LF_ISSET(DB_INIT_TXN))
+		FLD_SET(init_flags, DB_INITENV_TXN);
+	if ((ret = __env_attach(env, &init_flags, create_ok, retry_ok)) != 0)
+		goto err;
+
+	/*
+	 * __env_attach will return the saved init_flags field, which contains
+	 * the DB_INIT_* flags used when the environment was created.
+	 *
+	 * We may be joining an environment -- reset our flags to match the
+	 * ones in the environment.
+	 */
+	if (FLD_ISSET(init_flags, DB_INITENV_CDB))
+		LF_SET(DB_INIT_CDB);
+	if (FLD_ISSET(init_flags, DB_INITENV_LOCK))
+		LF_SET(DB_INIT_LOCK);
+	if (FLD_ISSET(init_flags, DB_INITENV_LOG))
+		LF_SET(DB_INIT_LOG);
+	if (FLD_ISSET(init_flags, DB_INITENV_MPOOL))
+		LF_SET(DB_INIT_MPOOL);
+	if (FLD_ISSET(init_flags, DB_INITENV_REP))
+		LF_SET(DB_INIT_REP);
+	if (FLD_ISSET(init_flags, DB_INITENV_TXN))
+		LF_SET(DB_INIT_TXN);
+	if (FLD_ISSET(init_flags, DB_INITENV_CDB_ALLDB) &&
+	    (ret = __env_set_flags(dbenv, DB_CDB_ALLDB, 1)) != 0)
+		goto err;
+
+	/* Initialize for CDB product. */
+	if (LF_ISSET(DB_INIT_CDB)) {
+		LF_SET(DB_INIT_LOCK);
+		F_SET(env, ENV_CDB);
+	}
+
+	/*
+	 * Update the flags to match the database environment.  The application
+	 * may have specified flags of 0 to join the environment, and this line
+	 * replaces that value with the flags corresponding to the existing,
+	 * underlying set of subsystems.  This means the DbEnv.get_open_flags
+	 * method returns the flags to open the existing environment instead of
+	 * the specific flags passed to the DbEnv.open method.
+	 */
+	env->open_flags = flags;
+
+	/*
+	 * The DB_ENV structure has now been initialized.  Turn off further
+	 * use of the DB_ENV structure and most initialization methods, we're
+	 * about to act on the values we currently have.
+	 */
+	F_SET(env, ENV_OPEN_CALLED);
+
+	infop = env->reginfo;
+
+#ifdef HAVE_MUTEX_SUPPORT
+	/*
+	 * Initialize the mutex regions first before ENV_ENTER().
+	 * Mutexes need to be 'on' when attaching to an existing env
+	 * in order to safely allocate the thread tracking info.
+	 */
+	if ((ret = __mutex_open(env, create_ok)) != 0)
+		goto err;
+	/* The MUTEX_REQUIRED() in __env_alloc() expects this to be set. */
+	infop->mtx_alloc = ((REGENV *)infop->primary)->mtx_regenv;
+#endif
+	/*
+	 * Initialize thread tracking and enter the API.
+	 */
+	if ((ret =
+	    __env_thread_init(env, F_ISSET(infop, REGION_CREATE) ? 1 : 0)) != 0)
+		goto err;
+
+	ENV_ENTER(env, ip);
+
+	/*
+	 * Initialize the subsystems.
+	 */
+	/*
+	 * We can now acquire/create mutexes: increment the region's reference
+	 * count.
+	 */
+	if ((ret = __env_ref_increment(env)) != 0)
+		goto err;
+
+	/*
+	 * Initialize the handle mutexes.
+	 */
+	if ((ret = __mutex_alloc(env,
+	    MTX_ENV_HANDLE, DB_MUTEX_PROCESS_ONLY, &dbenv->mtx_db_env)) != 0 ||
+	    (ret = __mutex_alloc(env,
+	    MTX_ENV_HANDLE, DB_MUTEX_PROCESS_ONLY, &env->mtx_env)) != 0)
+		goto err;
+
+	/*
+	 * Initialize the replication area next, so that we can lock out this
+	 * call if we're currently running recovery for replication.
+	 */
+	if (LF_ISSET(DB_INIT_REP) && (ret = __rep_open(env)) != 0)
+		goto err;
+
+	rep_check = IS_ENV_REPLICATED(env) ? 1 : 0;
+	if (rep_check && (ret = __env_rep_enter(env, 0)) != 0)
+		goto err;
+
+	if (LF_ISSET(DB_INIT_MPOOL)) {
+		if ((ret = __memp_open(env, create_ok)) != 0)
+			goto err;
+
+		/*
+		 * BDB does do cache I/O during recovery and when starting up
+		 * replication.  If creating a new environment, then suppress
+		 * any application max-write configuration.
+		 */
+		if (create_ok)
+			(void)__memp_set_config(
+			    dbenv, DB_MEMP_SUPPRESS_WRITE, 1);
+
+		/*
+		 * Initialize the DB list and its mutex.  If the mpool is
+		 * not initialized, we can't ever open a DB handle, which
+		 * is why this code lives here.
+		 */
+		TAILQ_INIT(&env->dblist);
+		if ((ret = __mutex_alloc(env, MTX_ENV_DBLIST,
+		    DB_MUTEX_PROCESS_ONLY, &env->mtx_dblist)) != 0)
+			goto err;
+
+		/* Register DB's pgin/pgout functions.  */
+		if ((ret = __memp_register(
+		    env, DB_FTYPE_SET, __db_pgin, __db_pgout)) != 0)
+			goto err;
+	}
+
+	/*
+	 * Initialize the ciphering area prior to any running of recovery so
+	 * that we can initialize the keys, etc. before recovery, including
+	 * the MT mutex.
+	 *
+	 * !!!
+	 * This must be after the mpool init, but before the log initialization
+	 * because log_open may attempt to run log_recover during its open.
+	 */
+	if (LF_ISSET(DB_INIT_MPOOL | DB_INIT_LOG | DB_INIT_TXN) &&
+	    (ret = __crypto_region_init(env)) != 0)
+		goto err;
+	if ((ret = __mutex_alloc(
+	    env, MTX_TWISTER, DB_MUTEX_PROCESS_ONLY, &env->mtx_mt)) != 0)
+		goto err;
+
+	/*
+	 * Transactions imply logging but do not imply locking.  While almost
+	 * all applications want both locking and logging, it would not be
+	 * unreasonable for a single threaded process to want transactions for
+	 * atomicity guarantees, but not necessarily need concurrency.
+	 */
+	if (LF_ISSET(DB_INIT_LOG | DB_INIT_TXN))
+		if ((ret = __log_open(env)) != 0)
+			goto err;
+	if (LF_ISSET(DB_INIT_LOCK))
+		if ((ret = __lock_open(env)) != 0)
+			goto err;
+
+	if (LF_ISSET(DB_INIT_TXN)) {
+		if ((ret = __txn_open(env)) != 0)
+			goto err;
+
+		/*
+		 * If the application is running with transactions, initialize
+		 * the function tables.
+		 */
+		if ((ret = __env_init_rec(env,
+		    ((LOG *)env->lg_handle->reginfo.primary)->persist.version))
+		    != 0)
+			goto err;
+	}
+
+#ifdef HAVE_TRANSACTIONS
+	/* Perform recovery for any previous run. */
+	if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) &&
+	    (ret = __db_apprec(env, ip, NULL, NULL, 1,
+	    LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL | DB_NO_CHECKPOINT))) != 0)
+		goto err;
+
+	/*
+	 * If we've created the regions, are running with transactions, and did
+	 * not just run recovery, we need to log the fact that the transaction
+	 * IDs got reset.
+	 *
+	 * If we ran recovery, there may be prepared-but-not-yet-committed
+	 * transactions that need to be resolved.  Recovery resets the minimum
+	 * transaction ID and logs the reset if that's appropriate, so we
+	 * don't need to do anything here in the recover case.
+	 */
+	if (TXN_ON(env) &&
+	    !FLD_ISSET(dbenv->lg_flags, DB_LOG_IN_MEMORY) &&
+	    F_ISSET(infop, REGION_CREATE) &&
+	    !LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) &&
+	    (ret = __txn_reset(env)) != 0)
+		goto err;
+#endif
+
+	/* The database environment is ready for business. */
+	if ((ret = __env_turn_on(env)) != 0)
+		goto err;
+
+	if (rep_check)
+		ret = __env_db_rep_exit(env);
+
+	/* Turn any application-specific max-write configuration back on. */
+	if (LF_ISSET(DB_INIT_MPOOL))
+		(void)__memp_set_config(dbenv, DB_MEMP_SUPPRESS_WRITE, 0);
+
+err:	if (ret == 0)
+		ENV_LEAVE(env, ip);
+	else {
+		/*
+		 * If we fail after creating regions, panic and remove them.
+		 *
+		 * !!!
+		 * No need to call __env_db_rep_exit, that work is done by the
+		 * calls to __env_refresh.
+		 */
+		infop = env->reginfo;
+		if (infop != NULL && F_ISSET(infop, REGION_CREATE)) {
+			ret = __env_panic(env, ret);
+
+			/* Refresh the DB_ENV so can use it to call remove. */
+			(void)__env_refresh(dbenv, orig_flags, rep_check);
+			(void)__env_remove_env(env);
+			(void)__env_refresh(dbenv, orig_flags, 0);
+		} else
+			(void)__env_refresh(dbenv, orig_flags, rep_check);
+		/* clear the fact that the region had been opened */
+		F_CLR(env, ENV_OPEN_CALLED);
+	}
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/env/env_region.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1519 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/mp.h"
+#include "dbinc/lock.h"
+#include "dbinc/log.h"
+#include "dbinc/txn.h"
+
+static int  __env_des_get __P((ENV *, REGINFO *, REGINFO *, REGION **));
+static int  __env_faultmem __P((ENV *, void *, size_t, int));
+static int  __env_sys_attach __P((ENV *, REGINFO *, REGION *));
+static int  __env_sys_detach __P((ENV *, REGINFO *, int));
+static void __env_des_destroy __P((ENV *, REGION *));
+static void __env_remove_file __P((ENV *));
+
+/*
+ * __env_attach
+ *	Join/create the environment
+ *
+ * PUBLIC: int __env_attach __P((ENV *, u_int32_t *, int, int));
+ */
+int
+__env_attach(env, init_flagsp, create_ok, retry_ok)
+	ENV *env;
+	u_int32_t *init_flagsp;
+	int create_ok, retry_ok;
+{
+	DB_ENV *dbenv;
+	REGENV rbuf, *renv;
+	REGENV_REF ref;
+	REGINFO *infop;
+	REGION *rp, tregion;
+	size_t max, nrw, size;
+	long segid;
+	u_int32_t bytes, i, mbytes, nregions, signature;
+	u_int retry_cnt;
+	int majver, minver, patchver, ret;
+	char buf[sizeof(DB_REGION_FMT) + 20];
+
+	/* Initialization */
+	dbenv = env->dbenv;
+	retry_cnt = 0;
+	signature = __env_struct_sig();
+
+	/* Repeated initialization. */
+loop:	renv = NULL;
+	rp = NULL;
+
+	/* Set up the ENV's REG_INFO structure. */
+	if ((ret = __os_calloc(env, 1, sizeof(REGINFO), &infop)) != 0)
+		return (ret);
+	infop->env = env;
+	infop->type = REGION_TYPE_ENV;
+	infop->id = REGION_ID_ENV;
+	infop->flags = REGION_JOIN_OK;
+	if (create_ok)
+		F_SET(infop, REGION_CREATE_OK);
+
+	/* Build the region name. */
+	if (F_ISSET(env, ENV_PRIVATE))
+		ret = __os_strdup(env, "process-private", &infop->name);
+	else {
+		(void)snprintf(buf, sizeof(buf), "%s", DB_REGION_ENV);
+		ret = __db_appname(env, DB_APP_NONE, buf, NULL, &infop->name);
+	}
+	if (ret != 0)
+		goto err;
+
+	/*
+	 * We have to single-thread the creation of the REGENV region.  Once
+	 * it exists, we can serialize using region mutexes, but until then
+	 * we have to be the only player in the game.
+	 *
+	 * If this is a private environment, we are only called once and there
+	 * are no possible race conditions.
+	 *
+	 * If this is a public environment, we use the filesystem to ensure
+	 * the creation of the environment file is single-threaded.
+	 *
+	 * If the application has specified their own mapping functions, try
+	 * and create the region.  The application will have to let us know if
+	 * it's actually a creation or not, and we'll have to fall-back to a
+	 * join if it's not a create.
+	 */
+	if (F_ISSET(env, ENV_PRIVATE) || DB_GLOBAL(j_region_map) != NULL)
+		goto creation;
+
+	/*
+	 * Try to create the file, if we have the authority.  We have to ensure
+	 * that multiple threads/processes attempting to simultaneously create
+	 * the file are properly ordered.  Open using the O_CREAT and O_EXCL
+	 * flags so that multiple attempts to create the region will return
+	 * failure in all but one.  POSIX 1003.1 requires that EEXIST be the
+	 * errno return value -- I sure hope they're right.
+	 */
+	if (create_ok) {
+		if ((ret = __os_open(env, infop->name, 0,
+		    DB_OSO_CREATE | DB_OSO_EXCL | DB_OSO_REGION,
+		    env->db_mode, &env->lockfhp)) == 0)
+			goto creation;
+		if (ret != EEXIST) {
+			__db_err(env, ret, "%s", infop->name);
+			goto err;
+		}
+	}
+
+	/* The region must exist, it's not okay to recreate it. */
+	F_CLR(infop, REGION_CREATE_OK);
+
+	/*
+	 * If we couldn't create the file, try and open it.  (If that fails,
+	 * we're done.)
+	 */
+	if ((ret = __os_open(
+	    env, infop->name, 0, DB_OSO_REGION, 0, &env->lockfhp)) != 0)
+		goto err;
+
+	/*
+	 * !!!
+	 * The region may be in system memory not backed by the filesystem
+	 * (more specifically, not backed by this file), and we're joining
+	 * it.  In that case, the process that created it will have written
+	 * out a REGENV_REF structure as its only contents.  We read that
+	 * structure before we do anything further, e.g., we can't just map
+	 * that file in and then figure out what's going on.
+	 *
+	 * All of this noise is because some systems don't have a coherent VM
+	 * and buffer cache, and what's worse, when you mix operations on the
+	 * VM and buffer cache, half the time you hang the system.
+	 *
+	 * If the file is the size of an REGENV_REF structure, then we know
+	 * the real region is in some other memory.  (The only way you get a
+	 * file that size is to deliberately write it, as it's smaller than
+	 * any possible disk sector created by writing a file or mapping the
+	 * file into memory.)  In which case, retrieve the structure from the
+	 * file and use it to acquire the referenced memory.
+	 *
+	 * If the structure is larger than a REGENV_REF structure, then this
+	 * file is backing the shared memory region, and we just map it into
+	 * memory.
+	 *
+	 * And yes, this makes me want to take somebody and kill them.  (I
+	 * digress -- but you have no freakin' idea.  This is unbelievably
+	 * stupid and gross, and I've probably spent six months of my life,
+	 * now, trying to make different versions of it work.)
+	 */
+	if ((ret = __os_ioinfo(env, infop->name,
+	    env->lockfhp, &mbytes, &bytes, NULL)) != 0) {
+		__db_err(env, ret, "%s", infop->name);
+		goto err;
+	}
+
+	/*
+	 * !!!
+	 * A size_t is OK -- regions get mapped into memory, and so can't
+	 * be larger than a size_t.
+	 */
+	size = mbytes * MEGABYTE + bytes;
+
+	/*
+	 * If the size is less than the size of a REGENV_REF structure, the
+	 * region (or, possibly, the REGENV_REF structure) has not yet been
+	 * completely written.  Shouldn't be possible, but there's no reason
+	 * not to wait awhile and try again.
+	 *
+	 * If the region is precisely the size of a ref, then we don't
+	 * have the region here, just the meta-data, which implies that
+	 * that we are using SYSTEM V shared memory (SYSTEM_MEM).  However,
+	 * if the flags say that we are using SYSTEM_MEM and the region is
+	 * bigger than the ref, something bad has happened -- we are storing
+	 * something in the region file other than meta-data and that
+	 * shouldn't happen.
+	 */
+	if (size < sizeof(ref))
+		goto retry;
+	else {
+
+		if (size == sizeof(ref))
+			F_SET(env, ENV_SYSTEM_MEM);
+		else if (F_ISSET(env, ENV_SYSTEM_MEM)) {
+			ret = EINVAL;
+			__db_err(env, ret, DB_STR_A("1535",
+		    "%s: existing environment not created in system memory",
+			    "%s"), infop->name);
+			goto err;
+		} else {
+			if ((ret = __os_read(env, env->lockfhp, &rbuf,
+			    sizeof(rbuf), &nrw)) != 0 ||
+			    nrw < (size_t)sizeof(rbuf) ||
+			    (ret = __os_seek(env,
+			    env->lockfhp, 0, 0, rbuf.region_off)) != 0) {
+				__db_err(env, ret, DB_STR_A("1536",
+				     "%s: unable to read region info", "%s"),
+				     infop->name);
+				goto err;
+			}
+		}
+
+		if ((ret = __os_read(env, env->lockfhp, &ref,
+		    sizeof(ref), &nrw)) != 0 || nrw < (size_t)sizeof(ref)) {
+			if (ret == 0)
+				ret = EIO;
+			__db_err(env, ret, DB_STR_A("1537",
+			    "%s: unable to read system-memory information",
+			    "%s"), infop->name);
+			goto err;
+		}
+		size = ref.size;
+		max = ref.max;
+		segid = ref.segid;
+	}
+
+#ifndef HAVE_MUTEX_FCNTL
+	/*
+	 * If we're not doing fcntl locking, we can close the file handle.  We
+	 * no longer need it and the less contact between the buffer cache and
+	 * the VM, the better.
+	 */
+	(void)__os_closehandle(env, env->lockfhp);
+	 env->lockfhp = NULL;
+#endif
+
+	/* Call the region join routine to acquire the region. */
+	memset(&tregion, 0, sizeof(tregion));
+	tregion.size = (roff_t)size;
+	tregion.max = (roff_t)max;
+	tregion.segid = segid;
+	if ((ret = __env_sys_attach(env, infop, &tregion)) != 0)
+		goto err;
+
+user_map_functions:
+	/*
+	 * The environment's REGENV structure has to live at offset 0 instead
+	 * of the usual alloc information.  Set the primary reference and
+	 * correct the "head" value to reference the alloc region.
+	 */
+	infop->primary = infop->addr;
+	infop->head = (u_int8_t *)infop->addr + sizeof(REGENV);
+	renv = infop->primary;
+
+	/*
+	 * Make sure the region matches our build.  Special case a region
+	 * that's all nul bytes, just treat it like any other corruption.
+	 */
+	if (renv->majver != DB_VERSION_MAJOR ||
+	    renv->minver != DB_VERSION_MINOR) {
+		if (renv->majver != 0 || renv->minver != 0) {
+			__db_errx(env, DB_STR_A("1538",
+	    "Program version %d.%d doesn't match environment version %d.%d",
+			    "%d %d %d %d"), DB_VERSION_MAJOR, DB_VERSION_MINOR,
+			    renv->majver, renv->minver);
+			ret = DB_VERSION_MISMATCH;
+		} else
+			ret = EINVAL;
+		goto err;
+	}
+	if (renv->signature != signature) {
+		__db_errx(env, DB_STR("1539",
+		    "Build signature doesn't match environment"));
+		ret = DB_VERSION_MISMATCH;
+		goto err;
+	}
+
+	/*
+	 * Check if the environment has had a catastrophic failure.
+	 *
+	 * Check the magic number to ensure the region is initialized.  If the
+	 * magic number isn't set, the lock may not have been initialized, and
+	 * an attempt to use it could lead to random behavior.
+	 *
+	 * The panic and magic values aren't protected by any lock, so we never
+	 * use them in any check that's more complex than set/not-set.
+	 *
+	 * !!!
+	 * I'd rather play permissions games using the underlying file, but I
+	 * can't because Windows/NT filesystems won't open files mode 0.
+	 */
+	if (renv->panic && !F_ISSET(dbenv, DB_ENV_NOPANIC)) {
+		ret = __env_panic_msg(env);
+		goto err;
+	}
+	if (renv->magic != DB_REGION_MAGIC)
+		goto retry;
+
+	/*
+	 * Get a reference to the underlying REGION information for this
+	 * environment.
+	 */
+	if ((ret = __env_des_get(env, infop, infop, &rp)) != 0 || rp == NULL)
+		goto find_err;
+	infop->rp = rp;
+
+	/*
+	 * There's still a possibility for inconsistent data.  When we acquired
+	 * the size of the region and attached to it, it might have still been
+	 * growing as part of its creation.  We can detect this by checking the
+	 * size we originally found against the region's current size.  (The
+	 * region's current size has to be final, the creator finished growing
+	 * it before setting the magic number in the region.)
+	 *
+	 * !!!
+	 * Skip this test when the application specified its own map functions.
+	 * The size of the region is essentially unknown in that case: some
+	 * other process asked the application's map function for some bytes,
+	 * but we were never told the final size of the region.  We could get
+	 * a size back from the map function, but for all we know, our process'
+	 * map function only knows how to join regions, it has no clue how big
+	 * those regions are.
+	 */
+	if (DB_GLOBAL(j_region_map) == NULL && rp->size != size)
+		goto retry;
+
+	/*
+	 * Check our callers configuration flags, it's an error to configure
+	 * incompatible or additional subsystems in an existing environment.
+	 * Return the total set of flags to the caller so they initialize the
+	 * correct set of subsystems.
+	 */
+	if (init_flagsp != NULL) {
+		FLD_CLR(*init_flagsp, renv->init_flags);
+		if (*init_flagsp != 0) {
+			__db_errx(env, DB_STR("1540",
+    "configured environment flags incompatible with existing environment"));
+			ret = EINVAL;
+			goto err;
+		}
+		*init_flagsp = renv->init_flags;
+	}
+
+	/*
+	 * Fault the pages into memory.  Note, do this AFTER releasing the
+	 * lock, because we're only reading the pages, not writing them.
+	 */
+	(void)__env_faultmem(env, infop->primary, rp->size, 0);
+
+	/* Everything looks good, we're done. */
+	env->reginfo = infop;
+	return (0);
+
+creation:
+	/* Create the environment region. */
+	F_SET(infop, REGION_CREATE);
+
+	/*
+	 * Allocate room for REGION structures plus overhead.
+	 */
+	memset(&tregion, 0, sizeof(tregion));
+	nregions = __memp_max_regions(env) + 5;
+	size = nregions * sizeof(REGION);
+	size += dbenv->passwd_len;
+	size += (dbenv->thr_max + dbenv->thr_max / 4) *
+	    __env_alloc_size(sizeof(DB_THREAD_INFO));
+	/* Space for replication buffer. */
+	if (init_flagsp != NULL && FLD_ISSET(*init_flagsp, DB_INITENV_REP))
+		size += MEGABYTE;
+	size += __txn_region_size(env);
+	size += __log_region_size(env);
+	size += __env_thread_size(env, size);
+	size += __lock_region_size(env, size);
+
+	tregion.size = (roff_t)size;
+	tregion.segid = INVALID_REGION_SEGID;
+
+	if ((tregion.max = dbenv->memory_max) == 0) {
+		/* Add some slop. */
+		size += 16 * 1024;
+		tregion.max = (roff_t)size;
+
+		tregion.max += (roff_t)__lock_region_max(env);
+		tregion.max += (roff_t)__txn_region_max(env);
+		tregion.max += (roff_t)__log_region_max(env);
+		tregion.max += (roff_t)__env_thread_max(env);
+	} else if (tregion.size > tregion.max) {
+		__db_errx(env, DB_STR_A("1542",
+	"Minimum environment memory size %ld is bigger than spcified max %ld.",
+		    "%ld %ld"), (u_long)tregion.size, (u_long)tregion.max);
+		ret = EINVAL;
+		goto err;
+	} else if (F_ISSET(env, ENV_PRIVATE))
+		infop->max_alloc = dbenv->memory_max;
+
+	if ((ret = __env_sys_attach(env, infop, &tregion)) != 0)
+		goto err;
+
+	/*
+	 * If the application has specified its own mapping functions, we don't
+	 * know until we get here if we are creating the region or not.   The
+	 * way we find out is underlying functions clear the REGION_CREATE flag.
+	 */
+	if (!F_ISSET(infop, REGION_CREATE))
+		goto user_map_functions;
+
+	/*
+	 * Fault the pages into memory.  Note, do this BEFORE we initialize
+	 * anything, because we're writing the pages, not just reading them.
+	 */
+	(void)__env_faultmem(env, infop->addr, tregion.size, 1);
+
+	/*
+	 * The first object in the region is the REGENV structure.  This is
+	 * different from the other regions, and, from everything else in
+	 * this region, where all objects are allocated from the pool, i.e.,
+	 * there aren't any fixed locations.  The remaining space is made
+	 * available for later allocation.
+	 *
+	 * The allocation space must be size_t aligned, because that's what
+	 * the initialization routine is going to store there.  To make sure
+	 * that happens, the REGENV structure was padded with a final size_t.
+	 * No other region needs to worry about it because all of them treat
+	 * the entire region as allocation space.
+	 *
+	 * Set the primary reference and correct the "head" value to reference
+	 * the alloc region.
+	 */
+	infop->primary = infop->addr;
+	infop->head = (u_int8_t *)infop->addr + sizeof(REGENV);
+	__env_alloc_init(infop, tregion.size - sizeof(REGENV));
+
+	/*
+	 * Initialize the rest of the REGENV structure.  (Don't set the magic
+	 * number to the correct value, that would validate the environment).
+	 */
+	renv = infop->primary;
+	renv->magic = 0;
+	renv->panic = 0;
+
+	(void)db_version(&majver, &minver, &patchver);
+	renv->majver = (u_int32_t)majver;
+	renv->minver = (u_int32_t)minver;
+	renv->patchver = (u_int32_t)patchver;
+	renv->signature = signature;
+
+	(void)time(&renv->timestamp);
+	__os_unique_id(env, &renv->envid);
+
+	/*
+	 * Initialize init_flags to store the flags that any other environment
+	 * handle that uses DB_JOINENV to join this environment will need.
+	 */
+	renv->init_flags = (init_flagsp == NULL) ? 0 : *init_flagsp;
+
+	/*
+	 * Set up the region array.  We use an array rather than a linked list
+	 * as we have to traverse this list after failure in some cases, and
+	 * we don't want to infinitely loop should the application fail while
+	 * we're manipulating the list.
+	 */
+	renv->region_cnt = nregions;
+	if ((ret = __env_alloc(infop, nregions * sizeof(REGION), &rp)) != 0) {
+		__db_err(env, ret, DB_STR("1543",
+		    "unable to create new master region array"));
+		goto err;
+	}
+	renv->region_off = R_OFFSET(infop, rp);
+	for (i = 0; i < nregions; ++i, ++rp)
+		rp->id = INVALID_REGION_ID;
+
+	renv->cipher_off = renv->thread_off = renv->rep_off = INVALID_ROFF;
+	renv->flags = 0;
+	renv->op_timestamp = renv->rep_timestamp = 0;
+	renv->mtx_regenv = MUTEX_INVALID;
+	renv->reg_panic = 0;
+
+	/*
+	 * Get the underlying REGION structure for this environment.  Note,
+	 * we created the underlying OS region before we acquired the REGION
+	 * structure, which is backwards from the normal procedure.  Update
+	 * the REGION structure.
+	 */
+	if ((ret = __env_des_get(env, infop, infop, &rp)) != 0) {
+find_err:	__db_errx(env, DB_STR_A("1544",
+		    "%s: unable to find environment", "%s"), infop->name);
+		if (ret == 0)
+			ret = EINVAL;
+		goto err;
+	}
+	infop->rp = rp;
+	rp->alloc = rp->size = tregion.size;
+	rp->max = tregion.max;
+	rp->segid = tregion.segid;
+
+	/*
+	 * !!!
+	 * If we create an environment where regions are public and in system
+	 * memory, we have to inform processes joining the environment how to
+	 * attach to the shared memory segment.  So, we write the shared memory
+	 * identifier into the file, to be read by those other processes.
+	 *
+	 * XXX
+	 * This is really OS-layer information, but I can't see any easy way
+	 * to move it down there without passing down information that it has
+	 * no right to know, e.g., that this is the one-and-only REGENV region
+	 * and not some other random region.
+	 */
+	if (tregion.segid != INVALID_REGION_SEGID) {
+		ref.size = tregion.size;
+		ref.segid = tregion.segid;
+		ref.max = tregion.max;
+		if ((ret = __os_write(
+		    env, env->lockfhp, &ref, sizeof(ref), &nrw)) != 0) {
+			__db_err(env, ret, DB_STR_A("1545",
+			    "%s: unable to write out public environment ID",
+			    "%s"), infop->name);
+			goto err;
+		}
+	}
+
+#ifndef HAVE_MUTEX_FCNTL
+	/*
+	 * If we're not doing fcntl locking, we can close the file handle.  We
+	 * no longer need it and the less contact between the buffer cache and
+	 * the VM, the better.
+	 */
+	if (env->lockfhp != NULL) {
+		 (void)__os_closehandle(env, env->lockfhp);
+		 env->lockfhp = NULL;
+	}
+#endif
+
+	/* Everything looks good, we're done. */
+	env->reginfo = infop;
+	return (0);
+
+err:
+retry:	/* Close any open file handle. */
+	if (env->lockfhp != NULL) {
+		(void)__os_closehandle(env, env->lockfhp);
+		env->lockfhp = NULL;
+	}
+
+	/*
+	 * If we joined or created the region, detach from it.  If we created
+	 * it, destroy it.  Note, there's a path in the above code where we're
+	 * using a temporary REGION structure because we haven't yet allocated
+	 * the real one.  In that case the region address (addr) will be filled
+	 * in, but the REGION pointer (rp) won't.  Fix it.
+	 */
+	if (infop->addr != NULL) {
+		if (infop->rp == NULL)
+			infop->rp = &tregion;
+
+		(void)__env_sys_detach(env,
+		    infop, F_ISSET(infop, REGION_CREATE));
+
+		if (rp != NULL && F_ISSET(env, DB_PRIVATE))
+			__env_alloc_free(infop, rp);
+	}
+
+	/* Free the allocated name and/or REGINFO structure. */
+	if (infop->name != NULL)
+		__os_free(env, infop->name);
+	__os_free(env, infop);
+
+	/* If we had a temporary error, wait awhile and try again. */
+	if (ret == 0) {
+		if (!retry_ok || ++retry_cnt > 3) {
+			__db_errx(env, DB_STR("1546",
+			    "unable to join the environment"));
+			ret = EAGAIN;
+		} else {
+			__os_yield(env, retry_cnt * 3, 0);
+			goto loop;
+		}
+	}
+
+	return (ret);
+}
+
+/*
+ * __env_turn_on --
+ *	Turn on the created environment.
+ *
+ * PUBLIC: int __env_turn_on __P((ENV *));
+ */
+int
+__env_turn_on(env)
+	ENV *env;
+{
+	REGENV *renv;
+	REGINFO *infop;
+
+	infop = env->reginfo;
+	renv = infop->primary;
+
+	/* If we didn't create the region, there's no need for further work. */
+	if (!F_ISSET(infop, REGION_CREATE))
+		return (0);
+
+	/*
+	 * Validate the file.  All other threads of control are waiting
+	 * on this value to be written -- "Let slip the hounds of war!"
+	 */
+	renv->magic = DB_REGION_MAGIC;
+
+	return (0);
+}
+
+/*
+ * __env_turn_off --
+ *	Turn off the environment.
+ *
+ * PUBLIC: int __env_turn_off __P((ENV *, u_int32_t));
+ */
+int
+__env_turn_off(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	REGENV *renv;
+	REGINFO *infop;
+	int ret, t_ret;
+
+	ret = 0;
+
+	/*
+	 * Connect to the environment: If we can't join the environment, we
+	 * guess it's because it doesn't exist and we're done.
+	 *
+	 * If the environment exists, attach and lock the environment.
+	 */
+	if (__env_attach(env, NULL, 0, 1) != 0)
+		return (0);
+
+	infop = env->reginfo;
+	renv = infop->primary;
+
+	MUTEX_LOCK(env, renv->mtx_regenv);
+
+	/*
+	 * If the environment is in use, we're done unless we're forcing the
+	 * issue or the environment has panic'd.  (If the environment panic'd,
+	 * the thread holding the reference count may not have cleaned up, so
+	 * we clean up.  It's possible the application didn't plan on removing
+	 * the environment in this particular call, but panic'd environments
+	 * aren't useful to anyone.)
+	 *
+	 * Otherwise, panic the environment and overwrite the magic number so
+	 * any thread of control attempting to connect (or racing with us) will
+	 * back off and retry, or just die.
+	 */
+	if (renv->refcnt > 0 && !LF_ISSET(DB_FORCE) && !renv->panic)
+		ret = EBUSY;
+	else
+		renv->panic = 1;
+
+	/*
+	 * Unlock the environment (nobody should need this lock because
+	 * we've poisoned the pool) and detach from the environment.
+	 */
+	MUTEX_UNLOCK(env, renv->mtx_regenv);
+
+	if ((t_ret = __env_detach(env, 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __env_panic_set --
+ *	Set/clear unrecoverable error.
+ *
+ * PUBLIC: void __env_panic_set __P((ENV *, int));
+ */
+void
+__env_panic_set(env, on)
+	ENV *env;
+	int on;
+{
+	if (env != NULL && env->reginfo != NULL)
+		((REGENV *)env->reginfo->primary)->panic = on ? 1 : 0;
+}
+
+/*
+ * __env_ref_increment --
+ *	Increment the environment's reference count.
+ *
+ * PUBLIC: int __env_ref_increment __P((ENV *));
+ */
+int
+__env_ref_increment(env)
+	ENV *env;
+{
+	REGENV *renv;
+	REGINFO *infop;
+	int ret;
+
+	infop = env->reginfo;
+	renv = infop->primary;
+
+	/* If we're creating the primary region, allocate a mutex. */
+	if (F_ISSET(infop, REGION_CREATE)) {
+		if ((ret = __mutex_alloc(
+		    env, MTX_ENV_REGION, 0, &renv->mtx_regenv)) != 0)
+			return (ret);
+		renv->refcnt = 1;
+	} else {
+		/* Lock the environment, increment the reference, unlock. */
+		MUTEX_LOCK(env, renv->mtx_regenv);
+		++renv->refcnt;
+		MUTEX_UNLOCK(env, renv->mtx_regenv);
+	}
+
+	F_SET(env, ENV_REF_COUNTED);
+	return (0);
+}
+
+/*
+ * __env_ref_decrement --
+ *	Decrement the environment's reference count.
+ *
+ * PUBLIC: int __env_ref_decrement __P((ENV *));
+ */
+int
+__env_ref_decrement(env)
+	ENV *env;
+{
+	REGENV *renv;
+	REGINFO *infop;
+
+	/* Be cautious -- we may not have an environment. */
+	if ((infop = env->reginfo) == NULL)
+		return (0);
+
+	renv = infop->primary;
+
+	/* Even if we have an environment, may not have reference counted it. */
+	if (F_ISSET(env, ENV_REF_COUNTED)) {
+		/* Lock the environment, decrement the reference, unlock. */
+		MUTEX_LOCK(env, renv->mtx_regenv);
+		if (renv->refcnt == 0)
+			__db_errx(env, DB_STR("1547",
+			    "environment reference count went negative"));
+		else
+			--renv->refcnt;
+		MUTEX_UNLOCK(env, renv->mtx_regenv);
+
+		F_CLR(env, ENV_REF_COUNTED);
+	}
+
+	/* If a private environment, we're done with the mutex, destroy it. */
+	return (F_ISSET(env, ENV_PRIVATE) ?
+	    __mutex_free(env, &renv->mtx_regenv) : 0);
+}
+
+/*
+ * __env_ref_get --
+ *	Get the number of environment references.  This is an unprotected
+ *	read of refcnt to simply provide a spot check of the value.  It
+ *	is only intended for use as an internal utility routine.
+ *
+ * PUBLIC: int __env_ref_get __P((DB_ENV *, u_int32_t *));
+ */
+int
+__env_ref_get(dbenv, countp)
+	DB_ENV *dbenv;
+	u_int32_t *countp;
+{
+	ENV *env;
+	REGENV *renv;
+	REGINFO *infop;
+
+	env = dbenv->env;
+	infop = env->reginfo;
+	renv = infop->primary;
+	*countp = renv->refcnt;
+	return (0);
+}
+
+/*
+ * __env_detach --
+ *	Detach from the environment.
+ *
+ * PUBLIC: int __env_detach __P((ENV *, int));
+ */
+int
+__env_detach(env, destroy)
+	ENV *env;
+	int destroy;
+{
+	REGENV *renv;
+	REGINFO *infop;
+	REGION rp;
+	int ret, t_ret;
+
+	infop = env->reginfo;
+	renv = infop->primary;
+	ret = 0;
+
+	/* Close the locking file handle. */
+	if (env->lockfhp != NULL) {
+		if ((t_ret =
+		    __os_closehandle(env, env->lockfhp)) != 0 && ret == 0)
+			ret = t_ret;
+		env->lockfhp = NULL;
+	}
+
+	/*
+	 * If a private region, return the memory to the heap.  Not needed for
+	 * filesystem-backed or system shared memory regions, that memory isn't
+	 * owned by any particular process.
+	 */
+	if (destroy) {
+		/*
+		 * Free the REGION array.
+		 *
+		 * The actual underlying region structure is allocated from the
+		 * primary shared region, and we're about to free it.  Save a
+		 * copy on our stack for the REGINFO to reference when it calls
+		 * down into the OS layer to release the shared memory segment.
+		 */
+		rp = *infop->rp;
+		infop->rp = &rp;
+
+		if (renv->region_off != INVALID_ROFF)
+			__env_alloc_free(
+			   infop, R_ADDR(infop, renv->region_off));
+	}
+
+	/*
+	 * Set the ENV->reginfo field to NULL.  BDB uses the ENV->reginfo
+	 * field to decide if the underlying region can be accessed or needs
+	 * cleanup.  We're about to destroy what it references, so it needs to
+	 * be cleared.
+	 */
+	env->reginfo = NULL;
+	env->thr_hashtab = NULL;
+
+	if ((t_ret = __env_sys_detach(env, infop, destroy)) != 0 && ret == 0)
+		ret = t_ret;
+	if (infop->name != NULL)
+		__os_free(env, infop->name);
+
+	/* Discard the ENV->reginfo field's memory. */
+	__os_free(env, infop);
+
+	return (ret);
+}
+
+/*
+ * __env_remove_env --
+ *	Remove an environment.
+ *
+ * PUBLIC: int __env_remove_env __P((ENV *));
+ */
+int
+__env_remove_env(env)
+	ENV *env;
+{
+	DB_ENV *dbenv;
+	REGENV *renv;
+	REGINFO *infop, reginfo;
+	REGION *rp;
+	u_int32_t flags_orig, i;
+
+	dbenv = env->dbenv;
+
+	/*
+	 * We do not want to hang on a mutex request, nor do we care about
+	 * panics.
+	 */
+	flags_orig = F_ISSET(dbenv, DB_ENV_NOLOCKING | DB_ENV_NOPANIC);
+	F_SET(dbenv, DB_ENV_NOLOCKING | DB_ENV_NOPANIC);
+
+	/*
+	 * This routine has to walk a nasty line between not looking into the
+	 * environment (which may be corrupted after an app or system crash),
+	 * and removing everything that needs removing.
+	 *
+	 * Connect to the environment: If we can't join the environment, we
+	 * guess it's because it doesn't exist.  Remove the underlying files,
+	 * at least.
+	 */
+	if (__env_attach(env, NULL, 0, 0) != 0)
+		goto remfiles;
+
+	infop = env->reginfo;
+	renv = infop->primary;
+
+	/*
+	 * Kill the environment, if it's not already dead.
+	 */
+	renv->panic = 1;
+
+	/*
+	 * Walk the array of regions.  Connect to each region and disconnect
+	 * with the destroy flag set.  This shouldn't cause any problems, even
+	 * if the region is corrupted, because we never look inside the region
+	 * (with the single exception of mutex regions on systems where we have
+	 * to return resources to the underlying system).
+	 */
+	for (rp = R_ADDR(infop, renv->region_off),
+	    i = 0; i < renv->region_cnt; ++i, ++rp) {
+		if (rp->id == INVALID_REGION_ID || rp->type == REGION_TYPE_ENV)
+			continue;
+		/*
+		 * !!!
+		 * The REGION_CREATE_OK flag is set for Windows/95 -- regions
+		 * are zero'd out when the last reference to the region goes
+		 * away, in which case the underlying OS region code requires
+		 * callers be prepared to create the region in order to join it.
+		 */
+		memset(&reginfo, 0, sizeof(reginfo));
+		reginfo.id = rp->id;
+		reginfo.flags = REGION_CREATE_OK;
+
+		/*
+		 * If we get here and can't attach and/or detach to the
+		 * region, it's a mess.  Ignore errors, there's nothing
+		 * we can do about them.
+		 */
+		if (__env_region_attach(env, &reginfo, 0, 0) != 0)
+			continue;
+
+#ifdef  HAVE_MUTEX_SYSTEM_RESOURCES
+		/*
+		 * If destroying the mutex region, return any system
+		 * resources to the system.
+		 */
+		if (reginfo.type == REGION_TYPE_MUTEX)
+			__mutex_resource_return(env, &reginfo);
+#endif
+		(void)__env_region_detach(env, &reginfo, 1);
+	}
+
+	/* Detach from the environment's primary region. */
+	(void)__env_detach(env, 1);
+
+remfiles:
+	/*
+	 * Walk the list of files in the directory, unlinking files in the
+	 * Berkeley DB name space.
+	 */
+	__env_remove_file(env);
+
+	F_CLR(dbenv, DB_ENV_NOLOCKING | DB_ENV_NOPANIC);
+	F_SET(dbenv, flags_orig);
+
+	return (0);
+}
+
+/*
+ * __env_remove_file --
+ *	Discard any region files in the filesystem.
+ */
+static void
+__env_remove_file(env)
+	ENV *env;
+{
+	int cnt, fcnt, lastrm, ret;
+	const char *dir;
+	char saved_char, *p, **names, *path, buf[sizeof(DB_REGION_FMT) + 20];
+
+	/* Get the full path of a file in the environment. */
+	(void)snprintf(buf, sizeof(buf), "%s", DB_REGION_ENV);
+	if ((ret = __db_appname(env,
+	    DB_APP_NONE, buf, NULL, &path)) != 0)
+		return;
+
+	/* Get the parent directory for the environment. */
+	if ((p = __db_rpath(path)) == NULL) {
+		p = path;
+		saved_char = *p;
+
+		dir = PATH_DOT;
+	} else {
+		saved_char = *p;
+		*p = '\0';
+
+		dir = path;
+	}
+
+	/* Get the list of file names. */
+	if ((ret = __os_dirlist(env, dir, 0, &names, &fcnt)) != 0)
+		__db_err(env, ret, "%s", dir);
+
+	/* Restore the path, and free it. */
+	*p = saved_char;
+	__os_free(env, path);
+
+	if (ret != 0)
+		return;
+
+	/*
+	 * Remove files from the region directory.
+	 */
+	for (lastrm = -1, cnt = fcnt; --cnt >= 0;) {
+		/* Skip anything outside our name space. */
+		if (!IS_DB_FILE(names[cnt]))
+			continue;
+
+		/* Skip queue extent files. */
+		if (strncmp(names[cnt], "__dbq.", 6) == 0)
+			continue;
+		if (strncmp(names[cnt], "__dbp.", 6) == 0)
+			continue;
+
+		/* Skip registry files. */
+		if (strncmp(names[cnt], "__db.register", 13) == 0)
+			continue;
+
+		/* Skip replication files. */
+		if (strncmp(names[cnt], "__db.rep", 8) == 0)
+			continue;
+
+		/*
+		 * Remove the primary environment region last, because it's
+		 * the key to this whole mess.
+		 */
+		if (strcmp(names[cnt], DB_REGION_ENV) == 0) {
+			lastrm = cnt;
+			continue;
+		}
+
+		/* Remove the file. */
+		if (__db_appname(env,
+		    DB_APP_NONE, names[cnt], NULL, &path) == 0) {
+			/*
+			 * Overwrite region files.  Temporary files would have
+			 * been maintained in encrypted format, so there's no
+			 * reason to overwrite them.  This is not an exact
+			 * check on the file being a region file, but it's
+			 * not likely to be wrong, and the worst thing that can
+			 * happen is we overwrite a file that didn't need to be
+			 * overwritten.
+			 */
+			(void)__os_unlink(env, path, 1);
+			__os_free(env, path);
+		}
+	}
+
+	if (lastrm != -1)
+		if (__db_appname(env,
+		    DB_APP_NONE, names[lastrm], NULL, &path) == 0) {
+			(void)__os_unlink(env, path, 1);
+			__os_free(env, path);
+		}
+	__os_dirfree(env, names, fcnt);
+}
+
+/*
+ * __env_region_attach
+ *	Join/create a region.
+ *
+ * PUBLIC: int __env_region_attach __P((ENV *, REGINFO *, size_t, size_t));
+ */
+int
+__env_region_attach(env, infop, init, max)
+	ENV *env;
+	REGINFO *infop;
+	size_t init, max;
+{
+	REGION *rp;
+	int ret;
+	char buf[sizeof(DB_REGION_FMT) + 20];
+
+	/*
+	 * Find or create a REGION structure for this region.  If we create
+	 * it, the REGION_CREATE flag will be set in the infop structure.
+	 */
+	F_CLR(infop, REGION_CREATE);
+	if ((ret = __env_des_get(env, env->reginfo, infop, &rp)) != 0)
+		return (ret);
+	infop->env = env;
+	infop->rp = rp;
+	infop->type = rp->type;
+	infop->id = rp->id;
+
+	/*
+	 * __env_des_get may have created the region and reset the create
+	 * flag.  If we're creating the region, set the desired size.
+	 */
+	if (F_ISSET(infop, REGION_CREATE)) {
+		rp->alloc = rp->size = (roff_t)init;
+		rp->max = (roff_t)max;
+	}
+
+	/* Join/create the underlying region. */
+	(void)snprintf(buf, sizeof(buf), DB_REGION_FMT, infop->id);
+	if ((ret = __db_appname(env,
+	    DB_APP_NONE, buf, NULL, &infop->name)) != 0)
+		goto err;
+	if ((ret = __env_sys_attach(env, infop, rp)) != 0)
+		goto err;
+
+	/*
+	 * Fault the pages into memory.  Note, do this BEFORE we initialize
+	 * anything because we're writing pages in created regions, not just
+	 * reading them.
+	 */
+	(void)__env_faultmem(env,
+	    infop->addr, rp->size, F_ISSET(infop, REGION_CREATE));
+
+	/*
+	 * !!!
+	 * The underlying layer may have just decided that we are going
+	 * to create the region.  There are various system issues that
+	 * can result in a useless region that requires re-initialization.
+	 *
+	 * If we created the region, initialize it for allocation.
+	 */
+	if (F_ISSET(infop, REGION_CREATE))
+		__env_alloc_init(infop, rp->size);
+
+	return (0);
+
+err:	/* Discard the underlying region. */
+	if (infop->addr != NULL)
+		(void)__env_sys_detach(env,
+		    infop, F_ISSET(infop, REGION_CREATE));
+	else if (infop->name != NULL) {
+		__os_free(env, infop->name);
+		infop->name = NULL;
+	}
+	infop->rp = NULL;
+	infop->id = INVALID_REGION_ID;
+
+	/* Discard the REGION structure if we created it. */
+	if (F_ISSET(infop, REGION_CREATE)) {
+		__env_des_destroy(env, rp);
+		F_CLR(infop, REGION_CREATE);
+	}
+
+	return (ret);
+}
+
+/*
+ * __env_region_share
+ *	Share the primary region.
+ *
+ * PUBLIC: int __env_region_share __P((ENV *, REGINFO *));
+ */
+int
+__env_region_share(env, infop)
+	ENV *env;
+	REGINFO *infop;
+{
+	REGINFO *envinfo;
+	REGION *rp;
+
+	envinfo = env->reginfo;
+	rp = envinfo->rp;
+	F_SET(infop, F_ISSET(envinfo, REGION_CREATE) | REGION_SHARED);
+	infop->addr = envinfo->addr;
+	infop->head = envinfo->head;
+
+	infop->env = env;
+	infop->rp = rp;
+	infop->name = envinfo->name;
+	infop->fhp = envinfo->fhp;
+	infop->type = rp->type;
+	infop->id = rp->id;
+
+	return (0);
+}
+
+/*
+ * __env_region_detach --
+ *	Detach from a region.
+ *
+ * PUBLIC: int __env_region_detach __P((ENV *, REGINFO *, int));
+ */
+int
+__env_region_detach(env, infop, destroy)
+	ENV *env;
+	REGINFO *infop;
+	int destroy;
+{
+	REGION *rp;
+	REGION_MEM  *mem, *next;
+	int ret;
+
+	if (F_ISSET(env, ENV_PRIVATE))
+		destroy = 1;
+	else if (F_ISSET(infop, REGION_SHARED))
+		return (0);
+
+	rp = infop->rp;
+
+	/*
+	 * When discarding the regions as we shut down a database environment,
+	 * discard any allocated shared memory segments.  This is the last time
+	 * we use them, and db_region_destroy is the last region-specific call
+	 * we make.
+	 */
+	if (F_ISSET(env, ENV_PRIVATE) && infop->primary != NULL) {
+		for (mem = infop->mem; mem != NULL; mem = next) {
+			next = mem->next;
+			__env_alloc_free(infop, mem);
+		}
+		__env_alloc_free(infop, infop->primary);
+	}
+
+	if (F_ISSET(infop, REGION_SHARED))
+		return (0);
+
+	/* Detach from the underlying OS region. */
+	ret = __env_sys_detach(env, infop, destroy);
+
+	/* If we destroyed the region, discard the REGION structure. */
+	if (destroy)
+		__env_des_destroy(env, rp);
+
+	/* Destroy the structure. */
+	if (infop->name != NULL)
+		__os_free(env, infop->name);
+
+	return (ret);
+}
+
+/*
+ * __env_sys_attach --
+ *	Prep and call the underlying OS attach function.
+ */
+static int
+__env_sys_attach(env, infop, rp)
+	ENV *env;
+	REGINFO *infop;
+	REGION *rp;
+{
+	int ret;
+
+	/*
+	 * All regions are created on 8K boundaries out of sheer paranoia,
+	 * so we don't make some underlying VM unhappy. Make sure we don't
+	 * overflow or underflow.
+	 */
+#define	OS_VMPAGESIZE		(8 * 1024)
+#define	OS_VMROUNDOFF(i) {						\
+	if ((i) + OS_VMPAGESIZE - 1 > (i))				\
+		(i) += OS_VMPAGESIZE - 1;				\
+	(i) -= (i) % OS_VMPAGESIZE;					\
+}
+	if (F_ISSET(infop, REGION_CREATE)) {
+		OS_VMROUNDOFF(rp->size);
+		OS_VMROUNDOFF(rp->max);
+	}
+
+#ifdef DB_REGIONSIZE_MAX
+	/* Some architectures have hard limits on the maximum region size. */
+	if (rp->size > DB_REGIONSIZE_MAX) {
+		__db_errx(env, DB_STR_A("1548",
+		    "region size %lu is too large; maximum is %lu", "%lu %lu"),
+		    (u_long)rp->size, (u_long)DB_REGIONSIZE_MAX);
+		return (EINVAL);
+	}
+	if (rp->max > DB_REGIONSIZE_MAX) {
+		__db_errx(env, DB_STR_A("1549",
+		    "region max %lu is too large; maximum is %lu", "%lu %lu"),
+		    (u_long)rp->max, (u_long)DB_REGIONSIZE_MAX);
+		return (EINVAL);
+	}
+#endif
+
+	/*
+	 * If a region is private, malloc the memory.
+	 *
+	 * !!!
+	 * If this fails because the region is too large to malloc, mmap(2)
+	 * using the MAP_ANON or MAP_ANONYMOUS flags would be an alternative.
+	 * I don't know of any architectures (yet!) where malloc is a problem.
+	 */
+	if (F_ISSET(env, ENV_PRIVATE)) {
+#if defined(HAVE_MUTEX_HPPA_MSEM_INIT)
+		/*
+		 * !!!
+		 * There exist spinlocks that don't work in malloc memory, e.g.,
+		 * the HP/UX msemaphore interface.  If we don't have locks that
+		 * will work in malloc memory, we better not be private or not
+		 * be threaded.
+		 */
+		if (F_ISSET(env, ENV_THREAD)) {
+			__db_errx(env, DB_STR("1550",
+"architecture does not support locks inside process-local (malloc) memory"));
+			__db_errx(env, DB_STR("1551",
+	    "application may not specify both DB_PRIVATE and DB_THREAD"));
+			return (EINVAL);
+		}
+#endif
+		if ((ret = __os_malloc(
+		    env, sizeof(REGENV), &infop->addr)) != 0)
+			return (ret);
+
+	} else {
+#if !defined(HAVE_MMAP_EXTEND)
+		/* Extend any disk file to its full size before mapping it. */
+		rp->size = rp->max;
+#endif
+		if ((ret = __os_attach(env, infop, rp)) != 0)
+			return (ret);
+	}
+
+	/* Set the start of the allocation region. */
+	infop->head = infop->addr;
+
+	/*
+	 * We require that the memory is aligned to fix the largest integral
+	 * type.  Otherwise, multiple processes mapping the same shared region
+	 * would have to memcpy every value before reading it.
+	 */
+	if (infop->addr != ALIGNP_INC(infop->addr, sizeof(uintmax_t))) {
+		__db_errx(env, DB_STR("1552",
+		    "region memory was not correctly aligned"));
+		(void)__env_sys_detach(env, infop,
+		    F_ISSET(infop, REGION_CREATE));
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+/*
+ * __env_sys_detach --
+ *	Prep and call the underlying OS detach function.
+ */
+static int
+__env_sys_detach(env, infop, destroy)
+	ENV *env;
+	REGINFO *infop;
+	int destroy;
+{
+
+	/* If a region is private, free the memory. */
+	if (F_ISSET(env, ENV_PRIVATE)) {
+		__os_free(env, infop->addr);
+		return (0);
+	}
+
+	return (__os_detach(env, infop, destroy));
+}
+
+/*
+ * __env_des_get --
+ *	Return a reference to the shared information for a REGION,
+ *	optionally creating a new entry.
+ */
+static int
+__env_des_get(env, env_infop, infop, rpp)
+	ENV *env;
+	REGINFO *env_infop, *infop;
+	REGION **rpp;
+{
+	REGENV *renv;
+	REGION *rp, *empty_slot, *first_type;
+	u_int32_t i, maxid;
+
+	*rpp = NULL;
+	renv = env_infop->primary;
+
+	/*
+	 * If the caller wants to join a region, walk through the existing
+	 * regions looking for a matching ID (if ID specified) or matching
+	 * type (if type specified).  If we return based on a matching type
+	 * return the "primary" region, that is, the first region that was
+	 * created of this type.
+	 *
+	 * Track the first empty slot and maximum region ID for new region
+	 * allocation.
+	 *
+	 * MaxID starts at REGION_ID_ENV, the ID of the primary environment.
+	 */
+	maxid = REGION_ID_ENV;
+	empty_slot = first_type = NULL;
+	for (rp = R_ADDR(env_infop, renv->region_off),
+	    i = 0; i < renv->region_cnt; ++i, ++rp) {
+		if (rp->id == INVALID_REGION_ID) {
+			if (empty_slot == NULL)
+				empty_slot = rp;
+			continue;
+		}
+		if (infop->id != INVALID_REGION_ID) {
+			if (infop->id == rp->id)
+				break;
+			continue;
+		}
+		if (infop->type == rp->type &&
+		    F_ISSET(infop, REGION_JOIN_OK) &&
+		    (first_type == NULL || first_type->id > rp->id))
+			first_type = rp;
+
+		if (rp->id > maxid)
+			maxid = rp->id;
+	}
+
+	/* If we found a matching ID (or a matching type), return it. */
+	if (i >= renv->region_cnt)
+		rp = first_type;
+	if (rp != NULL) {
+		*rpp = rp;
+		return (0);
+	}
+
+	/*
+	 * If we didn't find a region and we don't have permission to create
+	 * the region, fail.  The caller generates any error message.
+	 */
+	if (!F_ISSET(infop, REGION_CREATE_OK))
+		return (ENOENT);
+
+	/*
+	 * If we didn't find a region and don't have room to create the region
+	 * fail with an error message, there's a sizing problem.
+	 */
+	if (empty_slot == NULL) {
+		__db_errx(env, DB_STR("1553",
+		    "no room remaining for additional REGIONs"));
+		return (ENOENT);
+	}
+
+	/*
+	 * Initialize a REGION structure for the caller.  If id was set, use
+	 * that value, otherwise we use the next available ID.
+	 */
+	memset(empty_slot, 0, sizeof(REGION));
+	empty_slot->segid = INVALID_REGION_SEGID;
+
+	/*
+	 * Set the type and ID; if no region ID was specified,
+	 * allocate one.
+	 */
+	empty_slot->type = infop->type;
+	empty_slot->id = infop->id == INVALID_REGION_ID ? maxid + 1 : infop->id;
+
+	F_SET(infop, REGION_CREATE);
+
+	*rpp = empty_slot;
+	return (0);
+}
+
+/*
+ * __env_des_destroy --
+ *	Destroy a reference to a REGION.
+ */
+static void
+__env_des_destroy(env, rp)
+	ENV *env;
+	REGION *rp;
+{
+	COMPQUIET(env, NULL);
+
+	rp->id = INVALID_REGION_ID;
+}
+
+/*
+ * __env_faultmem --
+ *	Fault the region into memory.
+ */
+static int
+__env_faultmem(env, addr, size, created)
+	ENV *env;
+	void *addr;
+	size_t size;
+	int created;
+{
+	int ret;
+	u_int8_t *p, *t;
+
+	/* Ignore heap regions. */
+	if (F_ISSET(env, ENV_PRIVATE))
+		return (0);
+
+	/*
+	 * It's sometimes significantly faster to page-fault in all of the
+	 * region's pages before we run the application, as we see nasty
+	 * side-effects when we page-fault while holding various locks, i.e.,
+	 * the lock takes a long time to acquire because of the underlying
+	 * page fault, and the other threads convoy behind the lock holder.
+	 *
+	 * If we created the region, we write a non-zero value so that the
+	 * system can't cheat.  If we're just joining the region, we can
+	 * only read the value and try to confuse the compiler sufficiently
+	 * that it doesn't figure out that we're never really using it.
+	 *
+	 * Touch every page (assuming pages are 512B, the smallest VM page
+	 * size used in any general purpose processor).
+	 */
+	ret = 0;
+	if (F_ISSET(env->dbenv, DB_ENV_REGION_INIT)) {
+		if (created)
+			for (p = addr,
+			    t = (u_int8_t *)addr + size; p < t; p += 512)
+				p[0] = 0xdb;
+		else
+			for (p = addr,
+			    t = (u_int8_t *)addr + size; p < t; p += 512)
+				ret |= p[0];
+	}
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/env/env_sig.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,223 @@
+/*-
+ * DO NOT EDIT: automatically built by dist/s_sig.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+#include "dbinc/db_page.h"
+#include "dbinc/btree.h"
+#include "dbinc/crypto.h"
+#include "dbinc/db_join.h"
+#include "dbinc/db_verify.h"
+#include "dbinc/hash.h"
+#include "dbinc/heap.h"
+#include "dbinc/lock.h"
+#include "dbinc/log_verify.h"
+#include "dbinc/mp.h"
+#include "dbinc/partition.h"
+#include "dbinc/qam.h"
+#include "dbinc/txn.h"
+
+/* 
+ * For a pure 32bit/64bit environment, we check all structures and calculate a
+ * signature. For compatible environment, we only check the structures in
+ * shared memory.
+ */
+#ifdef HAVE_MIXED_SIZE_ADDRESSING
+#define	__STRUCTURE_COUNT	41
+#else
+#define	__STRUCTURE_COUNT	(41 + 104)
+#endif
+
+/*
+ * __env_struct_sig --
+ *	Compute signature of structures.
+ *
+ * PUBLIC: u_int32_t __env_struct_sig __P((void));
+ */
+u_int32_t
+__env_struct_sig()
+{
+	u_short t[__STRUCTURE_COUNT + 5];
+	u_int i;
+
+	i = 0;
+#define	__ADD(s)	(t[i++] = sizeof(struct s))
+
+#ifdef	HAVE_MUTEX_SUPPORT
+	__ADD(__db_mutex_stat);
+#endif
+	__ADD(__db_lock_stat);
+	__ADD(__db_lock_hstat);
+	__ADD(__db_lock_pstat);
+	__ADD(__db_ilock);
+	__ADD(__db_lock_u);
+	__ADD(__db_lsn);
+	__ADD(__db_log_stat);
+	__ADD(__db_mpool_stat);
+	__ADD(__db_rep_stat);
+	__ADD(__db_repmgr_stat);
+	__ADD(__db_seq_stat);
+	__ADD(__db_bt_stat);
+	__ADD(__db_h_stat);
+	__ADD(__db_heap_stat);
+	__ADD(__db_qam_stat);
+	__ADD(__db_thread_info);
+	__ADD(__db_lockregion);
+	__ADD(__sh_dbt);
+	__ADD(__db_lockobj);
+	__ADD(__db_locker);
+	__ADD(__db_lockpart);
+	__ADD(__db_lock);
+	__ADD(__log);
+	__ADD(__mpool);
+	__ADD(__db_mpool_fstat_int);
+	__ADD(__mpoolfile);
+	__ADD(__bh);
+#ifdef	HAVE_MUTEX_SUPPORT
+	__ADD(__db_mutexregion);
+#endif
+#ifdef	HAVE_MUTEX_SUPPORT
+	__ADD(__db_mutex_t);
+#endif
+	__ADD(__db_reg_env);
+	__ADD(__db_region);
+	__ADD(__rep);
+	__ADD(__db_txn_stat_int);
+	__ADD(__db_txnregion);
+
+#ifndef HAVE_MIXED_SIZE_ADDRESSING
+	__ADD(__db_dbt);
+	__ADD(__db_lockreq);
+	__ADD(__db_log_cursor);
+	__ADD(__log_rec_spec);
+	__ADD(__db_mpoolfile);
+	__ADD(__db_mpool_fstat);
+	__ADD(__db_txn);
+	__ADD(__kids);
+	__ADD(__my_cursors);
+	__ADD(__femfs);
+	__ADD(__db_preplist);
+	__ADD(__db_txn_active);
+	__ADD(__db_txn_stat);
+	__ADD(__db_txn_token);
+	__ADD(__db_repmgr_site);
+	__ADD(__db_repmgr_conn_err);
+	__ADD(__db_seq_record);
+	__ADD(__db_sequence);
+	__ADD(__db);
+	__ADD(__cq_fq);
+	__ADD(__cq_aq);
+	__ADD(__cq_jq);
+	__ADD(__db_heap_rid);
+	__ADD(__dbc);
+	__ADD(__key_range);
+	__ADD(__db_compact);
+	__ADD(__db_env);
+	__ADD(__db_distab);
+	__ADD(__db_logvrfy_config);
+	__ADD(__db_channel);
+	__ADD(__db_site);
+	__ADD(__fn);
+	__ADD(__db_msgbuf);
+	__ADD(__pin_list);
+	__ADD(__env_thread_info);
+	__ADD(__flag_map);
+	__ADD(__db_backup_handle);
+	__ADD(__env);
+	__ADD(__dbc_internal);
+	__ADD(__dbpginfo);
+	__ADD(__epg);
+	__ADD(__cursor);
+	__ADD(__btree);
+	__ADD(__db_cipher);
+	__ADD(__db_foreign_info);
+	__ADD(__join_cursor);
+	__ADD(__pg_chksum);
+	__ADD(__pg_crypto);
+	__ADD(__heaphdr);
+	__ADD(__heaphdrsplt);
+	__ADD(__pglist);
+	__ADD(__vrfy_dbinfo);
+	__ADD(__vrfy_pageinfo);
+	__ADD(__vrfy_childinfo);
+	__ADD(__db_globals);
+	__ADD(__envq);
+	__ADD(__heap);
+	__ADD(__heap_cursor);
+	__ADD(__db_locktab);
+	__ADD(__db_entry);
+	__ADD(__fname);
+	__ADD(__db_log);
+	__ADD(__hdr);
+	__ADD(__log_persist);
+	__ADD(__db_commit);
+	__ADD(__db_filestart);
+	__ADD(__log_rec_hdr);
+	__ADD(__db_log_verify_info);
+	__ADD(__txn_verify_info);
+	__ADD(__lv_filereg_info);
+	__ADD(__lv_filelife);
+	__ADD(__lv_ckp_info);
+	__ADD(__lv_timestamp_info);
+	__ADD(__lv_txnrange);
+	__ADD(__add_recycle_params);
+	__ADD(__ckp_verify_params);
+	__ADD(__db_mpool);
+	__ADD(__db_mpreg);
+	__ADD(__db_mpool_hash);
+	__ADD(__bh_frozen_p);
+	__ADD(__bh_frozen_a);
+#ifdef	HAVE_MUTEX_SUPPORT
+	__ADD(__db_mutexmgr);
+#endif
+	__ADD(__fh_t);
+	__ADD(__db_partition);
+	__ADD(__part_internal);
+	__ADD(__qcursor);
+	__ADD(__mpfarray);
+	__ADD(__qmpf);
+	__ADD(__queue);
+	__ADD(__qam_filelist);
+	__ADD(__db_reg_env_ref);
+	__ADD(__db_region_mem_t);
+	__ADD(__db_reginfo_t);
+	__ADD(__rep_waiter);
+	__ADD(__db_rep);
+	__ADD(__rep_lease_entry);
+	__ADD(__txn_detail);
+	__ADD(__db_txnmgr);
+	__ADD(__db_commit_info);
+	__ADD(__txn_logrec);
+#endif
+
+	return (__ham_func5(NULL, t, i * sizeof(t[0])));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/env/env_stat.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,901 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+#ifdef HAVE_STATISTICS
+static int   __env_print_all __P((ENV *, u_int32_t));
+static int   __env_print_dbenv_all __P((ENV *, u_int32_t));
+static int   __env_print_env_all __P((ENV *, u_int32_t));
+static int   __env_print_fh __P((ENV *));
+static int   __env_print_stats __P((ENV *, u_int32_t));
+static int   __env_print_thread __P((ENV *));
+static int   __env_stat_print __P((ENV *, u_int32_t));
+static char *__env_thread_state_print __P((DB_THREAD_STATE));
+static const char *
+	     __reg_type __P((reg_type_t));
+
+/*
+ * __env_stat_print_pp --
+ *	ENV->stat_print pre/post processor.
+ *
+ * PUBLIC: int __env_stat_print_pp __P((DB_ENV *, u_int32_t));
+ */
+int
+__env_stat_print_pp(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_BEFORE_OPEN(env, "DB_ENV->stat_print");
+
+	if ((ret = __db_fchk(env, "DB_ENV->stat_print",
+	    flags, DB_STAT_ALL | DB_STAT_ALLOC |
+	    DB_STAT_CLEAR | DB_STAT_SUBSYSTEM)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env, (__env_stat_print(env, flags)), 0, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __env_stat_print --
+ *	ENV->stat_print method.
+ */
+static int
+__env_stat_print(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	time_t now;
+	int ret;
+	char time_buf[CTIME_BUFLEN];
+
+	(void)time(&now);
+	__db_msg(env, "%.24s\tLocal time", __os_ctime(&now, time_buf));
+
+	if ((ret = __env_print_stats(env, flags)) != 0)
+		return (ret);
+
+	if (LF_ISSET(DB_STAT_ALL) &&
+	    (ret = __env_print_all(env, flags)) != 0)
+		return (ret);
+
+	if ((ret = __env_print_thread(env)) != 0)
+		return (ret);
+
+	if ((ret = __env_print_fh(env)) != 0)
+		return (ret);
+
+	if (!LF_ISSET(DB_STAT_SUBSYSTEM))
+		return (0);
+
+	if (LOGGING_ON(env)) {
+		__db_msg(env, "%s", DB_GLOBAL(db_line));
+		if ((ret = __log_stat_print(env, flags)) != 0)
+			return (ret);
+
+		__db_msg(env, "%s", DB_GLOBAL(db_line));
+		if ((ret = __dbreg_stat_print(env, flags)) != 0)
+			return (ret);
+	}
+
+	if (LOCKING_ON(env)) {
+		__db_msg(env, "%s", DB_GLOBAL(db_line));
+		if ((ret = __lock_stat_print(env, flags)) != 0)
+			return (ret);
+	}
+
+	if (MPOOL_ON(env)) {
+		__db_msg(env, "%s", DB_GLOBAL(db_line));
+		if ((ret = __memp_stat_print(env, flags)) != 0)
+			return (ret);
+	}
+
+	if (REP_ON(env)) {
+		__db_msg(env, "%s", DB_GLOBAL(db_line));
+		if ((ret = __rep_stat_print(env, flags)) != 0)
+			return (ret);
+#ifdef HAVE_REPLICATION_THREADS
+		if ((ret = __repmgr_stat_print(env, flags)) != 0)
+			return (ret);
+#endif
+	}
+
+	if (TXN_ON(env)) {
+		__db_msg(env, "%s", DB_GLOBAL(db_line));
+		if ((ret = __txn_stat_print(env, flags)) != 0)
+			return (ret);
+	}
+
+#ifdef HAVE_MUTEX_SUPPORT
+	/*
+	 * Dump the mutexes last.  If DB_STAT_CLEAR is set this will
+	 * clear out the mutex counters and we want to see them in
+	 * the context of the other subsystems first.
+	 */
+	if (MUTEX_ON(env)) {
+		__db_msg(env, "%s", DB_GLOBAL(db_line));
+		if ((ret = __mutex_stat_print(env, flags)) != 0)
+			return (ret);
+	}
+#endif
+
+	return (0);
+}
+
+/*
+ * __env_print_stats --
+ *	Display the default environment statistics.
+ *
+ */
+static int
+__env_print_stats(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	REGENV *renv;
+	REGINFO *infop;
+	char time_buf[CTIME_BUFLEN];
+
+	infop = env->reginfo;
+	renv = infop->primary;
+
+	if (LF_ISSET(DB_STAT_ALL)) {
+		__db_msg(env, "%s", DB_GLOBAL(db_line));
+		__db_msg(env, "Default database environment information:");
+	}
+	STAT_HEX("Magic number", renv->magic);
+	STAT_LONG("Panic value", renv->panic);
+	__db_msg(env, "%d.%d.%d\tEnvironment version",
+	    renv->majver, renv->minver, renv->patchver);
+	STAT_LONG("Btree version", DB_BTREEVERSION);
+	STAT_LONG("Hash version", DB_HASHVERSION);
+	STAT_LONG("Lock version", DB_LOCKVERSION);
+	STAT_LONG("Log version", DB_LOGVERSION);
+	STAT_LONG("Queue version", DB_QAMVERSION);
+	STAT_LONG("Sequence version", DB_SEQUENCE_VERSION);
+	STAT_LONG("Txn version", DB_TXNVERSION);
+	__db_msg(env,
+	    "%.24s\tCreation time", __os_ctime(&renv->timestamp, time_buf));
+	STAT_HEX("Environment ID", renv->envid);
+	__mutex_print_debug_single(env,
+	    "Primary region allocation and reference count mutex",
+	    renv->mtx_regenv, flags);
+	STAT_LONG("References", renv->refcnt);
+	__db_dlbytes(env, "Current region size",
+	    (u_long)0, (u_long)0, (u_long)infop->rp->size);
+	__db_dlbytes(env, "Maximum region size",
+	    (u_long)0, (u_long)0, (u_long)infop->rp->max);
+
+	return (0);
+}
+
+/*
+ * __env_print_all --
+ *	Display the debugging environment statistics.
+ */
+static int
+__env_print_all(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	int ret, t_ret;
+
+	/*
+	 * There are two structures -- DB_ENV and ENV.
+	 */
+	ret = __env_print_dbenv_all(env, flags);
+	if ((t_ret = __env_print_env_all(env, flags)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __env_print_dbenv_all --
+ *	Display the debugging environment statistics.
+ */
+static int
+__env_print_dbenv_all(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	static const FN db_env_fn[] = {
+		{ DB_ENV_AUTO_COMMIT,		"DB_ENV_AUTO_COMMIT" },
+		{ DB_ENV_CDB_ALLDB,		"DB_ENV_CDB_ALLDB" },
+		{ DB_ENV_DIRECT_DB,		"DB_ENV_DIRECT_DB" },
+		{ DB_ENV_DSYNC_DB,		"DB_ENV_DSYNC_DB" },
+		{ DB_ENV_MULTIVERSION,		"DB_ENV_MULTIVERSION" },
+		{ DB_ENV_NOLOCKING,		"DB_ENV_NOLOCKING" },
+		{ DB_ENV_NOMMAP,		"DB_ENV_NOMMAP" },
+		{ DB_ENV_NOPANIC,		"DB_ENV_NOPANIC" },
+		{ DB_ENV_OVERWRITE,		"DB_ENV_OVERWRITE" },
+		{ DB_ENV_REGION_INIT,		"DB_ENV_REGION_INIT" },
+		{ DB_ENV_TIME_NOTGRANTED,	"DB_ENV_TIME_NOTGRANTED" },
+		{ DB_ENV_TXN_NOSYNC,		"DB_ENV_TXN_NOSYNC" },
+		{ DB_ENV_TXN_NOWAIT,		"DB_ENV_TXN_NOWAIT" },
+		{ DB_ENV_TXN_SNAPSHOT,		"DB_ENV_TXN_SNAPSHOT" },
+		{ DB_ENV_TXN_WRITE_NOSYNC,	"DB_ENV_TXN_WRITE_NOSYNC" },
+		{ DB_ENV_YIELDCPU,		"DB_ENV_YIELDCPU" },
+		{ 0,				NULL }
+	};
+	static const FN vfn[] = {
+		{ DB_VERB_DEADLOCK,		"DB_VERB_DEADLOCK" },
+		{ DB_VERB_FILEOPS,		"DB_VERB_FILEOPS" },
+		{ DB_VERB_FILEOPS_ALL,		"DB_VERB_FILEOPS_ALL" },
+		{ DB_VERB_RECOVERY,		"DB_VERB_RECOVERY" },
+		{ DB_VERB_REGISTER,		"DB_VERB_REGISTER" },
+		{ DB_VERB_REPLICATION,		"DB_VERB_REPLICATION" },
+		{ DB_VERB_REP_ELECT,		"DB_VERB_REP_ELECT" },
+		{ DB_VERB_REP_LEASE,		"DB_VERB_REP_LEASE" },
+		{ DB_VERB_REP_MISC,		"DB_VERB_REP_MISC" },
+		{ DB_VERB_REP_MSGS,		"DB_VERB_REP_MSGS" },
+		{ DB_VERB_REP_SYNC,		"DB_VERB_REP_SYNC" },
+		{ DB_VERB_REP_SYSTEM,		"DB_VERB_REP_SYSTEM" },
+		{ DB_VERB_REP_TEST,		"DB_VERB_REP_TEST" },
+		{ DB_VERB_REPMGR_CONNFAIL,	"DB_VERB_REPMGR_CONNFAIL" },
+		{ DB_VERB_REPMGR_MISC,		"DB_VERB_REPMGR_MISC" },
+		{ DB_VERB_WAITSFOR,		"DB_VERB_WAITSFOR" },
+		{ 0,				NULL }
+	};
+	DB_ENV *dbenv;
+	DB_MSGBUF mb;
+	char **p;
+
+	dbenv = env->dbenv;
+	DB_MSGBUF_INIT(&mb);
+
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	STAT_POINTER("ENV", dbenv->env);
+	__mutex_print_debug_single(
+	    env, "DB_ENV handle mutex", dbenv->mtx_db_env, flags);
+	STAT_ISSET("Errcall", dbenv->db_errcall);
+	STAT_ISSET("Errfile", dbenv->db_errfile);
+	STAT_STRING("Errpfx", dbenv->db_errpfx);
+	STAT_ISSET("Msgfile", dbenv->db_msgfile);
+	STAT_ISSET("Msgcall", dbenv->db_msgcall);
+
+	STAT_ISSET("AppDispatch", dbenv->app_dispatch);
+	STAT_ISSET("Event", dbenv->db_event_func);
+	STAT_ISSET("Feedback", dbenv->db_feedback);
+	STAT_ISSET("Free", dbenv->db_free);
+	STAT_ISSET("Panic", dbenv->db_paniccall);
+	STAT_ISSET("Malloc", dbenv->db_malloc);
+	STAT_ISSET("Realloc", dbenv->db_realloc);
+	STAT_ISSET("IsAlive", dbenv->is_alive);
+	STAT_ISSET("ThreadId", dbenv->thread_id);
+	STAT_ISSET("ThreadIdString", dbenv->thread_id_string);
+
+	STAT_STRING("Log dir", dbenv->db_log_dir);
+	STAT_STRING("Metadata dir", dbenv->db_md_dir);
+	STAT_STRING("Tmp dir", dbenv->db_tmp_dir);
+	if (dbenv->db_data_dir == NULL)
+		STAT_ISSET("Data dir", dbenv->db_data_dir);
+	else {
+		for (p = dbenv->db_data_dir; *p != NULL; ++p)
+			__db_msgadd(env, &mb, "%s\tData dir", *p);
+		DB_MSGBUF_FLUSH(env, &mb);
+	}
+
+	STAT_STRING(
+	    "Intermediate directory mode", dbenv->intermediate_dir_mode);
+
+	STAT_LONG("Shared memory key", dbenv->shm_key);
+
+	STAT_ISSET("Password", dbenv->passwd);
+
+	STAT_ISSET("App private", dbenv->app_private);
+	STAT_ISSET("Api1 internal", dbenv->api1_internal);
+	STAT_ISSET("Api2 internal", dbenv->api2_internal);
+
+	__db_prflags(env, NULL, dbenv->verbose, vfn, NULL, "\tVerbose flags");
+
+	STAT_ULONG("Mutex align", dbenv->mutex_align);
+	STAT_ULONG("Mutex cnt", dbenv->mutex_cnt);
+	STAT_ULONG("Mutex inc", dbenv->mutex_inc);
+	STAT_ULONG("Mutex tas spins", dbenv->mutex_tas_spins);
+
+	STAT_ISSET("Lock conflicts", dbenv->lk_conflicts);
+	STAT_LONG("Lock modes", dbenv->lk_modes);
+	STAT_ULONG("Lock detect", dbenv->lk_detect);
+	STAT_ULONG("Lock init", dbenv->lk_init);
+	STAT_ULONG("Lock init lockers", dbenv->lk_init_lockers);
+	STAT_ULONG("Lock init objects", dbenv->lk_init_objects);
+	STAT_ULONG("Lock max", dbenv->lk_max);
+	STAT_ULONG("Lock max lockers", dbenv->lk_max_lockers);
+	STAT_ULONG("Lock max objects", dbenv->lk_max_objects);
+	STAT_ULONG("Lock partitions", dbenv->lk_partitions);
+	STAT_ULONG("Lock object hash table size", dbenv->object_t_size);
+	STAT_ULONG("Lock timeout", dbenv->lk_timeout);
+
+	STAT_ULONG("Log bsize", dbenv->lg_bsize);
+	STAT_FMT("Log file mode", "%#o", int, dbenv->lg_filemode);
+	STAT_ULONG("Log region max", dbenv->lg_regionmax);
+	STAT_ULONG("Log size", dbenv->lg_size);
+
+	STAT_ULONG("Cache GB", dbenv->mp_gbytes);
+	STAT_ULONG("Cache B", dbenv->mp_bytes);
+	STAT_ULONG("Cache max GB", dbenv->mp_max_gbytes);
+	STAT_ULONG("Cache max B", dbenv->mp_max_bytes);
+	STAT_ULONG("Cache mmap size", dbenv->mp_mmapsize);
+	STAT_ULONG("Cache max open fd", dbenv->mp_maxopenfd);
+	STAT_ULONG("Cache max write", dbenv->mp_maxwrite);
+	STAT_ULONG("Cache number", dbenv->mp_ncache);
+	STAT_ULONG("Cache max write sleep", dbenv->mp_maxwrite_sleep);
+
+	STAT_ULONG("Txn init", dbenv->tx_init);
+	STAT_ULONG("Txn max", dbenv->tx_max);
+	STAT_ULONG("Txn timestamp", dbenv->tx_timestamp);
+	STAT_ULONG("Txn timeout", dbenv->tx_timeout);
+
+	STAT_ULONG("Thread count", dbenv->thr_max);
+
+	STAT_ISSET("Registry", dbenv->registry);
+	STAT_ULONG("Registry offset", dbenv->registry_off);
+	STAT_ULONG("Registry timeout", dbenv->envreg_timeout);
+
+	__db_prflags(env,
+	    NULL, dbenv->flags, db_env_fn, NULL, "\tPublic environment flags");
+
+	return (0);
+}
+
+/*
+ * __env_print_env_all --
+ *	Display the debugging environment statistics.
+ */
+static int
+__env_print_env_all(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	static const FN env_fn[] = {
+		{ ENV_CDB,			"ENV_CDB" },
+		{ ENV_DBLOCAL,			"ENV_DBLOCAL" },
+		{ ENV_LOCKDOWN,			"ENV_LOCKDOWN" },
+		{ ENV_NO_OUTPUT_SET,		"ENV_NO_OUTPUT_SET" },
+		{ ENV_OPEN_CALLED,		"ENV_OPEN_CALLED" },
+		{ ENV_PRIVATE,			"ENV_PRIVATE" },
+		{ ENV_RECOVER_FATAL,		"ENV_RECOVER_FATAL" },
+		{ ENV_REF_COUNTED,		"ENV_REF_COUNTED" },
+		{ ENV_SYSTEM_MEM,		"ENV_SYSTEM_MEM" },
+		{ ENV_THREAD,			"ENV_THREAD" },
+		{ 0,				NULL }
+	};
+	static const FN ofn[] = {
+		{ DB_CREATE,			"DB_CREATE" },
+		{ DB_FORCE,			"DB_FORCE" },
+		{ DB_INIT_CDB,			"DB_INIT_CDB" },
+		{ DB_INIT_LOCK,			"DB_INIT_LOCK" },
+		{ DB_INIT_LOG,			"DB_INIT_LOG" },
+		{ DB_INIT_MPOOL,		"DB_INIT_MPOOL" },
+		{ DB_INIT_REP,			"DB_INIT_REP" },
+		{ DB_INIT_TXN,			"DB_INIT_TXN" },
+		{ DB_LOCKDOWN,			"DB_LOCKDOWN" },
+		{ DB_NOMMAP,			"DB_NOMMAP" },
+		{ DB_PRIVATE,			"DB_PRIVATE" },
+		{ DB_RDONLY,			"DB_RDONLY" },
+		{ DB_RECOVER,			"DB_RECOVER" },
+		{ DB_RECOVER_FATAL,		"DB_RECOVER_FATAL" },
+		{ DB_SYSTEM_MEM,		"DB_SYSTEM_MEM" },
+		{ DB_THREAD,			"DB_THREAD" },
+		{ DB_TRUNCATE,			"DB_TRUNCATE" },
+		{ DB_TXN_NOSYNC,		"DB_TXN_NOSYNC" },
+		{ DB_USE_ENVIRON,		"DB_USE_ENVIRON" },
+		{ DB_USE_ENVIRON_ROOT,		"DB_USE_ENVIRON_ROOT" },
+		{ 0,				NULL }
+	};
+	static const FN regenvfn[] = {
+		{ DB_REGENV_REPLOCKED,		"DB_REGENV_REPLOCKED" },
+		{ 0,				NULL }
+	};
+	REGENV *renv;
+	REGINFO *infop;
+	REGION *rp;
+	u_int32_t i;
+	char time_buf[CTIME_BUFLEN];
+
+	infop = env->reginfo;
+	renv = infop->primary;
+
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	STAT_POINTER("DB_ENV", env->dbenv);
+	__mutex_print_debug_single(
+	    env, "ENV handle mutex", env->mtx_env, flags);
+
+	STAT_STRING("Home", env->db_home);
+	__db_prflags(env, NULL, env->open_flags, ofn, NULL, "\tOpen flags");
+	STAT_FMT("Mode", "%#o", int, env->db_mode);
+
+	STAT_ULONG("Pid cache", env->pid_cache);
+
+	STAT_ISSET("Lockfhp", env->lockfhp);
+
+	STAT_ISSET("Locker", env->env_lref);
+
+	STAT_ISSET("Internal recovery table", env->recover_dtab.int_dispatch);
+	STAT_ULONG("Number of recovery table slots",
+	    env->recover_dtab.int_size);
+	STAT_ISSET("External recovery table", env->recover_dtab.ext_dispatch);
+	STAT_ULONG("Number of recovery table slots",
+	    env->recover_dtab.ext_size);
+
+	STAT_ULONG("Thread hash buckets", env->thr_nbucket);
+	STAT_ISSET("Thread hash table", env->thr_hashtab);
+
+	__mutex_print_debug_single(
+	    env, "ENV list of DB handles mutex", env->mtx_dblist, flags);
+	STAT_LONG("DB reference count", env->db_ref);
+
+	__mutex_print_debug_single(env, "MT mutex", env->mtx_mt, flags);
+
+	STAT_ISSET("Crypto handle", env->crypto_handle);
+	STAT_ISSET("Lock handle", env->lk_handle);
+	STAT_ISSET("Log handle", env->lg_handle);
+	STAT_ISSET("Cache handle", env->mp_handle);
+	STAT_ISSET("Mutex handle", env->mutex_handle);
+	STAT_ISSET("Replication handle", env->rep_handle);
+	STAT_ISSET("Txn handle", env->tx_handle);
+
+	STAT_ISSET("User copy", env->dbt_usercopy);
+
+	STAT_LONG("Test abort", env->test_abort);
+	STAT_LONG("Test check", env->test_check);
+	STAT_LONG("Test copy", env->test_copy);
+
+	__db_prflags(env,
+	    NULL, env->flags, env_fn, NULL, "\tPrivate environment flags");
+
+	__db_print_reginfo(env, infop, "Primary", flags);
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	__db_msg(env, "Per region database environment information:");
+	for (rp = R_ADDR(infop, renv->region_off),
+	    i = 0; i < renv->region_cnt; ++i, ++rp) {
+		if (rp->id == INVALID_REGION_ID)
+			continue;
+		__db_msg(env, "%s Region:", __reg_type(rp->type));
+		STAT_LONG("Region ID", rp->id);
+		STAT_LONG("Segment ID", rp->segid);
+		__db_dlbytes(env,
+		    "Size", (u_long)0, (u_long)0, (u_long)rp->size);
+	}
+	__db_prflags(env,
+	    NULL, renv->init_flags, ofn, NULL, "\tInitialization flags");
+	STAT_ULONG("Region slots", renv->region_cnt);
+	__db_prflags(env,
+	    NULL, renv->flags, regenvfn, NULL, "\tReplication flags");
+	__db_msg(env, "%.24s\tOperation timestamp",
+	    renv->op_timestamp == 0 ?
+	    "!Set" : __os_ctime(&renv->op_timestamp, time_buf));
+	__db_msg(env, "%.24s\tReplication timestamp",
+	    renv->rep_timestamp == 0 ?
+	    "!Set" : __os_ctime(&renv->rep_timestamp, time_buf));
+
+	return (0);
+}
+
+static char *
+__env_thread_state_print(state)
+	DB_THREAD_STATE state;
+{
+	switch (state) {
+	case THREAD_ACTIVE:
+		return ("active");
+	case THREAD_BLOCKED:
+		return ("blocked");
+	case THREAD_BLOCKED_DEAD:
+		return ("blocked and dead");
+	case THREAD_OUT:
+		return ("out");
+	default:
+		return ("unknown");
+	}
+	/* NOTREACHED */
+}
+
+/*
+ * __env_print_thread --
+ *	Display the thread block state.
+ */
+static int
+__env_print_thread(env)
+	ENV *env;
+{
+	BH *bhp;
+	DB_ENV *dbenv;
+	DB_HASHTAB *htab;
+	DB_MPOOL *dbmp;
+	DB_THREAD_INFO *ip;
+	PIN_LIST *list, *lp;
+	REGENV *renv;
+	REGINFO *infop;
+	THREAD_INFO *thread;
+	u_int32_t i;
+	char buf[DB_THREADID_STRLEN];
+
+	dbenv = env->dbenv;
+
+	/* The thread table may not be configured. */
+	if ((htab = env->thr_hashtab) == NULL)
+		return (0);
+
+	dbmp = env->mp_handle;
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	__db_msg(env, "Thread tracking information");
+
+	/* Dump out the info we have on thread tracking. */
+	infop = env->reginfo;
+	renv = infop->primary;
+	thread = R_ADDR(infop, renv->thread_off);
+	STAT_ULONG("Thread blocks allocated", thread->thr_count);
+	STAT_ULONG("Thread allocation threshold", thread->thr_max);
+	STAT_ULONG("Thread hash buckets", thread->thr_nbucket);
+
+	/* Dump out the info we have on active threads. */
+	__db_msg(env, "Thread status blocks:");
+	for (i = 0; i < env->thr_nbucket; i++)
+		SH_TAILQ_FOREACH(ip, &htab[i], dbth_links, __db_thread_info) {
+			if (ip->dbth_state == THREAD_SLOT_NOT_IN_USE)
+				continue;
+			__db_msg(env, "\tprocess/thread %s: %s",
+			    dbenv->thread_id_string(
+			    dbenv, ip->dbth_pid, ip->dbth_tid, buf),
+			    __env_thread_state_print(ip->dbth_state));
+			list = R_ADDR(env->reginfo, ip->dbth_pinlist);
+			for (lp = list; lp < &list[ip->dbth_pinmax]; lp++) {
+				if (lp->b_ref == INVALID_ROFF)
+					continue;
+				bhp = R_ADDR(
+				    &dbmp->reginfo[lp->region], lp->b_ref);
+				__db_msg(env,
+				     "\t\tpins: %lu", (u_long)bhp->pgno);
+			}
+		}
+	return (0);
+}
+
+/*
+ * __env_print_fh --
+ *	Display statistics for all handles open in this environment.
+ */
+static int
+__env_print_fh(env)
+	ENV *env;
+{
+	DB_FH *fhp;
+
+	if (TAILQ_FIRST(&env->fdlist) == NULL)
+		return (0);
+
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	__db_msg(env, "Environment file handle information");
+
+	MUTEX_LOCK(env, env->mtx_env);
+
+	TAILQ_FOREACH(fhp, &env->fdlist, q)
+		__db_print_fh(env, NULL, fhp, 0);
+
+	MUTEX_UNLOCK(env, env->mtx_env);
+
+	return (0);
+}
+
+/*
+ * __db_print_fh --
+ *	Print out a file handle.
+ *
+ * PUBLIC: void __db_print_fh __P((ENV *, const char *, DB_FH *, u_int32_t));
+ */
+void
+__db_print_fh(env, tag, fh, flags)
+	ENV *env;
+	const char *tag;
+	DB_FH *fh;
+	u_int32_t flags;
+{
+	static const FN fn[] = {
+		{ DB_FH_NOSYNC,	"DB_FH_NOSYNC" },
+		{ DB_FH_OPENED,	"DB_FH_OPENED" },
+		{ DB_FH_UNLINK,	"DB_FH_UNLINK" },
+		{ 0,		NULL }
+	};
+
+	if (fh == NULL) {
+		STAT_ISSET(tag, fh);
+		return;
+	}
+
+	STAT_STRING("file-handle.file name", fh->name);
+
+	__mutex_print_debug_single(
+	    env, "file-handle.mutex", fh->mtx_fh, flags);
+
+	STAT_LONG("file-handle.reference count", fh->ref);
+	STAT_LONG("file-handle.file descriptor", fh->fd);
+
+	STAT_ULONG("file-handle.page number", fh->pgno);
+	STAT_ULONG("file-handle.page size", fh->pgsize);
+	STAT_ULONG("file-handle.page offset", fh->offset);
+
+	STAT_ULONG("file-handle.seek count", fh->seek_count);
+	STAT_ULONG("file-handle.read count", fh->read_count);
+	STAT_ULONG("file-handle.write count", fh->write_count);
+
+	__db_prflags(env, NULL, fh->flags, fn, NULL, "\tfile-handle.flags");
+}
+
+/*
+ * __db_print_fileid --
+ *	Print out a file ID.
+ *
+ * PUBLIC: void __db_print_fileid __P((ENV *, u_int8_t *, const char *));
+ */
+void
+__db_print_fileid(env, id, suffix)
+	ENV *env;
+	u_int8_t *id;
+	const char *suffix;
+{
+	DB_MSGBUF mb;
+	int i;
+
+	if (id == NULL) {
+		STAT_ISSET("ID", id);
+		return;
+	}
+
+	DB_MSGBUF_INIT(&mb);
+	for (i = 0; i < DB_FILE_ID_LEN; ++i, ++id) {
+		__db_msgadd(env, &mb, "%x", (u_int)*id);
+		if (i < DB_FILE_ID_LEN - 1)
+			__db_msgadd(env, &mb, " ");
+	}
+	if (suffix != NULL)
+		__db_msgadd(env, &mb, "%s", suffix);
+	DB_MSGBUF_FLUSH(env, &mb);
+}
+
+/*
+ * __db_dl --
+ *	Display a big value.
+ *
+ * PUBLIC: void __db_dl __P((ENV *, const char *, u_long));
+ */
+void
+__db_dl(env, msg, value)
+	ENV *env;
+	const char *msg;
+	u_long value;
+{
+	/*
+	 * Two formats: if less than 10 million, display as the number, if
+	 * greater than 10 million display as ###M.
+	 */
+	if (value < 10000000)
+		__db_msg(env, "%lu\t%s", value, msg);
+	else
+		__db_msg(env, "%luM\t%s (%lu)", value / 1000000, msg, value);
+}
+
+/*
+ * __db_dl_pct --
+ *	Display a big value, and related percentage.
+ *
+ * PUBLIC: void __db_dl_pct
+ * PUBLIC:          __P((ENV *, const char *, u_long, int, const char *));
+ */
+void
+__db_dl_pct(env, msg, value, pct, tag)
+	ENV *env;
+	const char *msg, *tag;
+	u_long value;
+	int pct;
+{
+	DB_MSGBUF mb;
+
+	DB_MSGBUF_INIT(&mb);
+
+	/*
+	 * Two formats: if less than 10 million, display as the number, if
+	 * greater than 10 million, round it off and display as ###M.
+	 */
+	if (value < 10000000)
+		__db_msgadd(env, &mb, "%lu\t%s", value, msg);
+	else
+		__db_msgadd(env,
+		    &mb, "%luM\t%s", (value + 500000) / 1000000, msg);
+	if (tag == NULL)
+		__db_msgadd(env, &mb, " (%d%%)", pct);
+	else
+		__db_msgadd(env, &mb, " (%d%% %s)", pct, tag);
+
+	DB_MSGBUF_FLUSH(env, &mb);
+}
+
+/*
+ * __db_dlbytes --
+ *	Display a big number of bytes.
+ *
+ * PUBLIC: void __db_dlbytes
+ * PUBLIC:     __P((ENV *, const char *, u_long, u_long, u_long));
+ */
+void
+__db_dlbytes(env, msg, gbytes, mbytes, bytes)
+	ENV *env;
+	const char *msg;
+	u_long gbytes, mbytes, bytes;
+{
+	DB_MSGBUF mb;
+	const char *sep;
+
+	DB_MSGBUF_INIT(&mb);
+
+	/* Normalize the values. */
+	while (bytes >= MEGABYTE) {
+		++mbytes;
+		bytes -= MEGABYTE;
+	}
+	while (mbytes >= GIGABYTE / MEGABYTE) {
+		++gbytes;
+		mbytes -= GIGABYTE / MEGABYTE;
+	}
+
+	if (gbytes == 0 && mbytes == 0 && bytes == 0)
+		__db_msgadd(env, &mb, "0");
+	else {
+		sep = "";
+		if (gbytes > 0) {
+			__db_msgadd(env, &mb, "%luGB", gbytes);
+			sep = " ";
+		}
+		if (mbytes > 0) {
+			__db_msgadd(env, &mb, "%s%luMB", sep, mbytes);
+			sep = " ";
+		}
+		if (bytes >= 1024) {
+			__db_msgadd(env, &mb, "%s%luKB", sep, bytes / 1024);
+			bytes %= 1024;
+			sep = " ";
+		}
+		if (bytes > 0)
+			__db_msgadd(env, &mb, "%s%luB", sep, bytes);
+	}
+
+	__db_msgadd(env, &mb, "\t%s", msg);
+
+	DB_MSGBUF_FLUSH(env, &mb);
+}
+
+/*
+ * __db_print_reginfo --
+ *	Print out underlying shared region information.
+ *
+ * PUBLIC: void __db_print_reginfo
+ * PUBLIC:     __P((ENV *, REGINFO *, const char *, u_int32_t));
+ */
+void
+__db_print_reginfo(env, infop, s, flags)
+	ENV *env;
+	REGINFO *infop;
+	const char *s;
+	u_int32_t flags;
+{
+	static const FN fn[] = {
+		{ REGION_CREATE,	"REGION_CREATE" },
+		{ REGION_CREATE_OK,	"REGION_CREATE_OK" },
+		{ REGION_JOIN_OK,	"REGION_JOIN_OK" },
+		{ REGION_SHARED,	"REGION_SHARED" },
+		{ 0,			NULL }
+	};
+
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	__db_msg(env, "%s REGINFO information:",  s);
+	STAT_STRING("Region type", __reg_type(infop->type));
+	STAT_ULONG("Region ID", infop->id);
+	STAT_STRING("Region name", infop->name);
+	STAT_POINTER("Region address", infop->addr);
+	STAT_POINTER("Region allocation head", infop->head);
+	STAT_POINTER("Region primary address", infop->primary);
+	STAT_ULONG("Region maximum allocation", infop->max_alloc);
+	STAT_ULONG("Region allocated", infop->allocated);
+	__env_alloc_print(infop, flags);
+
+	__db_prflags(env, NULL, infop->flags, fn, NULL, "\tRegion flags");
+}
+
+/*
+ * __reg_type --
+ *	Return the region type string.
+ */
+static const char *
+__reg_type(t)
+	reg_type_t t;
+{
+	switch (t) {
+	case REGION_TYPE_ENV:
+		return ("Environment");
+	case REGION_TYPE_LOCK:
+		return ("Lock");
+	case REGION_TYPE_LOG:
+		return ("Log");
+	case REGION_TYPE_MPOOL:
+		return ("Mpool");
+	case REGION_TYPE_MUTEX:
+		return ("Mutex");
+	case REGION_TYPE_TXN:
+		return ("Transaction");
+	case INVALID_REGION_TYPE:
+		return ("Invalid");
+	}
+	return ("Unknown");
+}
+
+#else /* !HAVE_STATISTICS */
+
+/*
+ * __db_stat_not_built --
+ *	Common error routine when library not built with statistics.
+ *
+ * PUBLIC: int __db_stat_not_built __P((ENV *));
+ */
+int
+__db_stat_not_built(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("1554",
+	    "Library build did not include statistics support"));
+	return (DB_OPNOTSUP);
+}
+
+int
+__env_stat_print_pp(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+
+	return (__db_stat_not_built(dbenv->env));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/fileops/fop_basic.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,340 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/fop.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+#include "dbinc/db_am.h"
+
+/*
+ * The transactional guarantees Berkeley DB provides for file
+ * system level operations (database physical file create, delete,
+ * rename) are based on our understanding of current file system
+ * semantics; a system that does not provide these semantics and
+ * guarantees could be in danger.
+ *
+ * First, as in standard database changes, fsync and fdatasync must
+ * work: when applied to the log file, the records written into the
+ * log must be transferred to stable storage.
+ *
+ * Second, it must not be possible for the log file to be removed
+ * without previous file system level operations being flushed to
+ * stable storage.  Berkeley DB applications write log records
+ * describing file system operations into the log, then perform the
+ * file system operation, then commit the enclosing transaction
+ * (which flushes the log file to stable storage).  Subsequently,
+ * a database environment checkpoint may make it possible for the
+ * application to remove the log file containing the record of the
+ * file system operation.  DB's transactional guarantees for file
+ * system operations require the log file removal not succeed until
+ * all previous filesystem operations have been flushed to stable
+ * storage.  In other words, the flush of the log file, or the
+ * removal of the log file, must block until all previous
+ * filesystem operations have been flushed to stable storage.  This
+ * semantic is not, as far as we know, required by any existing
+ * standards document, but we have never seen a filesystem where
+ * it does not apply.
+ */
+
+/*
+ * __fop_create --
+ * Create a (transactionally protected) file system object.  This is used
+ * to create DB files now, potentially blobs, queue extents and anything
+ * else you wish to store in a file system object.
+ *
+ * PUBLIC: int __fop_create __P((ENV *, DB_TXN *,
+ * PUBLIC:     DB_FH **, const char *, const char **, APPNAME, int, u_int32_t));
+ */
+int
+__fop_create(env, txn, fhpp, name, dirp, appname, mode, flags)
+	ENV *env;
+	DB_TXN *txn;
+	DB_FH **fhpp;
+	const char *name, **dirp;
+	APPNAME appname;
+	int mode;
+	u_int32_t flags;
+{
+	DBT data, dirdata;
+	DB_FH *fhp;
+	DB_LSN lsn;
+	int ret;
+	char *real_name;
+
+	real_name = NULL;
+	fhp = NULL;
+
+	if ((ret = __db_appname(env, appname, name, dirp, &real_name)) != 0)
+		return (ret);
+
+	if (mode == 0)
+		mode = DB_MODE_600;
+
+	if (DBENV_LOGGING(env)
+#if !defined(DEBUG_WOP)
+	    && txn != NULL
+#endif
+	    ) {
+		DB_INIT_DBT(data, name, strlen(name) + 1);
+		if (dirp != NULL && *dirp != NULL)
+			DB_INIT_DBT(dirdata, *dirp, strlen(*dirp) + 1);
+		else
+			memset(&dirdata, 0, sizeof(dirdata));
+		if ((ret = __fop_create_log(env, txn, &lsn,
+		    flags | DB_FLUSH,
+		    &data, &dirdata, (u_int32_t)appname, (u_int32_t)mode)) != 0)
+			goto err;
+	}
+
+	DB_ENV_TEST_RECOVERY(env, DB_TEST_POSTLOG, ret, name);
+
+	if (fhpp == NULL)
+		fhpp = &fhp;
+	ret = __os_open(
+	    env, real_name, 0, DB_OSO_CREATE | DB_OSO_EXCL, mode, fhpp);
+
+err:
+DB_TEST_RECOVERY_LABEL
+	if (fhpp == &fhp && fhp != NULL)
+		(void)__os_closehandle(env, fhp);
+	if (real_name != NULL)
+		__os_free(env, real_name);
+	return (ret);
+}
+
+/*
+ * __fop_remove --
+ *	Remove a file system object.
+ *
+ * PUBLIC: int __fop_remove __P((ENV *, DB_TXN *,
+ * PUBLIC:     u_int8_t *, const char *, const char **, APPNAME, u_int32_t));
+ */
+int
+__fop_remove(env, txn, fileid, name, dirp, appname, flags)
+	ENV *env;
+	DB_TXN *txn;
+	u_int8_t *fileid;
+	const char *name, **dirp;
+	APPNAME appname;
+	u_int32_t flags;
+{
+	DBT fdbt, ndbt;
+	DB_LSN lsn;
+	char *real_name;
+	int ret;
+
+	real_name = NULL;
+
+	if ((ret = __db_appname(env, appname, name, dirp, &real_name)) != 0)
+		goto err;
+
+	if (!IS_REAL_TXN(txn)) {
+		if (fileid != NULL && (ret = __memp_nameop(
+		    env, fileid, NULL, real_name, NULL, 0)) != 0)
+			goto err;
+	} else {
+		if (DBENV_LOGGING(env)
+#if !defined(DEBUG_WOP)
+		    && txn != NULL
+#endif
+		) {
+			memset(&fdbt, 0, sizeof(ndbt));
+			fdbt.data = fileid;
+			fdbt.size = fileid == NULL ? 0 : DB_FILE_ID_LEN;
+			DB_INIT_DBT(ndbt, name, strlen(name) + 1);
+			if ((ret = __fop_remove_log(env, txn, &lsn,
+			    flags, &ndbt, &fdbt, (u_int32_t)appname)) != 0)
+				goto err;
+		}
+		ret = __txn_remevent(env, txn, real_name, fileid, 0);
+	}
+
+err:	if (real_name != NULL)
+		__os_free(env, real_name);
+	return (ret);
+}
+
+/*
+ * __fop_write
+ *
+ * Write "size" bytes from "buf" to file "name" beginning at offset "off."
+ * If the file is open, supply a handle in fhp.  Istmp indicate if this is
+ * an operation that needs to be undone in the face of failure (i.e., if
+ * this is a write to a temporary file, we're simply going to remove the
+ * file, so don't worry about undoing the write).
+ *
+ * Currently, we *only* use this with istmp true.  If we need more general
+ * handling, then we'll have to zero out regions on abort (and possibly
+ * log the before image of the data in the log record).
+ *
+ * PUBLIC: int __fop_write __P((ENV *, DB_TXN *,
+ * PUBLIC:     const char *, const char *, APPNAME, DB_FH *, u_int32_t,
+ * PUBLIC:     db_pgno_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t));
+ */
+int
+__fop_write(env, txn,
+    name, dirname, appname, fhp, pgsize, pageno, off, buf, size, istmp, flags)
+	ENV *env;
+	DB_TXN *txn;
+	const char *name, *dirname;
+	APPNAME appname;
+	DB_FH *fhp;
+	u_int32_t pgsize;
+	db_pgno_t pageno;
+	u_int32_t off;
+	void *buf;
+	u_int32_t size, istmp, flags;
+{
+	DBT data, namedbt, dirdbt;
+	DB_LSN lsn;
+	size_t nbytes;
+	int local_open, ret, t_ret;
+	char *real_name;
+
+	DB_ASSERT(env, istmp != 0);
+
+	ret = local_open = 0;
+	real_name = NULL;
+
+	if (DBENV_LOGGING(env)
+#if !defined(DEBUG_WOP)
+	    && txn != NULL
+#endif
+	    ) {
+		memset(&data, 0, sizeof(data));
+		data.data = buf;
+		data.size = size;
+		DB_INIT_DBT(namedbt, name, strlen(name) + 1);
+		if (dirname != NULL)
+			DB_INIT_DBT(dirdbt, dirname, strlen(dirname) + 1);
+		else
+			memset(&dirdbt, 0, sizeof(dirdbt));
+		if ((ret = __fop_write_log(env, txn,
+		    &lsn, flags, &namedbt, &dirdbt, (u_int32_t)appname,
+		    pgsize, pageno, off, &data, istmp)) != 0)
+			goto err;
+	}
+
+	if (fhp == NULL) {
+		/* File isn't open; we need to reopen it. */
+		if ((ret = __db_appname(env,
+		    appname, name, &dirname, &real_name)) != 0)
+			return (ret);
+
+		if ((ret = __os_open(env, real_name, 0, 0, 0, &fhp)) != 0)
+			goto err;
+		local_open = 1;
+	}
+
+	/* Seek to offset. */
+	if ((ret = __os_seek(env, fhp, pageno, pgsize, off)) != 0)
+		goto err;
+
+	/* Now do the write. */
+	if ((ret = __os_write(env, fhp, buf, size, &nbytes)) != 0)
+		goto err;
+
+err:	if (local_open &&
+	    (t_ret = __os_closehandle(env, fhp)) != 0 && ret == 0)
+			ret = t_ret;
+
+	if (real_name != NULL)
+		__os_free(env, real_name);
+	return (ret);
+}
+
+/*
+ * __fop_rename --
+ *	Change a file's name.
+ *
+ * PUBLIC: int __fop_rename __P((ENV *, DB_TXN *, const char *, const char *,
+ * PUBLIC:      const char **, u_int8_t *, APPNAME, int, u_int32_t));
+ */
+int
+__fop_rename(env, txn, oldname, newname, dirp, fid, appname, with_undo, flags)
+	ENV *env;
+	DB_TXN *txn;
+	const char *oldname;
+	const char *newname;
+	const char **dirp;
+	u_int8_t *fid;
+	APPNAME appname;
+	int with_undo;
+	u_int32_t flags;
+{
+	DBT fiddbt, dir, new, old;
+	DB_LSN lsn;
+	int ret;
+	char *n, *o;
+
+	o = n = NULL;
+	if ((ret = __db_appname(env, appname, oldname, dirp, &o)) != 0)
+		goto err;
+	if ((ret = __db_appname(env, appname, newname, dirp, &n)) != 0)
+		goto err;
+
+	if (DBENV_LOGGING(env)
+#if !defined(DEBUG_WOP)
+	    && txn != NULL
+#endif
+	    ) {
+		DB_INIT_DBT(old, oldname, strlen(oldname) + 1);
+		DB_INIT_DBT(new, newname, strlen(newname) + 1);
+		if (dirp != NULL && *dirp != NULL)
+			DB_INIT_DBT(dir, *dirp, strlen(*dirp) + 1);
+		else
+			memset(&dir, 0, sizeof(dir));
+		memset(&fiddbt, 0, sizeof(fiddbt));
+		fiddbt.data = fid;
+		fiddbt.size = DB_FILE_ID_LEN;
+		if (with_undo)
+			ret = __fop_rename_log(env,
+			    txn, &lsn, flags | DB_FLUSH,
+			    &old, &new, &dir, &fiddbt, (u_int32_t)appname);
+		else
+			ret = __fop_rename_noundo_log(env,
+			    txn, &lsn, flags | DB_FLUSH,
+			    &old, &new, &dir, &fiddbt, (u_int32_t)appname);
+		if (ret != 0)
+			goto err;
+	}
+
+	ret = __memp_nameop(env, fid, newname, o, n, 0);
+
+err:	if (o != NULL)
+		__os_free(env, o);
+	if (n != NULL)
+		__os_free(env, n);
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/fileops/fop_util.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1192 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/hash.h"
+#include "dbinc/fop.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+static int __fop_set_pgsize __P((DB *, DB_FH *, const char *));
+static int __fop_inmem_create __P((DB *, const char *, DB_TXN *, u_int32_t));
+static int __fop_inmem_read_meta __P((DB *, DB_TXN *, const char *, u_int32_t,
+	    u_int32_t));
+
+/*
+ * Acquire the environment meta-data lock.  The parameters are the
+ * environment (ENV), the locker id to use in acquiring the lock (ID)
+ * and a pointer to a DB_LOCK.
+ *
+ * !!!
+ * Turn off locking for Critical Path.  The application must do its own
+ * synchronization of open/create.  Two threads creating and opening a
+ * file at the same time may have unpredictable results.
+ */
+#ifdef CRITICALPATH_10266
+#define	GET_ENVLOCK(ENV, ID, L) (0)
+#else
+#define	GET_ENVLOCK(ENV, ID, L) do {					\
+	DBT __dbt;							\
+	u_int32_t __lockval;						\
+									\
+	if (LOCKING_ON((ENV))) {					\
+		__lockval = 1;						\
+		__dbt.data = &__lockval;				\
+		__dbt.size = sizeof(__lockval);				\
+		if ((ret = __lock_get((ENV), (ID),			\
+		    0, &__dbt, DB_LOCK_WRITE, (L))) != 0)		\
+			goto err;					\
+	}								\
+} while (0)
+#endif
+
+#define	RESET_MPF(D, F) do {						\
+	(void)__memp_fclose((D)->mpf, (F));				\
+	(D)->mpf = NULL;						\
+	F_CLR((D), DB_AM_OPEN_CALLED);					\
+	if ((ret = __memp_fcreate((D)->env, &(D)->mpf)) != 0)		\
+		goto err;						\
+} while (0)
+
+/*
+ * If we open a file handle and our caller is doing fcntl(2) locking,
+ * we can't close the handle because that would discard the caller's
+ * lock. Save it until we close or refresh the DB handle.
+ */
+#define	CLOSE_HANDLE(D, F) {						\
+	if ((F) != NULL) {						\
+		if (LF_ISSET(DB_FCNTL_LOCKING))				\
+			(D)->saved_open_fhp = (F);			\
+		else if ((t_ret =					\
+		    __os_closehandle((D)->env, (F))) != 0) {		\
+			if (ret == 0)					\
+				ret = t_ret;				\
+			goto err;					\
+		}							\
+		(F) = NULL;						\
+	}								\
+}
+
+/*
+ * __fop_lock_handle --
+ *
+ * Get the handle lock for a database.  If the envlock is specified, do this
+ * as a lock_vec call that releases the environment lock before acquiring the
+ * handle lock.
+ *
+ * PUBLIC: int __fop_lock_handle __P((ENV *,
+ * PUBLIC:     DB *, DB_LOCKER *, db_lockmode_t, DB_LOCK *, u_int32_t));
+ *
+ */
+int
+__fop_lock_handle(env, dbp, locker, mode, elockp, flags)
+	ENV *env;
+	DB *dbp;
+	DB_LOCKER *locker;
+	db_lockmode_t mode;
+	DB_LOCK *elockp;
+	u_int32_t flags;
+{
+	DBT fileobj;
+	DB_LOCKREQ reqs[2], *ereq;
+	DB_LOCK_ILOCK lock_desc;
+	int ret;
+
+	if (!LOCKING_ON(env) ||
+	    F_ISSET(dbp, DB_AM_COMPENSATE | DB_AM_RECOVER))
+		return (0);
+
+	/*
+	 * If we are in recovery, the only locking we should be
+	 * doing is on the global environment.  The one exception
+	 * is if we are opening an exclusive database on a client 
+	 * syncing with the master.
+	 */
+	if (IS_RECOVERING(env) && !F2_ISSET(dbp, DB2_AM_INTEXCL))
+		return (elockp == NULL ? 0 : __ENV_LPUT(env, *elockp));
+
+	memcpy(lock_desc.fileid, dbp->fileid, DB_FILE_ID_LEN);
+	lock_desc.pgno = dbp->meta_pgno;
+	lock_desc.type = DB_HANDLE_LOCK;
+
+	memset(&fileobj, 0, sizeof(fileobj));
+	fileobj.data = &lock_desc;
+	fileobj.size = sizeof(lock_desc);
+	DB_TEST_SUBLOCKS(env, flags);
+	if (F2_ISSET(dbp, DB2_AM_INTEXCL))
+	    flags |= DB_LOCK_IGNORE_REC;
+	if (elockp == NULL)
+		ret = __lock_get(env, locker,
+		    flags, &fileobj, mode, &dbp->handle_lock);
+	else {
+		reqs[0].op = DB_LOCK_PUT;
+		reqs[0].lock = *elockp;
+		reqs[1].op = DB_LOCK_GET;
+		reqs[1].mode = mode;
+		reqs[1].obj = &fileobj;
+		reqs[1].timeout = 0;
+		if ((ret = __lock_vec(env,
+		    locker, flags, reqs, 2, &ereq)) == 0) {
+			dbp->handle_lock = reqs[1].lock;
+			if (elockp != &dbp->handle_lock)
+				LOCK_INIT(*elockp);
+		} else if (ereq != reqs)
+			LOCK_INIT(*elockp);
+	}
+
+	dbp->cur_locker = locker;
+	return (ret);
+}
+
+/*
+ * __fop_file_setup --
+ *
+ * Perform all the needed checking and locking to open up or create a
+ * file.
+ *
+ * There's a reason we don't push this code down into the buffer cache.
+ * The problem is that there's no information external to the file that
+ * we can use as a unique ID.  UNIX has dev/inode pairs, but they are
+ * not necessarily unique after reboot, if the file was mounted via NFS.
+ * Windows has similar problems, as the FAT filesystem doesn't maintain
+ * dev/inode numbers across reboot.  So, we must get something from the
+ * file we can use to ensure that, even after a reboot, the file we're
+ * joining in the cache is the right file for us to join.  The solution
+ * we use is to maintain a file ID that's stored in the database, and
+ * that's why we have to open and read the file before calling into the
+ * buffer cache or obtaining a lock (we use this unique fileid to lock
+ * as well as to identify like files in the cache).
+ *
+ * There are a couple of idiosyncrasies that this code must support, in
+ * particular, DB_TRUNCATE and DB_FCNTL_LOCKING.  First, we disallow
+ * DB_TRUNCATE in the presence of transactions, since opening a file with
+ * O_TRUNC will result in data being lost in an unrecoverable fashion.
+ * We also disallow DB_TRUNCATE if locking is enabled, because even in
+ * the presence of locking, we cannot avoid race conditions, so allowing
+ * DB_TRUNCATE with locking would be misleading.  See SR [#7345] for more
+ * details.
+ *
+ * However, if you are running with neither locking nor transactions, then
+ * you can specify DB_TRUNCATE, and if you do so, we will truncate the file
+ * regardless of its contents.
+ *
+ * FCNTL locking introduces another set of complications.  First, the only
+ * reason we support the DB_FCNTL_LOCKING flag is for historic compatibility
+ * with programs like Sendmail and Postfix.  In these cases, the caller may
+ * already have a lock on the file; we need to make sure that any file handles
+ * we open remain open, because if we were to close them, the lock held by the
+ * caller would go away.  Furthermore, Sendmail and/or Postfix need the ability
+ * to create databases in empty files.  So, when you're doing FCNTL locking,
+ * it's reasonable that you are trying to create a database into a 0-length
+ * file and we allow it, while under normal conditions, we do not create
+ * databases if the files already exist and are not Berkeley DB files.
+ *
+ * PUBLIC: int __fop_file_setup __P((DB *, DB_THREAD_INFO *ip,
+ * PUBLIC:     DB_TXN *, const char *, int, u_int32_t, u_int32_t *));
+ */
+int
+__fop_file_setup(dbp, ip, txn, name, mode, flags, retidp)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name;
+	int mode;
+	u_int32_t flags, *retidp;
+{
+	DBTYPE save_type;
+	DB_FH *fhp;
+	DB_LOCK elock;
+	DB_LOCKER *locker;
+	DB_TXN *stxn;
+	ENV *env;
+	size_t len;
+	APPNAME aflags;
+	u_int32_t dflags, oflags;
+	u_int8_t mbuf[DBMETASIZE];
+	int created_locker, create_ok, ret, retries, t_ret, tmp_created;
+	int truncating, was_inval;
+	char *real_name, *real_tmpname, *tmpname;
+	db_lockmode_t lockmode;
+
+	*retidp = TXN_INVALID;
+
+	env = dbp->env;
+	fhp = NULL;
+	LOCK_INIT(elock);
+	stxn = NULL;
+	created_locker = tmp_created = truncating = was_inval = 0;
+	real_name = real_tmpname = tmpname = NULL;
+	dflags = F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0;
+	aflags = LF_ISSET(DB_INTERNAL_PERSISTENT_DB) ? DB_APP_META :
+	    (LF_ISSET(DB_INTERNAL_TEMPORARY_DB) ? DB_APP_NONE : DB_APP_DATA);
+	LF_CLR(DB_INTERNAL_PERSISTENT_DB | DB_INTERNAL_TEMPORARY_DB);
+
+	ret = 0;
+	retries = 0;
+	save_type = dbp->type;
+	if (F2_ISSET(dbp, DB2_AM_EXCL))
+		lockmode = DB_LOCK_WRITE;
+	else
+		lockmode = DB_LOCK_READ;
+
+	/*
+	 * Get a lockerid for this handle.  There are paths through queue
+	 * rename and remove where this dbp already has a locker, so make
+	 * sure we don't clobber it and conflict.
+	 */
+	if (LOCKING_ON(env) &&
+	    !F_ISSET(dbp, DB_AM_COMPENSATE) &&
+	    !F_ISSET(dbp, DB_AM_RECOVER) &&
+	    dbp->locker == DB_LOCK_INVALIDID) {
+		if ((ret = __lock_id(env, NULL, &dbp->locker)) != 0)
+			goto err;
+		created_locker = 1;
+	}
+	LOCK_INIT(dbp->handle_lock);
+
+	locker = dbp->locker;
+#ifdef HAVE_TRANSACTIONS
+	if (txn != NULL && dbp->locker != NULL && F_ISSET(txn, TXN_INFAMILY)) {
+		if ((ret = __lock_addfamilylocker(env,
+		    txn->txnid, dbp->locker->id, 1)) != 0)
+			goto err;
+		txn = NULL;
+	}
+
+	if (txn != NULL)
+		locker = txn->locker;
+#endif
+
+	oflags = 0;
+	if (F_ISSET(dbp, DB_AM_INMEM))
+		real_name = (char *)name;
+	else {
+		/* Get the real backing file name. */
+		if ((ret = __db_appname(env,
+		    aflags, name, &dbp->dirname, &real_name)) != 0)
+			goto err;
+
+		/* Fill in the default file mode. */
+		if (mode == 0)
+			mode = DB_MODE_660;
+
+		if (LF_ISSET(DB_RDONLY))
+			oflags |= DB_OSO_RDONLY;
+		if (LF_ISSET(DB_TRUNCATE))
+			oflags |= DB_OSO_TRUNC;
+	}
+
+	retries = 0;
+	create_ok = LF_ISSET(DB_CREATE);
+	LF_CLR(DB_CREATE);
+
+retry:
+	/*
+	 * If we cannot create the file, only retry a few times.  We
+	 * think we might be in a race with another create, but it could
+	 * be that the backup filename exists (that is, is left over from
+	 * a previous crash).  It is also possible to read the metadata
+	 * page while it is being written and fail the checksum.
+	 */
+	if (++retries > DB_RETRY) {
+		__db_errx(env, DB_STR_A("0002",
+		    "__fop_file_setup:  Retry limit (%d) exceeded", "%d"),
+		    DB_RETRY);
+		goto err;
+	}
+	if (!F_ISSET(dbp, DB_AM_COMPENSATE) && !F_ISSET(dbp, DB_AM_RECOVER))
+		GET_ENVLOCK(env, locker, &elock);
+	if (name == NULL)
+		ret = ENOENT;
+	else if (F_ISSET(dbp, DB_AM_INMEM)) {
+		ret = __env_mpool(dbp, name, flags);
+		/*
+		 * We are using __env_open as a check for existence.
+		 * However, __env_mpool does an actual open and there
+		 * are scenarios where the object exists, but cannot be
+		 * opened, because our settings don't match those internally.
+		 * We need to check for that explicitly.  We'll need the
+		 * mpool open to read the meta-data page, so we're going to
+		 * have to temporarily turn this dbp into an UNKNOWN one.
+		 */
+		if (ret == EINVAL) {
+			was_inval = 1;
+			save_type = dbp->type;
+			dbp->type = DB_UNKNOWN;
+			ret = __env_mpool(dbp, name, flags);
+			dbp->type = save_type;
+		}
+	} else
+		ret = __os_exists(env, real_name, NULL);
+
+	if (ret == 0) {
+		/*
+		 * If the file exists, there are 5 possible cases:
+		 * 1. DB_EXCL was specified so this is an error, unless
+		 *	this is a file left around after a rename and we
+		 *	are in the same transaction.  This gets decomposed
+		 *	into several subcases, because we check for various
+		 *	errors before we know we're in rename.
+		 * 2. We are truncating, and it doesn't matter what kind
+		 *	of file it is, we should open/create it.
+		 * 3. It is 0-length, we are not doing transactions (i.e.,
+		 *      we are sendmail), we should open/create into it.
+		 *	-- on-disk files only!
+		 * 4. Is it a Berkeley DB file and we should simply open it.
+		 * 5. It is not a BDB file and we should return an error.
+		 */
+
+		/* Open file (if there is one). */
+reopen:		if (!F_ISSET(dbp, DB_AM_INMEM) && (ret =
+		    __os_open(env, real_name, 0, oflags, 0, &fhp)) != 0)
+			goto err;
+
+		/* Case 2: DB_TRUNCATE: we must do the creation in place. */
+		if (LF_ISSET(DB_TRUNCATE)) {
+			if (LF_ISSET(DB_EXCL)) {
+				/* Case 1a: DB_EXCL and DB_TRUNCATE. */
+				ret = EEXIST;
+				goto err;
+			}
+			tmpname = (char *)name;
+			goto creat2;
+		}
+
+		/* Cases 1,3-5: we need to read the meta-data page. */
+		if (F_ISSET(dbp, DB_AM_INMEM)) {
+			if (LOGGING_ON(env) && (ret = __env_dbreg_setup(dbp,
+			    txn, NULL, name, TXN_INVALID)) != 0)
+				return (ret);
+			ret = __fop_inmem_read_meta(
+			    dbp, txn, name, flags, DB_CHK_META|DB_CHK_ONLY);
+		} else {
+			ret = __fop_read_meta(env, real_name, mbuf,
+			    sizeof(mbuf), fhp,
+			    LF_ISSET(DB_NOERROR) ||
+			    (LF_ISSET(DB_FCNTL_LOCKING) && txn == NULL) ? 1 : 0,
+			    &len);
+
+			/* Case 3: 0-length, no txns. */
+			if (ret != 0 && len == 0 && txn == NULL) {
+				if (LF_ISSET(DB_EXCL)) {
+					/*
+					 * Case 1b: DB_EXCL and
+					 * 0-length file exists.
+					 */
+					ret = EEXIST;
+					goto err;
+				}
+				tmpname = (char *)name;
+				if (create_ok)
+					goto creat2;
+				goto done;
+			}
+
+			/* 
+			 * Case 4: This is a valid file.  Now check the
+			 * checksum and decrypt the file so the file 
+			 * id can be obtained for the handle lock.  Note that
+			 * the checksum can fail if the database is being
+			 * written (possible because the handle lock has
+			 * not been obtained yet).  So on checksum fail retry
+			 * until the checksum succeeds or the number of 
+			 * retries is exhausted, then throw an error.
+			 */
+			if (ret == 0 && (ret = __db_chk_meta(env, dbp,
+			    (DBMETA *)mbuf, DB_CHK_META)) == DB_CHKSUM_FAIL) {
+				if ((t_ret = __ENV_LPUT(env, elock)) != 0) {
+					ret = t_ret;
+					goto err;
+				}
+				/* 
+				 * Retry unless the number of retries is
+				 * exhausted.
+				 */
+				if (!(retries < DB_RETRY)) {
+					__db_errx(env, DB_STR_A("0210",
+			"%s: metadata page checksum error", "%s"), real_name);
+					if (F_ISSET(dbp, DB_AM_RECOVER))
+						ret = ENOENT;
+					else
+						ret = EINVAL;
+					goto err;
+				}
+				CLOSE_HANDLE(dbp, fhp);
+				goto retry;
+			}
+			/* Get the file id for the handle lock. */
+			if (ret == 0)
+				memcpy(dbp->fileid,
+				((DBMETA *)mbuf)->uid, DB_FILE_ID_LEN);
+		}
+
+		/* Case 5: Invalid file. */
+		if (ret != 0)
+			goto err;
+
+		/* Now, get our handle lock. */
+		if ((ret = __fop_lock_handle(env,
+		    dbp, locker, lockmode, NULL, DB_LOCK_NOWAIT)) == 0) {
+			if ((ret = __ENV_LPUT(env, elock)) != 0)
+				goto err;
+		} else if (ret != DB_LOCK_NOTGRANTED ||
+		    ((txn != NULL && (F_ISSET(txn, TXN_NOWAIT))) ||
+		    F2_ISSET(dbp, DB2_AM_NOWAIT)))
+			goto err;
+		else {
+			PERFMON3(env,
+			    race, fop_file_setup, (char *) name, ret, flags);
+			/*
+			 * We were unable to acquire the handle lock without
+			 * blocking.  The fact that we are blocking might mean
+			 * that someone else is trying to delete the file.
+			 * Since some platforms cannot delete files while they
+			 * are open (Windows), we are going to have to close
+			 * the file.  This would be a problem if we were doing
+			 * FCNTL locking, because our closing the handle would
+			 * release the FCNTL locks.  Fortunately, if we are
+			 * doing FCNTL locking, then we should never fail to
+			 * acquire our handle lock, so we should never get here.
+			 * We assert it here to make sure we aren't destroying
+			 * any application level FCNTL semantics.
+			 */
+			DB_ASSERT(env, !LF_ISSET(DB_FCNTL_LOCKING));
+			if (!F_ISSET(dbp, DB_AM_INMEM))
+				CLOSE_HANDLE(dbp, fhp);
+			if ((ret = __fop_lock_handle(env,
+			    dbp, locker, lockmode, &elock, 0)) != 0) {
+				if (F_ISSET(dbp, DB_AM_INMEM))
+					RESET_MPF(dbp, 0);
+				goto err;
+			}
+
+			/*
+			 * If we had to wait, we might be waiting on a
+			 * dummy file used in create/destroy of a database.
+			 * To be sure we have the correct information we
+			 * try again.
+			 */
+			if (F_ISSET(dbp, DB_AM_INMEM)) {
+				RESET_MPF(dbp, 0);
+				MAKE_INMEM(dbp);
+			}
+			if ((ret =
+			    __ENV_LPUT(env, dbp->handle_lock)) != 0) {
+				LOCK_INIT(dbp->handle_lock);
+				goto err;
+			}
+			goto retry;
+
+		}
+
+		/* 
+		 * If we got here, then we have the handle lock, it is now
+		 * safe to check the rest of the meta data, since the file
+		 * will not be deleted out from under the handle.
+		 */
+		if (F_ISSET(dbp, DB_AM_INMEM)) {
+			if ((ret = __fop_inmem_read_meta(
+			    dbp, txn, name, flags, DB_SKIP_CHK)) != 0)
+				goto err;
+		} else {
+			if ((ret = __db_meta_setup(env, dbp, real_name, 
+			    (DBMETA *)mbuf, flags, DB_SKIP_CHK)) != 0)
+				goto err;
+		}
+
+		/*
+		 * Check for a file in the midst of a rename.  If we find that
+		 * the file is in the midst of a rename, it must be the case
+		 * that it is in our current transaction (else we would still
+		 * be blocking), so we can continue along and create a new file
+		 * with the same name.  In that case, we have to close the file
+		 * handle because we reuse it below.  This is a case where
+		 * a 'was_inval' above is OK.
+		 */
+		if (F_ISSET(dbp, DB_AM_IN_RENAME)) {
+			was_inval = 0;
+			if (create_ok) {
+				if (F_ISSET(dbp, DB_AM_INMEM)) {
+					RESET_MPF(dbp, DB_MPOOL_DISCARD);
+				} else 
+					CLOSE_HANDLE(dbp, fhp);
+				LF_SET(DB_CREATE);
+				goto create;
+			} else {
+				ret = ENOENT;
+				goto err;
+			}
+		}
+
+		/* If we get here, a was_inval is bad. */
+		if (was_inval) {
+			ret = EINVAL;
+			goto err;
+		}
+
+		/*
+		 * Now, case 1: check for DB_EXCL, because the file that exists
+		 * is not in the middle of a rename, so we have an error.  This
+		 * is a weird case, but we need to make sure that we don't
+		 * continue to hold the handle lock, since technically, we
+		 * should not have been allowed to open it.
+		 */
+		if (LF_ISSET(DB_EXCL)) {
+			ret = __ENV_LPUT(env, dbp->handle_lock);
+			LOCK_INIT(dbp->handle_lock);
+			if (ret == 0)
+				ret = EEXIST;
+			goto err;
+		}
+		goto done;
+	}
+
+	/* File does not exist. */
+#ifdef	HAVE_VXWORKS
+	/*
+	 * VxWorks can return file-system specific error codes if the
+	 * file does not exist, not ENOENT.
+	 */
+	if (!create_ok)
+#else
+	if (!create_ok || ret != ENOENT)
+#endif
+		goto err;
+	LF_SET(DB_CREATE);
+	/*
+	 * If we were trying to open a non-existent master database
+	 * readonly clear that here.
+	 */
+	LF_CLR(DB_RDONLY);
+	F_CLR(dbp, DB_AM_RDONLY);
+	ret = 0;
+
+	/*
+	 * We need to create file, which means that we need to set up the file,
+	 * the fileid and the locks.  Then we need to call the appropriate
+	 * routines to create meta-data pages.  For in-memory files, we retain
+	 * the environment lock, while for on-disk files, we drop the env lock
+	 * and create into a temporary.
+	 */
+	if (!F_ISSET(dbp, DB_AM_INMEM) &&
+	    (ret = __ENV_LPUT(env, elock)) != 0)
+		goto err;
+
+create:	if (txn != NULL && IS_REP_CLIENT(env) &&
+	    !F_ISSET(dbp, DB_AM_NOT_DURABLE)) {
+		__db_errx(env, DB_STR("0003",
+		    "Transactional create on replication client disallowed"));
+		ret = EINVAL;
+		goto err;
+	}
+
+	if (F_ISSET(dbp, DB_AM_INMEM)) {
+		if (LOGGING_ON(env) && (ret =
+		    __env_dbreg_setup(dbp, txn, NULL, name, TXN_INVALID)) != 0)
+			return (ret);
+		if ((ret = __fop_inmem_create(dbp, name, txn, flags)) != 0)
+			return (ret);
+	} else {
+		if ((ret = __db_backup_name(env, name, txn, &tmpname)) != 0)
+			goto err;
+		if (TXN_ON(env) && txn != NULL &&
+		    (ret = __txn_begin(env, NULL, txn, &stxn, 0)) != 0)
+			goto err;
+		if ((ret = __fop_create(env, stxn, &fhp,
+		    tmpname, &dbp->dirname, aflags, mode, dflags)) != 0) {
+			/*
+			 * If no transactions, there is a race on creating the
+			 * backup file, as the backup file name is the same for
+			 * all processes.  Wait for the other process to finish
+			 * with the name.
+			 */
+			if (!TXN_ON(env) && ret == EEXIST) {
+				PERFMON3(env,
+				    race, fop_file_setup, tmpname, ret, flags);
+				__os_free(env, tmpname);
+				tmpname = NULL;
+				__os_yield(env, 1, 0);
+				goto retry;
+			}
+			goto err;
+		}
+		tmp_created = 1;
+	}
+
+creat2:	if (!F_ISSET(dbp, DB_AM_INMEM)) {
+		if ((ret = __db_appname(env,
+		    aflags, tmpname, &dbp->dirname, &real_tmpname)) != 0)
+			goto err;
+
+		/* Set the pagesize if it isn't yet set. */
+		if (dbp->pgsize == 0 &&
+		    (ret = __fop_set_pgsize(dbp, fhp, real_tmpname)) != 0)
+			goto errmsg;
+
+		/* Construct a file_id. */
+		if ((ret =
+		    __os_fileid(env, real_tmpname, 1, dbp->fileid)) != 0)
+			goto errmsg;
+	}
+
+	if ((ret = __db_new_file(dbp, ip,
+	    F_ISSET(dbp, DB_AM_INMEM) ? txn : stxn, fhp, tmpname)) != 0)
+		goto err;
+
+	/* Output the REOPEN record after we create. */
+	if (F_ISSET(dbp, DB_AM_INMEM) && dbp->log_filename != NULL && (ret =
+	    __dbreg_log_id(dbp, txn, dbp->log_filename->id, 0)) != 0)
+		return (ret);
+
+	/*
+	 * We need to close the handle here on platforms where remove and
+	 * rename fail if a handle is open (including Windows).
+	 */
+	CLOSE_HANDLE(dbp, fhp);
+
+	/*
+	 * Now move the file into place unless we are creating in place (because
+	 * we created a database in a file that started out 0-length).  If
+	 * this is an in-memory file, we may or may not hold the environment
+	 * lock depending on how we got here.
+	 */
+	if (!F_ISSET(dbp, DB_AM_COMPENSATE) &&
+	    !F_ISSET(dbp, DB_AM_RECOVER) && !LOCK_ISSET(elock))
+		GET_ENVLOCK(env, locker, &elock);
+
+	if (F_ISSET(dbp, DB_AM_IN_RENAME)) {
+		F_CLR(dbp, DB_AM_IN_RENAME);
+		__txn_remrem(env, txn, real_name);
+	} else if (name == tmpname) {
+		/* We created it in place. */
+	} else if (!F_ISSET(dbp, DB_AM_INMEM) &&
+	    __os_exists(env, real_name, NULL) == 0) {
+		/*
+		 * Someone managed to create the file; remove our temp
+		 * and try to open the file that now exists.
+		 */
+		(void)__fop_remove(env, NULL,
+		    dbp->fileid, tmpname, &dbp->dirname, aflags, dflags);
+		(void)__ENV_LPUT(env, dbp->handle_lock);
+		LOCK_INIT(dbp->handle_lock);
+
+		if (stxn != NULL) {
+			ret = __txn_abort(stxn);
+			stxn = NULL;
+		}
+		if (ret != 0)
+			goto err;
+		goto reopen;
+	}
+
+	if (name != NULL && (ret = __fop_lock_handle(env,
+	    dbp, locker, DB_LOCK_WRITE, NULL, NOWAIT_FLAG(txn)|
+	    (F2_ISSET(dbp,DB2_AM_NOWAIT) ? DB_LOCK_NOWAIT : 0))) != 0)
+		goto err;
+	if (tmpname != NULL &&
+	    tmpname != name && (ret = __fop_rename(env, stxn, tmpname,
+	    name, &dbp->dirname, dbp->fileid, aflags, 1, dflags)) != 0)
+		goto err;
+	if ((ret = __ENV_LPUT(env, elock)) != 0)
+		goto err;
+
+#ifdef HAVE_TRANSACTIONS
+	if (stxn != NULL) {
+		*retidp = stxn->txnid;
+		ret = __txn_commit(stxn, 0);
+		stxn = NULL;
+	} else
+#endif
+		*retidp = TXN_INVALID;
+
+	if (ret != 0)
+		goto err;
+
+	F_SET(dbp, DB_AM_CREATED);
+
+	if (0) {
+errmsg:		__db_err(env, ret, "%s", name);
+
+err:		CLOSE_HANDLE(dbp, fhp);
+		if (stxn != NULL)
+			(void)__txn_abort(stxn);
+		if (tmp_created && txn == NULL)
+			(void)__fop_remove(env,
+			    NULL, NULL, tmpname, NULL, aflags, dflags);
+		if (txn == NULL)
+			(void)__ENV_LPUT(env, dbp->handle_lock);
+		(void)__ENV_LPUT(env, elock);
+		if (created_locker) {
+			(void)__lock_id_free(env, dbp->locker);
+			dbp->locker = NULL;
+		}
+	}
+
+done:	/*
+	 * There are cases where real_name and tmpname take on the
+	 * exact same string, so we need to make sure that we do not
+	 * free twice.
+	 */
+	if (!truncating && tmpname != NULL && tmpname != name)
+		__os_free(env, tmpname);
+	if (real_name != name && real_name != NULL)
+		__os_free(env, real_name);
+	if (real_tmpname != NULL)
+		__os_free(env, real_tmpname);
+	CLOSE_HANDLE(dbp, fhp);
+
+	return (ret);
+}
+
+/*
+ * __fop_set_pgsize --
+ *	Set the page size based on file information.
+ */
+static int
+__fop_set_pgsize(dbp, fhp, name)
+	DB *dbp;
+	DB_FH *fhp;
+	const char *name;
+{
+	ENV *env;
+	u_int32_t iopsize;
+	int ret;
+
+	env = dbp->env;
+
+	/*
+	 * Use the filesystem's optimum I/O size as the pagesize if a pagesize
+	 * not specified.  Some filesystems have 64K as their optimum I/O size,
+	 * but as that results in fairly large default caches, we limit the
+	 * default pagesize to 16K.
+	 */
+	if ((ret = __os_ioinfo(env, name, fhp, NULL, NULL, &iopsize)) != 0) {
+		__db_err(env, ret, "%s", name);
+		return (ret);
+	}
+	if (iopsize < 512)
+		iopsize = 512;
+	if (iopsize > 16 * 1024)
+		iopsize = 16 * 1024;
+
+	/*
+	 * Sheer paranoia, but we don't want anything that's not a power-of-2
+	 * (we rely on that for alignment of various types on the pages), and
+	 * we want a multiple of the sector size as well.  If the value
+	 * we got out of __os_ioinfo looks bad, use a default instead.
+	 */
+	if (!IS_VALID_PAGESIZE(iopsize))
+		iopsize = DB_DEF_IOSIZE;
+
+	dbp->pgsize = iopsize;
+	F_SET(dbp, DB_AM_PGDEF);
+
+	return (0);
+}
+
+/*
+ * __fop_remove_setup --
+ *	Open handle appropriately and lock for removal of a database file.
+ *
+ * PUBLIC: int __fop_remove_setup __P((DB *,
+ * PUBLIC:      DB_TXN *, const char *, u_int32_t));
+ */
+int
+__fop_remove_setup(dbp, txn, name, flags)
+	DB *dbp;
+	DB_TXN *txn;
+	const char *name;
+	u_int32_t flags;
+{
+	DB_FH *fhp;
+	DB_LOCK elock;
+	ENV *env;
+	u_int8_t mbuf[DBMETASIZE];
+	int ret;
+
+	COMPQUIET(flags, 0);
+
+	env = dbp->env;
+
+	LOCK_INIT(elock);
+	fhp = NULL;
+	ret = 0;
+
+	/* Create locker if necessary. */
+retry:	if (LOCKING_ON(env)) {
+		if (IS_REAL_TXN(txn))
+			dbp->locker = txn->locker;
+		else if (dbp->locker == DB_LOCK_INVALIDID) {
+			if ((ret = __lock_id(env, NULL, &dbp->locker)) != 0)
+				goto err;
+			if (txn != NULL && F_ISSET(txn, TXN_INFAMILY) &&
+			    (ret = __lock_addfamilylocker(env,
+			    txn->txnid, dbp->locker->id, 1)) != 0)
+				goto err;
+		}
+	}
+
+	/*
+	 * We are about to open a file handle and then possibly close it.
+	 * We cannot close handles if we are doing FCNTL locking.  However,
+	 * there is no way to pass the FCNTL flag into this routine via the
+	 * user API.  The only way we can get in here and be doing FCNTL
+	 * locking is if we are trying to clean up an open that was called
+	 * with FCNTL locking.  In that case, the save_fhp should already be
+	 * set.  So, we use that field to tell us if we need to make sure
+	 * that we shouldn't close the handle.
+	 */
+	fhp = dbp->saved_open_fhp;
+	DB_ASSERT(env, LF_ISSET(DB_FCNTL_LOCKING) || fhp == NULL);
+
+	/*
+	 * Lock environment to protect file open.  That will enable us to
+	 * read the meta-data page and get the fileid so that we can lock
+	 * the handle.
+	 */
+	GET_ENVLOCK(env, dbp->locker, &elock);
+
+	/* Open database. */
+	if (F_ISSET(dbp, DB_AM_INMEM)) {
+		if ((ret = __env_mpool(dbp, name, flags)) == 0)
+			ret = __os_strdup(env, name, &dbp->dname);
+	} else if (fhp == NULL)
+		ret = __os_open(env, name, 0, DB_OSO_RDONLY, 0, &fhp);
+	if (ret != 0)
+		goto err;
+
+	/* Get meta-data */
+	if (F_ISSET(dbp, DB_AM_INMEM))
+		ret = __fop_inmem_read_meta(
+		    dbp, txn, name, flags, DB_CHK_META);
+	else if ((ret = __fop_read_meta(env,
+	    name, mbuf, sizeof(mbuf), fhp, 0, NULL)) == 0)
+		ret = __db_meta_setup(env, dbp,
+		    name, (DBMETA *)mbuf, flags, DB_CHK_META | DB_CHK_NOLSN);
+	if (ret != 0)
+		goto err;
+
+	/*
+	 * Now, get the handle lock.  We first try with NOWAIT, because if
+	 * we have to wait, we're going to have to close the file and reopen
+	 * it, so that if there is someone else removing it, our open doesn't
+	 * prevent that.
+	 */
+	if ((ret = __fop_lock_handle(env,
+	    dbp, dbp->locker, DB_LOCK_WRITE, NULL, DB_LOCK_NOWAIT)) != 0) {
+		/*
+		 * Close the file, block on the lock, clean up the dbp, and
+		 * then start all over again.
+		 */
+		if (!F_ISSET(dbp, DB_AM_INMEM) && !LF_ISSET(DB_FCNTL_LOCKING)) {
+			(void)__os_closehandle(env, fhp);
+			fhp = NULL;
+		}
+		if (ret != DB_LOCK_NOTGRANTED ||
+		    (txn != NULL && F_ISSET(txn, TXN_NOWAIT)))
+			goto err;
+		else if ((ret = __fop_lock_handle(env,
+		    dbp, dbp->locker, DB_LOCK_WRITE, &elock, 0)) != 0)
+			goto err;
+
+		if (F_ISSET(dbp, DB_AM_INMEM)) {
+			(void)__lock_put(env, &dbp->handle_lock);
+			(void)__db_refresh(dbp, txn, DB_NOSYNC, NULL, 1);
+		} else {
+			if (txn != NULL)
+				dbp->locker = NULL;
+			(void)__db_refresh(dbp, txn, DB_NOSYNC, NULL, 0);
+		}
+		goto retry;
+	} else if ((ret = __ENV_LPUT(env, elock)) != 0)
+		goto err;
+	else if (F_ISSET(dbp, DB_AM_IN_RENAME))
+		ret = ENOENT;
+
+	if (0) {
+err:		(void)__ENV_LPUT(env, elock);
+	}
+	if (fhp != NULL && !LF_ISSET(DB_FCNTL_LOCKING))
+		(void)__os_closehandle(env, fhp);
+	/*
+	 * If this is a real file and we are going to proceed with the removal,
+	 * then we need to make sure that we don't leave any pages around in the
+	 * mpool since the file is closed and will be reopened again before
+	 * access.  However, this might be an in-memory file, in which case
+	 * we will handle the discard from the mpool later as it's the "real"
+	 * removal of the database.
+	 */
+	if (ret == 0 && !F_ISSET(dbp, DB_AM_INMEM))
+		F_SET(dbp, DB_AM_DISCARD);
+	return (ret);
+}
+
+/*
+ * __fop_read_meta --
+ *	Read the meta-data page from a file and return it in buf.
+ *
+ * PUBLIC: int __fop_read_meta __P((ENV *, const char *,
+ * PUBLIC:     u_int8_t *, size_t, DB_FH *, int, size_t *));
+ */
+int
+__fop_read_meta(env, name, buf, size, fhp, errok, nbytesp)
+	ENV *env;
+	const char *name;
+	u_int8_t *buf;
+	size_t size;
+	DB_FH *fhp;
+	int errok;
+	size_t *nbytesp;
+{
+	size_t nr;
+	int ret;
+
+	/*
+	 * Our caller wants to know the number of bytes read, even if we
+	 * return an error.
+	 */
+	if (nbytesp != NULL)
+		*nbytesp = 0;
+
+	nr = 0;
+	ret = __os_read(env, fhp, buf, size, &nr);
+	if (nbytesp != NULL)
+		*nbytesp = nr;
+
+	if (ret != 0) {
+		if (!errok)
+			__db_err(env, ret, "%s", name);
+		goto err;
+	}
+
+	if (nr != size) {
+		if (!errok)
+			__db_errx(env, DB_STR_A("0004",
+			    "fop_read_meta: %s: unexpected file type or format",
+			    "%s"), name);
+		ret = EINVAL;
+	}
+
+err:
+	return (ret);
+}
+
+/*
+ * __fop_dbrename --
+ *	Do the appropriate file locking and file system operations
+ * to effect a dbrename in the absence of transactions (__fop_dummy
+ * and the subsequent calls in __db_rename do the work for the
+ * transactional case).
+ *
+ * PUBLIC: int __fop_dbrename __P((DB *, const char *, const char *));
+ */
+int
+__fop_dbrename(dbp, old, new)
+	DB *dbp;
+	const char *old, *new;
+{
+	DB_LOCK elock;
+	ENV *env;
+	char *real_new, *real_old;
+	int ret, t_ret;
+
+	env = dbp->env;
+	real_new = NULL;
+	real_old = NULL;
+	LOCK_INIT(elock);
+
+	if (F_ISSET(dbp, DB_AM_INMEM)) {
+		real_new = (char *)new;
+		real_old = (char *)old;
+	} else {
+		/* Get full names. */
+		if ((ret = __db_appname(env,
+		    DB_APP_DATA, old, &dbp->dirname, &real_old)) != 0)
+			goto err;
+
+		if ((ret = __db_appname(env,
+		    DB_APP_DATA, new, &dbp->dirname, &real_new)) != 0)
+			goto err;
+	}
+
+	/*
+	 * It is an error to rename a file over one that already exists,
+	 * as that wouldn't be transaction-safe.  We check explicitly
+	 * for ondisk files, but it's done memp_nameop for in-memory ones.
+	 */
+	GET_ENVLOCK(env, dbp->locker, &elock);
+	ret = F_ISSET(dbp, DB_AM_INMEM) ? ENOENT :
+	    __os_exists(env, real_new, NULL);
+
+	if (ret == 0) {
+		ret = EEXIST;
+		__db_errx(env, DB_STR_A("0005",
+		    "rename: file %s exists", "%s"), real_new);
+		goto err;
+	}
+
+	ret = __memp_nameop(env,
+	    dbp->fileid, new, real_old, real_new, F_ISSET(dbp, DB_AM_INMEM));
+
+err:	if ((t_ret = __ENV_LPUT(env, elock)) != 0 && ret == 0)
+		ret = t_ret;
+	if (!F_ISSET(dbp, DB_AM_INMEM) && real_old != NULL)
+		__os_free(env, real_old);
+	if (!F_ISSET(dbp, DB_AM_INMEM) && real_new != NULL)
+		__os_free(env, real_new);
+	return (ret);
+}
+
+static int
+__fop_inmem_create(dbp, name, txn, flags)
+	DB *dbp;
+	const char *name;
+	DB_TXN *txn;
+	u_int32_t flags;
+{
+	DBT fid_dbt, name_dbt;
+	DB_LSN lsn;
+	ENV *env;
+	int ret;
+	int32_t lfid;
+	u_int32_t dflags, *p32;
+
+	env = dbp->env;
+	dflags = F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0;
+
+	MAKE_INMEM(dbp);
+
+	/* Set the pagesize if it isn't yet set. */
+	if (dbp->pgsize == 0)
+		dbp->pgsize = DB_DEF_IOSIZE;
+
+	/*
+	 * Construct a file_id.
+	 *
+	 * If this file has no name, then we only need a fileid for locking.
+	 * If this file has a name, we need the fileid both for locking and
+	 * matching in the memory pool.  So, with unnamed in-memory databases,
+	 * use a lock_id.  For named in-memory files, we need to find a value
+	 * that we can use to uniquely identify a name/fid pair.  We use a
+	 * combination of a unique id (__os_unique_id) and a hash of the
+	 * original name.
+	 */
+	if (name == NULL) {
+		if (LOCKING_ON(env) && (ret =
+		    __lock_id(env, (u_int32_t *)dbp->fileid, NULL)) != 0)
+			goto err;
+	}  else {
+		p32 = (u_int32_t *)(&dbp->fileid[0]);
+		__os_unique_id(env, p32);
+		p32++;
+		(void)strncpy(
+		    (char *)p32, name, DB_FILE_ID_LEN - sizeof(u_int32_t));
+		dbp->preserve_fid = 1;
+
+		if (DBENV_LOGGING(env) &&
+#if !defined(DEBUG_WOP) && !defined(DIAGNOSTIC)
+		    txn != NULL &&
+#endif
+		    dbp->log_filename != NULL)
+			memcpy(dbp->log_filename->ufid,
+			    dbp->fileid, DB_FILE_ID_LEN);
+	}
+
+	/* Now, set the fileid. */
+	if ((ret = __memp_set_fileid(dbp->mpf, dbp->fileid)) != 0)
+		goto err;
+
+	if ((ret = __env_mpool(dbp, name, flags)) != 0)
+		goto err;
+
+	if (DBENV_LOGGING(env) &&
+#if !defined(DEBUG_WOP)
+	    txn != NULL &&
+#endif
+	    name != NULL) {
+		DB_INIT_DBT(name_dbt, name, strlen(name) + 1);
+		memset(&fid_dbt, 0, sizeof(fid_dbt));
+		fid_dbt.data = dbp->fileid;
+		fid_dbt.size = DB_FILE_ID_LEN;
+		lfid = dbp->log_filename == NULL ?
+		    DB_LOGFILEID_INVALID : dbp->log_filename->id;
+		if ((ret = __crdel_inmem_create_log(env, txn,
+		    &lsn, dflags, lfid, &name_dbt, &fid_dbt, dbp->pgsize)) != 0)
+			goto err;
+	}
+
+	F_SET(dbp, DB_AM_CREATED);
+
+err:
+	return (ret);
+}
+
+static int
+__fop_inmem_read_meta(dbp, txn, name, flags, chkflags)
+	DB *dbp;
+	DB_TXN *txn;
+	const char *name;
+	u_int32_t flags;
+	u_int32_t chkflags;
+{
+	DBMETA *metap;
+	DB_THREAD_INFO *ip;
+	db_pgno_t pgno;
+	int ret, t_ret;
+
+#ifdef HAVE_TRANSACTIONS
+	if (txn != NULL)
+		ip = txn->thread_info;
+	else
+#endif
+		ENV_GET_THREAD_INFO(dbp->env, ip);
+
+	pgno  = PGNO_BASE_MD;
+	if ((ret = __memp_fget(dbp->mpf, &pgno, ip, txn, 0, &metap)) != 0)
+		return (ret);
+	if (FLD_ISSET(chkflags, DB_CHK_ONLY)) {
+		if ((ret = __db_chk_meta(dbp->env, dbp, metap, chkflags)) == 0)
+			memcpy(dbp->fileid,
+			    ((DBMETA *)metap)->uid, DB_FILE_ID_LEN);
+	} else 
+		ret = __db_meta_setup(
+		    dbp->env, dbp, name, metap, flags, chkflags);
+
+	if ((t_ret =
+	    __memp_fput(dbp->mpf, ip, metap, dbp->priority)) && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hash/hash_func.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,262 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Copyright (c) 1990, 1993
+ *	Margo Seltzer.  All rights reserved.
+ */
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Margo Seltzer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/hash.h"
+
+/*
+ * __ham_func2 --
+ *	Phong Vo's linear congruential hash.
+ *
+ * PUBLIC: u_int32_t __ham_func2 __P((DB *, const void *, u_int32_t));
+ */
+#define	DCHARHASH(h, c)	((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
+
+u_int32_t
+__ham_func2(dbp, key, len)
+	DB *dbp;
+	const void *key;
+	u_int32_t len;
+{
+	const u_int8_t *e, *k;
+	u_int32_t h;
+	u_int8_t c;
+
+	if (dbp != NULL)
+		COMPQUIET(dbp, NULL);
+
+	k = key;
+	e = k + len;
+	for (h = 0; k != e;) {
+		c = *k++;
+		if (!c && k > e)
+			break;
+		DCHARHASH(h, c);
+	}
+	return (h);
+}
+
+/*
+ * __ham_func3 --
+ *	Ozan Yigit's original sdbm hash.
+ *
+ * Ugly, but fast.  Break the string up into 8 byte units.  On the first time
+ * through the loop get the "leftover bytes" (strlen % 8).  On every other
+ * iteration, perform 8 HASHC's so we handle all 8 bytes.  Essentially, this
+ * saves us 7 cmp & branch instructions.
+ *
+ * PUBLIC: u_int32_t __ham_func3 __P((DB *, const void *, u_int32_t));
+ */
+u_int32_t
+__ham_func3(dbp, key, len)
+	DB *dbp;
+	const void *key;
+	u_int32_t len;
+{
+	const u_int8_t *k;
+	u_int32_t n, loop;
+
+	if (dbp != NULL)
+		COMPQUIET(dbp, NULL);
+
+	if (len == 0)
+		return (0);
+
+#define	HASHC	n = *k++ + 65599 * n
+	n = 0;
+	k = key;
+
+	loop = (len + 8 - 1) >> 3;
+	switch (len & (8 - 1)) {
+	case 0:
+		do {
+			HASHC;
+	case 7:
+			HASHC;
+	case 6:
+			HASHC;
+	case 5:
+			HASHC;
+	case 4:
+			HASHC;
+	case 3:
+			HASHC;
+	case 2:
+			HASHC;
+	case 1:
+			HASHC;
+		} while (--loop);
+	}
+	return (n);
+}
+
+/*
+ * __ham_func4 --
+ *	Chris Torek's hash function.  Although this function performs only
+ *	slightly worse than __ham_func5 on strings, it performs horribly on
+ *	numbers.
+ *
+ * PUBLIC: u_int32_t __ham_func4 __P((DB *, const void *, u_int32_t));
+ */
+u_int32_t
+__ham_func4(dbp, key, len)
+	DB *dbp;
+	const void *key;
+	u_int32_t len;
+{
+	const u_int8_t *k;
+	u_int32_t h, loop;
+
+	if (dbp != NULL)
+		COMPQUIET(dbp, NULL);
+
+	if (len == 0)
+		return (0);
+
+#define	HASH4a	h = (h << 5) - h + *k++;
+#define	HASH4b	h = (h << 5) + h + *k++;
+#define	HASH4	HASH4b
+	h = 0;
+	k = key;
+
+	loop = (len + 8 - 1) >> 3;
+	switch (len & (8 - 1)) {
+	case 0:
+		do {
+			HASH4;
+	case 7:
+			HASH4;
+	case 6:
+			HASH4;
+	case 5:
+			HASH4;
+	case 4:
+			HASH4;
+	case 3:
+			HASH4;
+	case 2:
+			HASH4;
+	case 1:
+			HASH4;
+		} while (--loop);
+	}
+	return (h);
+}
+
+/*
+ * Fowler/Noll/Vo hash
+ *
+ * The basis of the hash algorithm was taken from an idea sent by email to the
+ * IEEE Posix P1003.2 mailing list from Phong Vo (kpv@research.att.com) and
+ * Glenn Fowler (gsf@research.att.com).  Landon Curt Noll (chongo@toad.com)
+ * later improved on their algorithm.
+ *
+ * The magic is in the interesting relationship between the special prime
+ * 16777619 (2^24 + 403) and 2^32 and 2^8.
+ *
+ * This hash produces the fewest collisions of any function that we've seen so
+ * far, and works well on both numbers and strings.
+ *
+ * PUBLIC: u_int32_t __ham_func5 __P((DB *, const void *, u_int32_t));
+ */
+u_int32_t
+__ham_func5(dbp, key, len)
+	DB *dbp;
+	const void *key;
+	u_int32_t len;
+{
+	const u_int8_t *k, *e;
+	u_int32_t h;
+
+	if (dbp != NULL)
+		COMPQUIET(dbp, NULL);
+
+	k = key;
+	e = k + len;
+	for (h = 0; k < e; ++k) {
+		h *= 16777619;
+		h ^= *k;
+	}
+	return (h);
+}
+
+/*
+ * __ham_test --
+ *
+ * PUBLIC: u_int32_t __ham_test __P((DB *, const void *, u_int32_t));
+ */
+u_int32_t
+__ham_test(dbp, key, len)
+	DB *dbp;
+	const void *key;
+	u_int32_t len;
+{
+	COMPQUIET(dbp, NULL);
+	COMPQUIET(len, 0);
+	return ((u_int32_t)*(char *)key);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hash/hash_stub.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,492 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef HAVE_HASH
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/hash.h"
+
+/*
+ * If the library wasn't compiled with the Hash access method, various
+ * routines aren't available.  Stub them here, returning an appropriate
+ * error.
+ */
+
+/*
+ * __db_nohasham --
+ *	Error when a Berkeley DB build doesn't include the access method.
+ *
+ * PUBLIC: int __db_no_hash_am __P((ENV *));
+ */
+int
+__db_no_hash_am(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("1133",
+    "library build did not include support for the Hash access method"));
+	return (DB_OPNOTSUP);
+}
+
+int
+__ham_30_hashmeta(dbp, real_name, obuf)
+	DB *dbp;
+	char *real_name;
+	u_int8_t *obuf;
+{
+	COMPQUIET(real_name, NULL);
+	COMPQUIET(obuf, NULL);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_30_sizefix(dbp, fhp, realname, metabuf)
+	DB *dbp;
+	DB_FH *fhp;
+	char *realname;
+	u_int8_t *metabuf;
+{
+	COMPQUIET(fhp, NULL);
+	COMPQUIET(realname, NULL);
+	COMPQUIET(metabuf, NULL);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_31_hash(dbp, real_name, flags, fhp, h, dirtyp)
+	DB *dbp;
+	char *real_name;
+	u_int32_t flags;
+	DB_FH *fhp;
+	PAGE *h;
+	int *dirtyp;
+{
+	COMPQUIET(real_name, NULL);
+	COMPQUIET(flags, 0);
+	COMPQUIET(fhp, NULL);
+	COMPQUIET(h, NULL);
+	COMPQUIET(dirtyp, NULL);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_31_hashmeta(dbp, real_name, flags, fhp, h, dirtyp)
+	DB *dbp;
+	char *real_name;
+	u_int32_t flags;
+	DB_FH *fhp;
+	PAGE *h;
+	int *dirtyp;
+{
+	COMPQUIET(real_name, NULL);
+	COMPQUIET(flags, 0);
+	COMPQUIET(fhp, NULL);
+	COMPQUIET(h, NULL);
+	COMPQUIET(dirtyp, NULL);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_46_hash(dbp, real_name, flags, fhp, h, dirtyp)
+	DB *dbp;
+	char *real_name;
+	u_int32_t flags;
+	DB_FH *fhp;
+	PAGE *h;
+	int *dirtyp;
+{
+	COMPQUIET(real_name, NULL);
+	COMPQUIET(flags, 0);
+	COMPQUIET(fhp, NULL);
+	COMPQUIET(h, NULL);
+	COMPQUIET(dirtyp, NULL);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_46_hashmeta(dbp, real_name, flags, fhp, h, dirtyp)
+	DB *dbp;
+	char *real_name;
+	u_int32_t flags;
+	DB_FH *fhp;
+	PAGE *h;
+	int *dirtyp;
+{
+	COMPQUIET(real_name, NULL);
+	COMPQUIET(flags, 0);
+	COMPQUIET(fhp, NULL);
+	COMPQUIET(h, NULL);
+	COMPQUIET(dirtyp, NULL);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__hamc_cmp(dbc, other_dbc, result)
+	DBC *dbc, *other_dbc;
+	int *result;
+{
+	COMPQUIET(other_dbc, NULL);
+	COMPQUIET(result, NULL);
+	return (__db_no_hash_am(dbc->env));
+}
+
+int
+__hamc_count(dbc, recnop)
+	DBC *dbc;
+	db_recno_t *recnop;
+{
+	COMPQUIET(recnop, NULL);
+	return (__db_no_hash_am(dbc->env));
+}
+
+int
+__hamc_dup(orig_dbc, new_dbc)
+	DBC *orig_dbc, *new_dbc;
+{
+	COMPQUIET(new_dbc, NULL);
+	return (__db_no_hash_am(orig_dbc->env));
+}
+
+int
+__hamc_init(dbc)
+	DBC *dbc;
+{
+	return (__db_no_hash_am(dbc->env));
+}
+
+int
+__ham_db_close(dbp)
+	DB *dbp;
+{
+	COMPQUIET(dbp, NULL);
+	return (0);
+}
+
+int
+__ham_db_create(dbp)
+	DB *dbp;
+{
+	COMPQUIET(dbp, NULL);
+	return (0);
+}
+
+int
+__ham_init_print(env, dtabp)
+	ENV *env;
+	DB_DISTAB *dtabp;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(dtabp, NULL);
+	return (0);
+}
+
+int
+__ham_init_recover(env, dtabp)
+	ENV *env;
+	DB_DISTAB *dtabp;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(dtabp, NULL);
+	return (0);
+}
+
+int
+__ham_meta2pgset(dbp, vdp, hmeta, flags, pgset)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	HMETA *hmeta;
+	u_int32_t flags;
+	DB *pgset;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(hmeta, NULL);
+	COMPQUIET(flags, 0);
+	COMPQUIET(pgset, NULL);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_metachk(dbp, name, hashm)
+	DB *dbp;
+	const char *name;
+	HMETA *hashm;
+{
+	COMPQUIET(name, NULL);
+	COMPQUIET(hashm, NULL);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_metagroup_42_recover(env, dbtp, lsnp, op, info)
+	ENV *env;
+	DBT *dbtp;
+	DB_LSN *lsnp;
+	db_recops op;
+	void *info;
+{
+	COMPQUIET(dbtp, NULL);
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(op, (db_recops)0);
+	COMPQUIET(info, NULL);
+	return (__db_no_hash_am(env));
+}
+
+int
+__ham_mswap(env, pg)
+	ENV *env;
+	void *pg;
+{
+	COMPQUIET(pg, NULL);
+	return (__db_no_hash_am(env));
+}
+
+int
+__ham_groupalloc_42_recover(env, dbtp, lsnp, op, info)
+	ENV *env;
+	DBT *dbtp;
+	DB_LSN *lsnp;
+	db_recops op;
+	void *info;
+{
+	COMPQUIET(dbtp, NULL);
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(op, (db_recops)0);
+	COMPQUIET(info, NULL);
+	return (__db_no_hash_am(env));
+}
+
+int
+__ham_new_file(dbp, ip, txn, fhp, name)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DB_FH *fhp;
+	const char *name;
+{
+	COMPQUIET(ip, NULL);
+	COMPQUIET(txn, NULL);
+	COMPQUIET(fhp, NULL);
+	COMPQUIET(name, NULL);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_new_subdb(mdbp, dbp, ip, txn)
+	DB *mdbp, *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+{
+	COMPQUIET(dbp, NULL);
+	COMPQUIET(txn, NULL);
+	COMPQUIET(ip, NULL);
+	return (__db_no_hash_am(mdbp->env));
+}
+
+int
+__ham_open(dbp, ip, txn, name, base_pgno, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name;
+	db_pgno_t base_pgno;
+	u_int32_t flags;
+{
+	COMPQUIET(ip, NULL);
+	COMPQUIET(txn, NULL);
+	COMPQUIET(name, NULL);
+	COMPQUIET(base_pgno, 0);
+	COMPQUIET(flags, 0);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_pgin(dbp, pg, pp, cookie)
+	DB *dbp;
+	db_pgno_t pg;
+	void *pp;
+	DBT *cookie;
+{
+	COMPQUIET(pg, 0);
+	COMPQUIET(pp, NULL);
+	COMPQUIET(cookie, NULL);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_pgout(dbp, pg, pp, cookie)
+	DB *dbp;
+	db_pgno_t pg;
+	void *pp;
+	DBT *cookie;
+{
+	COMPQUIET(pg, 0);
+	COMPQUIET(pp, NULL);
+	COMPQUIET(cookie, NULL);
+	return (__db_no_hash_am(dbp->env));
+}
+
+void
+__ham_print_cursor(dbc)
+	DBC *dbc;
+{
+	(void)__db_no_hash_am(dbc->env);
+}
+
+int
+__ham_quick_delete(dbc)
+	DBC *dbc;
+{
+	return (__db_no_hash_am(dbc->env));
+}
+
+int
+__ham_reclaim(dbp, ip, txn, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	u_int32_t flags;
+{
+	COMPQUIET(txn, NULL);
+	COMPQUIET(ip, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_salvage(dbp, vdp, pgno, h, handle, callback, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	PAGE *h;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(h, NULL);
+	COMPQUIET(handle, NULL);
+	COMPQUIET(callback, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_stat(dbc, spp, flags)
+	DBC *dbc;
+	void *spp;
+	u_int32_t flags;
+{
+	COMPQUIET(spp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_no_hash_am(dbc->env));
+}
+
+int
+__ham_stat_print(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_no_hash_am(dbc->env));
+}
+
+int
+__ham_truncate(dbc, countp)
+	DBC *dbc;
+	u_int32_t *countp;
+{
+	COMPQUIET(countp, NULL);
+	return (__db_no_hash_am(dbc->env));
+}
+
+int
+__ham_vrfy(dbp, vdp, h, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(h, NULL);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(flags, 0);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_vrfy_hashing(dbc, nentries, m, thisbucket, pgno, flags, hfunc)
+	DBC *dbc;
+	u_int32_t nentries;
+	HMETA *m;
+	u_int32_t thisbucket;
+	db_pgno_t pgno;
+	u_int32_t flags;
+	u_int32_t (*hfunc) __P((DB *, const void *, u_int32_t));
+{
+	COMPQUIET(nentries, 0);
+	COMPQUIET(m, NULL);
+	COMPQUIET(thisbucket, 0);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(flags, 0);
+	COMPQUIET(hfunc, NULL);
+	return (__db_no_hash_am(dbc->dbp->env));
+}
+
+int
+__ham_vrfy_meta(dbp, vdp, m, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	HMETA *m;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(m, NULL);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(flags, 0);
+	return (__db_no_hash_am(dbp->env));
+}
+
+int
+__ham_vrfy_structure(dbp, vdp, meta_pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t meta_pgno;
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(meta_pgno, 0);
+	COMPQUIET(flags, 0);
+	return (__db_no_hash_am(dbp->env));
+}
+#endif /* !HAVE_HASH */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/heap/heap_stub.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,350 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2010, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id:
+ */
+
+#ifndef HAVE_HEAP
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/heap.h"
+
+/*
+ * If the library wasn't compiled with the Heap access method, various
+ * routines aren't available.  Stub them here, returning an appropriate
+ * error.
+ */
+
+/*
+ * __db_no_heap_am --
+ *	Error when a Berkeley DB build doesn't include the access method.
+ *
+ * PUBLIC: int __db_no_heap_am __P((ENV *));
+ */
+int
+__db_no_heap_am(env)
+	ENV *env;
+{
+	__db_errx(env,
+	    "library build did not include support for the Heap access method");
+	return (DB_OPNOTSUP);
+}
+
+int
+__heap_db_create(dbp)
+	DB *dbp;
+{
+	COMPQUIET(dbp, NULL);
+	return (0);
+}
+
+int
+__heap_db_close(dbp)
+	DB *dbp;
+{
+	COMPQUIET(dbp, NULL);
+	return (0);
+}
+
+int
+__heap_get_heapsize(dbp, gbytes, bytes)
+	DB *dbp;
+	u_int32_t *gbytes, *bytes;
+{
+	COMPQUIET(gbytes, NULL);
+	COMPQUIET(bytes, NULL);
+	return (__db_no_heap_am(dbp->env));
+}
+
+int
+__heapc_dup(orig_dbc, new_dbc)
+	DBC *orig_dbc, *new_dbc;
+{
+	COMPQUIET(new_dbc, NULL);
+	return (__db_no_heap_am(orig_dbc->env));
+}
+
+int
+__heapc_gsplit(dbc, dbt, bpp, bpsz)
+	DBC *dbc;
+	DBT *dbt;
+	void **bpp;
+	u_int32_t *bpsz;
+{
+	COMPQUIET(dbt, NULL);
+	COMPQUIET(bpp, NULL);
+	COMPQUIET(bpsz, NULL);
+	return (__db_no_heap_am(dbc->env));
+}
+
+int
+__heap_append(dbc, key, data)
+	DBC *dbc;
+	DBT *key, *data;
+{
+	COMPQUIET(key, NULL);
+	COMPQUIET(data, NULL);
+	return (__db_no_heap_am(dbc->env));
+}
+
+int
+__heap_backup(dbenv, dbp, ip, fp, handle, flags)
+	DB_ENV *dbenv;
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_FH *fp;
+	void *handle;
+	u_int32_t flags;
+{
+	COMPQUIET(dbp, NULL);
+	COMPQUIET(ip, NULL);
+	COMPQUIET(fp, NULL);
+	COMPQUIET(handle, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_no_heap_am(dbenv->env));
+}
+
+int
+__heapc_init(dbc)
+	DBC *dbc;
+{
+	return (__db_no_heap_am(dbc->env));
+}
+
+int
+__heap_init_print(env, dtabp)
+	ENV *env;
+	DB_DISTAB *dtabp;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(dtabp, NULL);
+	return (0);
+}
+
+int
+__heap_init_recover(env, dtabp)
+	ENV *env;
+	DB_DISTAB *dtabp;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(dtabp, NULL);
+	return (0);
+}
+
+int
+__heap_meta2pgset(dbp, vdp, heapmeta, pgset)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	HEAPMETA *heapmeta;
+	DB *pgset;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(heapmeta, NULL);
+	COMPQUIET(pgset, NULL);
+	return (__db_no_heap_am(dbp->env));
+}
+
+int
+__heap_metachk(dbp, name, hm)
+	DB *dbp;
+	const char *name;
+	HEAPMETA *hm;
+{
+	COMPQUIET(name, NULL);
+	COMPQUIET(hm, NULL);
+	return (__db_no_heap_am(dbp->env));
+}
+
+int
+__heap_new_file(dbp, ip, txn, fhp, name)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DB_FH *fhp;
+	const char *name;
+{
+	COMPQUIET(ip, NULL);
+	COMPQUIET(txn, NULL);
+	COMPQUIET(fhp, NULL);
+	COMPQUIET(name, NULL);
+	return (__db_no_heap_am(dbp->env));
+}
+
+int
+__heap_open(dbp, ip, txn, name, base_pgno, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name;
+	db_pgno_t base_pgno;
+	u_int32_t flags;
+{
+	COMPQUIET(ip, NULL);
+	COMPQUIET(txn, NULL);
+	COMPQUIET(name, NULL);
+	COMPQUIET(base_pgno, 0);
+	COMPQUIET(flags, 0);
+	return (__db_no_heap_am(dbp->env));
+}
+
+int
+__heap_pgin(dbp, pg, pp, cookie)
+	DB *dbp;
+	db_pgno_t pg;
+	void *pp;
+	DBT *cookie;
+{
+	COMPQUIET(pg, 0);
+	COMPQUIET(pp, NULL);
+	COMPQUIET(cookie, NULL);
+	return (__db_no_heap_am(dbp->env));
+}
+
+int
+__heap_pgout(dbp, pg, pp, cookie)
+	 DB *dbp;
+	 db_pgno_t pg;
+	 void *pp;
+	 DBT *cookie;
+{
+	COMPQUIET(pg, 0);
+	COMPQUIET(pp, NULL);
+	COMPQUIET(cookie, NULL);
+	return (__db_no_heap_am(dbp->env));
+}
+
+void
+__heap_print_cursor(dbc)
+	DBC *dbc;
+{
+	(void)__db_no_heap_am(dbc->env);
+}
+
+int
+__heapc_refresh(dbc)
+	DBC *dbc;
+{
+	return (__db_no_heap_am(dbc->env));
+}
+
+int
+__heap_salvage(dbp, vdp, pgno, h, handle, callback, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	PAGE *h;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(handle, NULL);
+	COMPQUIET(h, NULL);
+	COMPQUIET(callback, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_no_heap_am(dbp->env));
+}
+
+int
+__heap_stat(dbc, spp, flags)
+	DBC *dbc;
+	void *spp;
+	u_int32_t flags;
+{
+	COMPQUIET(spp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_no_heap_am(dbc->env));
+}
+
+int
+__heap_stat_print(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_no_heap_am(dbc->env));
+}
+
+int
+__heap_truncate(dbc, countp)
+	DBC *dbc;
+	u_int32_t *countp;
+{
+	COMPQUIET(countp, NULL);
+	return (__db_no_heap_am(dbc->env));
+}
+
+int
+__heap_vrfy(dbp, vdbp, h, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdbp;
+	PAGE *h;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	COMPQUIET(h, NULL);
+	COMPQUIET(vdbp, NULL);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(flags, 0);
+	return (__db_no_heap_am(dbp->env));
+}
+
+int
+__heap_vrfy_meta(dbp, vdp, meta, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	HEAPMETA *meta;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(meta, NULL);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(flags, 0);
+	return (__db_no_heap_am(dbp->env));
+}
+
+int
+__heap_vrfy_structure(dbp, vdp, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_no_heap_am(dbp->env));
+}
+
+int
+__heap_exist()
+{
+	return (0);
+}
+#endif /* !HAVE_HEAP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lock/lock_stub.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,688 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/lock.h"
+
+/*
+ * If the library wasn't compiled with locking support, various routines
+ * aren't available.  Stub them here, returning an appropriate error.
+ */
+static int __db_nolocking __P((ENV *));
+
+/*
+ * __db_nolocking --
+ *	Error when a Berkeley DB build doesn't include the locking subsystem.
+ */
+static int
+__db_nolocking(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("2054",
+	    "library build did not include support for locking"));
+	return (DB_OPNOTSUP);
+}
+
+int
+__lock_env_create(dbenv)
+	DB_ENV *dbenv;
+{
+	COMPQUIET(dbenv, 0);
+	return (0);
+}
+
+void
+__lock_env_destroy(dbenv)
+	DB_ENV *dbenv;
+{
+	COMPQUIET(dbenv, 0);
+}
+
+int
+__lock_get_lk_conflicts(dbenv, lk_conflictsp, lk_modesp)
+	DB_ENV *dbenv;
+	const u_int8_t **lk_conflictsp;
+	int *lk_modesp;
+{
+	COMPQUIET(lk_conflictsp, NULL);
+	COMPQUIET(lk_modesp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_lk_detect(dbenv, lk_detectp)
+	DB_ENV *dbenv;
+	u_int32_t *lk_detectp;
+{
+	COMPQUIET(lk_detectp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_lk_init_lockers(dbenv, lk_initp)
+	DB_ENV *dbenv;
+	u_int32_t *lk_initp;
+{
+	COMPQUIET(lk_initp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_lk_init_locks(dbenv, lk_initp)
+	DB_ENV *dbenv;
+	u_int32_t *lk_initp;
+{
+	COMPQUIET(lk_initp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_lk_init_objects(dbenv, lk_initp)
+	DB_ENV *dbenv;
+	u_int32_t *lk_initp;
+{
+	COMPQUIET(lk_initp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_lk_max_lockers(dbenv, lk_maxp)
+	DB_ENV *dbenv;
+	u_int32_t *lk_maxp;
+{
+	COMPQUIET(lk_maxp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_lk_max_locks(dbenv, lk_maxp)
+	DB_ENV *dbenv;
+	u_int32_t *lk_maxp;
+{
+	COMPQUIET(lk_maxp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_lk_max_objects(dbenv, lk_maxp)
+	DB_ENV *dbenv;
+	u_int32_t *lk_maxp;
+{
+	COMPQUIET(lk_maxp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_lk_partitions(dbenv, lk_maxp)
+	DB_ENV *dbenv;
+	u_int32_t *lk_maxp;
+{
+	COMPQUIET(lk_maxp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_lk_tablesize(dbenv, lk_tablesizep)
+	DB_ENV *dbenv;
+	u_int32_t *lk_tablesizep;
+{
+	COMPQUIET(lk_tablesizep, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_set_lk_tablesize(dbenv, lk_tablesize)
+	DB_ENV *dbenv;
+	u_int32_t lk_tablesize;
+{
+	COMPQUIET(lk_tablesize, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_lk_priority(dbenv, lockid, priorityp)
+	DB_ENV *dbenv;
+	u_int32_t lockid, *priorityp;
+{
+	COMPQUIET(lockid, 0);
+	COMPQUIET(priorityp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_set_lk_priority(dbenv, lockid, priority)
+	DB_ENV *dbenv;
+	u_int32_t lockid, priority;
+{
+	COMPQUIET(lockid, 0);
+	COMPQUIET(priority, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_env_timeout(dbenv, timeoutp, flag)
+	DB_ENV *dbenv;
+	db_timeout_t *timeoutp;
+	u_int32_t flag;
+{
+	COMPQUIET(timeoutp, NULL);
+	COMPQUIET(flag, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_detect_pp(dbenv, flags, atype, abortp)
+	DB_ENV *dbenv;
+	u_int32_t flags, atype;
+	int *abortp;
+{
+	COMPQUIET(flags, 0);
+	COMPQUIET(atype, 0);
+	COMPQUIET(abortp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_get_pp(dbenv, locker, flags, obj, lock_mode, lock)
+	DB_ENV *dbenv;
+	u_int32_t locker, flags;
+	DBT *obj;
+	db_lockmode_t lock_mode;
+	DB_LOCK *lock;
+{
+	COMPQUIET(locker, 0);
+	COMPQUIET(flags, 0);
+	COMPQUIET(obj, NULL);
+	COMPQUIET(lock_mode, 0);
+	COMPQUIET(lock, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_id_pp(dbenv, idp)
+	DB_ENV *dbenv;
+	u_int32_t *idp;
+{
+	COMPQUIET(idp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_id_free_pp(dbenv, id)
+	DB_ENV *dbenv;
+	u_int32_t id;
+{
+	COMPQUIET(id, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_put_pp(dbenv, lock)
+	DB_ENV *dbenv;
+	DB_LOCK *lock;
+{
+	COMPQUIET(lock, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_stat_pp(dbenv, statp, flags)
+	DB_ENV *dbenv;
+	DB_LOCK_STAT **statp;
+	u_int32_t flags;
+{
+	COMPQUIET(statp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_stat_print_pp(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_vec_pp(dbenv, locker, flags, list, nlist, elistp)
+	DB_ENV *dbenv;
+	u_int32_t locker, flags;
+	int nlist;
+	DB_LOCKREQ *list, **elistp;
+{
+	COMPQUIET(locker, 0);
+	COMPQUIET(flags, 0);
+	COMPQUIET(list, NULL);
+	COMPQUIET(nlist, 0);
+	COMPQUIET(elistp, NULL);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_set_lk_conflicts(dbenv, lk_conflicts, lk_modes)
+	DB_ENV *dbenv;
+	u_int8_t *lk_conflicts;
+	int lk_modes;
+{
+	COMPQUIET(lk_conflicts, NULL);
+	COMPQUIET(lk_modes, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_set_lk_detect(dbenv, lk_detect)
+	DB_ENV *dbenv;
+	u_int32_t lk_detect;
+{
+	COMPQUIET(lk_detect, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_set_lk_max_locks(dbenv, lk_max)
+	DB_ENV *dbenv;
+	u_int32_t lk_max;
+{
+	COMPQUIET(lk_max, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_set_lk_max_lockers(dbenv, lk_max)
+	DB_ENV *dbenv;
+	u_int32_t lk_max;
+{
+	COMPQUIET(lk_max, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_set_lk_max_objects(dbenv, lk_max)
+	DB_ENV *dbenv;
+	u_int32_t lk_max;
+{
+	COMPQUIET(lk_max, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_set_lk_partitions(dbenv, lk_max)
+	DB_ENV *dbenv;
+	u_int32_t lk_max;
+{
+	COMPQUIET(lk_max, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_set_env_timeout(dbenv, timeout, flags)
+	DB_ENV *dbenv;
+	db_timeout_t timeout;
+	u_int32_t flags;
+{
+	COMPQUIET(timeout, 0);
+	COMPQUIET(flags, 0);
+	return (__db_nolocking(dbenv->env));
+}
+
+int
+__lock_open(env)
+	ENV *env;
+{
+	return (__db_nolocking(env));
+}
+
+u_int32_t
+__lock_region_mutex_count(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+u_int32_t
+__lock_region_mutex_max(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+size_t
+__lock_region_max(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+size_t
+__lock_region_size(env, other_alloc)
+	ENV *env;
+	size_t other_alloc;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(other_alloc, 0);
+	return (0);
+}
+
+int
+__lock_id_free(env, sh_locker)
+	ENV *env;
+	DB_LOCKER *sh_locker;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(sh_locker, 0);
+	return (0);
+}
+
+int
+__lock_env_refresh(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+int
+__lock_stat_print(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(flags, 0);
+	return (0);
+}
+
+int
+__lock_put(env, lock)
+	ENV *env;
+	DB_LOCK *lock;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(lock, NULL);
+	return (0);
+}
+
+int
+__lock_vec(env, sh_locker, flags, list, nlist, elistp)
+	ENV *env;
+	DB_LOCKER *sh_locker;
+	u_int32_t flags;
+	int nlist;
+	DB_LOCKREQ *list, **elistp;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(sh_locker, 0);
+	COMPQUIET(flags, 0);
+	COMPQUIET(list, NULL);
+	COMPQUIET(nlist, 0);
+	COMPQUIET(elistp, NULL);
+	return (0);
+}
+
+int
+__lock_get(env, locker, flags, obj, lock_mode, lock)
+	ENV *env;
+	DB_LOCKER *locker;
+	u_int32_t flags;
+	const DBT *obj;
+	db_lockmode_t lock_mode;
+	DB_LOCK *lock;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(locker, NULL);
+	COMPQUIET(flags, 0);
+	COMPQUIET(obj, NULL);
+	COMPQUIET(lock_mode, 0);
+	COMPQUIET(lock, NULL);
+	return (0);
+}
+
+int
+__lock_id(env, idp, lkp)
+	ENV *env;
+	u_int32_t *idp;
+	DB_LOCKER **lkp;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(idp, NULL);
+	COMPQUIET(lkp, NULL);
+	return (0);
+}
+
+int
+__lock_inherit_timeout(env, parent, locker)
+	ENV *env;
+	DB_LOCKER *parent, *locker;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(parent, NULL);
+	COMPQUIET(locker, NULL);
+	return (0);
+}
+
+int
+__lock_set_timeout(env, locker, timeout, op)
+	ENV *env;
+	DB_LOCKER *locker;
+	db_timeout_t timeout;
+	u_int32_t op;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(locker, NULL);
+	COMPQUIET(timeout, 0);
+	COMPQUIET(op, 0);
+	return (0);
+}
+
+int
+__lock_addfamilylocker(env, pid, id, is_family)
+	ENV *env;
+	u_int32_t pid, id, is_family;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(pid, 0);
+	COMPQUIET(id, 0);
+	COMPQUIET(is_family, 0);
+	return (0);
+}
+
+int
+__lock_freelocker(lt, sh_locker)
+	DB_LOCKTAB *lt;
+	DB_LOCKER *sh_locker;
+{
+	COMPQUIET(lt, NULL);
+	COMPQUIET(sh_locker, NULL);
+	return (0);
+}
+
+int
+__lock_familyremove(lt, sh_locker)
+	DB_LOCKTAB *lt;
+	DB_LOCKER *sh_locker;
+{
+	COMPQUIET(lt, NULL);
+	COMPQUIET(sh_locker, NULL);
+	return (0);
+}
+
+int
+__lock_downgrade(env, lock, new_mode, flags)
+	ENV *env;
+	DB_LOCK *lock;
+	db_lockmode_t new_mode;
+	u_int32_t flags;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(lock, NULL);
+	COMPQUIET(new_mode, 0);
+	COMPQUIET(flags, 0);
+	return (0);
+}
+
+int
+__lock_locker_same_family(env, locker1, locker2, retp)
+	ENV *env;
+	DB_LOCKER *locker1;
+	DB_LOCKER *locker2;
+	int *retp;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(locker1, NULL);
+	COMPQUIET(locker2, NULL);
+
+	*retp = 1;
+	return (0);
+}
+
+void
+__lock_set_thread_id(lref, pid, tid)
+	void *lref;
+	pid_t pid;
+	db_threadid_t tid;
+{
+	COMPQUIET(lref, NULL);
+	COMPQUIET(pid, 0);
+	COMPQUIET(tid, 0);
+}
+
+int
+__lock_failchk(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+int
+__lock_get_list(env, locker, flags, lock_mode, list)
+	ENV *env;
+	DB_LOCKER *locker;
+	u_int32_t flags;
+	db_lockmode_t lock_mode;
+	DBT *list;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(locker, NULL);
+	COMPQUIET(flags, 0);
+	COMPQUIET(lock_mode, 0);
+	COMPQUIET(list, NULL);
+	return (0);
+}
+
+void
+__lock_list_print(env, mbp, list)
+	ENV *env;
+	DB_MSGBUF *mbp;
+	DBT *list;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(mbp, NULL);
+	COMPQUIET(list, NULL);
+}
+
+int
+__lock_getlocker(lt, locker, create, retp)
+	DB_LOCKTAB *lt;
+	u_int32_t locker;
+	int create;
+	DB_LOCKER **retp;
+{
+	COMPQUIET(locker, 0);
+	COMPQUIET(create, 0);
+	COMPQUIET(retp, NULL);
+	return (__db_nolocking(lt->env));
+}
+
+int
+__lock_id_set(env, cur_id, max_id)
+	ENV *env;
+	u_int32_t cur_id, max_id;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(cur_id, 0);
+	COMPQUIET(max_id, 0);
+	return (0);
+}
+
+int
+__lock_wakeup(env, obj)
+	ENV *env;
+	const DBT *obj;
+{
+	COMPQUIET(obj, NULL);
+	return (__db_nolocking(env));
+}
+
+int
+__lock_change(env, old_lock, new_lock)
+	ENV *env;
+	DB_LOCK *old_lock, *new_lock;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(old_lock, NULL);
+	COMPQUIET(new_lock, NULL);
+	return (0);
+}
+
+int
+__db_lget(dbc, action, pgno, mode, lkflags, lockp)
+	DBC *dbc;
+	int action;
+	db_pgno_t pgno;
+	db_lockmode_t mode;
+	u_int32_t lkflags;
+	DB_LOCK *lockp;
+{
+	COMPQUIET(dbc, NULL);
+	COMPQUIET(action, 0);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(mode, 0);
+	COMPQUIET(lkflags, 0);
+	LOCK_INIT(*lockp);
+	return (0);
+}
+
+int
+__db_lput(dbc, lockp)
+	DBC *dbc;
+	DB_LOCK *lockp;
+{
+	COMPQUIET(lockp, NULL);
+	(void) __db_nolocking(dbc->env);
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/log/log_verify_stub.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,101 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef HAVE_VERIFY
+
+#include "db_config.h"
+#include "db_int.h"
+
+static int __db_log_novrfy __P((ENV *));
+int __log_verify_pp __P((DB_ENV *, const DB_LOG_VERIFY_CONFIG *));
+int __log_verify __P((DB_ENV *, const DB_LOG_VERIFY_CONFIG *));
+int __log_verify_wrap __P((ENV *env, const char *, u_int32_t, const char *,
+    const char *, time_t, time_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t,
+    int, int));
+
+/*
+ * __db_log_novrfy --
+ *	Error when a Berkeley DB build doesn't include verification for logs.
+ */
+static int
+__db_log_novrfy(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("2523",
+	    "library build did not include support for log verification"));
+	return (DB_OPNOTSUP);
+}
+
+int
+__log_verify_pp(dbenv, lvconfig)
+	DB_ENV *dbenv;
+	const DB_LOG_VERIFY_CONFIG *lvconfig;
+{
+	COMPQUIET(lvconfig, NULL);
+
+	/* The dbenv is intact, callers should properly take care of it. */
+	return (__db_log_novrfy(dbenv->env));
+}
+
+int
+__log_verify(dbenv, lvconfig)
+	DB_ENV *dbenv;
+	const DB_LOG_VERIFY_CONFIG *lvconfig;
+{
+	COMPQUIET(lvconfig, NULL);
+
+	return (__db_log_novrfy(dbenv->env));
+}
+
+int
+__log_verify_wrap(env, envhome, cachesize, dbfile, dbname,
+    stime, etime, stfile, stoffset, efile, eoffset, caf, verbose)
+	ENV *env;
+	const char *envhome, *dbfile, *dbname;
+	time_t stime, etime;
+	u_int32_t cachesize, stfile, stoffset, efile, eoffset;
+	int caf, verbose;
+{
+	COMPQUIET(envhome, NULL);
+	COMPQUIET(dbfile, NULL);
+	COMPQUIET(dbname, NULL);
+	COMPQUIET(stime, 0);
+	COMPQUIET(etime, 0);
+	COMPQUIET(cachesize, 0);
+	COMPQUIET(stfile, 0);
+	COMPQUIET(stoffset, 0);
+	COMPQUIET(efile, 0);
+	COMPQUIET(eoffset, 0);
+	COMPQUIET(caf, 0);
+	COMPQUIET(verbose, 0);
+	return (__db_log_novrfy(env));
+}
+
+#endif /* !HAVE_VERIFY */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_alloc.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,767 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+/*
+ * This configuration parameter limits the number of hash buckets which
+ * __memp_alloc() searches through while excluding buffers with a 'high'
+ * priority.
+ */
+#if !defined(MPOOL_ALLOC_SEARCH_LIMIT)
+#define	MPOOL_ALLOC_SEARCH_LIMIT	500
+#endif
+
+/*
+ * __memp_alloc --
+ *	Allocate some space from a cache region.
+ *
+ * PUBLIC: int __memp_alloc __P((DB_MPOOL *,
+ * PUBLIC:     REGINFO *, MPOOLFILE *, size_t, roff_t *, void *));
+ */
+int
+__memp_alloc(dbmp, infop, mfp, len, offsetp, retp)
+	DB_MPOOL *dbmp;
+	REGINFO *infop;
+	MPOOLFILE *mfp;
+	size_t len;
+	roff_t *offsetp;
+	void *retp;
+{
+	BH *bhp, *current_bhp;
+#ifdef HAVE_TRANSACTIONS
+	BH *mvcc_bhp, *oldest_bhp;
+	BH_FROZEN_PAGE *frozen_bhp;
+	DB_LSN oldest_reader, vlsn;
+#endif
+	DB_MPOOL_HASH *dbht, *hp, *hp_end, *hp_saved, *hp_tmp;
+	ENV *env;
+	MPOOL *c_mp;
+	MPOOLFILE *bh_mfp;
+	size_t freed_space;
+	u_int32_t buckets, bucket_priority, buffers, cache_reduction;
+	u_int32_t dirty_eviction, high_priority, priority, versions;
+	u_int32_t priority_saved, put_counter, lru_generation, total_buckets;
+	int aggressive, alloc_freeze, b_lock, giveup;
+	int h_locked, obsolete, ret, write_error;
+#ifdef HAVE_TRANSACTIONS
+	int need_free;
+	u_int8_t *endp;
+#endif
+	void *p;
+
+	env = dbmp->env;
+	c_mp = infop->primary;
+	dbht = R_ADDR(infop, c_mp->htab);
+	hp_end = &dbht[c_mp->htab_buckets];
+	hp_saved = NULL;
+	priority_saved = 0;
+	write_error = 0;
+
+	buckets = buffers = put_counter = total_buckets = versions = 0;
+	aggressive = alloc_freeze = giveup = h_locked = 0;
+
+	/*
+	 * If we're allocating a buffer, and the one we're discarding is the
+	 * same size, we don't want to waste the time to re-integrate it into
+	 * the shared memory free list.  If the DB_MPOOLFILE argument isn't
+	 * NULL, we'll compare the underlying page sizes of the two buffers
+	 * before free-ing and re-allocating buffers.
+	 */
+	if (mfp != NULL) {
+		len = SSZA(BH, buf) + mfp->pagesize;
+		/* Add space for alignment padding for MVCC diagnostics. */
+		MVCC_BHSIZE(mfp, len);
+	}
+
+	STAT_INC(env, mpool, nallocs, c_mp->stat.st_alloc, len);
+
+	MPOOL_REGION_LOCK(env, infop);
+
+	/*
+	 * First we try to allocate from free memory.  If that fails, scan the
+	 * buffer pool to find buffers with low priorities.  We consider small
+	 * sets of hash buckets each time to limit the amount of work needing
+	 * to be done.  This approximates LRU, but not very well.  We either
+	 * find a buffer of the same size to use, or we will free 3 times what
+	 * we need in the hopes it will coalesce into a contiguous chunk of the
+	 * right size.  In the latter case we branch back here and try again.
+	 */
+alloc:	if ((ret = __env_alloc(infop, len, &p)) == 0) {
+		if (mfp != NULL) {
+			/*
+			 * For MVCC diagnostics, align the pointer so that the
+			 * buffer starts on a page boundary.
+			 */
+			MVCC_BHALIGN(p);
+			bhp = (BH *)p;
+
+			if ((ret = __mutex_alloc(env, MTX_MPOOL_BH,
+			    DB_MUTEX_SHARED, &bhp->mtx_buf)) != 0) {
+				MVCC_BHUNALIGN(bhp);
+				__env_alloc_free(infop, bhp);
+				goto search;
+			}
+			c_mp->pages++;
+		}
+		MPOOL_REGION_UNLOCK(env, infop);
+found:		if (offsetp != NULL)
+			*offsetp = R_OFFSET(infop, p);
+		*(void **)retp = p;
+
+		/*
+		 * Update the search statistics.
+		 *
+		 * We're not holding the region locked here, these statistics
+		 * can't be trusted.
+		 */
+#ifdef HAVE_STATISTICS
+		total_buckets += buckets;
+		if (total_buckets != 0) {
+			if (total_buckets > c_mp->stat.st_alloc_max_buckets)
+				STAT_SET(env, mpool, alloc_max_buckets,
+				    c_mp->stat.st_alloc_max_buckets,
+				    total_buckets, infop->id);
+			STAT_ADJUST(env, mpool, alloc_buckets,
+			    c_mp->stat.st_alloc_buckets,
+			    total_buckets, infop->id);
+		}
+		if (buffers != 0) {
+			if (buffers > c_mp->stat.st_alloc_max_pages)
+				STAT_SET(env, mpool, alloc_max_pages,
+				    c_mp->stat.st_alloc_max_pages,
+				    buffers, infop->id);
+			STAT_ADJUST(env, mpool, alloc_pages,
+			    c_mp->stat.st_alloc_pages, buffers, infop->id);
+		}
+#endif
+		return (0);
+	} else if (giveup || c_mp->pages == 0) {
+		MPOOL_REGION_UNLOCK(env, infop);
+
+		__db_errx(env, DB_STR("3017",
+		    "unable to allocate space from the buffer cache"));
+		return ((ret == ENOMEM && write_error != 0) ? EIO : ret);
+	}
+
+search:
+	/*
+	 * Anything newer than 1/10th of the buffer pool is ignored during the
+	 * first MPOOL_SEARCH_ALLOC_LIMIT buckets worth of allocation.
+	 */
+	cache_reduction = c_mp->pages / 10;
+	high_priority = aggressive ? MPOOL_LRU_MAX :
+	    c_mp->lru_priority - cache_reduction;
+	lru_generation = c_mp->lru_generation;
+
+	ret = 0;
+#ifdef HAVE_TRANSACTIONS
+	MAX_LSN(oldest_reader);
+#endif
+
+	/*
+	 * We re-attempt the allocation every time we've freed 3 times what
+	 * we need.  Reset our free-space counter.
+	 */
+	freed_space = 0;
+	total_buckets += buckets;
+	buckets = 0;
+
+	/*
+	 * Walk the hash buckets and find the next two with potentially useful
+	 * buffers.  Free the buffer with the lowest priority from the buckets'
+	 * chains.
+	 */
+	for (;;) {
+		/* All pages have been freed, make one last try */
+		if (c_mp->pages == 0)
+			goto alloc;
+
+		/* Check for wrap around. */
+		hp = &dbht[c_mp->last_checked++];
+		if (hp >= hp_end) {
+			c_mp->last_checked = 0;
+			hp = &dbht[c_mp->last_checked++];
+		}
+
+		/*
+		 * The failure mode is when there are too many buffers we can't
+		 * write or there's not enough memory in the system to support
+		 * the number of pinned buffers.
+		 *
+		 * Get aggressive if we've reviewed the entire cache without
+		 * freeing the needed space.  (The code resets "aggressive"
+		 * when we free any space.)  Aggressive means:
+		 *
+		 * a: set a flag to attempt to flush high priority buffers as
+		 *    well as other buffers.
+		 * b: look at a buffer in every hash bucket rather than choose
+		 *    the more preferable of two.
+		 * c: start to think about giving up.
+		 *
+		 * If we get here three or more times, sync the mpool to force
+		 * out queue extent pages.  While we might not have enough
+		 * space for what we want and flushing is expensive, why not?
+		 * Then sleep for a second, hopefully someone else will run and
+		 * free up some memory.
+		 *
+		 * Always try to allocate memory too, in case some other thread
+		 * returns its memory to the region.
+		 *
+		 * We don't have any way to know an allocation has no way to
+		 * succeed.  Fail if no pages are returned to the cache after
+		 * we've been trying for a relatively long time.
+		 *
+		 * !!!
+		 * This test ignores pathological cases like no buffers in the
+		 * system -- we check for that early on, so it isn't possible.
+		 */
+		if (buckets++ == c_mp->htab_buckets) {
+			if (freed_space > 0)
+				goto alloc;
+			MPOOL_REGION_UNLOCK(env, infop);
+
+			aggressive++;
+			/*
+			 * Once aggressive, we consider all buffers. By setting
+			 * this to MPOOL_LRU_MAX, we'll still select a victim
+			 * even if all buffers have the highest normal priority.
+			 */
+			high_priority = MPOOL_LRU_MAX;
+			PERFMON4(env, mpool, alloc_wrap,
+			    len, infop->id, aggressive, c_mp->put_counter);
+			switch (aggressive) {
+			case 1:
+				break;
+			case 2:
+				put_counter = c_mp->put_counter;
+				break;
+			case 3:
+			case 4:
+			case 5:
+			case 6:
+				(void)__memp_sync_int(
+				    env, NULL, 0, DB_SYNC_ALLOC, NULL, NULL);
+
+				__os_yield(env, 1, 0);
+				break;
+			default:
+				aggressive = 1;
+				if (put_counter == c_mp->put_counter)
+					giveup = 1;
+				break;
+			}
+
+			MPOOL_REGION_LOCK(env, infop);
+			goto alloc;
+		}
+
+		/*
+		 * Skip empty buckets.
+		 *
+		 * We can check for empty buckets before locking the hash
+		 * bucket as we only care if the pointer is zero or non-zero.
+		 */
+		if (SH_TAILQ_FIRST(&hp->hash_bucket, __bh) == NULL)
+			continue;
+
+		/* Set aggressive if we have already searched for too long. */
+		if (aggressive == 0 && buckets >= MPOOL_ALLOC_SEARCH_LIMIT) {
+			aggressive = 1;
+			/* Once aggressive, we consider all buffers. */
+			high_priority = MPOOL_LRU_MAX;
+		}
+
+		/* Unlock the region and lock the hash bucket. */
+		MPOOL_REGION_UNLOCK(env, infop);
+		MUTEX_READLOCK(env, hp->mtx_hash);
+		h_locked = 1;
+		b_lock = 0;
+
+		/*
+		 * Find a buffer we can use.
+		 *
+		 * We use the lowest-LRU singleton buffer if we find one and
+		 * it's better than the result of another hash bucket we've
+		 * reviewed.  We do not use a buffer which has a priority
+		 * greater than high_priority unless we are being aggressive.
+		 *
+		 * With MVCC buffers, the situation is more complicated: we
+		 * don't want to free a buffer out of the middle of an MVCC
+		 * chain, since that requires I/O.  So, walk the buffers,
+		 * looking for an obsolete buffer at the end of an MVCC chain.
+		 * Once a buffer becomes obsolete, its LRU priority is
+		 * irrelevant because that version can never be accessed again.
+		 *
+		 * If we don't find any obsolete MVCC buffers, we will get
+		 * aggressive, and in that case consider the lowest priority
+		 * buffer within a chain.
+		 *
+		 * Ignore referenced buffers, we can't get rid of them.
+		 */
+retry_search:	bhp = NULL;
+		bucket_priority = high_priority;
+		obsolete = 0;
+		SH_TAILQ_FOREACH(current_bhp, &hp->hash_bucket, hq, __bh) {
+			/*
+			 * First, do the standard LRU check for singletons.
+			 * We can use the buffer if it is unreferenced, has a
+			 * priority that isn't too high (unless we are
+			 * aggressive), and is better than the best candidate
+			 * we have found so far in this bucket.
+			 */
+#ifdef MPOOL_ALLOC_SEARCH_DYN
+			if (aggressive == 0 &&
+			     ++high_priority >= c_mp->lru_priority)
+				aggressive = 1;
+#endif
+
+			if (SH_CHAIN_SINGLETON(current_bhp, vc)) {
+				if (BH_REFCOUNT(current_bhp) != 0)
+					continue;
+				buffers++;
+				if (bucket_priority > current_bhp->priority) {
+					bucket_priority = current_bhp->priority;
+					if (bhp != NULL)
+						atomic_dec(env, &bhp->ref);
+					bhp = current_bhp;
+					atomic_inc(env, &bhp->ref);
+				}
+				continue;
+			}
+
+#ifdef HAVE_TRANSACTIONS
+			/*
+			 * For MVCC buffers, walk through the chain.  If we are
+			 * aggressive, choose the best candidate from within
+			 * the chain for freezing.
+			 */
+			for (mvcc_bhp = oldest_bhp = current_bhp;
+			    mvcc_bhp != NULL;
+			    oldest_bhp = mvcc_bhp,
+			    mvcc_bhp = SH_CHAIN_PREV(mvcc_bhp, vc, __bh)) {
+#ifdef MPOOL_ALLOC_SEARCH_DYN
+				if (aggressive == 0 &&
+				     ++high_priority >= c_mp->lru_priority)
+					aggressive = 1;
+#endif
+				DB_ASSERT(env, mvcc_bhp !=
+				    SH_CHAIN_PREV(mvcc_bhp, vc, __bh));
+				if ((aggressive < 2 &&
+				    ++versions < (buffers >> 2)) ||
+				    BH_REFCOUNT(mvcc_bhp) != 0)
+					continue;
+				buffers++;
+				if (!F_ISSET(mvcc_bhp, BH_FROZEN) &&
+				    (bhp == NULL ||
+				    bhp->priority > mvcc_bhp->priority)) {
+					if (bhp != NULL)
+						atomic_dec(env, &bhp->ref);
+					bhp = mvcc_bhp;
+					atomic_inc(env, &bhp->ref);
+				}
+			}
+
+			/*
+			 * oldest_bhp is the last buffer on the MVCC chain, and
+			 * an obsolete buffer at the end of the MVCC chain gets
+			 * used without further search. Before checking for
+			 * obsolescence, update the cached oldest reader LSN in
+			 * the bucket if it is older than call's oldest_reader.
+			 */
+			if (BH_REFCOUNT(oldest_bhp) != 0)
+				continue;
+
+			if (LOG_COMPARE(&oldest_reader, &hp->old_reader) > 0) {
+				if (IS_MAX_LSN(oldest_reader) &&
+				   (ret = __txn_oldest_reader(
+				    env, &oldest_reader)) != 0) {
+					MUTEX_UNLOCK(env, hp->mtx_hash);
+					if (bhp != NULL)
+						atomic_dec(env, &bhp->ref);
+					return (ret);
+				}
+				if (LOG_COMPARE(&oldest_reader,
+				    &hp->old_reader) > 0)
+					hp->old_reader = oldest_reader;
+			}
+
+			if (BH_OBSOLETE(oldest_bhp, hp->old_reader, vlsn)) {
+				if (aggressive < 2)
+					buffers++;
+				obsolete = 1;
+				if (bhp != NULL)
+					atomic_dec(env, &bhp->ref);
+				bhp = oldest_bhp;
+				atomic_inc(env, &bhp->ref);
+				goto this_buffer;
+			}
+#endif
+		}
+
+		/*
+		 * bhp is either NULL or the best candidate buffer.
+		 * We'll use the chosen buffer only if we have compared its
+		 * priority against one chosen from another hash bucket.
+		 */
+		if (bhp == NULL)
+			goto next_hb;
+
+		priority = bhp->priority;
+
+		/*
+		 * Compare two hash buckets and select the one with the lower
+		 * priority. Performance testing showed looking at two improves
+		 * the LRU-ness and looking at more only does a little better.
+		 */
+		if (hp_saved == NULL) {
+			hp_saved = hp;
+			priority_saved = priority;
+			goto next_hb;
+		}
+
+		/*
+		 * If the buffer we just found is a better choice than our
+		 * previous choice, use it.
+		 *
+		 * If the previous choice was better, pretend we're moving
+		 * from this hash bucket to the previous one and re-do the
+		 * search.
+		 *
+		 * We don't worry about simply swapping between two buckets
+		 * because that could only happen if a buffer was removed
+		 * from the chain, or its priority updated.   If a buffer
+		 * is removed from the chain, some other thread has managed
+		 * to discard a buffer, so we're moving forward.  Updating
+		 * a buffer's priority will make it a high-priority buffer,
+		 * so we'll ignore it when we search again, and so we will
+		 * eventually zero in on a buffer to use, or we'll decide
+		 * there are no buffers we can use.
+		 *
+		 * If there's only a single hash bucket with buffers, we'll
+		 * search the bucket once, choose a buffer, walk the entire
+		 * list of buckets and search it again.   In the case of a
+		 * system that's busy, it's possible to imagine a case where
+		 * we'd loop for a long while.  For that reason, and because
+		 * the test is easy, we special case and test for it.
+		 */
+		if (priority > priority_saved && hp != hp_saved) {
+			MUTEX_UNLOCK(env, hp->mtx_hash);
+			hp_tmp = hp_saved;
+			hp_saved = hp;
+			hp = hp_tmp;
+			priority_saved = priority;
+			MUTEX_READLOCK(env, hp->mtx_hash);
+			h_locked = 1;
+			DB_ASSERT(env, BH_REFCOUNT(bhp) > 0);
+			atomic_dec(env, &bhp->ref);
+			goto retry_search;
+		}
+
+		/*
+		 * If another thread has called __memp_reset_lru() while we were
+		 * looking for this buffer, it is possible that we've picked a
+		 * poor choice for a victim. If so toss it and start over.
+		 */
+		if (lru_generation != c_mp->lru_generation) {
+			DB_ASSERT(env, BH_REFCOUNT(bhp) > 0);
+			atomic_dec(env, &bhp->ref);
+			MUTEX_UNLOCK(env, hp->mtx_hash);
+			MPOOL_REGION_LOCK(env, infop);
+			hp_saved = NULL;
+			goto search;
+		}
+
+#ifdef HAVE_TRANSACTIONS
+this_buffer:
+#endif
+		/*
+		 * Discard any previously remembered hash bucket, we've got
+		 * a winner.
+		 */
+		hp_saved = NULL;
+
+		/* Drop the hash mutex and lock the buffer exclusively. */
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+		h_locked = 0;
+
+		/* Don't bother trying to latch a busy buffer. */
+		if (BH_REFCOUNT(bhp) > 1)
+			goto next_hb;
+
+		/* We cannot block as the caller is probably holding locks. */
+		if ((ret = MUTEX_TRYLOCK(env, bhp->mtx_buf)) != 0) {
+			if (ret != DB_LOCK_NOTGRANTED)
+				return (ret);
+			goto next_hb;
+		}
+		F_SET(bhp, BH_EXCLUSIVE);
+		b_lock = 1;
+
+		/* Someone may have grabbed it while we got the lock. */
+		if (BH_REFCOUNT(bhp) != 1)
+			goto next_hb;
+
+		/* Find the associated MPOOLFILE. */
+		bh_mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
+
+		/* If the page is dirty, write it. */
+		ret = 0;
+		dirty_eviction = 0;
+		if (F_ISSET(bhp, BH_DIRTY)) {
+			DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0);
+			ret = __memp_bhwrite(dbmp, hp, bh_mfp, bhp, 0);
+			DB_ASSERT(env, atomic_read(&bhp->ref) > 0);
+
+			/*
+			 * If a write fails for any reason, we can't proceed.
+			 *
+			 * If there's a write error and we're having problems
+			 * finding something to allocate, avoid selecting this
+			 * buffer again by maximizing its priority.
+			 */
+			if (ret != 0) {
+				if (ret != EPERM && ret != EAGAIN) {
+					write_error++;
+					__db_errx(env, DB_STR_A("3018",
+		"%s: unwritable page %d remaining in the cache after error %d",
+					    "%s %d %d"),
+					    __memp_fns(dbmp, bh_mfp),
+					    bhp->pgno, ret);
+				}
+				bhp->priority = MPOOL_LRU_REDZONE;
+
+				goto next_hb;
+			}
+
+			dirty_eviction = 1;
+		}
+
+#ifdef HAVE_TRANSACTIONS
+		/*
+		 * Freeze this buffer, if necessary.  That is, if the buffer is
+		 * part of an MVCC chain and could be required by a reader.
+		 */
+		if (SH_CHAIN_HASPREV(bhp, vc) ||
+		    (SH_CHAIN_HASNEXT(bhp, vc) && !obsolete)) {
+			if (!aggressive ||
+			    F_ISSET(bhp, BH_DIRTY | BH_FROZEN))
+				goto next_hb;
+			ret = __memp_bh_freeze(
+			    dbmp, infop, hp, bhp, &alloc_freeze);
+			if (ret == EIO)
+				write_error++;
+			if (ret == EBUSY || ret == EIO ||
+			    ret == ENOMEM || ret == ENOSPC) {
+				ret = 0;
+				goto next_hb;
+			} else if (ret != 0) {
+				DB_ASSERT(env, BH_REFCOUNT(bhp) > 0);
+				atomic_dec(env, &bhp->ref);
+				DB_ASSERT(env, b_lock);
+				F_CLR(bhp, BH_EXCLUSIVE);
+				MUTEX_UNLOCK(env, bhp->mtx_buf);
+				DB_ASSERT(env, !h_locked);
+				return (ret);
+			}
+		}
+#endif
+
+		MUTEX_LOCK(env, hp->mtx_hash);
+		h_locked = 1;
+
+		/*
+		 * We released the hash bucket lock while doing I/O, so another
+		 * thread may have acquired this buffer and incremented the ref
+		 * count or dirtied the buffer or installed a new version after
+		 * we wrote it, in which case we can't have it.
+		 */
+		if (BH_REFCOUNT(bhp) != 1 || F_ISSET(bhp, BH_DIRTY))
+			goto next_hb;
+
+#ifdef HAVE_TRANSACTIONS
+		if ((SH_CHAIN_HASNEXT(bhp, vc) &&
+		    SH_CHAIN_NEXTP(bhp, vc, __bh)->td_off != bhp->td_off &&
+		    !BH_OBSOLETE(bhp, hp->old_reader, vlsn)))
+			goto next_hb;
+
+		/*
+		 * If the buffer is frozen, thaw it and look for another one
+		 * we can use. (Calling __memp_bh_freeze above will not
+		 * mark bhp BH_FROZEN.)
+		 */
+		if (F_ISSET(bhp, BH_FROZEN)) {
+			DB_ASSERT(env, obsolete || SH_CHAIN_SINGLETON(bhp, vc));
+			DB_ASSERT(env, BH_REFCOUNT(bhp) > 0);
+			if (!F_ISSET(bhp, BH_THAWED)) {
+				/*
+				 * This call releases the hash bucket mutex.
+				 * We're going to retry the search, so we need
+				 * to re-lock it.
+				 */
+				if ((ret = __memp_bh_thaw(dbmp,
+				    infop, hp, bhp, NULL)) != 0)
+					return (ret);
+				MUTEX_READLOCK(env, hp->mtx_hash);
+			} else {
+				need_free = (atomic_dec(env, &bhp->ref) == 0);
+				F_CLR(bhp, BH_EXCLUSIVE);
+				MUTEX_UNLOCK(env, bhp->mtx_buf);
+				if (need_free) {
+					MPOOL_REGION_LOCK(env, infop);
+					SH_TAILQ_INSERT_TAIL(&c_mp->free_frozen,
+					    bhp, hq);
+					MPOOL_REGION_UNLOCK(env, infop);
+				}
+			}
+			bhp = NULL;
+			b_lock = alloc_freeze = 0;
+			goto retry_search;
+		}
+#endif
+
+		/* We are certainly freeing this buf; now update statistic. */
+		if (dirty_eviction)
+			STAT_INC(env, mpool,
+			    dirty_eviction, c_mp->stat.st_rw_evict, infop->id);
+		else
+			STAT_INC(env, mpool,
+			    clean_eviction, c_mp->stat.st_ro_evict, infop->id);
+#ifdef HAVE_TRANSACTIONS
+		/*
+		 * If we need some empty buffer headers for freezing, turn the
+		 * buffer we've found into frozen headers and put them on the
+		 * free list.  Only reset alloc_freeze if we've actually
+		 * allocated some frozen buffer headers.
+		 */
+		if (alloc_freeze) {
+			if ((ret = __memp_bhfree(dbmp,
+			     infop, bh_mfp, hp, bhp, 0)) != 0)
+				return (ret);
+			b_lock = 0;
+			h_locked = 0;
+
+			MVCC_MPROTECT(bhp->buf, bh_mfp->pagesize,
+			    PROT_READ | PROT_WRITE | PROT_EXEC);
+
+			MPOOL_REGION_LOCK(env, infop);
+			SH_TAILQ_INSERT_TAIL(&c_mp->alloc_frozen,
+			    (BH_FROZEN_ALLOC *)bhp, links);
+			frozen_bhp = (BH_FROZEN_PAGE *)
+			    ((BH_FROZEN_ALLOC *)bhp + 1);
+			endp = (u_int8_t *)bhp->buf + bh_mfp->pagesize;
+			while ((u_int8_t *)(frozen_bhp + 1) < endp) {
+				frozen_bhp->header.mtx_buf = MUTEX_INVALID;
+				SH_TAILQ_INSERT_TAIL(&c_mp->free_frozen,
+				    (BH *)frozen_bhp, hq);
+				frozen_bhp++;
+			}
+			MPOOL_REGION_UNLOCK(env, infop);
+
+			alloc_freeze = 0;
+			MUTEX_READLOCK(env, hp->mtx_hash);
+			h_locked = 1;
+			goto retry_search;
+		}
+#endif
+
+		/*
+		 * Check to see if the buffer is the size we're looking for.
+		 * If so, we can simply reuse it.  Otherwise, free the buffer
+		 * and its space and keep looking.
+		 */
+		if (mfp != NULL && mfp->pagesize == bh_mfp->pagesize) {
+			if ((ret = __memp_bhfree(dbmp,
+			     infop, bh_mfp, hp, bhp, 0)) != 0)
+				return (ret);
+			p = bhp;
+			goto found;
+		}
+
+		freed_space += sizeof(*bhp) + bh_mfp->pagesize;
+		if ((ret =
+		    __memp_bhfree(dbmp, infop,
+			 bh_mfp, hp, bhp, BH_FREE_FREEMEM)) != 0)
+			return (ret);
+
+		/* Reset "aggressive" and "write_error" if we free any space. */
+		if (aggressive > 1)
+			aggressive = 1;
+		write_error = 0;
+
+		/*
+		 * Unlock this buffer and re-acquire the region lock. If
+		 * we're reaching here as a result of calling memp_bhfree, the
+		 * buffer lock has already been discarded.
+		 */
+		if (0) {
+next_hb:		if (bhp != NULL) {
+				DB_ASSERT(env, BH_REFCOUNT(bhp) > 0);
+				atomic_dec(env, &bhp->ref);
+				if (b_lock) {
+					F_CLR(bhp, BH_EXCLUSIVE);
+					MUTEX_UNLOCK(env, bhp->mtx_buf);
+				}
+			}
+			if (h_locked)
+				MUTEX_UNLOCK(env, hp->mtx_hash);
+			h_locked = 0;
+		}
+		MPOOL_REGION_LOCK(env, infop);
+
+		/*
+		 * Retry the allocation as soon as we've freed up sufficient
+		 * space.  We're likely to have to coalesce of memory to
+		 * satisfy the request, don't try until it's likely (possible?)
+		 * we'll succeed.
+		 */
+		if (freed_space >= 3 * len)
+			goto alloc;
+	}
+	/* NOTREACHED */
+}
+
+/*
+ * __memp_free --
+ *	Free some space from a cache region.
+ *
+ * PUBLIC: void __memp_free __P((REGINFO *, void *));
+ */
+void
+__memp_free(infop, buf)
+	REGINFO *infop;
+	void *buf;
+{
+	__env_alloc_free(infop, buf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_bh.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,716 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"		/* Required for diagnostic code. */
+#include "dbinc/mp.h"
+#include "dbinc/log.h"
+#include "dbinc/txn.h"
+
+static int __memp_pgwrite
+	       __P((ENV *, DB_MPOOLFILE *, DB_MPOOL_HASH *, BH *));
+
+/*
+ * __memp_bhwrite --
+ *	Write the page associated with a given buffer header.
+ *
+ * PUBLIC: int __memp_bhwrite __P((DB_MPOOL *,
+ * PUBLIC:      DB_MPOOL_HASH *, MPOOLFILE *, BH *, int));
+ */
+int
+__memp_bhwrite(dbmp, hp, mfp, bhp, open_extents)
+	DB_MPOOL *dbmp;
+	DB_MPOOL_HASH *hp;
+	MPOOLFILE *mfp;
+	BH *bhp;
+	int open_extents;
+{
+	DB_MPOOLFILE *dbmfp;
+	DB_MPREG *mpreg;
+	ENV *env;
+	int opened, ret;
+
+	env = dbmp->env;
+	opened = 0;
+
+	/*
+	 * If the file has been removed or is a closed temporary file, we're
+	 * done -- the page-write function knows how to handle the fact that
+	 * we don't have (or need!) any real file descriptor information.
+	 */
+	if (mfp->deadfile)
+		return (__memp_pgwrite(env, NULL, hp, bhp));
+
+	/*
+	 * Walk the process' DB_MPOOLFILE list and find a file descriptor for
+	 * the file.  We also check that the descriptor is open for writing.
+	 */
+	MUTEX_LOCK(env, dbmp->mutex);
+	TAILQ_FOREACH(dbmfp, &dbmp->dbmfq, q)
+		if (dbmfp->mfp == mfp && !F_ISSET(dbmfp, MP_READONLY)) {
+			++dbmfp->ref;
+			break;
+		}
+	MUTEX_UNLOCK(env, dbmp->mutex);
+
+	if (dbmfp != NULL) {
+		/*
+		 * Temporary files may not have been created.  We only handle
+		 * temporary files in this path, because only the process that
+		 * created a temporary file will ever flush buffers to it.
+		 */
+		if (dbmfp->fhp == NULL) {
+			/* We may not be allowed to create backing files. */
+			if (mfp->no_backing_file) {
+				--dbmfp->ref;
+				return (EPERM);
+			}
+
+			MUTEX_LOCK(env, dbmp->mutex);
+			if (dbmfp->fhp == NULL) {
+				ret = __db_tmp_open(env,
+				    F_ISSET(env->dbenv, DB_ENV_DIRECT_DB) ?
+				    DB_OSO_DIRECT : 0, &dbmfp->fhp);
+			} else
+				ret = 0;
+			MUTEX_UNLOCK(env, dbmp->mutex);
+			if (ret != 0) {
+				__db_errx(env, DB_STR("3014",
+			    "unable to create temporary backing file"));
+				--dbmfp->ref;
+				return (ret);
+			}
+		}
+
+		goto pgwrite;
+	}
+
+	/*
+	 * There's no file handle for this file in our process.
+	 *
+	 * !!!
+	 * It's the caller's choice if we're going to open extent files.
+	 */
+	if (!open_extents && F_ISSET(mfp, MP_EXTENT))
+		return (EPERM);
+
+	/*
+	 * !!!
+	 * Don't try to attach to temporary files.  There are two problems in
+	 * trying to do that.  First, if we have different privileges than the
+	 * process that "owns" the temporary file, we might create the backing
+	 * disk file such that the owning process couldn't read/write its own
+	 * buffers, e.g., memp_trickle running as root creating a file owned
+	 * as root, mode 600.  Second, if the temporary file has already been
+	 * created, we don't have any way of finding out what its real name is,
+	 * and, even if we did, it was already unlinked (so that it won't be
+	 * left if the process dies horribly).  This decision causes a problem,
+	 * however: if the temporary file consumes the entire buffer cache,
+	 * and the owner doesn't flush the buffers to disk, we could end up
+	 * with resource starvation, and the memp_trickle thread couldn't do
+	 * anything about it.  That's a pretty unlikely scenario, though.
+	 *
+	 * Note we should never get here when the temporary file in question
+	 * has already been closed in another process, in which case it should
+	 * be marked dead.
+	 */
+	if (F_ISSET(mfp, MP_TEMP) || mfp->no_backing_file)
+		return (EPERM);
+
+	/*
+	 * It's not a page from a file we've opened.  If the file requires
+	 * application-specific input/output processing, see if this process
+	 * has ever registered information as to how to write this type of
+	 * file.  If not, there's nothing we can do.
+	 */
+	if (mfp->ftype != 0 && mfp->ftype != DB_FTYPE_SET) {
+		MUTEX_LOCK(env, dbmp->mutex);
+		LIST_FOREACH(mpreg, &dbmp->dbregq, q)
+			if (mpreg->ftype == mfp->ftype)
+				break;
+		MUTEX_UNLOCK(env, dbmp->mutex);
+		if (mpreg == NULL)
+			return (EPERM);
+	}
+
+	/*
+	 * Try and open the file, specifying the known underlying shared area.
+	 *
+	 * !!!
+	 * There's no negative cache, so we may repeatedly try and open files
+	 * that we have previously tried (and failed) to open.
+	 */
+	if ((ret = __memp_fcreate(env, &dbmfp)) != 0)
+		return (ret);
+	/*
+	 * The open will set MP_FLUSH and so we need to keep
+	 * a checkpoint from closing this before we finish with it.
+	 */
+	dbmfp->ref++;
+	opened = 1;
+	if ((ret = __memp_fopen(dbmfp, mfp, NULL,
+	    NULL, DB_FLUSH | DB_DURABLE_UNKNOWN, 0, mfp->pagesize)) != 0) {
+	    	dbmfp->ref--;
+		(void)__memp_fclose(dbmfp, 0);
+
+		/*
+		 * Ignore any error if the file is marked dead, assume the file
+		 * was removed from under us.
+		 */
+		if (!mfp->deadfile)
+			return (ret);
+
+		dbmfp = NULL;
+	}
+
+pgwrite:
+	MVCC_MPROTECT(bhp->buf, mfp->pagesize,
+	    PROT_READ | PROT_WRITE | PROT_EXEC);
+	ret = __memp_pgwrite(env, dbmfp, hp, bhp);
+	if (dbmfp == NULL)
+		return (ret);
+
+	/*
+	 * Discard our reference, and, if we're the last reference, make sure
+	 * the file eventually gets closed.
+	 */
+	MUTEX_LOCK(env, dbmp->mutex);
+	if (!opened && dbmfp->ref == 1) {
+		/*
+		 * If we are the last reference, then we need to mark
+		 * this as having been used to flush.  If this dbmf
+		 * has not been counted as a neutral reference do it.
+		 *
+		 * Getting the mfp mutex while holding the dbmp is
+		 * ok we never do it in the reverse order.
+		 */
+		if (!F_ISSET(dbmfp, MP_FLUSH)) {
+			F_SET(dbmfp, MP_FLUSH);
+			MUTEX_LOCK(env,dbmfp->mfp->mutex);
+			if (!F_ISSET(dbmfp, MP_FOR_FLUSH)) {
+				mfp->neutral_cnt++;
+				F_SET(dbmfp, MP_FOR_FLUSH);
+			}
+			MUTEX_UNLOCK(env, dbmfp->mfp->mutex);
+		}
+	} else
+		--dbmfp->ref;
+	MUTEX_UNLOCK(env, dbmp->mutex);
+
+	return (ret);
+}
+
+/*
+ * __memp_pgread --
+ *	Read a page from a file.
+ *
+ * PUBLIC: int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
+ */
+int
+__memp_pgread(dbmfp, bhp, can_create)
+	DB_MPOOLFILE *dbmfp;
+	BH *bhp;
+	int can_create;
+{
+	ENV *env;
+	MPOOLFILE *mfp;
+	size_t len, nr;
+	u_int32_t pagesize;
+	int ret;
+
+	env = dbmfp->env;
+	mfp = dbmfp->mfp;
+	pagesize = mfp->pagesize;
+
+	/* We should never be called with a dirty or unlocked buffer. */
+	DB_ASSERT(env, !F_ISSET(bhp, BH_DIRTY_CREATE | BH_FROZEN));
+	DB_ASSERT(env, can_create ||
+	    F_ISSET(bhp, BH_TRASH) || !F_ISSET(bhp, BH_DIRTY));
+	DB_ASSERT(env, F_ISSET(bhp, BH_EXCLUSIVE));
+
+	/* Mark the buffer as in transition. */
+	F_SET(bhp, BH_TRASH);
+
+	/*
+	 * Temporary files may not yet have been created.  We don't create
+	 * them now, we create them when the pages have to be flushed.
+	 */
+	nr = 0;
+	if (dbmfp->fhp != NULL) {
+		PERFMON3(env, mpool, read, __memp_fn(dbmfp), bhp->pgno, bhp);
+		if ((ret = __os_io(env, DB_IO_READ, dbmfp->fhp,
+		    bhp->pgno, pagesize, 0, pagesize, bhp->buf, &nr)) != 0)
+			goto err;
+	}
+
+	/*
+	 * The page may not exist; if it doesn't, nr may well be 0, but we
+	 * expect the underlying OS calls not to return an error code in
+	 * this case.
+	 */
+	if (nr < pagesize) {
+		/*
+		 * Don't output error messages for short reads.  In particular,
+		 * DB recovery processing may request pages never written to
+		 * disk or for which only some part have been written to disk,
+		 * in which case we won't find the page.  The caller must know
+		 * how to handle the error.
+		 */
+		if (!can_create) {
+			ret = DB_PAGE_NOTFOUND;
+			goto err;
+		}
+
+		/* Clear any bytes that need to be cleared. */
+		len = mfp->clear_len == DB_CLEARLEN_NOTSET ?
+		    pagesize : mfp->clear_len;
+		memset(bhp->buf, 0, len);
+
+#if defined(DIAGNOSTIC) || defined(UMRW)
+		/*
+		 * If we're running in diagnostic mode, corrupt any bytes on
+		 * the page that are unknown quantities for the caller.
+		 */
+		if (len < pagesize)
+			memset(bhp->buf + len, CLEAR_BYTE, pagesize - len);
+#endif
+		STAT_INC_VERB(env, mpool, page_create,
+		    mfp->stat.st_page_create, __memp_fn(dbmfp), bhp->pgno);
+	} else
+		STAT_INC_VERB(env, mpool, page_in,
+		    mfp->stat.st_page_in, __memp_fn(dbmfp), bhp->pgno);
+
+	/* Call any pgin function. */
+	ret = mfp->ftype == 0 ? 0 : __memp_pg(dbmfp, bhp->pgno, bhp->buf, 1);
+
+	/*
+	 * If no errors occurred, the data is now valid, clear the BH_TRASH
+	 * flag.
+	 */
+	if (ret == 0)
+		F_CLR(bhp, BH_TRASH);
+err:	return (ret);
+}
+
+/*
+ * __memp_pgwrite --
+ *	Write a page to a file.
+ */
+static int
+__memp_pgwrite(env, dbmfp, hp, bhp)
+	ENV *env;
+	DB_MPOOLFILE *dbmfp;
+	DB_MPOOL_HASH *hp;
+	BH *bhp;
+{
+	DB_LSN lsn;
+	MPOOLFILE *mfp;
+	size_t nw;
+	int ret;
+	void * buf;
+
+	/*
+	 * Since writing does not require exclusive access, another thread
+	 * could have already written this buffer.
+	 */
+	if (!F_ISSET(bhp, BH_DIRTY))
+		return (0);
+
+	mfp = dbmfp == NULL ? NULL : dbmfp->mfp;
+	ret = 0;
+	buf = NULL;
+
+	/* We should never be called with a frozen or trashed buffer. */
+	DB_ASSERT(env, !F_ISSET(bhp, BH_FROZEN | BH_TRASH));
+
+	/*
+	 * It's possible that the underlying file doesn't exist, either
+	 * because of an outright removal or because it was a temporary
+	 * file that's been closed.
+	 *
+	 * !!!
+	 * Once we pass this point, we know that dbmfp and mfp aren't NULL,
+	 * and that we have a valid file reference.
+	 */
+	if (mfp == NULL || mfp->deadfile)
+		goto file_dead;
+
+	/*
+	 * If the page is in a file for which we have LSN information, we have
+	 * to ensure the appropriate log records are on disk.
+	 */
+	if (LOGGING_ON(env) && mfp->lsn_off != DB_LSN_OFF_NOTSET &&
+	    !IS_CLIENT_PGRECOVER(env)) {
+		memcpy(&lsn, bhp->buf + mfp->lsn_off, sizeof(DB_LSN));
+		if (!IS_NOT_LOGGED_LSN(lsn) &&
+		    (ret = __log_flush(env, &lsn)) != 0)
+			goto err;
+	}
+
+#ifdef DIAGNOSTIC
+	/*
+	 * Verify write-ahead logging semantics.
+	 *
+	 * !!!
+	 * Two special cases.  There is a single field on the meta-data page,
+	 * the last-page-number-in-the-file field, for which we do not log
+	 * changes.  If the page was originally created in a database that
+	 * didn't have logging turned on, we can see a page marked dirty but
+	 * for which no corresponding log record has been written.  However,
+	 * the only way that a page can be created for which there isn't a
+	 * previous log record and valid LSN is when the page was created
+	 * without logging turned on, and so we check for that special-case
+	 * LSN value.
+	 *
+	 * Second, when a client is reading database pages from a master
+	 * during an internal backup, we may get pages modified after
+	 * the current end-of-log.
+	 */
+	if (LOGGING_ON(env) && !IS_NOT_LOGGED_LSN(LSN(bhp->buf)) &&
+	    !IS_CLIENT_PGRECOVER(env)) {
+		/*
+		 * There is a potential race here.  If we are in the midst of
+		 * switching log files, it's possible we could test against the
+		 * old file and the new offset in the log region's LSN.  If we
+		 * fail the first test, acquire the log mutex and check again.
+		 */
+		DB_LOG *dblp;
+		LOG *lp;
+
+		dblp = env->lg_handle;
+		lp = dblp->reginfo.primary;
+		if (!lp->db_log_inmemory &&
+		    LOG_COMPARE(&lp->s_lsn, &LSN(bhp->buf)) <= 0) {
+			MUTEX_LOCK(env, lp->mtx_flush);
+			DB_ASSERT(env, F_ISSET(env->dbenv, DB_ENV_NOLOCKING) ||
+			    LOG_COMPARE(&lp->s_lsn, &LSN(bhp->buf)) > 0);
+			MUTEX_UNLOCK(env, lp->mtx_flush);
+		}
+	}
+#endif
+
+#ifndef HAVE_ATOMICFILEREAD
+	if (mfp->backup_in_progress != 0) {
+		MUTEX_READLOCK(env, mfp->mtx_write);
+		if (bhp->pgno >= mfp->low_pgno && bhp->pgno <= mfp->high_pgno) {
+			MUTEX_UNLOCK(env, mfp->mtx_write);
+			ret = EAGAIN;
+			goto err;
+		}
+		atomic_inc(env, &mfp->writers);
+		MUTEX_UNLOCK(env, mfp->mtx_write);
+	} else
+		atomic_inc(env, &mfp->writers);
+#endif
+
+	/*
+	 * Call any pgout function.  If we have the page exclusive then
+	 * we are going to reuse it otherwise make a copy of the page so
+	 * that others can continue looking at the page while we write it.
+	 */
+	buf = bhp->buf;
+	if (mfp->ftype != 0) {
+		if (F_ISSET(bhp, BH_EXCLUSIVE))
+			F_SET(bhp, BH_TRASH);
+		else {
+			if ((ret = __os_malloc(env, mfp->pagesize, &buf)) != 0)
+				goto err;
+			memcpy(buf, bhp->buf, mfp->pagesize);
+		}
+		if ((ret = __memp_pg(dbmfp, bhp->pgno, buf, 0)) != 0)
+			goto err;
+	}
+
+	PERFMON3(env, mpool, write, __memp_fn(dbmfp), bhp->pgno, bhp);
+	/* Write the page. */
+	if ((ret = __os_io(env, DB_IO_WRITE, dbmfp->fhp, bhp->pgno,
+	    mfp->pagesize, 0, mfp->pagesize, buf, &nw)) != 0) {
+#ifndef HAVE_ATOMICFILEREAD
+		atomic_dec(env, &mfp->writers);
+#endif
+		__db_errx(env, DB_STR_A("3015",
+		    "%s: write failed for page %lu", "%s %lu"),
+		    __memp_fn(dbmfp), (u_long)bhp->pgno);
+		goto err;
+	}
+#ifndef HAVE_ATOMICFILEREAD
+	atomic_dec(env, &mfp->writers);
+#endif
+	STAT_INC_VERB(env, mpool, page_out,
+	    mfp->stat.st_page_out, __memp_fn(dbmfp), bhp->pgno);
+	if (bhp->pgno > mfp->last_flushed_pgno) {
+		MUTEX_LOCK(env, mfp->mutex);
+		if (bhp->pgno > mfp->last_flushed_pgno)
+			mfp->last_flushed_pgno = bhp->pgno;
+		MUTEX_UNLOCK(env, mfp->mutex);
+	}
+
+err:
+file_dead:
+	if (buf != NULL && buf != bhp->buf)
+		__os_free(env, buf);
+	/*
+	 * !!!
+	 * Once we pass this point, dbmfp and mfp may be NULL, we may not have
+	 * a valid file reference.
+	 */
+
+	/*
+	 * Update the hash bucket statistics, reset the flags.  If we were
+	 * successful, the page is no longer dirty.  Someone else may have
+	 * also written the page so we need to latch the hash bucket here
+	 * to get the accounting correct.  Since we have the buffer
+	 * shared it cannot be marked dirty again till we release it.
+	 * This is the only place we update the flags field only holding
+	 * a shared latch.
+	 */
+	if (F_ISSET(bhp, BH_DIRTY | BH_TRASH)) {
+		MUTEX_LOCK(env, hp->mtx_hash);
+		DB_ASSERT(env, !SH_CHAIN_HASNEXT(bhp, vc));
+		if (ret == 0 && F_ISSET(bhp, BH_DIRTY)) {
+			F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
+			DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0);
+			atomic_dec(env, &hp->hash_page_dirty);
+		}
+
+		/* put the page back if necessary. */
+		if ((ret != 0 || BH_REFCOUNT(bhp) > 1) &&
+		    F_ISSET(bhp, BH_TRASH)) {
+			ret = __memp_pg(dbmfp, bhp->pgno, bhp->buf, 1);
+			F_CLR(bhp, BH_TRASH);
+		}
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+	}
+
+	return (ret);
+}
+
+/*
+ * __memp_pg --
+ *	Call the pgin/pgout routine.
+ *
+ * PUBLIC: int __memp_pg __P((DB_MPOOLFILE *, db_pgno_t, void *, int));
+ */
+int
+__memp_pg(dbmfp, pgno, buf, is_pgin)
+	DB_MPOOLFILE *dbmfp;
+	db_pgno_t pgno;
+	void *buf;
+	int is_pgin;
+{
+	DBT dbt, *dbtp;
+	DB_MPOOL *dbmp;
+	DB_MPREG *mpreg;
+	ENV *env;
+	MPOOLFILE *mfp;
+	int ftype, ret;
+
+	env = dbmfp->env;
+	dbmp = env->mp_handle;
+	mfp = dbmfp->mfp;
+
+	if ((ftype = mfp->ftype) == DB_FTYPE_SET)
+		mpreg = dbmp->pg_inout;
+	else {
+		MUTEX_LOCK(env, dbmp->mutex);
+		LIST_FOREACH(mpreg, &dbmp->dbregq, q)
+			if (ftype == mpreg->ftype)
+				break;
+		MUTEX_UNLOCK(env, dbmp->mutex);
+	}
+	if (mpreg == NULL)
+		return (0);
+
+	if (mfp->pgcookie_len == 0)
+		dbtp = NULL;
+	else {
+		DB_SET_DBT(dbt, R_ADDR(
+		    dbmp->reginfo, mfp->pgcookie_off), mfp->pgcookie_len);
+		dbtp = &dbt;
+	}
+
+	if (is_pgin) {
+		if (mpreg->pgin != NULL && (ret =
+		    mpreg->pgin(env->dbenv, pgno, buf, dbtp)) != 0)
+			goto err;
+	} else
+		if (mpreg->pgout != NULL && (ret =
+		    mpreg->pgout(env->dbenv, pgno, buf, dbtp)) != 0)
+			goto err;
+
+	return (0);
+
+err:	__db_errx(env, DB_STR_A("3016",
+	    "%s: %s failed for page %lu", "%s %s %lu"), __memp_fn(dbmfp),
+	    is_pgin ? DB_STR_P("pgin") : DB_STR_P("pgout"), (u_long)pgno);
+	return (ret);
+}
+
+/*
+ * __memp_bhfree --
+ *	Free a bucket header and its referenced data.
+ *
+ * PUBLIC: int __memp_bhfree __P((DB_MPOOL *,
+ * PUBLIC:	REGINFO *, MPOOLFILE *, DB_MPOOL_HASH *, BH *, u_int32_t));
+ */
+int
+__memp_bhfree(dbmp, infop, mfp, hp, bhp, flags)
+	DB_MPOOL *dbmp;
+	REGINFO *infop;
+	MPOOLFILE *mfp;
+	DB_MPOOL_HASH *hp;
+	BH *bhp;
+	u_int32_t flags;
+{
+	ENV *env;
+#ifdef DIAGNOSTIC
+	DB_LSN vlsn;
+#endif
+	BH *prev_bhp;
+	MPOOL *c_mp;
+	int ret, t_ret;
+#ifdef DIAG_MVCC
+	size_t pagesize;
+#endif
+
+	ret = 0;
+
+	/*
+	 * Assumes the hash bucket is locked and the MPOOL is not.
+	 */
+	env = dbmp->env;
+#ifdef DIAG_MVCC
+	if (mfp != NULL)
+		pagesize = mfp->pagesize;
+#endif
+
+	DB_ASSERT(env, LF_ISSET(BH_FREE_UNLOCKED) ||
+	    (hp != NULL && MUTEX_IS_OWNED(env, hp->mtx_hash)));
+	DB_ASSERT(env, BH_REFCOUNT(bhp) == 1 &&
+	    !F_ISSET(bhp, BH_DIRTY | BH_FROZEN));
+	DB_ASSERT(env, LF_ISSET(BH_FREE_UNLOCKED) ||
+	    SH_CHAIN_SINGLETON(bhp, vc) || (SH_CHAIN_HASNEXT(bhp, vc) &&
+	    (SH_CHAIN_NEXTP(bhp, vc, __bh)->td_off == bhp->td_off ||
+	    bhp->td_off == INVALID_ROFF ||
+	    IS_MAX_LSN(*VISIBLE_LSN(env, bhp)) ||
+	    BH_OBSOLETE(bhp, hp->old_reader, vlsn))));
+
+	PERFMON3(env, mpool, evict, __memp_fns(dbmp, mfp), bhp->pgno, bhp);
+
+	/*
+	 * Delete the buffer header from the hash bucket queue or the
+	 * version chain.
+	 */
+	if (hp == NULL)
+		goto no_hp;
+	prev_bhp = SH_CHAIN_PREV(bhp, vc, __bh);
+	if (!SH_CHAIN_HASNEXT(bhp, vc)) {
+		if (prev_bhp != NULL)
+			SH_TAILQ_INSERT_AFTER(&hp->hash_bucket,
+			    bhp, prev_bhp, hq, __bh);
+		SH_TAILQ_REMOVE(&hp->hash_bucket, bhp, hq, __bh);
+	}
+	SH_CHAIN_REMOVE(bhp, vc, __bh);
+
+	/*
+	 * Remove the reference to this buffer from the transaction that
+	 * created it, if any.  When the BH_FREE_UNLOCKED flag is set, we're
+	 * discarding the environment, so the transaction region is already
+	 * gone.
+	 */
+	if (bhp->td_off != INVALID_ROFF && !LF_ISSET(BH_FREE_UNLOCKED)) {
+		ret = __txn_remove_buffer(
+		    env, BH_OWNER(env, bhp), hp->mtx_hash);
+		bhp->td_off = INVALID_ROFF;
+	}
+
+	/*
+	 * We're going to use the memory for something else -- it had better be
+	 * accessible.
+	 */
+no_hp:	if (mfp != NULL)
+		MVCC_MPROTECT(bhp->buf,
+		    pagesize, PROT_READ | PROT_WRITE | PROT_EXEC);
+
+	/*
+	 * Discard the hash bucket's mutex, it's no longer needed, and
+	 * we don't want to be holding it when acquiring other locks.
+	 */
+	if (!LF_ISSET(BH_FREE_UNLOCKED))
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+
+	/*
+	 * If we're only removing this header from the chain for reuse, we're
+	 * done.
+	 */
+	if (LF_ISSET(BH_FREE_REUSE))
+		return (ret);
+
+	/*
+	 * If we're not reusing the buffer immediately, free the buffer for
+	 * real.
+	 */
+	if (!LF_ISSET(BH_FREE_UNLOCKED))
+		MUTEX_UNLOCK(env, bhp->mtx_buf);
+	if (LF_ISSET(BH_FREE_FREEMEM)) {
+		if ((ret = __mutex_free(env, &bhp->mtx_buf)) != 0)
+			return (ret);
+		MPOOL_REGION_LOCK(env, infop);
+
+		MVCC_BHUNALIGN(bhp);
+		__memp_free(infop, bhp);
+		c_mp = infop->primary;
+		c_mp->pages--;
+
+		MPOOL_REGION_UNLOCK(env, infop);
+	}
+
+	if (mfp == NULL)
+		return (ret);
+
+	/*
+	 * Decrement the reference count of the underlying MPOOLFILE.
+	 * If this is its last reference, remove it.
+	 */
+	MUTEX_LOCK(env, mfp->mutex);
+	if (--mfp->block_cnt == 0 && mfp->mpf_cnt == 0) {
+		if ((t_ret = __memp_mf_discard(dbmp, mfp, 0)) != 0 && ret == 0)
+			ret = t_ret;
+	} else
+		MUTEX_UNLOCK(env, mfp->mutex);
+
+#ifdef DIAGNOSTIC
+	COMPQUIET(vlsn.file, 0);
+#endif
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_fget.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1223 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/log.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+#ifdef DIAGNOSTIC
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/lock.h"
+#endif
+
+/*
+ * __memp_fget_pp --
+ *	DB_MPOOLFILE->get pre/post processing.
+ *
+ * PUBLIC: int __memp_fget_pp
+ * PUBLIC:     __P((DB_MPOOLFILE *, db_pgno_t *, DB_TXN *, u_int32_t, void *));
+ */
+int
+__memp_fget_pp(dbmfp, pgnoaddr, txnp, flags, addrp)
+	DB_MPOOLFILE *dbmfp;
+	db_pgno_t *pgnoaddr;
+	DB_TXN *txnp;
+	u_int32_t flags;
+	void *addrp;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int rep_blocked, ret;
+
+	env = dbmfp->env;
+
+	MPF_ILLEGAL_BEFORE_OPEN(dbmfp, "DB_MPOOLFILE->get");
+
+	/*
+	 * Validate arguments.
+	 *
+	 * !!!
+	 * Don't test for DB_MPOOL_CREATE and DB_MPOOL_NEW flags for readonly
+	 * files here, and create non-existent pages in readonly files if the
+	 * flags are set, later.  The reason is that the hash access method
+	 * wants to get empty pages that don't really exist in readonly files.
+	 * The only alternative is for hash to write the last "bucket" all the
+	 * time, which we don't want to do because one of our big goals in life
+	 * is to keep database files small.  It's sleazy as hell, but we catch
+	 * any attempt to actually write the file in memp_fput().
+	 */
+#undef	OKFLAGS
+#define	OKFLAGS		(DB_MPOOL_CREATE | DB_MPOOL_DIRTY | \
+	    DB_MPOOL_EDIT | DB_MPOOL_LAST | DB_MPOOL_NEW)
+	if (flags != 0) {
+		if ((ret = __db_fchk(env, "memp_fget", flags, OKFLAGS)) != 0)
+			return (ret);
+
+		switch (FLD_CLR(flags, DB_MPOOL_DIRTY | DB_MPOOL_EDIT)) {
+		case DB_MPOOL_CREATE:
+		case DB_MPOOL_LAST:
+		case DB_MPOOL_NEW:
+		case 0:
+			break;
+		default:
+			return (__db_ferr(env, "memp_fget", 1));
+		}
+	}
+
+	ENV_ENTER(env, ip);
+
+	rep_blocked = 0;
+	if (txnp == NULL && IS_ENV_REPLICATED(env)) {
+		if ((ret = __op_rep_enter(env, 0, 1)) != 0)
+			goto err;
+		rep_blocked = 1;
+	}
+	ret = __memp_fget(dbmfp, pgnoaddr, ip, txnp, flags, addrp);
+	/*
+	 * We only decrement the count in op_rep_exit if the operation fails.
+	 * Otherwise the count will be decremented when the page is no longer
+	 * pinned in memp_fput.
+	 */
+	if (ret != 0 && rep_blocked)
+		(void)__op_rep_exit(env);
+
+	/* Similarly if an app has a page pinned it is ACTIVE. */
+err:	if (ret != 0)
+		ENV_LEAVE(env, ip);
+
+	return (ret);
+}
+
+/*
+ * __memp_fget --
+ *	Get a page from the file.
+ *
+ * PUBLIC: int __memp_fget __P((DB_MPOOLFILE *,
+ * PUBLIC:     db_pgno_t *, DB_THREAD_INFO *, DB_TXN *, u_int32_t, void *));
+ */
+int
+__memp_fget(dbmfp, pgnoaddr, ip, txn, flags, addrp)
+	DB_MPOOLFILE *dbmfp;
+	db_pgno_t *pgnoaddr;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	u_int32_t flags;
+	void *addrp;
+{
+	enum { FIRST_FOUND, FIRST_MISS, SECOND_FOUND, SECOND_MISS } state;
+	BH *alloc_bhp, *bhp, *oldest_bhp;
+	ENV *env;
+	DB_LSN *read_lsnp, vlsn;
+	DB_MPOOL *dbmp;
+	DB_MPOOL_HASH *hp;
+	MPOOL *c_mp;
+	MPOOLFILE *mfp;
+	PIN_LIST *list, *lp;
+	REGENV *renv;
+	REGINFO *infop, *t_infop, *reginfo;
+	TXN_DETAIL *td;
+	roff_t list_off, mf_offset;
+	u_int32_t bucket, pinmax, st_hsearch;
+	int b_incr, b_lock, h_locked, dirty, extending;
+	int makecopy, mvcc, need_free, ret;
+#ifdef DIAGNOSTIC
+	DB_LOCKTAB *lt;
+	DB_LOCKER *locker;
+#endif
+
+	*(void **)addrp = NULL;
+	COMPQUIET(c_mp, NULL);
+	COMPQUIET(infop, NULL);
+	COMPQUIET(vlsn.file, 0);
+
+	env = dbmfp->env;
+	dbmp = env->mp_handle;
+
+	mfp = dbmfp->mfp;
+	mvcc = atomic_read(&mfp->multiversion) && (txn != NULL);
+	mf_offset = R_OFFSET(dbmp->reginfo, mfp);
+	alloc_bhp = bhp = oldest_bhp = NULL;
+	read_lsnp = NULL;
+	td = NULL;
+	hp = NULL;
+	b_incr = b_lock = h_locked = extending = makecopy = ret = 0;
+
+	if (LF_ISSET(DB_MPOOL_DIRTY)) {
+		if (F_ISSET(dbmfp, MP_READONLY)) {
+			__db_errx(env, DB_STR_A("3021",
+			    "%s: dirty flag set for readonly file page",
+			    "%s"), __memp_fn(dbmfp));
+			return (EINVAL);
+		}
+		if ((ret = __db_fcchk(env, "DB_MPOOLFILE->get",
+		    flags, DB_MPOOL_DIRTY, DB_MPOOL_EDIT)) != 0)
+			return (ret);
+	}
+
+	dirty = LF_ISSET(DB_MPOOL_DIRTY | DB_MPOOL_EDIT | DB_MPOOL_FREE);
+	LF_CLR(DB_MPOOL_DIRTY | DB_MPOOL_EDIT);
+
+#ifdef HAVE_TRANSACTIONS
+	/*
+	 * If the transaction is being used to update a multiversion database
+	 * for the first time, set the read LSN.  In addition, if this is an
+	 * update, allocate a mutex.  If no transaction has been supplied, that
+	 * will be caught later, when we know whether one is required.
+	 */
+	if (mvcc && txn != NULL && txn->td != NULL) {
+		/* We're only interested in the ultimate parent transaction. */
+		while (txn->parent != NULL)
+			txn = txn->parent;
+		td = (TXN_DETAIL *)txn->td;
+		if (F_ISSET(txn, TXN_SNAPSHOT)) {
+			read_lsnp = &td->read_lsn;
+			if (IS_MAX_LSN(*read_lsnp) &&
+			    (ret = __log_current_lsn_int(env, read_lsnp,
+			    NULL, NULL)) != 0)
+				return (ret);
+		}
+		if ((dirty || LF_ISSET(DB_MPOOL_CREATE | DB_MPOOL_NEW)) &&
+		    td->mvcc_mtx == MUTEX_INVALID && (ret =
+		    __mutex_alloc(env, MTX_TXN_MVCC, 0, &td->mvcc_mtx)) != 0)
+			return (ret);
+	}
+#endif
+
+	switch (flags) {
+	case DB_MPOOL_LAST:
+		/* Get the last page number in the file. */
+		MUTEX_LOCK(env, mfp->mutex);
+		*pgnoaddr = mfp->last_pgno;
+		MUTEX_UNLOCK(env, mfp->mutex);
+		break;
+	case DB_MPOOL_NEW:
+		/*
+		 * If always creating a page, skip the first search
+		 * of the hash bucket.
+		 */
+		goto newpg;
+	case DB_MPOOL_CREATE:
+	default:
+		break;
+	}
+
+	/*
+	 * If mmap'ing the file and the page is not past the end of the file,
+	 * just return a pointer.  We can't use R_ADDR here: this is an offset
+	 * into an mmap'd file, not a shared region, and doesn't change for
+	 * private environments.
+	 *
+	 * The page may be past the end of the file, so check the page number
+	 * argument against the original length of the file.  If we previously
+	 * returned pages past the original end of the file, last_pgno will
+	 * have been updated to match the "new" end of the file, and checking
+	 * against it would return pointers past the end of the mmap'd region.
+	 *
+	 * If another process has opened the file for writing since we mmap'd
+	 * it, we will start playing the game by their rules, i.e. everything
+	 * goes through the cache.  All pages previously returned will be safe,
+	 * as long as the correct locking protocol was observed.
+	 *
+	 * We don't discard the map because we don't know when all of the
+	 * pages will have been discarded from the process' address space.
+	 * It would be possible to do so by reference counting the open
+	 * pages from the mmap, but it's unclear to me that it's worth it.
+	 */
+	if (dbmfp->addr != NULL &&
+	    F_ISSET(mfp, MP_CAN_MMAP) && *pgnoaddr <= mfp->orig_last_pgno) {
+		*(void **)addrp = (u_int8_t *)dbmfp->addr +
+		    (*pgnoaddr * mfp->pagesize);
+		STAT_INC_VERB(env,
+		    mpool, map, mfp->stat.st_map, __memp_fn(dbmfp), *pgnoaddr);
+		return (0);
+	}
+
+	/*
+	 * Determine the cache and hash bucket where this page lives and get
+	 * local pointers to them.  Reset on each pass through this code, the
+	 * page number can change.
+	 */
+	MP_GET_BUCKET(env, mfp, *pgnoaddr, &infop, hp, bucket, ret);
+	if (ret != 0)
+		return (ret);
+	c_mp = infop->primary;
+
+	if (0) {
+		/* if we search again, get an exclusive lock. */
+retry:		MUTEX_LOCK(env, hp->mtx_hash);
+	}
+
+	/* Search the hash chain for the page. */
+	st_hsearch = 0;
+	h_locked = 1;
+	SH_TAILQ_FOREACH(bhp, &hp->hash_bucket, hq, __bh) {
+		++st_hsearch;
+		if (bhp->pgno != *pgnoaddr || bhp->mf_offset != mf_offset)
+			continue;
+
+		/* Snapshot reads -- get the version visible at read_lsn. */
+		if (read_lsnp != NULL) {
+			while (bhp != NULL &&
+			    !BH_OWNED_BY(env, bhp, txn) &&
+			    !BH_VISIBLE(env, bhp, read_lsnp, vlsn))
+				bhp = SH_CHAIN_PREV(bhp, vc, __bh);
+
+			/*
+			 * We can get a null bhp if we are looking for a
+			 * page that was created after the transaction was
+			 * started so its not visible  (i.e. page added to
+			 * the BTREE in a subsequent txn).
+			 */
+			if (bhp == NULL) {
+				ret = DB_PAGE_NOTFOUND;
+				goto err;
+			}
+		}
+
+		makecopy = mvcc && dirty && !BH_OWNED_BY(env, bhp, txn);
+
+		/*
+		 * Increment the reference count.  This signals that the
+		 * buffer may not be discarded.  We must drop the hash
+		 * mutex before we lock the buffer mutex.
+		 */
+		if (BH_REFCOUNT(bhp) == UINT16_MAX) {
+			__db_errx(env, DB_STR_A("3022",
+			    "%s: page %lu: reference count overflow",
+			    "%s %lu"), __memp_fn(dbmfp), (u_long)bhp->pgno);
+			ret = __env_panic(env, EINVAL);
+			goto err;
+		}
+		atomic_inc(env, &bhp->ref);
+		b_incr = 1;
+
+		/*
+		 * Lock the buffer. If the page is being read in or modified it
+		 * will be exclusively locked and we will block.
+		 */
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+		h_locked = 0;
+		if (dirty || extending || makecopy || F_ISSET(bhp, BH_FROZEN)) {
+xlatch:			if (LF_ISSET(DB_MPOOL_TRY)) {
+				if ((ret =
+				    MUTEX_TRYLOCK(env, bhp->mtx_buf)) != 0)
+					goto err;
+			} else
+				MUTEX_LOCK(env, bhp->mtx_buf);
+			F_SET(bhp, BH_EXCLUSIVE);
+		} else if (LF_ISSET(DB_MPOOL_TRY)) {
+			if ((ret = MUTEX_TRY_READLOCK(env, bhp->mtx_buf)) != 0)
+				goto err;
+		} else
+			MUTEX_READLOCK(env, bhp->mtx_buf);
+
+#ifdef HAVE_SHARED_LATCHES
+		/*
+		 * If buffer is still in transit once we have a shared latch,
+		 * upgrade to an exclusive latch.
+		 */
+		if (F_ISSET(bhp, BH_FREED | BH_TRASH) &&
+		    !F_ISSET(bhp, BH_EXCLUSIVE)) {
+			MUTEX_UNLOCK(env, bhp->mtx_buf);
+			goto xlatch;
+		}
+#else
+		F_SET(bhp, BH_EXCLUSIVE);
+#endif
+		b_lock = 1;
+
+		/*
+		 * If the buffer was frozen before we waited for any I/O to
+		 * complete and is still frozen, we will need to thaw it.
+		 * Otherwise, it was thawed while we waited, and we need to
+		 * search again.
+		 */
+		if (F_ISSET(bhp, BH_THAWED)) {
+			need_free = (atomic_dec(env, &bhp->ref) == 0);
+			b_incr = 0;
+			MUTEX_UNLOCK(env, bhp->mtx_buf);
+			b_lock = 0;
+			if (need_free) {
+				MPOOL_REGION_LOCK(env, infop);
+				SH_TAILQ_INSERT_TAIL(&c_mp->free_frozen,
+				    bhp, hq);
+				MPOOL_REGION_UNLOCK(env, infop);
+			}
+			bhp = NULL;
+			goto retry;
+		}
+
+		/*
+		 * If the buffer we wanted was frozen or thawed while we
+		 * waited, we need to start again.  That is indicated by
+		 * a new buffer header in the version chain owned by the same
+		 * transaction as the one we pinned.
+		 *
+		 * Also, if we're doing an unversioned read on a multiversion
+		 * file, another thread may have dirtied this buffer while we
+		 * swapped from the hash bucket lock to the buffer lock.
+		 */
+		if (SH_CHAIN_HASNEXT(bhp, vc) &&
+		    (SH_CHAIN_NEXTP(bhp, vc, __bh)->td_off == bhp->td_off ||
+		    (!dirty && read_lsnp == NULL))) {
+			DB_ASSERT(env, b_incr && BH_REFCOUNT(bhp) != 0);
+			atomic_dec(env, &bhp->ref);
+			b_incr = 0;
+			MUTEX_UNLOCK(env, bhp->mtx_buf);
+			b_lock = 0;
+			bhp = NULL;
+			goto retry;
+		} else if (dirty && SH_CHAIN_HASNEXT(bhp, vc)) {
+			ret = DB_LOCK_DEADLOCK;
+			goto err;
+		} else if (F_ISSET(bhp, BH_FREED) && flags != DB_MPOOL_CREATE &&
+		    flags != DB_MPOOL_NEW && flags != DB_MPOOL_FREE) {
+			ret = DB_PAGE_NOTFOUND;
+			goto err;
+		}
+
+		/* Is it worthwhile to publish oh-so-frequent cache hits? */
+		STAT_INC_VERB(env, mpool, hit,
+		    mfp->stat.st_cache_hit, __memp_fn(dbmfp), *pgnoaddr);
+		break;
+	}
+
+#ifdef HAVE_STATISTICS
+	/*
+	 * Update the hash bucket search statistics -- do now because our next
+	 * search may be for a different bucket. Are these too frequent also?
+	 */
+	STAT_INC_VERB(env, mpool, hash_search,
+	    c_mp->stat.st_hash_searches, __memp_fn(dbmfp), *pgnoaddr);
+	if (st_hsearch > c_mp->stat.st_hash_longest)
+		STAT_SET_VERB(env, mpool, hash_longest,
+		    c_mp->stat.st_hash_longest,
+		    st_hsearch, __memp_fn(dbmfp), *pgnoaddr);
+	STAT_ADJUST_VERB(env, mpool, hash_examined, c_mp->stat.st_hash_searches,
+	    st_hsearch, __memp_fn(dbmfp), *pgnoaddr);
+#endif
+
+	/*
+	 * There are 4 possible paths to this location:
+	 *
+	 * FIRST_MISS:
+	 *	Didn't find the page in the hash bucket on our first pass:
+	 *	bhp == NULL, alloc_bhp == NULL
+	 *
+	 * FIRST_FOUND:
+	 *	Found the page in the hash bucket on our first pass:
+	 *	bhp != NULL, alloc_bhp == NULL
+	 *
+	 * SECOND_FOUND:
+	 *	Didn't find the page in the hash bucket on the first pass,
+	 *	allocated space, and found the page in the hash bucket on
+	 *	our second pass:
+	 *	bhp != NULL, alloc_bhp != NULL
+	 *
+	 * SECOND_MISS:
+	 *	Didn't find the page in the hash bucket on the first pass,
+	 *	allocated space, and didn't find the page in the hash bucket
+	 *	on our second pass:
+	 *	bhp == NULL, alloc_bhp != NULL
+	 */
+	state = bhp == NULL ?
+	    (alloc_bhp == NULL ? FIRST_MISS : SECOND_MISS) :
+	    (alloc_bhp == NULL ? FIRST_FOUND : SECOND_FOUND);
+
+	switch (state) {
+	case FIRST_FOUND:
+		/*
+		 * If we are to free the buffer, then this had better be the
+		 * only reference. If so, just free the buffer.  If not,
+		 * complain and get out.
+		 */
+		if (flags == DB_MPOOL_FREE) {
+freebuf:		MUTEX_LOCK(env, hp->mtx_hash);
+			h_locked = 1;
+			if (F_ISSET(bhp, BH_DIRTY)) {
+				F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
+				DB_ASSERT(env,
+				   atomic_read(&hp->hash_page_dirty) > 0);
+				atomic_dec(env, &hp->hash_page_dirty);
+			}
+
+			/*
+			 * If the buffer we found is already freed, we're done.
+			 * If the ref count is not 1 then someone may be
+			 * peeking at the buffer.  We cannot free it until they
+			 * determine that it is not what they want.  Clear the
+			 * buffer so that waiting threads get an empty page.
+			 */
+			if (F_ISSET(bhp, BH_FREED))
+				goto done;
+			else if (BH_REFCOUNT(bhp) != 1 ||
+			    !SH_CHAIN_SINGLETON(bhp, vc)) {
+				/*
+				 * Create an empty page in the chain for
+				 * subsequent gets.  Otherwise, a thread that
+				 * re-creates this page while it is still in
+				 * cache will see stale data.
+				 */
+				F_SET(bhp, BH_FREED);
+				F_CLR(bhp, BH_TRASH);
+#ifdef HAVE_TRANSACTIONS
+			} else if (F_ISSET(bhp, BH_FROZEN)) {
+				/*
+				 * Freeing a singleton frozen buffer: just free
+				 * it.  This call will release the hash bucket
+				 * mutex.
+				 */
+				ret =
+				    __memp_bh_thaw(dbmp, infop, hp, bhp, NULL);
+				bhp = NULL;
+				b_incr = b_lock = h_locked = 0;
+#endif
+			} else {
+				ret = __memp_bhfree(dbmp, infop, mfp,
+				    hp, bhp, BH_FREE_FREEMEM);
+				bhp = NULL;
+				b_incr = b_lock = h_locked = 0;
+			}
+			goto done;
+		} else if (F_ISSET(bhp, BH_FREED | BH_TRASH)) {
+revive:			if (F_ISSET(bhp, BH_FREED))
+				makecopy = makecopy ||
+				    (mvcc && !BH_OWNED_BY(env, bhp, txn)) ||
+				    F_ISSET(bhp, BH_FROZEN);
+			if (flags == DB_MPOOL_CREATE) {
+				MUTEX_LOCK(env, mfp->mutex);
+				if (*pgnoaddr > mfp->last_pgno)
+					mfp->last_pgno = *pgnoaddr;
+				MUTEX_UNLOCK(env, mfp->mutex);
+			}
+			/* We can race with a thread trying to free this. */
+			if (F_ISSET(bhp, BH_TRASH) &&
+			    *pgnoaddr <= mfp->last_pgno)
+				break;
+
+			/* Otherwise this page does not currently exist. */
+			if (flags != DB_MPOOL_CREATE && flags != DB_MPOOL_NEW) {
+				ret = DB_PAGE_NOTFOUND;
+				goto done;
+			}
+		}
+		if (mvcc) {
+			/*
+			 * With multiversion databases, we might need to
+			 * allocate a new buffer into which we can copy the one
+			 * that we found.  In that case, check the last buffer
+			 * in the chain to see whether we can reuse an obsolete
+			 * buffer.
+			 *
+			 * To provide snapshot isolation, we need to make sure
+			 * that we've seen a buffer older than the oldest
+			 * snapshot read LSN.
+			 */
+reuse:			if ((makecopy || F_ISSET(bhp, BH_FROZEN)) &&
+			    !h_locked) {
+				MUTEX_LOCK(env, hp->mtx_hash);
+				h_locked = 1;
+			}
+			if ((makecopy || F_ISSET(bhp, BH_FROZEN)) &&
+			    SH_CHAIN_HASPREV(bhp, vc)) {
+				oldest_bhp = SH_CHAIN_PREVP(bhp, vc, __bh);
+				while (SH_CHAIN_HASPREV(oldest_bhp, vc))
+					oldest_bhp = SH_CHAIN_PREVP(
+					    oldest_bhp, vc, __bh);
+
+				if (BH_REFCOUNT(oldest_bhp) == 0 &&
+				    !BH_OBSOLETE(
+				    oldest_bhp, hp->old_reader, vlsn) &&
+				    (ret = __txn_oldest_reader(env,
+				    &hp->old_reader)) != 0)
+					goto err;
+
+				if (BH_OBSOLETE(
+				    oldest_bhp, hp->old_reader, vlsn) &&
+				    BH_REFCOUNT(oldest_bhp) == 0) {
+					DB_ASSERT(env,
+					    !F_ISSET(oldest_bhp, BH_DIRTY));
+					atomic_inc(env, &oldest_bhp->ref);
+					if (F_ISSET(oldest_bhp, BH_FROZEN)) {
+						/*
+						 * This call will release the
+						 * hash bucket mutex.
+						 */
+						ret = __memp_bh_thaw(dbmp,
+						    infop, hp, oldest_bhp,
+						    NULL);
+						h_locked = 0;
+						if (ret != 0)
+							goto err;
+						goto reuse;
+					}
+					if ((ret = __memp_bhfree(dbmp,
+					    infop, mfp, hp, oldest_bhp,
+					    BH_FREE_REUSE)) != 0)
+						goto err;
+					alloc_bhp = oldest_bhp;
+					h_locked = 0;
+				}
+
+				DB_ASSERT(env, alloc_bhp == NULL ||
+				    !F_ISSET(alloc_bhp, BH_FROZEN));
+			}
+		}
+
+		/* We found the buffer or we're ready to copy -- we're done. */
+		if (!(makecopy || F_ISSET(bhp, BH_FROZEN)) || alloc_bhp != NULL)
+			break;
+
+		/* FALLTHROUGH */
+	case FIRST_MISS:
+		/*
+		 * We didn't find the buffer in our first check.  Figure out
+		 * if the page exists, and allocate structures so we can add
+		 * the page to the buffer pool.
+		 */
+		if (h_locked)
+			MUTEX_UNLOCK(env, hp->mtx_hash);
+		h_locked = 0;
+
+		/*
+		 * The buffer is not in the pool, so we don't need to free it.
+		 */
+		if (LF_ISSET(DB_MPOOL_FREE) &&
+		    (bhp == NULL || F_ISSET(bhp, BH_FREED) || !makecopy))
+			goto done;
+
+		if (bhp != NULL)
+			goto alloc;
+
+newpg:		/*
+		 * If DB_MPOOL_NEW is set, we have to allocate a page number.
+		 * If neither DB_MPOOL_CREATE or DB_MPOOL_NEW is set, then
+		 * it's an error to try and get a page past the end of file.
+		 */
+		DB_ASSERT(env, !h_locked);
+		MUTEX_LOCK(env, mfp->mutex);
+		switch (flags) {
+		case DB_MPOOL_NEW:
+			extending = 1;
+			if (mfp->maxpgno != 0 &&
+			    mfp->last_pgno >= mfp->maxpgno) {
+				__db_errx(env, DB_STR_A("3023",
+				    "%s: file limited to %lu pages", "%s %lu"),
+				    __memp_fn(dbmfp), (u_long)mfp->maxpgno);
+				ret = ENOSPC;
+			} else
+				*pgnoaddr = mfp->last_pgno + 1;
+			break;
+		case DB_MPOOL_CREATE:
+			if (mfp->maxpgno != 0 && *pgnoaddr > mfp->maxpgno) {
+				__db_errx(env, DB_STR_A("3024",
+				    "%s: file limited to %lu pages", "%s %lu"),
+				    __memp_fn(dbmfp), (u_long)mfp->maxpgno);
+				ret = ENOSPC;
+			} else if (!extending)
+				extending = *pgnoaddr > mfp->last_pgno;
+			break;
+		default:
+			ret = *pgnoaddr > mfp->last_pgno ? DB_PAGE_NOTFOUND : 0;
+			break;
+		}
+		MUTEX_UNLOCK(env, mfp->mutex);
+		if (ret != 0)
+			goto err;
+
+		/*
+		 * !!!
+		 * In the DB_MPOOL_NEW code path, hp, infop and c_mp have
+		 * not yet been initialized.
+		 */
+		if (hp == NULL) {
+			MP_GET_BUCKET(env,
+			    mfp, *pgnoaddr, &infop, hp, bucket, ret);
+			if (ret != 0)
+				goto err;
+			MUTEX_UNLOCK(env, hp->mtx_hash);
+			c_mp = infop->primary;
+		}
+
+alloc:		/* Allocate a new buffer header and data space. */
+		if (alloc_bhp == NULL && (ret =
+		    __memp_alloc(dbmp, infop, mfp, 0, NULL, &alloc_bhp)) != 0)
+			goto err;
+
+		/* Initialize enough so we can call __memp_bhfree. */
+		alloc_bhp->flags = 0;
+		atomic_init(&alloc_bhp->ref, 1);
+#ifdef DIAGNOSTIC
+		if ((uintptr_t)alloc_bhp->buf & (sizeof(size_t) - 1)) {
+			__db_errx(env, DB_STR("3025",
+		    "DB_MPOOLFILE->get: buffer data is NOT size_t aligned"));
+			ret = __env_panic(env, EINVAL);
+			goto err;
+		}
+#endif
+
+		/*
+		 * If we're doing copy-on-write, we will already have the
+		 * buffer header.  In that case, we don't need to search again.
+		 */
+		if (bhp != NULL)
+			break;
+
+		/*
+		 * If we are extending the file, we'll need the mfp lock
+		 * again.
+		 */
+		if (extending)
+			MUTEX_LOCK(env, mfp->mutex);
+
+		/*
+		 * DB_MPOOL_NEW does not guarantee you a page unreferenced by
+		 * any other thread of control.  (That guarantee is interesting
+		 * for DB_MPOOL_NEW, unlike DB_MPOOL_CREATE, because the caller
+		 * did not specify the page number, and so, may reasonably not
+		 * have any way to lock the page outside of mpool.) Regardless,
+		 * if we allocate the page, and some other thread of control
+		 * requests the page by number, we will not detect that and the
+		 * thread of control that allocated using DB_MPOOL_NEW may not
+		 * have a chance to initialize the page.  (Note: we *could*
+		 * detect this case if we set a flag in the buffer header which
+		 * guaranteed that no gets of the page would succeed until the
+		 * reference count went to 0, that is, until the creating page
+		 * put the page.)  What we do guarantee is that if two threads
+		 * of control are both doing DB_MPOOL_NEW calls, they won't
+		 * collide, that is, they won't both get the same page.
+		 *
+		 * There's a possibility that another thread allocated the page
+		 * we were planning to allocate while we were off doing buffer
+		 * allocation.  We can do that by making sure the page number
+		 * we were going to use is still available.  If it's not, then
+		 * we check to see if the next available page number hashes to
+		 * the same mpool region as the old one -- if it does, we can
+		 * continue, otherwise, we have to start over.
+		 */
+		if (flags == DB_MPOOL_NEW && *pgnoaddr != mfp->last_pgno + 1) {
+			*pgnoaddr = mfp->last_pgno + 1;
+			MP_GET_REGION(dbmfp, *pgnoaddr, &t_infop, ret);
+			if (ret != 0)
+				goto err;
+			if (t_infop != infop) {
+				/*
+				 * flags == DB_MPOOL_NEW, so extending is set
+				 * and we're holding the mfp locked.
+				 */
+				MUTEX_UNLOCK(env, mfp->mutex);
+				hp = NULL;
+				goto newpg;
+			}
+		}
+
+		/*
+		 * We released the mfp lock, so another thread might have
+		 * extended the file.  Update the last_pgno and initialize
+		 * the file, as necessary, if we extended the file.
+		 */
+		if (extending) {
+			if (*pgnoaddr > mfp->last_pgno)
+				mfp->last_pgno = *pgnoaddr;
+			else
+				extending = 0;
+			MUTEX_UNLOCK(env, mfp->mutex);
+			if (ret != 0)
+				goto err;
+		}
+		goto retry;
+	case SECOND_FOUND:
+		/*
+		 * We allocated buffer space for the requested page, but then
+		 * found the page in the buffer cache on our second check.
+		 * That's OK -- we can use the page we found in the pool,
+		 * unless DB_MPOOL_NEW is set.  If we're about to copy-on-write,
+		 * this is exactly the situation we want.
+		 *
+		 * For multiversion files, we may have left some pages in cache
+		 * beyond the end of a file after truncating.  In that case, we
+		 * would get to here with extending set.  If so, we need to
+		 * insert the new page in the version chain similar to when
+		 * we copy on write.
+		 */
+		if (F_ISSET(bhp, BH_FREED) &&
+		    (flags == DB_MPOOL_NEW || flags == DB_MPOOL_CREATE))
+			goto revive;
+		else if (flags == DB_MPOOL_FREE)
+			goto freebuf;
+		else if (makecopy || F_ISSET(bhp, BH_FROZEN))
+			break;
+
+		/*
+		 * We can't use the page we found in the pool if DB_MPOOL_NEW
+		 * was set.  (For details, see the above comment beginning
+		 * "DB_MPOOL_NEW does not guarantee you a page unreferenced by
+		 * any other thread of control".)  If DB_MPOOL_NEW is set, we
+		 * release our pin on this particular buffer, and try to get
+		 * another one.
+		 */
+		if (flags == DB_MPOOL_NEW) {
+			DB_ASSERT(env, b_incr && BH_REFCOUNT(bhp) != 0);
+			atomic_dec(env, &bhp->ref);
+			b_incr = 0;
+			if (F_ISSET(bhp, BH_EXCLUSIVE))
+				F_CLR(bhp, BH_EXCLUSIVE);
+			MUTEX_UNLOCK(env, bhp->mtx_buf);
+			b_lock = 0;
+			bhp = NULL;
+			hp = NULL;
+			goto newpg;
+		}
+
+		break;
+	case SECOND_MISS:
+		/*
+		 * We allocated buffer space for the requested page, and found
+		 * the page still missing on our second pass through the buffer
+		 * cache.  Instantiate the page.
+		 */
+		DB_ASSERT(env, alloc_bhp != NULL);
+		bhp = alloc_bhp;
+		alloc_bhp = NULL;
+
+		/*
+		 * Initialize all the BH and hash bucket fields so we can call
+		 * __memp_bhfree if an error occurs.
+		 *
+		 * Append the buffer to the tail of the bucket list.
+		 */
+		bhp->priority = MPOOL_LRU_REDZONE;
+		bhp->pgno = *pgnoaddr;
+		bhp->mf_offset = mf_offset;
+		bhp->bucket = bucket;
+		bhp->region = (int)(infop - dbmp->reginfo);
+		bhp->td_off = INVALID_ROFF;
+		SH_CHAIN_INIT(bhp, vc);
+		bhp->flags = 0;
+
+		/*
+		 * Reference the buffer and lock exclusive.  We either
+		 * need to read the buffer or create it from scratch
+		 * and don't want anyone looking at it till we do.
+		 */
+		MUTEX_LOCK(env, bhp->mtx_buf);
+		b_lock = 1;
+		F_SET(bhp, BH_EXCLUSIVE);
+		b_incr = 1;
+
+		/* We created a new page, it starts dirty. */
+		if (extending) {
+			atomic_inc(env, &hp->hash_page_dirty);
+			F_SET(bhp, BH_DIRTY | BH_DIRTY_CREATE);
+		}
+
+		MUTEX_REQUIRED(env, hp->mtx_hash);
+		SH_TAILQ_INSERT_HEAD(&hp->hash_bucket, bhp, hq, __bh);
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+		h_locked = 0;
+
+		/*
+		 * If we created the page, zero it out.  If we didn't create
+		 * the page, read from the backing file.
+		 *
+		 * !!!
+		 * DB_MPOOL_NEW doesn't call the pgin function.
+		 *
+		 * If DB_MPOOL_CREATE is used, then the application's pgin
+		 * function has to be able to handle pages of 0's -- if it
+		 * uses DB_MPOOL_NEW, it can detect all of its page creates,
+		 * and not bother.
+		 *
+		 * If we're running in diagnostic mode, smash any bytes on the
+		 * page that are unknown quantities for the caller.
+		 *
+		 * Otherwise, read the page into memory, optionally creating it
+		 * if DB_MPOOL_CREATE is set.
+		 */
+		if (extending) {
+			MVCC_MPROTECT(bhp->buf, mfp->pagesize,
+			    PROT_READ | PROT_WRITE);
+			memset(bhp->buf, 0,
+			    (mfp->clear_len == DB_CLEARLEN_NOTSET) ?
+			    mfp->pagesize : mfp->clear_len);
+#if defined(DIAGNOSTIC) || defined(UMRW)
+			if (mfp->clear_len != DB_CLEARLEN_NOTSET)
+				memset(bhp->buf + mfp->clear_len, CLEAR_BYTE,
+				    mfp->pagesize - mfp->clear_len);
+#endif
+
+			if (flags == DB_MPOOL_CREATE && mfp->ftype != 0 &&
+			    (ret = __memp_pg(dbmfp,
+			    bhp->pgno, bhp->buf, 1)) != 0)
+				goto err;
+
+			STAT_INC_VERB(env, mpool, page_create,
+			    mfp->stat.st_page_create,
+			    __memp_fn(dbmfp), *pgnoaddr);
+		} else {
+			F_SET(bhp, BH_TRASH);
+			STAT_INC_VERB(env, mpool, miss, mfp->stat.st_cache_miss,
+			    __memp_fn(dbmfp), *pgnoaddr);
+		}
+
+		makecopy = mvcc && dirty && !extending;
+
+		/* Increment buffer count referenced by MPOOLFILE. */
+		MUTEX_LOCK(env, mfp->mutex);
+		++mfp->block_cnt;
+		MUTEX_UNLOCK(env, mfp->mutex);
+	}
+
+	DB_ASSERT(env, bhp != NULL && BH_REFCOUNT(bhp) != 0 && b_lock);
+	DB_ASSERT(env, !F_ISSET(bhp, BH_FROZEN) || !F_ISSET(bhp, BH_FREED) ||
+	    makecopy);
+
+	/*
+	 * BH_TRASH --
+	 * The buffer we found may need to be filled from the disk.
+	 *
+	 * It's possible for the read function to fail, which means we fail
+	 * as well.  Discard the buffer on failure unless another thread
+	 * is waiting on our I/O to complete.  It's OK to leave the buffer
+	 * around, as the waiting thread will see the BH_TRASH flag set,
+	 * and will also attempt to discard it.  If there's a waiter,
+	 * we need to decrement our reference count.
+	 */
+	if (F_ISSET(bhp, BH_TRASH) &&
+	    flags != DB_MPOOL_FREE && !F_ISSET(bhp, BH_FREED)) {
+		MVCC_MPROTECT(bhp->buf, mfp->pagesize,
+		    PROT_READ | PROT_WRITE);
+		if ((ret = __memp_pgread(dbmfp,
+		    bhp, LF_ISSET(DB_MPOOL_CREATE) ? 1 : 0)) != 0)
+			goto err;
+		DB_ASSERT(env, read_lsnp != NULL || !SH_CHAIN_HASNEXT(bhp, vc));
+	}
+
+	/* Copy-on-write. */
+	if (makecopy) {
+		/*
+		 * If we read a page from disk that we want to modify, we now
+		 * need to make copy, so we now need to allocate another buffer
+		 * to hold the new copy.
+		 */
+		if (alloc_bhp == NULL)
+			goto reuse;
+
+		DB_ASSERT(env, bhp != NULL && alloc_bhp != bhp);
+		DB_ASSERT(env, bhp->td_off == INVALID_ROFF ||
+		    !IS_MAX_LSN(*VISIBLE_LSN(env, bhp)) ||
+		    (F_ISSET(bhp, BH_FREED) && F_ISSET(bhp, BH_FROZEN)));
+		DB_ASSERT(env, txn != NULL ||
+		    (F_ISSET(bhp, BH_FROZEN) && F_ISSET(bhp, BH_FREED)));
+		DB_ASSERT(env, (extending || flags == DB_MPOOL_FREE ||
+		    F_ISSET(bhp, BH_FREED)) ||
+		    !F_ISSET(bhp, BH_FROZEN | BH_TRASH));
+		MUTEX_REQUIRED(env, bhp->mtx_buf);
+
+		if (BH_REFCOUNT(bhp) == 1)
+			MVCC_MPROTECT(bhp->buf, mfp->pagesize,
+			    PROT_READ);
+
+		atomic_init(&alloc_bhp->ref, 1);
+		MUTEX_LOCK(env, alloc_bhp->mtx_buf);
+		alloc_bhp->priority = bhp->priority;
+		alloc_bhp->pgno = bhp->pgno;
+		alloc_bhp->bucket = bhp->bucket;
+		alloc_bhp->region = bhp->region;
+		alloc_bhp->mf_offset = bhp->mf_offset;
+		alloc_bhp->td_off = INVALID_ROFF;
+		if (txn == NULL) {
+			DB_ASSERT(env,
+			    F_ISSET(bhp, BH_FROZEN) && F_ISSET(bhp, BH_FREED));
+			if (bhp->td_off != INVALID_ROFF && (ret =
+			    __memp_bh_settxn(dbmp, mfp, alloc_bhp,
+			    BH_OWNER(env, bhp))) != 0)
+				goto err;
+		} else if ((ret =
+		    __memp_bh_settxn(dbmp, mfp, alloc_bhp, td)) != 0)
+			goto err;
+		MVCC_MPROTECT(alloc_bhp->buf, mfp->pagesize,
+		    PROT_READ | PROT_WRITE);
+		if (extending ||
+		    F_ISSET(bhp, BH_FREED) || flags == DB_MPOOL_FREE) {
+			memset(alloc_bhp->buf, 0,
+			    (mfp->clear_len == DB_CLEARLEN_NOTSET) ?
+			    mfp->pagesize : mfp->clear_len);
+#if defined(DIAGNOSTIC) || defined(UMRW)
+			if (mfp->clear_len != DB_CLEARLEN_NOTSET)
+				memset(alloc_bhp->buf + mfp->clear_len,
+				    CLEAR_BYTE,
+				    mfp->pagesize - mfp->clear_len);
+#endif
+			if (mfp->ftype != 0 && (ret = __memp_pg(dbmfp,
+			    alloc_bhp->pgno, alloc_bhp->buf, 1)) != 0)
+				goto err;
+		} else
+			memcpy(alloc_bhp->buf, bhp->buf, mfp->pagesize);
+		MVCC_MPROTECT(alloc_bhp->buf, mfp->pagesize, 0);
+
+		if (h_locked == 0)
+			MUTEX_LOCK(env, hp->mtx_hash);
+		MUTEX_REQUIRED(env, hp->mtx_hash);
+		h_locked = 1;
+
+		alloc_bhp->flags = BH_EXCLUSIVE |
+		    ((flags == DB_MPOOL_FREE) ? BH_FREED :
+		    F_ISSET(bhp, BH_DIRTY | BH_DIRTY_CREATE));
+		DB_ASSERT(env, flags != DB_MPOOL_FREE ||
+		    !F_ISSET(bhp, BH_DIRTY));
+		F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
+		DB_ASSERT(env, !SH_CHAIN_HASNEXT(bhp, vc));
+		SH_CHAIN_INSERT_AFTER(bhp, alloc_bhp, vc, __bh);
+		SH_TAILQ_INSERT_BEFORE(&hp->hash_bucket,
+		    bhp, alloc_bhp, hq, __bh);
+		SH_TAILQ_REMOVE(&hp->hash_bucket, bhp, hq, __bh);
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+		h_locked = 0;
+		DB_ASSERT(env, b_incr && BH_REFCOUNT(bhp) > 0);
+		if (atomic_dec(env, &bhp->ref) == 0) {
+			bhp->priority = c_mp->lru_priority;
+			MVCC_MPROTECT(bhp->buf, mfp->pagesize, 0);
+		}
+		F_CLR(bhp, BH_EXCLUSIVE);
+		MUTEX_UNLOCK(env, bhp->mtx_buf);
+
+		bhp = alloc_bhp;
+		DB_ASSERT(env, BH_REFCOUNT(bhp) > 0);
+		b_incr = 1;
+		MUTEX_REQUIRED(env, bhp->mtx_buf);
+		b_lock = 1;
+
+		if (alloc_bhp != oldest_bhp) {
+			MUTEX_LOCK(env, mfp->mutex);
+			++mfp->block_cnt;
+			MUTEX_UNLOCK(env, mfp->mutex);
+		}
+
+		alloc_bhp = NULL;
+	} else if (mvcc && extending &&
+	    (ret = __memp_bh_settxn(dbmp, mfp, bhp, td)) != 0)
+		goto err;
+
+	if (flags == DB_MPOOL_FREE) {
+		DB_ASSERT(env, !SH_CHAIN_HASNEXT(bhp, vc));
+		/* If we have created an empty buffer, it is not returned. */
+		if (!F_ISSET(bhp, BH_FREED))
+			goto freebuf;
+		goto done;
+	}
+
+	/*
+	 * Free the allocated memory, we no longer need it.
+	 */
+	if (alloc_bhp != NULL) {
+		if ((ret = __memp_bhfree(dbmp, infop, NULL,
+		     NULL, alloc_bhp, BH_FREE_FREEMEM | BH_FREE_UNLOCKED)) != 0)
+			goto err;
+		alloc_bhp = NULL;
+	}
+
+	if (dirty || extending ||
+	    (F_ISSET(bhp, BH_FREED) &&
+	    (flags == DB_MPOOL_CREATE || flags == DB_MPOOL_NEW))) {
+		MUTEX_REQUIRED(env, bhp->mtx_buf);
+		if (F_ISSET(bhp, BH_FREED)) {
+			DB_ASSERT(env, bhp->pgno <= mfp->last_pgno);
+			memset(bhp->buf, 0,
+			    (mfp->clear_len == DB_CLEARLEN_NOTSET) ?
+			    mfp->pagesize : mfp->clear_len);
+			F_CLR(bhp, BH_FREED);
+			if (mfp->ftype != 0 && (ret =
+			    __memp_pg(dbmfp, bhp->pgno, bhp->buf, 1)) != 0)
+				goto err;
+		}
+		if (!F_ISSET(bhp, BH_DIRTY)) {
+#ifdef DIAGNOSTIC
+			MUTEX_LOCK(env, hp->mtx_hash);
+#endif
+			DB_ASSERT(env, !SH_CHAIN_HASNEXT(bhp, vc));
+			atomic_inc(env, &hp->hash_page_dirty);
+			F_SET(bhp, BH_DIRTY);
+#ifdef DIAGNOSTIC
+			MUTEX_UNLOCK(env, hp->mtx_hash);
+#endif
+		}
+	} else if (F_ISSET(bhp, BH_EXCLUSIVE)) {
+		F_CLR(bhp, BH_EXCLUSIVE);
+#ifdef HAVE_SHARED_LATCHES
+		MUTEX_UNLOCK(env, bhp->mtx_buf);
+		MUTEX_READLOCK(env, bhp->mtx_buf);
+		/*
+		 * If another thread has dirtied the page while we
+		 * switched locks, we have to go through it all again.
+		 */
+		if (SH_CHAIN_HASNEXT(bhp, vc) && read_lsnp == NULL) {
+			atomic_dec(env, &bhp->ref);
+			b_incr = 0;
+			MUTEX_UNLOCK(env, bhp->mtx_buf);
+			b_lock = 0;
+			bhp = NULL;
+			goto retry;
+		}
+#endif
+	}
+
+	MVCC_MPROTECT(bhp->buf, mfp->pagesize, PROT_READ |
+	    (dirty || extending || F_ISSET(bhp, BH_DIRTY) ?
+	    PROT_WRITE : 0));
+
+#ifdef DIAGNOSTIC
+	MUTEX_LOCK(env, hp->mtx_hash);
+	{
+	BH *next_bhp = SH_CHAIN_NEXT(bhp, vc, __bh);
+
+	DB_ASSERT(env, !atomic_read(&mfp->multiversion) || read_lsnp != NULL ||
+	    next_bhp == NULL);
+	DB_ASSERT(env, !mvcc || read_lsnp == NULL ||
+	    bhp->td_off == INVALID_ROFF || BH_OWNED_BY(env, bhp, txn) ||
+	    (BH_VISIBLE(env, bhp, read_lsnp, vlsn) &&
+	    (next_bhp == NULL || F_ISSET(next_bhp, BH_FROZEN) ||
+	    (next_bhp->td_off != INVALID_ROFF &&
+	    (BH_OWNER(env, next_bhp)->status != TXN_COMMITTED ||
+	    IS_ZERO_LSN(BH_OWNER(env, next_bhp)->last_lsn) ||
+	    !BH_VISIBLE(env, next_bhp, read_lsnp, vlsn))))));
+	}
+	MUTEX_UNLOCK(env, hp->mtx_hash);
+#endif
+
+	/*
+	 * Record this pin for this thread.  Holding the page pinned
+	 * without recording the pin is ok since we do not recover from
+	 * a death from within the library itself.
+	 */
+	if (ip != NULL) {
+		reginfo = env->reginfo;
+		if (ip->dbth_pincount == ip->dbth_pinmax) {
+			pinmax = ip->dbth_pinmax;
+			renv = reginfo->primary;
+			MUTEX_LOCK(env, renv->mtx_regenv);
+			if ((ret = __env_alloc(reginfo,
+			    2 * pinmax * sizeof(PIN_LIST), &list)) != 0) {
+				MUTEX_UNLOCK(env, renv->mtx_regenv);
+				goto err;
+			}
+
+			memcpy(list, R_ADDR(reginfo, ip->dbth_pinlist),
+			    pinmax * sizeof(PIN_LIST));
+			memset(&list[pinmax], 0, pinmax * sizeof(PIN_LIST));
+			list_off = R_OFFSET(reginfo, list);
+			list = R_ADDR(reginfo, ip->dbth_pinlist);
+			ip->dbth_pinmax = 2 * pinmax;
+			ip->dbth_pinlist = list_off;
+			if (list != ip->dbth_pinarray)
+				__env_alloc_free(reginfo, list);
+			MUTEX_UNLOCK(env, renv->mtx_regenv);
+		}
+		list = R_ADDR(reginfo, ip->dbth_pinlist);
+		for (lp = list; lp < &list[ip->dbth_pinmax]; lp++)
+			if (lp->b_ref == INVALID_ROFF)
+				break;
+
+		ip->dbth_pincount++;
+		lp->b_ref = R_OFFSET(infop, bhp);
+		lp->region = (int)(infop - dbmp->reginfo);
+#ifdef DIAGNOSTIC
+		if (dirty && ip->dbth_locker != INVALID_ROFF &&
+		    ip->dbth_check_off == 0) {
+			lt = env->lk_handle;
+			locker = (DB_LOCKER *)
+			    (R_ADDR(&lt->reginfo, ip->dbth_locker));
+			DB_ASSERT(env, __db_has_pagelock(env, locker, dbmfp,
+			    (PAGE*)bhp->buf, DB_LOCK_WRITE) == 0);
+		}
+#endif
+
+	}
+	/*
+	 * During recovery we can read past the end of the file.  Also
+	 * last_pgno is not versioned, so if this is an older version
+	 * that is ok as well.
+	 */
+	DB_ASSERT(env, IS_RECOVERING(env) ||
+	     bhp->pgno <= mfp->last_pgno || !SH_CHAIN_SINGLETON(bhp, vc));
+
+#ifdef DIAGNOSTIC
+	/* Update the file's pinned reference count. */
+	MPOOL_SYSTEM_LOCK(env);
+	++dbmfp->pinref;
+	MPOOL_SYSTEM_UNLOCK(env);
+
+	/*
+	 * We want to switch threads as often as possible, and at awkward
+	 * times.  Yield every time we get a new page to ensure contention.
+	 */
+	if (F_ISSET(env->dbenv, DB_ENV_YIELDCPU))
+		__os_yield(env, 0, 0);
+#endif
+
+	DB_ASSERT(env, alloc_bhp == NULL);
+	DB_ASSERT(env, !(dirty || extending) ||
+	    atomic_read(&hp->hash_page_dirty) > 0);
+	DB_ASSERT(env, BH_REFCOUNT(bhp) > 0 &&
+	    !F_ISSET(bhp, BH_FREED | BH_FROZEN | BH_TRASH));
+
+	*(void **)addrp = bhp->buf;
+	return (0);
+
+done:
+err:	/*
+	 * We should only get to here with ret == 0 if freeing a buffer.
+	 * In that case, check that it has in fact been freed.
+	 */
+	DB_ASSERT(env, ret != 0 || flags != DB_MPOOL_FREE || bhp == NULL ||
+	    (F_ISSET(bhp, BH_FREED) && !SH_CHAIN_HASNEXT(bhp, vc)));
+
+	if (bhp != NULL) {
+		if (b_incr)
+			atomic_dec(env, &bhp->ref);
+		if (b_lock) {
+			F_CLR(bhp, BH_EXCLUSIVE);
+			MUTEX_UNLOCK(env, bhp->mtx_buf);
+		}
+	}
+
+	if (h_locked)
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+
+	/* If alloc_bhp is set, free the memory. */
+	if (alloc_bhp != NULL)
+		(void)__memp_bhfree(dbmp, infop, NULL,
+		     NULL, alloc_bhp, BH_FREE_FREEMEM | BH_FREE_UNLOCKED);
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_fmethod.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,611 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/log.h"
+#include "dbinc/mp.h"
+
+static int __memp_get_clear_len __P((DB_MPOOLFILE *, u_int32_t *));
+static int __memp_get_lsn_offset __P((DB_MPOOLFILE *, int32_t *));
+static int __memp_get_maxsize __P((DB_MPOOLFILE *, u_int32_t *, u_int32_t *));
+static int __memp_set_maxsize __P((DB_MPOOLFILE *, u_int32_t, u_int32_t));
+static int __memp_set_priority __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY));
+static int __memp_get_last_pgno_pp __P((DB_MPOOLFILE *, db_pgno_t *));
+
+/*
+ * __memp_fcreate_pp --
+ *	ENV->memp_fcreate pre/post processing.
+ *
+ * PUBLIC: int __memp_fcreate_pp __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t));
+ */
+int
+__memp_fcreate_pp(dbenv, retp, flags)
+	DB_ENV *dbenv;
+	DB_MPOOLFILE **retp;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	/* Validate arguments. */
+	if ((ret =
+	    __db_fchk(env, "DB_ENV->memp_fcreate", flags, DB_VERIFY)) != 0)
+		return (ret);
+
+	/* We look the other way on mpool operations if we're verifying. */
+	if (REP_ON(env) && !LF_ISSET(DB_VERIFY)) {
+		__db_errx(env, DB_STR("3029",
+"DB_ENV->memp_fcreate: method not permitted when replication is configured"));
+		return (EINVAL);
+	}
+
+	ENV_ENTER(env, ip);
+	ret = __memp_fcreate(env, retp);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __memp_fcreate --
+ *	ENV->memp_fcreate.
+ *
+ * PUBLIC: int __memp_fcreate __P((ENV *, DB_MPOOLFILE **));
+ */
+int
+__memp_fcreate(env, retp)
+	ENV *env;
+	DB_MPOOLFILE **retp;
+{
+	DB_MPOOLFILE *dbmfp;
+	int ret;
+
+	/* Allocate and initialize the per-process structure. */
+	if ((ret = __os_calloc(env, 1, sizeof(DB_MPOOLFILE), &dbmfp)) != 0)
+		return (ret);
+
+	dbmfp->ref = 1;
+	dbmfp->lsn_offset = DB_LSN_OFF_NOTSET;
+	dbmfp->env = env;
+	dbmfp->mfp = INVALID_ROFF;
+
+	dbmfp->close = __memp_fclose_pp;
+	dbmfp->get = __memp_fget_pp;
+	dbmfp->get_clear_len = __memp_get_clear_len;
+	dbmfp->get_fileid = __memp_get_fileid;
+	dbmfp->get_flags = __memp_get_flags;
+	dbmfp->get_ftype = __memp_get_ftype;
+	dbmfp->get_last_pgno = __memp_get_last_pgno_pp;
+	dbmfp->get_lsn_offset = __memp_get_lsn_offset;
+	dbmfp->get_maxsize = __memp_get_maxsize;
+	dbmfp->get_pgcookie = __memp_get_pgcookie;
+	dbmfp->get_priority = __memp_get_priority;
+	dbmfp->open = __memp_fopen_pp;
+	dbmfp->put = __memp_fput_pp;
+	dbmfp->set_clear_len = __memp_set_clear_len;
+	dbmfp->set_fileid = __memp_set_fileid;
+	dbmfp->set_flags = __memp_set_flags;
+	dbmfp->set_ftype = __memp_set_ftype;
+	dbmfp->set_lsn_offset = __memp_set_lsn_offset;
+	dbmfp->set_maxsize = __memp_set_maxsize;
+	dbmfp->set_pgcookie = __memp_set_pgcookie;
+	dbmfp->set_priority = __memp_set_priority;
+	dbmfp->sync = __memp_fsync_pp;
+
+	*retp = dbmfp;
+	return (0);
+}
+
+/*
+ * __memp_get_clear_len --
+ *	Get the clear length.
+ */
+static int
+__memp_get_clear_len(dbmfp, clear_lenp)
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t *clear_lenp;
+{
+	*clear_lenp = dbmfp->clear_len;
+	return (0);
+}
+
+/*
+ * __memp_set_clear_len --
+ *	DB_MPOOLFILE->set_clear_len.
+ *
+ * PUBLIC: int __memp_set_clear_len __P((DB_MPOOLFILE *, u_int32_t));
+ */
+int
+__memp_set_clear_len(dbmfp, clear_len)
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t clear_len;
+{
+	MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_clear_len");
+
+	dbmfp->clear_len = clear_len;
+	return (0);
+}
+
+/*
+ * __memp_get_fileid --
+ *	DB_MPOOLFILE->get_fileid.
+ *
+ * PUBLIC: int __memp_get_fileid __P((DB_MPOOLFILE *, u_int8_t *));
+ */
+int
+__memp_get_fileid(dbmfp, fileid)
+	DB_MPOOLFILE *dbmfp;
+	u_int8_t *fileid;
+{
+	if (!F_ISSET(dbmfp, MP_FILEID_SET)) {
+		__db_errx(dbmfp->env, DB_STR("3030",
+		    "get_fileid: file ID not set"));
+		return (EINVAL);
+	}
+
+	memcpy(fileid, dbmfp->fileid, DB_FILE_ID_LEN);
+	return (0);
+}
+
+/*
+ * __memp_set_fileid --
+ *	DB_MPOOLFILE->set_fileid.
+ *
+ * PUBLIC: int __memp_set_fileid __P((DB_MPOOLFILE *, u_int8_t *));
+ */
+int
+__memp_set_fileid(dbmfp, fileid)
+	DB_MPOOLFILE *dbmfp;
+	u_int8_t *fileid;
+{
+	MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_fileid");
+
+	memcpy(dbmfp->fileid, fileid, DB_FILE_ID_LEN);
+	F_SET(dbmfp, MP_FILEID_SET);
+
+	return (0);
+}
+
+/*
+ * __memp_get_flags --
+ *	Get the DB_MPOOLFILE flags;
+ *
+ * PUBLIC: int __memp_get_flags __P((DB_MPOOLFILE *, u_int32_t *));
+ */
+int
+__memp_get_flags(dbmfp, flagsp)
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t *flagsp;
+{
+	MPOOLFILE *mfp;
+
+	mfp = dbmfp->mfp;
+
+	*flagsp = 0;
+
+	if (mfp == NULL)
+		*flagsp = FLD_ISSET(dbmfp->config_flags,
+		     DB_MPOOL_NOFILE | DB_MPOOL_UNLINK);
+	else {
+		if (mfp->no_backing_file)
+			FLD_SET(*flagsp, DB_MPOOL_NOFILE);
+		if (mfp->unlink_on_close)
+			FLD_SET(*flagsp, DB_MPOOL_UNLINK);
+	}
+	return (0);
+}
+
+/*
+ * __memp_set_flags --
+ *	Set the DB_MPOOLFILE flags;
+ *
+ * PUBLIC: int __memp_set_flags __P((DB_MPOOLFILE *, u_int32_t, int));
+ */
+int
+__memp_set_flags(dbmfp, flags, onoff)
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t flags;
+	int onoff;
+{
+	ENV *env;
+	MPOOLFILE *mfp;
+	int ret;
+
+	env = dbmfp->env;
+	mfp = dbmfp->mfp;
+
+	switch (flags) {
+	case DB_MPOOL_NOFILE:
+		if (mfp == NULL)
+			if (onoff)
+				FLD_SET(dbmfp->config_flags, DB_MPOOL_NOFILE);
+			else
+				FLD_CLR(dbmfp->config_flags, DB_MPOOL_NOFILE);
+		else
+			mfp->no_backing_file = onoff;
+		break;
+	case DB_MPOOL_UNLINK:
+		if (mfp == NULL)
+			if (onoff)
+				FLD_SET(dbmfp->config_flags, DB_MPOOL_UNLINK);
+			else
+				FLD_CLR(dbmfp->config_flags, DB_MPOOL_UNLINK);
+		else
+			mfp->unlink_on_close = onoff;
+		break;
+	default:
+		if ((ret = __db_fchk(env, "DB_MPOOLFILE->set_flags",
+		    flags, DB_MPOOL_NOFILE | DB_MPOOL_UNLINK)) != 0)
+			return (ret);
+		break;
+	}
+	return (0);
+}
+
+/*
+ * __memp_get_ftype --
+ *	Get the file type (as registered).
+ *
+ * PUBLIC: int __memp_get_ftype __P((DB_MPOOLFILE *, int *));
+ */
+int
+__memp_get_ftype(dbmfp, ftypep)
+	DB_MPOOLFILE *dbmfp;
+	int *ftypep;
+{
+	*ftypep = dbmfp->ftype;
+	return (0);
+}
+
+/*
+ * __memp_set_ftype --
+ *	DB_MPOOLFILE->set_ftype.
+ *
+ * PUBLIC: int __memp_set_ftype __P((DB_MPOOLFILE *, int));
+ */
+int
+__memp_set_ftype(dbmfp, ftype)
+	DB_MPOOLFILE *dbmfp;
+	int ftype;
+{
+	MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_ftype");
+
+	dbmfp->ftype = ftype;
+	return (0);
+}
+
+/*
+ * __memp_get_lsn_offset --
+ *	Get the page's LSN offset.
+ */
+static int
+__memp_get_lsn_offset(dbmfp, lsn_offsetp)
+	DB_MPOOLFILE *dbmfp;
+	int32_t *lsn_offsetp;
+{
+	*lsn_offsetp = dbmfp->lsn_offset;
+	return (0);
+}
+
+/*
+ * __memp_set_lsn_offset --
+ *	Set the page's LSN offset.
+ *
+ * PUBLIC: int __memp_set_lsn_offset __P((DB_MPOOLFILE *, int32_t));
+ */
+int
+__memp_set_lsn_offset(dbmfp, lsn_offset)
+	DB_MPOOLFILE *dbmfp;
+	int32_t lsn_offset;
+{
+	MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_lsn_offset");
+
+	dbmfp->lsn_offset = lsn_offset;
+	return (0);
+}
+
+/*
+ * __memp_get_maxsize --
+ *	Get the file's maximum size.
+ */
+static int
+__memp_get_maxsize(dbmfp, gbytesp, bytesp)
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t *gbytesp, *bytesp;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	MPOOLFILE *mfp;
+
+	if ((mfp = dbmfp->mfp) == NULL) {
+		*gbytesp = dbmfp->gbytes;
+		*bytesp = dbmfp->bytes;
+	} else {
+		env = dbmfp->env;
+		ENV_ENTER(env, ip);
+
+		MUTEX_LOCK(env, mfp->mutex);
+		*gbytesp = (u_int32_t)
+		    (mfp->maxpgno / (GIGABYTE / mfp->pagesize));
+		*bytesp = (u_int32_t)
+		    ((mfp->maxpgno % (GIGABYTE / mfp->pagesize)) *
+		    mfp->pagesize);
+		MUTEX_UNLOCK(env, mfp->mutex);
+
+		ENV_LEAVE(env, ip);
+	}
+
+	return (0);
+}
+
+/*
+ * __memp_set_maxsize --
+ *	Set the file's maximum size.
+ */
+static int
+__memp_set_maxsize(dbmfp, gbytes, bytes)
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t gbytes, bytes;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	MPOOLFILE *mfp;
+
+	if ((mfp = dbmfp->mfp) == NULL) {
+		dbmfp->gbytes = gbytes;
+		dbmfp->bytes = bytes;
+	} else {
+		env = dbmfp->env;
+		ENV_ENTER(env, ip);
+
+		MUTEX_LOCK(env, mfp->mutex);
+		mfp->maxpgno = (db_pgno_t)
+		    (gbytes * (GIGABYTE / mfp->pagesize));
+		mfp->maxpgno += (db_pgno_t)
+		    ((bytes + mfp->pagesize - 1) / mfp->pagesize);
+		MUTEX_UNLOCK(env, mfp->mutex);
+
+		ENV_LEAVE(env, ip);
+	}
+
+	return (0);
+}
+
+/*
+ * __memp_get_pgcookie --
+ *	Get the pgin/pgout cookie.
+ *
+ * PUBLIC: int __memp_get_pgcookie __P((DB_MPOOLFILE *, DBT *));
+ */
+int
+__memp_get_pgcookie(dbmfp, pgcookie)
+	DB_MPOOLFILE *dbmfp;
+	DBT *pgcookie;
+{
+	if (dbmfp->pgcookie == NULL) {
+		pgcookie->size = 0;
+		pgcookie->data = "";
+	} else
+		memcpy(pgcookie, dbmfp->pgcookie, sizeof(DBT));
+	return (0);
+}
+
+/*
+ * __memp_set_pgcookie --
+ *	Set the pgin/pgout cookie.
+ *
+ * PUBLIC: int __memp_set_pgcookie __P((DB_MPOOLFILE *, DBT *));
+ */
+int
+__memp_set_pgcookie(dbmfp, pgcookie)
+	DB_MPOOLFILE *dbmfp;
+	DBT *pgcookie;
+{
+	DBT *cookie;
+	ENV *env;
+	int ret;
+
+	MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_pgcookie");
+	env = dbmfp->env;
+
+	if ((ret = __os_calloc(env, 1, sizeof(*cookie), &cookie)) != 0)
+		return (ret);
+	if ((ret = __os_malloc(env, pgcookie->size, &cookie->data)) != 0) {
+		__os_free(env, cookie);
+		return (ret);
+	}
+
+	memcpy(cookie->data, pgcookie->data, pgcookie->size);
+	cookie->size = pgcookie->size;
+
+	dbmfp->pgcookie = cookie;
+	return (0);
+}
+
+/*
+ * __memp_get_priority --
+ *	Set the cache priority for pages from this file.
+ *
+ * PUBLIC: int __memp_get_priority __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY *));
+ */
+int
+__memp_get_priority(dbmfp, priorityp)
+	DB_MPOOLFILE *dbmfp;
+	DB_CACHE_PRIORITY *priorityp;
+{
+	switch (dbmfp->priority) {
+	case MPOOL_PRI_VERY_LOW:
+		*priorityp = DB_PRIORITY_VERY_LOW;
+		break;
+	case MPOOL_PRI_LOW:
+		*priorityp = DB_PRIORITY_LOW;
+		break;
+	case MPOOL_PRI_DEFAULT:
+		*priorityp = DB_PRIORITY_DEFAULT;
+		break;
+	case MPOOL_PRI_HIGH:
+		*priorityp = DB_PRIORITY_HIGH;
+		break;
+	case MPOOL_PRI_VERY_HIGH:
+		*priorityp = DB_PRIORITY_VERY_HIGH;
+		break;
+	default:
+		__db_errx(dbmfp->env, DB_STR_A("3031",
+		    "DB_MPOOLFILE->get_priority: unknown priority value: %d",
+		    "%d"), dbmfp->priority);
+		return (EINVAL);
+	}
+
+	return (0);
+}
+
+/*
+ * __memp_set_priority --
+ *	Set the cache priority for pages from this file.
+ */
+static int
+__memp_set_priority(dbmfp, priority)
+	DB_MPOOLFILE *dbmfp;
+	DB_CACHE_PRIORITY priority;
+{
+	switch (priority) {
+	case DB_PRIORITY_VERY_LOW:
+		dbmfp->priority = MPOOL_PRI_VERY_LOW;
+		break;
+	case DB_PRIORITY_LOW:
+		dbmfp->priority = MPOOL_PRI_LOW;
+		break;
+	case DB_PRIORITY_DEFAULT:
+		dbmfp->priority = MPOOL_PRI_DEFAULT;
+		break;
+	case DB_PRIORITY_HIGH:
+		dbmfp->priority = MPOOL_PRI_HIGH;
+		break;
+	case DB_PRIORITY_VERY_HIGH:
+		dbmfp->priority = MPOOL_PRI_VERY_HIGH;
+		break;
+	default:
+		__db_errx(dbmfp->env, DB_STR_A("3032",
+		    "DB_MPOOLFILE->set_priority: unknown priority value: %d",
+		    "%d"), priority);
+		return (EINVAL);
+	}
+
+	/* Update the underlying file if we've already opened it. */
+	if (dbmfp->mfp != NULL)
+		dbmfp->mfp->priority = dbmfp->priority;
+
+	return (0);
+}
+
+/*
+ * __memp_get_last_pgno --
+ *	Return the page number of the last page in the file.
+ *
+ * !!!
+ * The method is undocumented, but the handle is exported, users occasionally
+ * ask for it.
+ *
+ * PUBLIC: int __memp_get_last_pgno __P((DB_MPOOLFILE *, db_pgno_t *));
+ */
+int
+__memp_get_last_pgno(dbmfp, pgnoaddr)
+	DB_MPOOLFILE *dbmfp;
+	db_pgno_t *pgnoaddr;
+{
+	ENV *env;
+	MPOOLFILE *mfp;
+
+	env = dbmfp->env;
+	mfp = dbmfp->mfp;
+
+	MUTEX_LOCK(env, mfp->mutex);
+	*pgnoaddr = mfp->last_pgno;
+	MUTEX_UNLOCK(env, mfp->mutex);
+
+	return (0);
+}
+
+/*
+ * __memp_get_last_pgno_pp --
+ *	pre/post processing for __memp_get_last_pgno.
+ *
+ */
+static int
+__memp_get_last_pgno_pp(dbmfp, pgnoaddr)
+	DB_MPOOLFILE *dbmfp;
+	db_pgno_t *pgnoaddr;
+{
+	DB_THREAD_INFO *ip;
+	int ret;
+
+	ret = 0;
+	ENV_ENTER(dbmfp->env, ip);
+
+	ret = __memp_get_last_pgno(dbmfp, pgnoaddr);
+
+	ENV_LEAVE(dbmfp->env, ip);
+	return (ret);
+}
+
+/*
+ * __memp_fn --
+ *	On errors we print whatever is available as the file name.
+ *
+ * PUBLIC: char * __memp_fn __P((DB_MPOOLFILE *));
+ */
+char *
+__memp_fn(dbmfp)
+	DB_MPOOLFILE *dbmfp;
+{
+	return (__memp_fns(dbmfp->env->mp_handle, dbmfp->mfp));
+}
+
+/*
+ * __memp_fns --
+ *	On errors we print whatever is available as the file name.
+ *
+ * PUBLIC: char * __memp_fns __P((DB_MPOOL *, MPOOLFILE *));
+ *
+ */
+char *
+__memp_fns(dbmp, mfp)
+	DB_MPOOL *dbmp;
+	MPOOLFILE *mfp;
+{
+	if (mfp == NULL || mfp->path_off == 0)
+		return ((char *)"unknown");
+
+	return ((char *)R_ADDR(dbmp->reginfo, mfp->path_off));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_fopen.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1275 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/log.h"
+#include "dbinc/mp.h"
+#include "dbinc/db_page.h"
+#include "dbinc/hash.h"
+
+static int __memp_mpf_alloc __P((DB_MPOOL *,
+    DB_MPOOLFILE *, const char *, u_int32_t, u_int32_t, MPOOLFILE **));
+static int __memp_mpf_find __P((ENV *,
+    DB_MPOOLFILE *, DB_MPOOL_HASH *, const char *, u_int32_t, MPOOLFILE **));
+
+/*
+ * __memp_fopen_pp --
+ *	DB_MPOOLFILE->open pre/post processing.
+ *
+ * PUBLIC: int __memp_fopen_pp
+ * PUBLIC:     __P((DB_MPOOLFILE *, const char *, u_int32_t, int, size_t));
+ */
+int
+__memp_fopen_pp(dbmfp, path, flags, mode, pagesize)
+	DB_MPOOLFILE *dbmfp;
+	const char *path;
+	u_int32_t flags;
+	int mode;
+	size_t pagesize;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbmfp->env;
+
+	/* Validate arguments. */
+	if ((ret = __db_fchk(env, "DB_MPOOLFILE->open", flags,
+	    DB_CREATE | DB_DIRECT | DB_EXTENT | DB_MULTIVERSION |
+	    DB_NOMMAP | DB_ODDFILESIZE | DB_RDONLY | DB_TRUNCATE)) != 0)
+		return (ret);
+
+	/*
+	 * Require a power-of-two pagesize, smaller than the clear length.  A
+	 * non-zero page size is only allowed if opening an existing, in-memory
+	 * db.
+	 */
+	if (!POWER_OF_TWO(pagesize) ||
+	    (pagesize == 0 && (LF_ISSET(DB_CREATE) ||
+	    !FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)))) {
+		__db_errx(env, DB_STR("3033",
+		    "DB_MPOOLFILE->open: page sizes must be a power-of-2"));
+		return (EINVAL);
+	}
+	if (pagesize != 0 && dbmfp->clear_len > pagesize) {
+		__db_errx(env, DB_STR("3034",
+		    "DB_MPOOLFILE->open: clear length larger than page size"));
+		return (EINVAL);
+	}
+
+	/* Read-only checks, and local flag. */
+	if (LF_ISSET(DB_RDONLY) && path == NULL) {
+		__db_errx(env, DB_STR("3035",
+		    "DB_MPOOLFILE->open: temporary files can't be readonly"));
+		return (EINVAL);
+	}
+
+	if (LF_ISSET(DB_MULTIVERSION) && !TXN_ON(env)) {
+		__db_errx(env, DB_STR("3036",
+	    "DB_MPOOLFILE->open: DB_MULTIVERSION requires transactions"));
+		return (EINVAL);
+	}
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env,
+	    (__memp_fopen(dbmfp, NULL,
+	    path, NULL, flags, mode, pagesize)), 0, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * Generate the number of user opens.  If there is no backing file
+ * there is an extra open count to keep the in memory db around.
+ */
+#define MFP_OPEN_CNT(mfp)	((mfp)->mpf_cnt - ((mfp)->neutral_cnt +	\
+				   (u_int32_t)(mfp)->no_backing_file))
+#define	MP_IOINFO_RETRIES	5
+/*
+ * __memp_fopen --
+ *	DB_MPOOLFILE->open.
+ *
+ * PUBLIC: int __memp_fopen __P((DB_MPOOLFILE *, MPOOLFILE *,
+ * PUBLIC:     const char *, const char **, u_int32_t, int, size_t));
+ */
+int
+__memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize)
+	DB_MPOOLFILE *dbmfp;
+	MPOOLFILE *mfp;
+	const char *path;
+	const char **dirp;
+	u_int32_t flags;
+	int mode;
+	size_t pgsize;
+{
+	DB_ENV *dbenv;
+	DB_MPOOL *dbmp;
+	DB_MPOOLFILE *tmp_dbmfp;
+	DB_MPOOL_HASH *hp;
+	ENV *env;
+	MPOOL *mp;
+	MPOOLFILE *alloc_mfp;
+	size_t maxmap;
+	db_pgno_t last_pgno;
+	u_int32_t bucket, mbytes, bytes, oflags, pagesize;
+	int isdir, refinc, ret, tries;
+	char *rpath;
+
+	/* If this handle is already open, return. */
+	if (F_ISSET(dbmfp, MP_OPEN_CALLED))
+		return (0);
+
+	env = dbmfp->env;
+	dbmp = env->mp_handle;
+	dbenv = env->dbenv;
+	mp = dbmp->reginfo[0].primary;
+	alloc_mfp = NULL;
+	mbytes = bytes = 0;
+	refinc = ret = isdir = 0;
+	rpath = NULL;
+
+	/*
+	 * We're keeping the page size as a size_t in the public API, but
+	 * it's a u_int32_t everywhere internally.
+	 */
+	pagesize = (u_int32_t)pgsize;
+
+	/*
+	 * We're called internally with a specified mfp, in which case the
+	 * path is NULL, but we'll get the path from the underlying region
+	 * information.  Otherwise, if the path is NULL, it's a temporary
+	 * file -- we know we can't join any existing files, and we'll delay
+	 * the open until we actually need to write the file. All temporary
+	 * files will go into the first hash bucket.
+	 */
+	DB_ASSERT(env, mfp == NULL || path == NULL);
+
+	bucket = 0;
+	hp = R_ADDR(dbmp->reginfo, mp->ftab);
+	if (mfp == NULL) {
+		if (path == NULL)
+			goto alloc;
+
+		/*
+		 * If fileid is not set but the file exists on the disk,
+		 * we try to use __os_fileid to set it. We do this
+		 * because we want to use the fileid to check if we have
+		 * opened the mpoolfile as early as possible.
+		 *
+		 * Note: DB layer always calls __memp_fopen with fileid set,
+		 * so this is only for using mpool api to open a file.
+		 */
+
+		if (!FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE) &&
+		    !F_ISSET(dbmfp, MP_FILEID_SET)) {
+			if ((ret = __db_appname(env,
+			     DB_APP_DATA, path, dirp, &rpath)) != 0)
+				goto err;
+			ret = __os_exists(env, rpath, &isdir);
+			if (ret == 0 && isdir) {
+				ret = EINVAL;
+				goto err;
+			} else if (ret == 0) {
+				if  ((ret = __os_fileid(env,
+				    rpath, 0, dbmfp->fileid)) != 0)
+					goto err;
+				F_SET(dbmfp, MP_FILEID_SET);
+			}
+		}
+
+		/*
+		 * Hash to the proper file table entry and walk it.
+		 *
+		 * The fileID is a filesystem unique number (e.g., a
+		 * UNIX dev/inode pair) plus a timestamp.  If files are
+		 * removed and created in less than a second, the fileID
+		 * can be repeated.  The problem with repetition happens
+		 * when the file that previously had the fileID value still
+		 * has pages in the pool, since we don't want to use them
+		 * to satisfy requests for the new file. Because the
+		 * DB_TRUNCATE flag reuses the dev/inode pair, repeated
+		 * opens with that flag set guarantees matching fileIDs
+		 * when the machine can open a file and then re-open
+		 * with truncate within a second.  For this reason, we
+		 * pass that flag down, and, if we find a matching entry,
+		 * we ensure that it's never found again, and we create
+		 * a new entry for the current request.
+		 */
+		if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE) ||
+		    F_ISSET(dbmfp, MP_FILEID_SET)) {
+			if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE))
+				bucket = FNBUCKET(path, strlen(path));
+			else
+				bucket = FNBUCKET(dbmfp->fileid,
+				    DB_FILE_ID_LEN);
+
+			hp += bucket;
+			/*
+			 * If we find the MPOOLFILE and inc its ref count.
+			 * That way it cannot go away while we open it.
+			 */
+			MUTEX_LOCK(env, hp->mtx_hash);
+			ret =
+			    __memp_mpf_find(env, dbmfp, hp, path, flags, &mfp);
+			if (ret == 0 && mfp != NULL) {
+				refinc = 1;
+
+				if (LF_ISSET(DB_MULTIVERSION)) {
+					if (MFP_OPEN_CNT(mfp) > (u_int32_t)
+					    (LF_ISSET(DB_RDONLY) ? 0 : 1) &&
+					    atomic_read(
+					    &mfp->multiversion) == 0) {
+						MUTEX_UNLOCK(env, hp->mtx_hash);
+						goto mvcc_err;
+					}
+					atomic_inc(env, &mfp->multiversion);
+					F_SET(dbmfp, MP_MULTIVERSION);
+				}
+			}
+			MUTEX_UNLOCK(env, hp->mtx_hash);
+			if (ret != 0)
+				goto err;
+		}
+	} else {
+		/*
+		 * Deadfile can only be set if mpf_cnt goes to zero (or if we
+		 * failed creating the file DB_AM_DISCARD).  Increment the ref
+		 * count so the file cannot become dead and be unlinked.
+		 */
+		MUTEX_LOCK(env, mfp->mutex);
+		if (!mfp->deadfile) {
+			if (LF_ISSET(DB_MULTIVERSION)) {
+				MUTEX_UNLOCK(env, mfp->mutex);
+				if (MFP_OPEN_CNT(mfp) > 0 &&
+				     atomic_read(&mfp->multiversion) == 0) {
+mvcc_err:				__db_errx(env, DB_STR("3041",
+"DB_MULTIVERSION cannot be specified on a database file which is already open"));
+					ret = EINVAL;
+					goto err;
+				}
+
+				atomic_inc(env, &mfp->multiversion);
+				F_SET(dbmfp, MP_MULTIVERSION);
+			}
+			/*
+			 * Increment the reference count.  We also track
+			 * those references that don't effect the ability
+			 * to convert the handle to either NOT_DURABLE or
+			 * MVCC.  These are readonly opens or threads that
+			 * are using the handle just to flush a buffer.
+			 */
+			++mfp->mpf_cnt;
+			if (LF_ISSET(DB_FLUSH | DB_RDONLY))
+				++mfp->neutral_cnt;
+			if (LF_ISSET(DB_FLUSH))
+				F_SET(dbmfp, MP_FOR_FLUSH);
+			refinc = 1;
+		}
+		MUTEX_UNLOCK(env, mfp->mutex);
+
+		/*
+		 * Test one last time to see if the file is dead -- it may have
+		 * been removed.  This happens when a checkpoint trying to open
+		 * the file to flush a buffer races with the Db::remove method.
+		 * The error will be ignored, so don't output an error message.
+		 */
+		if (mfp->deadfile) {
+			ret = EINVAL;
+			goto err;
+		}
+	}
+
+	if (LF_ISSET(DB_RDONLY))
+		F_SET(dbmfp, MP_READONLY);
+	if (LF_ISSET(DB_FLUSH))
+		F_SET(dbmfp, MP_FLUSH);
+	/*
+	 * Share the underlying file descriptor if that's possible.
+	 */
+	if (mfp != NULL && !FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)) {
+		MUTEX_LOCK(env, dbmp->mutex);
+		TAILQ_FOREACH(tmp_dbmfp, &dbmp->dbmfq, q)
+			if (mfp == tmp_dbmfp->mfp &&
+			    (F_ISSET(dbmfp, MP_READONLY) ||
+			    !F_ISSET(tmp_dbmfp, MP_READONLY))) {
+				++tmp_dbmfp->fhp->ref;
+				dbmfp->fhp = tmp_dbmfp->fhp;
+				dbmfp->addr = tmp_dbmfp->addr;
+				dbmfp->len = tmp_dbmfp->len;
+				break;
+			}
+		MUTEX_UNLOCK(env, dbmp->mutex);
+		if (dbmfp->fhp != NULL)
+			goto have_mfp;
+	}
+
+	/*
+	 * If there's no backing file, we can join existing files in the cache,
+	 * but there's nothing to read from disk.
+	 */
+	if (!FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)) {
+		/* Convert MP open flags to DB OS-layer open flags. */
+		oflags = 0;
+		if (LF_ISSET(DB_CREATE))
+			oflags |= DB_OSO_CREATE;
+		if (LF_ISSET(DB_DIRECT))
+			oflags |= DB_OSO_DIRECT;
+		if (LF_ISSET(DB_RDONLY))
+			oflags |= DB_OSO_RDONLY;
+
+		/*
+		 * XXX
+		 * A grievous layering violation, the DB_DSYNC_DB flag
+		 * was left in the ENV structure and not driven through
+		 * the cache API.  This needs to be fixed when the general
+		 * API configuration is fixed.
+		 */
+		if (F_ISSET(env->dbenv, DB_ENV_DSYNC_DB))
+			oflags |= DB_OSO_DSYNC;
+
+		/*
+		 * Get the real name for this file and open it.
+		 *
+		 * Supply a page size so os_open can decide whether to
+		 * turn buffering off if the DB_DIRECT_DB flag is set.
+		 *
+		 * Acquire the region lock if we're using a path from
+		 * an underlying MPOOLFILE -- there's a race in accessing
+		 * the path name stored in the region, __memp_nameop may
+		 * be simultaneously renaming the file.
+		 */
+
+		ret = 0;
+		if (mfp != NULL) {
+			MPOOL_SYSTEM_LOCK(env);
+			path = R_ADDR(dbmp->reginfo, mfp->path_off);
+			if (rpath != NULL) {
+				__os_free(env, rpath);
+				rpath = NULL;
+			}
+		}
+		if (rpath == NULL)
+			ret = __db_appname(env,
+			    DB_APP_DATA, path, dirp, &rpath);
+		if (ret == 0)
+			ret = __os_open(env, rpath,
+			     (u_int32_t)pagesize, oflags, mode, &dbmfp->fhp);
+		if (mfp != NULL)
+			MPOOL_SYSTEM_UNLOCK(env);
+		if (ret != 0)
+			goto err;
+
+		/*
+		 * Cache file handles are shared, and have mutexes to
+		 * protect the underlying file handle across seek and
+		 * read/write calls.
+		 */
+		dbmfp->fhp->ref = 1;
+		if ((ret = __mutex_alloc(env, MTX_MPOOL_FH,
+		     DB_MUTEX_PROCESS_ONLY, &dbmfp->fhp->mtx_fh)) != 0)
+			goto err;
+
+		/* Figure out the file's size. */
+		if ((ret = __os_ioinfo(
+		    env, rpath, dbmfp->fhp, &mbytes, &bytes, NULL)) != 0) {
+			__db_err(env, ret, "%s", rpath);
+			goto err;
+		}
+
+		/*
+		 * Don't permit files that aren't a multiple of the pagesize,
+		 * and find the number of the last page in the file, all the
+		 * time being careful not to overflow 32 bits.
+		 *
+		 * During verify or recovery, we might have to cope with a
+		 * truncated file; if the file size is not a multiple of the
+		 * page size, round down to a page, we'll take care of the
+		 * partial page outside the mpool system.
+		 *
+		 * Pagesize of 0 is only allowed for in-mem dbs.
+		 */
+		DB_ASSERT(env, pagesize != 0);
+		if (bytes % pagesize != 0) {
+			if (LF_ISSET(DB_ODDFILESIZE))
+				bytes -= (u_int32_t)(bytes % pagesize);
+			else {
+				/*
+				 * If the file size is not a multiple of the
+				 * pagesize, it is likely because the ioinfo
+				 * call is racing with a write that is extending
+				 * the file.  Many file systems will extend
+				 * in fs block size units, and if the pagesize
+				 * is larger than that, we can briefly see a
+				 * file size that is not a multiple of pagesize.
+				 *
+				 * Yield the processor to allow that to finish
+				 * and try again a few times.
+				 */
+				tries = 0;
+				STAT((mp->stat.st_oddfsize_detect++));
+				while (tries < MP_IOINFO_RETRIES) {
+					if ((ret = __os_ioinfo(env, rpath,
+					    dbmfp->fhp, &mbytes, &bytes,
+					    NULL)) != 0) {
+						__db_err(env, ret, "%s", rpath);
+						goto err;
+					}
+					if (bytes % pagesize != 0) {
+						__os_yield(env, 0, 50000);
+						tries++;
+					} else {
+						STAT((mp->stat.st_oddfsize_resolve++));
+						break;
+					}
+				}
+				if (tries == MP_IOINFO_RETRIES) {
+					__db_errx(env, DB_STR_A("3037",
+    "%s: file size (%lu %lu) not a multiple of the pagesize %lu",
+    "%s %lu %lu %lu"),
+    rpath, (u_long)mbytes, (u_long)bytes, (u_long)pagesize);
+					ret = EINVAL;
+					goto err;
+				}
+			}
+		}
+
+		/*
+		 * Get the file id if we weren't given one.  Generated file id's
+		 * don't use timestamps, otherwise there'd be no chance of any
+		 * other process joining the party.  Don't bother looking for
+		 * this id in the hash table, its new.
+		 */
+		if (mfp == NULL && !F_ISSET(dbmfp, MP_FILEID_SET)) {
+			if  ((ret =
+			     __os_fileid(env, rpath, 0, dbmfp->fileid)) != 0)
+				goto err;
+			F_SET(dbmfp, MP_FILEID_SET);
+			bucket = FNBUCKET(dbmfp->fileid, DB_FILE_ID_LEN);
+			hp += bucket;
+			goto alloc;
+		}
+	}
+
+	if (mfp != NULL)
+		goto have_mfp;
+
+	/*
+	 * We can race with another process opening the same file when
+	 * we allocate the mpoolfile structure.  We will come back
+	 * here and check the hash table again to see if it has appeared.
+	 * For most files this is not a problem, since the name is locked
+	 * at a higher layer but QUEUE extent files are not locked.
+	 */
+check:	MUTEX_LOCK(env, hp->mtx_hash);
+	if ((ret = __memp_mpf_find(env, dbmfp, hp, path, flags, &mfp) != 0))
+		goto err;
+
+	if (alloc_mfp != NULL && mfp == NULL) {
+		mfp = alloc_mfp;
+		alloc_mfp = NULL;
+		SH_TAILQ_INSERT_HEAD(&hp->hash_bucket, mfp, q, __mpoolfile);
+	} else if (mfp != NULL) {
+		refinc = 1;
+		/*
+		 * Some things about a file cannot be changed: the clear length,
+		 * page size, or LSN location.  However, if this is an attempt
+		 * to open a named in-memory file, we may not yet have that
+		 * information. so accept uninitialized entries.
+		 *
+		 * The file type can change if the application's pre- and post-
+		 * processing needs change.  For example, an application that
+		 * created a hash subdatabase in a database that was previously
+		 * all btree.
+		 *
+		 * !!!
+		 * We do not check to see if the pgcookie information changed,
+		 * or update it if it is.
+		 */
+		if ((dbmfp->clear_len != DB_CLEARLEN_NOTSET &&
+		    mfp->clear_len != DB_CLEARLEN_NOTSET &&
+		    dbmfp->clear_len != mfp->clear_len) ||
+		    (pagesize != 0 && pagesize != mfp->pagesize) ||
+		    (dbmfp->lsn_offset != DB_LSN_OFF_NOTSET &&
+		    mfp->lsn_off != DB_LSN_OFF_NOTSET &&
+		    dbmfp->lsn_offset != mfp->lsn_off)) {
+			__db_errx(env, DB_STR_A("3038",
+		    "%s: clear length, page size or LSN location changed",
+			    "%s"), path);
+			MUTEX_UNLOCK(env, hp->mtx_hash);
+			ret = EINVAL;
+			goto err;
+		}
+	}
+	if (mfp != NULL && LF_ISSET(DB_MULTIVERSION)) {
+		if (MFP_OPEN_CNT(mfp) > 1 &&
+		    atomic_read(&mfp->multiversion) == 0) {
+			MUTEX_UNLOCK(env, hp->mtx_hash);
+			goto mvcc_err;
+		}
+		atomic_inc(env, &mfp->multiversion);
+		F_SET(dbmfp, MP_MULTIVERSION);
+	}
+
+	MUTEX_UNLOCK(env, hp->mtx_hash);
+	if (alloc_mfp != NULL) {
+		MUTEX_LOCK(env, alloc_mfp->mutex);
+		if ((ret = __memp_mf_discard(dbmp, alloc_mfp, 0)) != 0)
+			goto err;
+	}
+
+	if (mfp == NULL) {
+		/*
+		 * If we didn't find the file and this is an in-memory file,
+		 * then the create flag should be set.
+		 */
+		if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE) &&
+		    !LF_ISSET(DB_CREATE)) {
+			ret = ENOENT;
+			goto err;
+		}
+
+alloc:		if ((ret = __memp_mpf_alloc(dbmp,
+		     dbmfp, path, pagesize, flags, &alloc_mfp)) != 0)
+			goto err;
+
+		/*
+		 * If the user specifies DB_MPOOL_LAST or DB_MPOOL_NEW on a
+		 * page get, we have to increment the last page in the file.
+		 * Figure it out and save it away.
+		 *
+		 * Note correction: page numbers are zero-based, not 1-based.
+		 */
+		DB_ASSERT(env, pagesize != 0);
+		last_pgno = (db_pgno_t)(mbytes * (MEGABYTE / pagesize));
+		last_pgno += (db_pgno_t)(bytes / pagesize);
+		if (last_pgno != 0)
+			--last_pgno;
+
+		alloc_mfp->last_flushed_pgno = alloc_mfp->orig_last_pgno =
+		    alloc_mfp->last_pgno = last_pgno;
+
+		alloc_mfp->bucket = bucket;
+
+		/* Go back and see if someone else has opened the file. */
+		if (path != NULL)
+			goto check;
+
+		mfp = alloc_mfp;
+
+		if (LF_ISSET(DB_MULTIVERSION)) {
+			atomic_inc(env, &mfp->multiversion);
+			F_SET(dbmfp, MP_MULTIVERSION);
+		}
+
+		/* This is a temp, noone else can see it, put it at the end. */
+		MUTEX_LOCK(env, hp->mtx_hash);
+		SH_TAILQ_INSERT_TAIL(&hp->hash_bucket, mfp, q);
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+	}
+have_mfp:
+	/*
+	 * We need to verify that all handles open a file either durable or not
+	 * durable.  This needs to be cross process and cross sub-databases, so
+	 * mpool is the place to do it.
+	 */
+	if (!LF_ISSET(DB_DURABLE_UNKNOWN | DB_RDONLY)) {
+		if (F_ISSET(mfp, MP_DURABLE_UNKNOWN)) {
+			if (LF_ISSET(DB_TXN_NOT_DURABLE))
+				F_SET(mfp, MP_NOT_DURABLE);
+			F_CLR(mfp, MP_DURABLE_UNKNOWN);
+		} else if (!LF_ISSET(DB_TXN_NOT_DURABLE) !=
+		    !F_ISSET(mfp, MP_NOT_DURABLE)) {
+			__db_errx(env, DB_STR("3039",
+	     "Cannot open DURABLE and NOT DURABLE handles in the same file"));
+			ret = EINVAL;
+			goto err;
+		}
+	}
+
+	/*
+	 * All paths to here have initialized the mfp variable to reference
+	 * the selected (or allocated) MPOOLFILE.
+	 */
+	dbmfp->mfp = mfp;
+
+	/*
+	 * Check to see if we can mmap the file.  If a file:
+	 *	+ isn't temporary
+	 *	+ is read-only
+	 *	+ doesn't require any pgin/pgout support
+	 *	+ the DB_NOMMAP flag wasn't set (in either the file open or
+	 *	  the environment in which it was opened)
+	 *	+ and is less than mp_mmapsize bytes in size
+	 *
+	 * we can mmap it instead of reading/writing buffers.  Don't do error
+	 * checking based on the mmap call failure.  We want to do normal I/O
+	 * on the file if the reason we failed was because the file was on an
+	 * NFS mounted partition, and we can fail in buffer I/O just as easily
+	 * as here.
+	 *
+	 * We'd like to test to see if the file is too big to mmap.  Since we
+	 * don't know what size or type off_t's or size_t's are, or the largest
+	 * unsigned integral type is, or what random insanity the local C
+	 * compiler will perpetrate, doing the comparison in a portable way is
+	 * flatly impossible.  Hope that mmap fails if the file is too large.
+	 */
+#define	DB_MAXMMAPSIZE	(10 * 1024 * 1024)	/* 10 MB. */
+	if (F_ISSET(mfp, MP_CAN_MMAP) && dbmfp->addr == NULL) {
+		maxmap = dbenv->mp_mmapsize == 0 ?
+		    DB_MAXMMAPSIZE : dbenv->mp_mmapsize;
+		if (path == NULL ||
+		    FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE))
+			F_CLR(mfp, MP_CAN_MMAP);
+		else if (!F_ISSET(dbmfp, MP_READONLY))
+			F_CLR(mfp, MP_CAN_MMAP);
+		else if (dbmfp->ftype != 0)
+			F_CLR(mfp, MP_CAN_MMAP);
+		else if (LF_ISSET(DB_NOMMAP) || F_ISSET(dbenv, DB_ENV_NOMMAP))
+			F_CLR(mfp, MP_CAN_MMAP);
+		else {
+			MPOOL_SYSTEM_LOCK(env);
+			maxmap = mp->mp_mmapsize == 0 ?
+			    DB_MAXMMAPSIZE : mp->mp_mmapsize;
+			MPOOL_SYSTEM_UNLOCK(env);
+			if (mbytes > maxmap / MEGABYTE ||
+			    (mbytes == maxmap / MEGABYTE &&
+			    bytes >= maxmap % MEGABYTE))
+				F_CLR(mfp, MP_CAN_MMAP);
+		}
+
+		dbmfp->addr = NULL;
+		if (F_ISSET(mfp, MP_CAN_MMAP)) {
+			dbmfp->len = (size_t)mbytes * MEGABYTE + bytes;
+			if (__os_mapfile(env, rpath,
+			    dbmfp->fhp, dbmfp->len, 1, &dbmfp->addr) != 0) {
+				dbmfp->addr = NULL;
+				F_CLR(mfp, MP_CAN_MMAP);
+			}
+		}
+	}
+
+	F_SET(dbmfp, MP_OPEN_CALLED);
+
+	/*
+	 * Add the file to the process' list of DB_MPOOLFILEs.
+	 */
+	MUTEX_LOCK(env, dbmp->mutex);
+	TAILQ_INSERT_TAIL(&dbmp->dbmfq, dbmfp, q);
+	MUTEX_UNLOCK(env, dbmp->mutex);
+
+	if (0) {
+err:		if (refinc) {
+			/*
+			 * If mpf_cnt goes to zero here and unlink_on_close is
+			 * set, then we missed the last close, but there was an
+			 * error trying to open the file, so we probably cannot
+			 * unlink it anyway.
+			 */
+			MUTEX_LOCK(env, mfp->mutex);
+			--mfp->mpf_cnt;
+			if (LF_ISSET(DB_FLUSH | DB_RDONLY)) {
+				DB_ASSERT(env, mfp->neutral_cnt != 0);
+				--mfp->neutral_cnt;
+			}
+			MUTEX_UNLOCK(env, mfp->mutex);
+		}
+
+	}
+	if (rpath != NULL)
+		__os_free(env, rpath);
+	return (ret);
+}
+
+/*
+ * __memp_mpf_find --
+ *	Search a hash bucket for a MPOOLFILE.
+ */
+static int
+__memp_mpf_find(env, dbmfp, hp, path, flags, mfpp)
+	ENV *env;
+	DB_MPOOLFILE *dbmfp;
+	DB_MPOOL_HASH *hp;
+	const char *path;
+	u_int32_t flags;
+	MPOOLFILE **mfpp;
+{
+	DB_MPOOL *dbmp;
+	MPOOLFILE *mfp;
+
+	dbmp = env->mp_handle;
+
+	SH_TAILQ_FOREACH(mfp, &hp->hash_bucket, q, __mpoolfile) {
+		/* Skip dead files and temporary files. */
+		if (mfp->deadfile || F_ISSET(mfp, MP_TEMP))
+			continue;
+
+		/*
+		 * Any remaining DB_MPOOL_NOFILE databases are in-memory
+		 * named databases and need only match other in-memory
+		 * databases with the same name.
+		 */
+		if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)) {
+			if (!mfp->no_backing_file)
+				continue;
+
+			if (strcmp(path, R_ADDR(dbmp->reginfo, mfp->path_off)))
+				continue;
+
+			/*
+			 * We matched an in-memory file; grab the fileid if
+			 * it is set in the region, but not in the dbmfp.
+			 */
+			if (!F_ISSET(dbmfp, MP_FILEID_SET))
+				(void)__memp_set_fileid(dbmfp,
+				    R_ADDR(dbmp->reginfo, mfp->fileid_off));
+		} else
+			if (memcmp(dbmfp->fileid, R_ADDR(dbmp->reginfo,
+			    mfp->fileid_off), DB_FILE_ID_LEN) != 0)
+				continue;
+
+		/*
+		 * If the file is being truncated, remove it from the system
+		 * and create a new entry.
+		 *
+		 * !!!
+		 * We should be able to set mfp to NULL and break out of the
+		 * loop, but I like the idea of checking all the entries.
+		 */
+		if (LF_ISSET(DB_TRUNCATE)) {
+			MUTEX_LOCK(env, mfp->mutex);
+			mfp->deadfile = 1;
+			MUTEX_UNLOCK(env, mfp->mutex);
+			continue;
+		}
+
+		/*
+		 * Check to see if this file has died while we waited.
+		 *
+		 * We normally don't lock the deadfile field when we read it as
+		 * we only care if the field is zero or non-zero.  We do lock
+		 * on read when searching for a matching MPOOLFILE so that two
+		 * threads of control don't race between setting the deadfile
+		 * bit and incrementing the reference count, that is, a thread
+		 * of control decrementing the reference count and then setting
+		 * deadfile because the reference count is 0 blocks us finding
+		 * the file without knowing it's about to be marked dead.
+		 */
+		MUTEX_LOCK(env, mfp->mutex);
+		if (mfp->deadfile) {
+			MUTEX_UNLOCK(env, mfp->mutex);
+			continue;
+		}
+		++mfp->mpf_cnt;
+		if (LF_ISSET(DB_FLUSH | DB_RDONLY))
+			++mfp->neutral_cnt;
+		if (LF_ISSET(DB_FLUSH))
+			F_SET(dbmfp, MP_FOR_FLUSH);
+		MUTEX_UNLOCK(env, mfp->mutex);
+
+		/* Initialize any fields that are not yet set. */
+		if (dbmfp->ftype != 0)
+			mfp->ftype = dbmfp->ftype;
+		if (dbmfp->clear_len != DB_CLEARLEN_NOTSET)
+			mfp->clear_len = dbmfp->clear_len;
+		if (dbmfp->lsn_offset != -1)
+			mfp->lsn_off = dbmfp->lsn_offset;
+
+		break;
+	}
+
+	*mfpp = mfp;
+	return (0);
+}
+
+static int
+__memp_mpf_alloc(dbmp, dbmfp, path, pagesize, flags, retmfp)
+	DB_MPOOL *dbmp;
+	DB_MPOOLFILE *dbmfp;
+	const char *path;
+	u_int32_t pagesize;
+	u_int32_t flags;
+	MPOOLFILE **retmfp;
+{
+	ENV *env;
+	MPOOLFILE *mfp;
+	int ret;
+	void *p;
+
+	env = dbmp->env;
+	ret = 0;
+	/* Allocate and initialize a new MPOOLFILE. */
+	if ((ret = __memp_alloc(dbmp,
+	     dbmp->reginfo, NULL, sizeof(MPOOLFILE), NULL, &mfp)) != 0)
+		goto err;
+	memset(mfp, 0, sizeof(MPOOLFILE));
+	mfp->mpf_cnt = 1;
+	if (LF_ISSET(DB_FLUSH | DB_RDONLY))
+		mfp->neutral_cnt = 1;
+	if (LF_ISSET(DB_FLUSH))
+		F_SET(dbmfp, MP_FOR_FLUSH);
+	mfp->ftype = dbmfp->ftype;
+	mfp->pagesize = pagesize;
+	mfp->lsn_off = dbmfp->lsn_offset;
+	mfp->clear_len = dbmfp->clear_len;
+	mfp->priority = dbmfp->priority;
+	if (dbmfp->gbytes != 0 || dbmfp->bytes != 0) {
+		mfp->maxpgno = (db_pgno_t)
+		    (dbmfp->gbytes * (GIGABYTE / mfp->pagesize));
+		mfp->maxpgno += (db_pgno_t)
+		    ((dbmfp->bytes + mfp->pagesize - 1) /
+		    mfp->pagesize);
+	}
+	if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE))
+		mfp->no_backing_file = 1;
+	if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_UNLINK))
+		mfp->unlink_on_close = 1;
+
+	F_SET(mfp, MP_CAN_MMAP);
+	if (F_ISSET(env->dbenv, DB_ENV_DATABASE_LOCKING))
+		F_SET(mfp, MP_DATABASE_LOCKING);
+	if (LF_ISSET(DB_DIRECT))
+		F_SET(mfp, MP_DIRECT);
+	if (LF_ISSET(DB_DURABLE_UNKNOWN | DB_RDONLY))
+		F_SET(mfp, MP_DURABLE_UNKNOWN);
+	if (LF_ISSET(DB_EXTENT))
+		F_SET(mfp, MP_EXTENT);
+	if (LF_ISSET(DB_TXN_NOT_DURABLE))
+		F_SET(mfp, MP_NOT_DURABLE);
+
+	/*
+	 * An in-memory database with no name is a temp file.  Named
+	 * in-memory databases get an artificially  bumped reference
+	 * count so they don't disappear on close; they need a remove
+	 * to make them disappear.
+	 */
+	if (path == NULL)
+		F_SET(mfp, MP_TEMP);
+	else if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE))
+		mfp->mpf_cnt++;
+
+	/* Copy the file identification string into shared memory. */
+	if (F_ISSET(dbmfp, MP_FILEID_SET)) {
+		if ((ret = __memp_alloc(dbmp, dbmp->reginfo,
+		    NULL, DB_FILE_ID_LEN, &mfp->fileid_off, &p)) != 0)
+			goto err;
+		memcpy(p, dbmfp->fileid, DB_FILE_ID_LEN);
+	}
+
+	/* Copy the file path into shared memory. */
+	if (path != NULL) {
+		if ((ret = __memp_alloc(dbmp, dbmp->reginfo,
+		    NULL, strlen(path) + 1, &mfp->path_off, &p)) != 0)
+			goto err;
+		memcpy(p, path, strlen(path) + 1);
+	}
+
+	/* Copy the page cookie into shared memory. */
+	if (dbmfp->pgcookie == NULL || dbmfp->pgcookie->size == 0) {
+		mfp->pgcookie_len = 0;
+		mfp->pgcookie_off = 0;
+	} else {
+		if ((ret = __memp_alloc(dbmp, dbmp->reginfo,
+		    NULL, dbmfp->pgcookie->size,
+		    &mfp->pgcookie_off, &p)) != 0)
+			goto err;
+		memcpy(p,
+		     dbmfp->pgcookie->data, dbmfp->pgcookie->size);
+		mfp->pgcookie_len = dbmfp->pgcookie->size;
+	}
+
+	if ((ret = __mutex_alloc(env,
+	    MTX_MPOOLFILE_HANDLE, 0, &mfp->mutex)) != 0)
+		goto err;
+#ifndef HAVE_ATOMICFILEREAD
+	if ((ret = __mutex_alloc(env,
+	    MTX_MPOOLFILE_HANDLE, DB_MUTEX_SHARED, &mfp->mtx_write)) != 0)
+		goto err;
+#endif
+	*retmfp = mfp;
+
+err:	return (ret);
+}
+
+/*
+ * memp_fclose_pp --
+ *	DB_MPOOLFILE->close pre/post processing.
+ *
+ * PUBLIC: int __memp_fclose_pp __P((DB_MPOOLFILE *, u_int32_t));
+ */
+int
+__memp_fclose_pp(dbmfp, flags)
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbmfp->env;
+
+	/*
+	 * Validate arguments, but as a handle destructor, we can't fail.
+	 */
+	if (flags != 0)
+		(void)__db_ferr(env, "DB_MPOOLFILE->close", 0);
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env, (__memp_fclose(dbmfp, 0)), 0, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __memp_fclose --
+ *	DB_MPOOLFILE->close.
+ *
+ * PUBLIC: int __memp_fclose __P((DB_MPOOLFILE *, u_int32_t));
+ */
+int
+__memp_fclose(dbmfp, flags)
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t flags;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOLFILE *mfp;
+	char *rpath;
+	u_int32_t ref;
+	int deleted, ret, t_ret;
+
+	env = dbmfp->env;
+	dbmp = env->mp_handle;
+	ret = 0;
+
+	/*
+	 * Remove the DB_MPOOLFILE from the process' list.
+	 *
+	 * It's possible the underlying mpool cache may never have been created.
+	 * In that case, all we have is a structure, discard it.
+	 *
+	 * It's possible the DB_MPOOLFILE was never added to the DB_MPOOLFILE
+	 * file list, check the MP_OPEN_CALLED flag to be sure.
+	 */
+	if (dbmp == NULL)
+		goto done;
+
+	MUTEX_LOCK(env, dbmp->mutex);
+
+	DB_ASSERT(env, dbmfp->ref >= 1);
+	if ((ref = --dbmfp->ref) == 0 && F_ISSET(dbmfp, MP_OPEN_CALLED))
+		TAILQ_REMOVE(&dbmp->dbmfq, dbmfp, q);
+
+	/*
+	 * Decrement the file descriptor's ref count -- if we're the last ref,
+	 * we'll discard the file descriptor.
+	 */
+	if (ref == 0 && dbmfp->fhp != NULL && --dbmfp->fhp->ref > 0)
+		dbmfp->fhp = NULL;
+	MUTEX_UNLOCK(env, dbmp->mutex);
+	if (ref != 0)
+		return (0);
+
+	/* Complain if pinned blocks never returned. */
+	if (dbmfp->pinref != 0) {
+		__db_errx(env, DB_STR_A("3040",
+		    "%s: close: %lu blocks left pinned", "%s %lu"),
+		    __memp_fn(dbmfp), (u_long)dbmfp->pinref);
+		ret = __env_panic(env, DB_RUNRECOVERY);
+	}
+
+	/* Discard any mmap information. */
+	if (dbmfp->addr != NULL && dbmfp->fhp != NULL &&
+	    (ret = __os_unmapfile(env, dbmfp->addr, dbmfp->len)) != 0)
+		__db_err(env, ret, "%s", __memp_fn(dbmfp));
+
+	/*
+	 * Close the file and discard the descriptor structure; temporary
+	 * files may not yet have been created.
+	 */
+	if (dbmfp->fhp != NULL) {
+		if ((t_ret =
+		    __mutex_free(env, &dbmfp->fhp->mtx_fh)) != 0 && ret == 0)
+			ret = t_ret;
+		if ((t_ret = __os_closehandle(env, dbmfp->fhp)) != 0) {
+			__db_err(env, t_ret, "%s", __memp_fn(dbmfp));
+			if (ret == 0)
+				ret = t_ret;
+		}
+		dbmfp->fhp = NULL;
+	}
+
+	/*
+	 * Discard our reference on the underlying MPOOLFILE, and close it
+	 * if it's no longer useful to anyone.  It possible the open of the
+	 * file never happened or wasn't successful, in which case, mpf will
+	 * be NULL and MP_OPEN_CALLED will not be set.
+	 */
+	mfp = dbmfp->mfp;
+	DB_ASSERT(env,
+	    (F_ISSET(dbmfp, MP_OPEN_CALLED) && mfp != NULL) ||
+	    (!F_ISSET(dbmfp, MP_OPEN_CALLED) && mfp == NULL));
+	if (!F_ISSET(dbmfp, MP_OPEN_CALLED))
+		goto done;
+
+	/*
+	 * If it's a temp file, all outstanding references belong to unflushed
+	 * buffers.  (A temp file can only be referenced by one DB_MPOOLFILE).
+	 * We don't care about preserving any of those buffers, so mark the
+	 * MPOOLFILE as dead so that even the dirty ones just get discarded
+	 * when we try to flush them.
+	 */
+	deleted = 0;
+	if (!LF_ISSET(DB_MPOOL_NOLOCK))
+		MUTEX_LOCK(env, mfp->mutex);
+	if (F_ISSET(dbmfp, MP_MULTIVERSION))
+		atomic_dec(env, &mfp->multiversion);
+	if (F_ISSET(dbmfp, MP_READONLY) ||
+	    (LF_ISSET(DB_FLUSH) && F_ISSET(dbmfp, MP_FOR_FLUSH))) {
+		DB_ASSERT(env, mfp->neutral_cnt != 0);
+		--mfp->neutral_cnt;
+	}
+	DB_ASSERT(env, mfp->neutral_cnt < mfp->mpf_cnt);
+	if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) {
+		if (LF_ISSET(DB_MPOOL_DISCARD) ||
+		    F_ISSET(mfp, MP_TEMP) || mfp->unlink_on_close) {
+			mfp->deadfile = 1;
+		}
+		if (mfp->unlink_on_close) {
+			if ((t_ret = __db_appname(dbmp->env, DB_APP_DATA,
+			    R_ADDR(dbmp->reginfo, mfp->path_off), NULL,
+			    &rpath)) != 0 && ret == 0)
+				ret = t_ret;
+			if (t_ret == 0) {
+				if ((t_ret = __os_unlink(
+				    dbmp->env, rpath, 0)) != 0 && ret == 0)
+					ret = t_ret;
+				__os_free(env, rpath);
+			}
+		}
+		if (MFP_OPEN_CNT(mfp) == 0) {
+			F_CLR(mfp, MP_NOT_DURABLE);
+			F_SET(mfp, MP_DURABLE_UNKNOWN);
+		}
+		if (mfp->block_cnt == 0) {
+			/*
+			 * We should never discard this mp file if our caller
+			 * is holding the lock on it.  See comment in
+			 * __memp_sync_file.
+			 */
+			DB_ASSERT(env, !LF_ISSET(DB_MPOOL_NOLOCK));
+			if ((t_ret =
+			    __memp_mf_discard(dbmp, mfp, 0)) != 0 && ret == 0)
+				ret = t_ret;
+			deleted = 1;
+		}
+	}
+	if (!deleted && !LF_ISSET(DB_MPOOL_NOLOCK))
+		MUTEX_UNLOCK(env, mfp->mutex);
+
+done:	/* Discard the DB_MPOOLFILE structure. */
+	if (dbmfp->pgcookie != NULL) {
+		__os_free(env, dbmfp->pgcookie->data);
+		__os_free(env, dbmfp->pgcookie);
+	}
+	__os_free(env, dbmfp);
+
+	return (ret);
+}
+
+/*
+ * __memp_mf_discard --
+ *	Discard an MPOOLFILE.
+ *
+ * PUBLIC: int __memp_mf_discard __P((DB_MPOOL *, MPOOLFILE *, int));
+ */
+int
+__memp_mf_discard(dbmp, mfp, hp_locked)
+	DB_MPOOL *dbmp;
+	MPOOLFILE *mfp;
+	int hp_locked;
+{
+	DB_MPOOL_HASH *hp;
+	ENV *env;
+#ifdef HAVE_STATISTICS
+	DB_MPOOL_STAT *sp;
+#endif
+	MPOOL *mp;
+	int need_sync, ret, t_ret;
+
+	env = dbmp->env;
+	mp = dbmp->reginfo[0].primary;
+	hp = R_ADDR(dbmp->reginfo, mp->ftab);
+	hp += mfp->bucket;
+	ret = 0;
+
+	/*
+	 * Expects caller to be holding the MPOOLFILE mutex.
+	 *
+	 * When discarding a file, we have to flush writes from it to disk.
+	 * The scenario is that dirty buffers from this file need to be
+	 * flushed to satisfy a future checkpoint, but when the checkpoint
+	 * calls mpool sync, the sync code won't know anything about them.
+	 * Ignore files not written, discarded, or only temporary.
+	 */
+	need_sync = mfp->file_written && !mfp->deadfile &&
+	    !F_ISSET(mfp, MP_TEMP) && !mfp->no_backing_file;
+
+	/*
+	 * We have to release the MPOOLFILE mutex before acquiring the region
+	 * mutex so we don't deadlock.  Make sure nobody ever looks at this
+	 * structure again.
+	 */
+	mfp->deadfile = 1;
+
+	/* Discard the mutex we're holding and return it too the pool. */
+	MUTEX_UNLOCK(env, mfp->mutex);
+	if ((t_ret = __mutex_free(env, &mfp->mutex)) != 0 && ret == 0)
+		ret = t_ret;
+#ifndef HAVE_ATOMICFILEREAD
+	if ((ret = __mutex_free(env, &mfp->mtx_write)) != 0 && ret == 0)
+		ret = t_ret;
+#endif
+
+	/*
+	 * Lock the bucket and delete from the list of MPOOLFILEs.
+	 * If this function is called by __memp_discard_all_mpfs,
+	 * the MPOOLFILE hash bucket is already locked.
+	 */
+	if (!hp_locked)
+		MUTEX_LOCK(env, hp->mtx_hash);
+	SH_TAILQ_REMOVE(&hp->hash_bucket, mfp, q, __mpoolfile);
+	if (!hp_locked)
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+
+	/* Lock the region and collect stats and free the space. */
+	MPOOL_SYSTEM_LOCK(env);
+	if (need_sync &&
+	    (t_ret = __memp_mf_sync(dbmp, mfp, 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+#ifdef HAVE_STATISTICS
+	/* Copy the statistics into the region. */
+	sp = &mp->stat;
+	sp->st_cache_hit += mfp->stat.st_cache_hit;
+	sp->st_cache_miss += mfp->stat.st_cache_miss;
+	sp->st_map += mfp->stat.st_map;
+	sp->st_page_create += mfp->stat.st_page_create;
+	sp->st_page_in += mfp->stat.st_page_in;
+	sp->st_page_out += mfp->stat.st_page_out;
+#endif
+
+	/* Free the space. */
+	if (mfp->path_off != 0)
+		__memp_free(&dbmp->reginfo[0],
+		    R_ADDR(dbmp->reginfo, mfp->path_off));
+	if (mfp->fileid_off != 0)
+		__memp_free(&dbmp->reginfo[0],
+		    R_ADDR(dbmp->reginfo, mfp->fileid_off));
+	if (mfp->pgcookie_off != 0)
+		__memp_free(&dbmp->reginfo[0],
+		    R_ADDR(dbmp->reginfo, mfp->pgcookie_off));
+	__memp_free(&dbmp->reginfo[0], mfp);
+
+	MPOOL_SYSTEM_UNLOCK(env);
+
+	return (ret);
+}
+
+/*
+ * __memp_inmemlist --
+ *	Return a list of the named in-memory databases.
+ *
+ * PUBLIC: int __memp_inmemlist __P((ENV *, char ***, int *));
+ */
+int
+__memp_inmemlist(env, namesp, cntp)
+	ENV *env;
+	char ***namesp;
+	int *cntp;
+{
+	DB_MPOOL *dbmp;
+	DB_MPOOL_HASH *hp;
+	MPOOL *mp;
+	MPOOLFILE *mfp;
+	int arraysz, cnt, i, ret;
+	char **names;
+
+	names = NULL;
+	dbmp = env->mp_handle;
+	mp = dbmp->reginfo[0].primary;
+	hp = R_ADDR(dbmp->reginfo, mp->ftab);
+
+	arraysz = cnt = 0;
+	for (i = 0; i < MPOOL_FILE_BUCKETS; i++, hp++) {
+		MUTEX_LOCK(env, hp->mtx_hash);
+		SH_TAILQ_FOREACH(mfp, &hp->hash_bucket, q, __mpoolfile) {
+			/* Skip dead files and temporary files. */
+			if (mfp->deadfile || F_ISSET(mfp, MP_TEMP))
+				continue;
+
+			/* Skip entries that allow files. */
+			if (!mfp->no_backing_file)
+				continue;
+
+			/* We found one. */
+			if (cnt >= arraysz) {
+				arraysz += 100;
+				if ((ret = __os_realloc(env,
+				    (u_int)arraysz * sizeof(names[0]),
+				    &names)) != 0)
+					goto nomem;
+			}
+			if ((ret = __os_strdup(env,
+			    R_ADDR(dbmp->reginfo, mfp->path_off),
+			    &names[cnt])) != 0)
+				goto nomem;
+
+			cnt++;
+		}
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+	}
+	*namesp = names;
+	*cntp = cnt;
+	return (0);
+
+nomem:	MUTEX_UNLOCK(env, hp->mtx_hash);
+	if (names != NULL) {
+		while (--cnt >= 0)
+			__os_free(env, names[cnt]);
+		__os_free(env, names);
+	}
+
+	/* Make sure we don't return any garbage. */
+	*cntp = 0;
+	*namesp = NULL;
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_fput.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,396 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/log.h"
+#include "dbinc/mp.h"
+
+static int __memp_reset_lru __P((ENV *, REGINFO *));
+
+/*
+ * __memp_fput_pp --
+ *	DB_MPOOLFILE->put pre/post processing.
+ *
+ * PUBLIC: int __memp_fput_pp
+ * PUBLIC:     __P((DB_MPOOLFILE *, void *, DB_CACHE_PRIORITY, u_int32_t));
+ */
+int
+__memp_fput_pp(dbmfp, pgaddr, priority, flags)
+	DB_MPOOLFILE *dbmfp;
+	void *pgaddr;
+	DB_CACHE_PRIORITY priority;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret, t_ret;
+
+	env = dbmfp->env;
+
+	if (flags != 0)
+		return (__db_ferr(env, "DB_MPOOLFILE->put", 0));
+
+	MPF_ILLEGAL_BEFORE_OPEN(dbmfp, "DB_MPOOLFILE->put");
+
+	ENV_ENTER(env, ip);
+
+	ret = __memp_fput(dbmfp, ip, pgaddr, priority);
+	if (IS_ENV_REPLICATED(env) &&
+	    (t_ret = __op_rep_exit(env)) != 0 && ret == 0)
+		ret = t_ret;
+
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __memp_fput --
+ *	DB_MPOOLFILE->put.
+ *
+ * PUBLIC: int __memp_fput __P((DB_MPOOLFILE *,
+ * PUBLIC:      DB_THREAD_INFO *, void *, DB_CACHE_PRIORITY));
+ */
+int
+__memp_fput(dbmfp, ip, pgaddr, priority)
+	DB_MPOOLFILE *dbmfp;
+	DB_THREAD_INFO *ip;
+	void *pgaddr;
+	DB_CACHE_PRIORITY priority;
+{
+	BH *bhp;
+	DB_ENV *dbenv;
+	DB_MPOOL *dbmp;
+	DB_MPOOL_HASH *hp;
+	ENV *env;
+	MPOOL *c_mp;
+	MPOOLFILE *mfp;
+	PIN_LIST *list, *lp;
+	REGINFO *infop, *reginfo;
+	roff_t b_ref;
+	int region;
+	int adjust, pfactor, ret, t_ret;
+	char buf[DB_THREADID_STRLEN];
+
+	env = dbmfp->env;
+	dbenv = env->dbenv;
+	dbmp = env->mp_handle;
+	mfp = dbmfp->mfp;
+	bhp = (BH *)((u_int8_t *)pgaddr - SSZA(BH, buf));
+	ret = 0;
+
+	/*
+	 * If this is marked dummy, we are using it to unpin a buffer for
+	 * another thread.
+	 */
+	if (F_ISSET(dbmfp, MP_DUMMY))
+		goto unpin;
+
+	/*
+	 * If we're mapping the file, there's nothing to do.  Because we can
+	 * stop mapping the file at any time, we have to check on each buffer
+	 * to see if the address we gave the application was part of the map
+	 * region.
+	 */
+	if (dbmfp->addr != NULL && pgaddr >= dbmfp->addr &&
+	    (u_int8_t *)pgaddr <= (u_int8_t *)dbmfp->addr + dbmfp->len)
+		return (0);
+
+	DB_ASSERT(env, IS_RECOVERING(env) || bhp->pgno <= mfp->last_pgno ||
+	    F_ISSET(bhp, BH_FREED) || !SH_CHAIN_SINGLETON(bhp, vc));
+#ifdef DIAGNOSTIC
+	/*
+	 * Decrement the per-file pinned buffer count (mapped pages aren't
+	 * counted).
+	 */
+	MPOOL_SYSTEM_LOCK(env);
+	if (dbmfp->pinref == 0) {
+		MPOOL_SYSTEM_UNLOCK(env);
+		__db_errx(env, DB_STR_A("3011",
+		    "%s: more pages returned than retrieved", "%s"),
+		    __memp_fn(dbmfp));
+		return (__env_panic(env, EACCES));
+	}
+	--dbmfp->pinref;
+	MPOOL_SYSTEM_UNLOCK(env);
+#endif
+
+unpin:
+	infop = &dbmp->reginfo[bhp->region];
+	c_mp = infop->primary;
+	hp = R_ADDR(infop, c_mp->htab);
+	hp = &hp[bhp->bucket];
+
+	/*
+	 * Check for a reference count going to zero.  This can happen if the
+	 * application returns a page twice.
+	 */
+	if (atomic_read(&bhp->ref) == 0) {
+		__db_errx(env, DB_STR_A("3012",
+		    "%s: page %lu: unpinned page returned", "%s %lu"),
+		    __memp_fn(dbmfp), (u_long)bhp->pgno);
+		DB_ASSERT(env, atomic_read(&bhp->ref) != 0);
+		return (__env_panic(env, EACCES));
+	}
+
+	/* Note the activity so allocation won't decide to quit. */
+	++c_mp->put_counter;
+
+	if (ip != NULL) {
+		reginfo = env->reginfo;
+		list = R_ADDR(reginfo, ip->dbth_pinlist);
+		region = (int)(infop - dbmp->reginfo);
+		b_ref = R_OFFSET(infop, bhp);
+		for (lp = list; lp < &list[ip->dbth_pinmax]; lp++)
+			if (lp->b_ref == b_ref && lp->region == region)
+				break;
+
+		if (lp == &list[ip->dbth_pinmax]) {
+			__db_errx(env, DB_STR_A("3013",
+		    "__memp_fput: pinned buffer not found for thread %s",
+			    "%s"), dbenv->thread_id_string(dbenv,
+			    ip->dbth_pid, ip->dbth_tid, buf));
+			return (__env_panic(env, EINVAL));
+		}
+
+		lp->b_ref = INVALID_ROFF;
+		ip->dbth_pincount--;
+	}
+
+	/*
+	 * Mark the file dirty.
+	 */
+	if (F_ISSET(bhp, BH_EXCLUSIVE) && F_ISSET(bhp, BH_DIRTY)) {
+		DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0);
+		mfp->file_written = 1;
+	}
+
+	/*
+	 * If more than one reference to the page we're done.  Ignore the
+	 * discard flags (for now) and leave the buffer's priority alone.
+	 * We are doing this a little early as the remaining ref may or
+	 * may not be a write behind.  If it is we set the priority
+	 * here, if not it will get set again later.  We might race
+	 * and miss setting the priority which would leave it wrong
+	 * for a while.
+	 */
+	DB_ASSERT(env, atomic_read(&bhp->ref) != 0);
+	if (atomic_dec(env, &bhp->ref) > 1 || (atomic_read(&bhp->ref) == 1 &&
+	    !F_ISSET(bhp, BH_DIRTY))) {
+		/*
+		 * __memp_pgwrite only has a shared lock while it clears
+		 * the BH_DIRTY bit. If we only have a shared latch then
+		 * we can't touch the flags bits.
+		 */
+		if (F_ISSET(bhp, BH_EXCLUSIVE))
+			F_CLR(bhp, BH_EXCLUSIVE);
+		MUTEX_UNLOCK(env, bhp->mtx_buf);
+		return (0);
+	}
+
+	/* The buffer should not be accessed again. */
+#ifdef DIAG_MVCC
+	MUTEX_LOCK(env, hp->mtx_hash);
+	if (BH_REFCOUNT(bhp) == 0)
+		MVCC_MPROTECT(bhp->buf, mfp->pagesize, 0);
+	MUTEX_UNLOCK(env, hp->mtx_hash);
+#endif
+
+	/* Update priority values. */
+	if (priority == DB_PRIORITY_VERY_LOW ||
+	    mfp->priority == MPOOL_PRI_VERY_LOW)
+		bhp->priority = 0;
+	else {
+		/*
+		 * We don't lock the LRU priority or the pages field, if
+		 * we get garbage (which won't happen on a 32-bit machine), it
+		 * only means a buffer has the wrong priority.
+		 */
+		bhp->priority = c_mp->lru_priority;
+
+		switch (priority) {
+		default:
+		case DB_PRIORITY_UNCHANGED:
+			pfactor = mfp->priority;
+			break;
+		case DB_PRIORITY_VERY_LOW:
+			pfactor = MPOOL_PRI_VERY_LOW;
+			break;
+		case DB_PRIORITY_LOW:
+			pfactor = MPOOL_PRI_LOW;
+			break;
+		case DB_PRIORITY_DEFAULT:
+			pfactor = MPOOL_PRI_DEFAULT;
+			break;
+		case DB_PRIORITY_HIGH:
+			pfactor = MPOOL_PRI_HIGH;
+			break;
+		case DB_PRIORITY_VERY_HIGH:
+			pfactor = MPOOL_PRI_VERY_HIGH;
+			break;
+		}
+
+		adjust = 0;
+		if (pfactor != 0)
+			adjust = (int)c_mp->pages / pfactor;
+
+		if (F_ISSET(bhp, BH_DIRTY))
+			adjust += (int)c_mp->pages / MPOOL_PRI_DIRTY;
+
+		if (adjust > 0) {
+			if (MPOOL_LRU_REDZONE - bhp->priority >=
+			    (u_int32_t)adjust)
+				bhp->priority += adjust;
+		} else if (adjust < 0)
+			if (bhp->priority > (u_int32_t)-adjust)
+				bhp->priority += adjust;
+	}
+
+	/*
+	 * __memp_pgwrite only has a shared lock while it clears the
+	 * BH_DIRTY bit. If we only have a shared latch then we can't
+	 * touch the flags bits.
+	 */
+	if (F_ISSET(bhp, BH_EXCLUSIVE))
+		F_CLR(bhp, BH_EXCLUSIVE);
+	MUTEX_UNLOCK(env, bhp->mtx_buf);
+
+	/*
+	 * On every buffer put we update the cache lru priority and check
+	 * for wraparound. The increment doesn't need to be atomic: occasional
+	 * lost increments are okay; __memp_reset_lru handles race conditions.
+	 */
+	if (++c_mp->lru_priority >= MPOOL_LRU_REDZONE &&
+	    (t_ret = __memp_reset_lru(env, infop)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __memp_reset_lru --
+ *	Reset the cache LRU priority when it reaches the upper limit.
+ */
+static int
+__memp_reset_lru(env, infop)
+	ENV *env;
+	REGINFO *infop;
+{
+	BH *bhp, *tbhp;
+	DB_MPOOL_HASH *hp;
+	MPOOL *c_mp;
+	u_int32_t bucket;
+	int reset;
+
+	/*
+	 * Update the priority so all future allocations will start at the
+	 * bottom. Lock this cache region to ensure that exactly one thread
+	 * will reset this cache's buffers.
+	 */
+	c_mp = infop->primary;
+	MPOOL_REGION_LOCK(env, infop);
+	reset = c_mp->lru_priority >= MPOOL_LRU_DECREMENT;
+	if (reset) {
+		c_mp->lru_priority -= MPOOL_LRU_DECREMENT;
+		c_mp->lru_generation++;
+	}
+	MPOOL_REGION_UNLOCK(env, infop);
+
+	if (!reset)
+		return (0);
+
+	/* Reduce the priority of every buffer in this cache region. */
+	for (hp = R_ADDR(infop, c_mp->htab),
+	    bucket = 0; bucket < c_mp->htab_buckets; ++hp, ++bucket) {
+		/*
+		 * Skip empty buckets.
+		 *
+		 * We can check for empty buckets before locking as we
+		 * only care if the pointer is zero or non-zero.
+		 */
+		if (SH_TAILQ_FIRST(&hp->hash_bucket, __bh) == NULL)
+			continue;
+
+		MUTEX_LOCK(env, hp->mtx_hash);
+		SH_TAILQ_FOREACH(bhp, &hp->hash_bucket, hq, __bh) {
+			for (tbhp = bhp; tbhp != NULL;
+			    tbhp = SH_CHAIN_PREV(tbhp, vc, __bh)) {
+				if (tbhp->priority > MPOOL_LRU_DECREMENT)
+					tbhp->priority -= MPOOL_LRU_DECREMENT;
+				else
+					tbhp->priority = 0;
+			}
+		}
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+	}
+
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+/*
+ * __memp_unpin_buffers --
+ *	Unpin buffers pinned by a thread.
+ *
+ * PUBLIC: int __memp_unpin_buffers __P((ENV *, DB_THREAD_INFO *));
+ */
+int
+__memp_unpin_buffers(env, ip)
+	ENV *env;
+	DB_THREAD_INFO *ip;
+{
+	BH *bhp;
+	DB_MPOOL *dbmp;
+	DB_MPOOLFILE dbmf;
+	PIN_LIST *list, *lp;
+	REGINFO *rinfop, *reginfo;
+	int ret;
+
+	memset(&dbmf, 0, sizeof(dbmf));
+	dbmf.env = env;
+	dbmf.flags = MP_DUMMY;
+	dbmp = env->mp_handle;
+	reginfo = env->reginfo;
+
+	list = R_ADDR(reginfo, ip->dbth_pinlist);
+	for (lp = list; lp < &list[ip->dbth_pinmax]; lp++) {
+		if (lp->b_ref == INVALID_ROFF)
+			continue;
+		rinfop = &dbmp->reginfo[lp->region];
+		bhp = R_ADDR(rinfop, lp->b_ref);
+		dbmf.mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
+		if ((ret = __memp_fput(&dbmf, ip,
+		    (u_int8_t *)bhp + SSZA(BH, buf),
+		    DB_PRIORITY_UNCHANGED)) != 0)
+			return (ret);
+	}
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_fset.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,145 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/log.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+/*
+ * __memp_dirty --
+ *	Upgrade a page from a read-only to a writable pointer.
+ *
+ * PUBLIC: int __memp_dirty __P((DB_MPOOLFILE *, void *,
+ * PUBLIC:     DB_THREAD_INFO *, DB_TXN *, DB_CACHE_PRIORITY, u_int32_t));
+ */
+int
+__memp_dirty(dbmfp, addrp, ip, txn, priority, flags)
+	DB_MPOOLFILE *dbmfp;
+	void *addrp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DB_CACHE_PRIORITY priority;
+	u_int32_t flags;
+{
+	BH *bhp;
+	DB_MPOOL *dbmp;
+	DB_MPOOL_HASH *hp;
+	ENV *env;
+	MPOOL *c_mp;
+	REGINFO *infop;
+	db_pgno_t pgno;
+	void *pgaddr;
+
+	env = dbmfp->env;
+	dbmp = env->mp_handle;
+
+	/* Convert the page address to a buffer header. */
+	pgaddr = *(void **)addrp;
+	bhp = (BH *)((u_int8_t *)pgaddr - SSZA(BH, buf));
+	pgno = bhp->pgno;
+
+	/* If we have it exclusively then its already dirty. */
+	if (F_ISSET(bhp, BH_EXCLUSIVE)) {
+		DB_ASSERT(env, F_ISSET(bhp, BH_DIRTY));
+		return (0);
+	}
+
+	if (flags == 0)
+		flags = DB_MPOOL_DIRTY;
+	DB_ASSERT(env, flags == DB_MPOOL_DIRTY || flags == DB_MPOOL_EDIT);
+
+	if (F_ISSET(dbmfp, MP_READONLY)) {
+		__db_errx(env, DB_STR_A("3008",
+		    "%s: dirty flag set for readonly file page", "%s"),
+		    __memp_fn(dbmfp));
+		return (EACCES);
+	}
+
+	infop = &dbmp->reginfo[bhp->region];
+	c_mp = infop->primary;
+	hp = R_ADDR(infop, c_mp->htab);
+	hp = &hp[bhp->bucket];
+
+	/* Drop the shared latch and get an exclusive. We have the buf ref'ed.*/
+	MUTEX_UNLOCK(env, bhp->mtx_buf);
+	MUTEX_LOCK(env, bhp->mtx_buf);
+	DB_ASSERT(env, !F_ISSET(bhp, BH_EXCLUSIVE));
+	F_SET(bhp, BH_EXCLUSIVE);
+
+	/* Set/clear the page bits. */
+	if (!F_ISSET(bhp, BH_DIRTY)) {
+#ifdef DIAGNOSTIC
+		MUTEX_LOCK(env, hp->mtx_hash);
+#endif
+		atomic_inc(env, &hp->hash_page_dirty);
+		F_SET(bhp, BH_DIRTY);
+#ifdef DIAGNOSTIC
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+#endif
+	}
+
+	DB_ASSERT(env, !F_ISSET(bhp, BH_DIRTY) ||
+	    atomic_read(&hp->hash_page_dirty) != 0);
+	COMPQUIET(ip, NULL);
+	COMPQUIET(txn, NULL);
+	COMPQUIET(priority, 0);
+	return (0);
+}
+
+/*
+ * __memp_shared --
+ *	Downgrade a page from exlusively held to shared.
+ *
+ * PUBLIC: int __memp_shared __P((DB_MPOOLFILE *, void *));
+ */
+int
+__memp_shared(dbmfp, pgaddr)
+	DB_MPOOLFILE *dbmfp;
+	void *pgaddr;
+{
+	BH *bhp;
+	ENV *env;
+
+	env = dbmfp->env;
+	/* Convert the page address to a buffer header. */
+	bhp = (BH *)((u_int8_t *)pgaddr - SSZA(BH, buf));
+
+	if (F_ISSET(bhp, BH_DIRTY))
+		dbmfp->mfp->file_written = 1;
+	DB_ASSERT(env, F_ISSET(bhp, BH_EXCLUSIVE));
+	F_CLR(bhp, BH_EXCLUSIVE);
+	MUTEX_UNLOCK(env, bhp->mtx_buf);
+	MUTEX_READLOCK(env, bhp->mtx_buf);
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_method.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1113 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/mp.h"
+#include "dbinc/db_page.h"
+#include "dbinc/hash.h"
+
+/*
+ * __memp_env_create --
+ *	Mpool specific creation of the DB_ENV structure.
+ *
+ * PUBLIC: int __memp_env_create __P((DB_ENV *));
+ */
+int
+__memp_env_create(dbenv)
+	DB_ENV *dbenv;
+{
+	/*
+	 * !!!
+	 * Our caller has not yet had the opportunity to reset the panic
+	 * state or turn off mutex locking, and so we can neither check
+	 * the panic state or acquire a mutex in the DB_ENV create path.
+	 *
+	 * We default to 32 8K pages.  We don't default to a flat 256K, because
+	 * we want to include the size of the buffer header which can vary
+	 * from system to system.
+	 */
+	dbenv->mp_bytes =
+	    32 * ((8 * 1024) + sizeof(BH)) + 37 * sizeof(DB_MPOOL_HASH);
+	dbenv->mp_ncache = 1;
+
+	return (0);
+}
+
+/*
+ * __memp_env_destroy --
+ *	Mpool specific destruction of the DB_ENV structure.
+ *
+ * PUBLIC: void __memp_env_destroy __P((DB_ENV *));
+ */
+void
+__memp_env_destroy(dbenv)
+	DB_ENV *dbenv;
+{
+	COMPQUIET(dbenv, NULL);
+}
+
+/*
+ * __memp_get_cachesize --
+ *	{DB_ENV,DB}->get_cachesize.
+ *
+ * PUBLIC: int __memp_get_cachesize
+ * PUBLIC:         __P((DB_ENV *, u_int32_t *, u_int32_t *, int *));
+ */
+int
+__memp_get_cachesize(dbenv, gbytesp, bytesp, ncachep)
+	DB_ENV *dbenv;
+	u_int32_t *gbytesp, *bytesp;
+	int *ncachep;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_cachesize", DB_INIT_MPOOL);
+
+	if (MPOOL_ON(env)) {
+		dbmp = env->mp_handle;
+		mp = dbmp->reginfo[0].primary;
+		if (gbytesp != NULL)
+			*gbytesp = mp->gbytes;
+		if (bytesp != NULL)
+			*bytesp = mp->bytes;
+		if (ncachep != NULL)
+			*ncachep = (int)mp->nreg;
+	} else {
+		if (gbytesp != NULL)
+			*gbytesp = dbenv->mp_gbytes;
+		if (bytesp != NULL)
+			*bytesp = dbenv->mp_bytes;
+		if (ncachep != NULL)
+			*ncachep = (int)dbenv->mp_ncache;
+	}
+
+	return (0);
+}
+
+/*
+ * __memp_set_cachesize --
+ *	{DB_ENV,DB}->set_cachesize.
+ *
+ * PUBLIC: int __memp_set_cachesize __P((DB_ENV *, u_int32_t, u_int32_t, int));
+ */
+int
+__memp_set_cachesize(dbenv, gbytes, bytes, arg_ncache)
+	DB_ENV *dbenv;
+	u_int32_t gbytes, bytes;
+	int arg_ncache;
+{
+	ENV *env;
+	DB_THREAD_INFO *ip;
+	u_int ncache;
+	int ret;
+
+	env = dbenv->env;
+	ret = 0;
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->set_cachesize", DB_INIT_MPOOL);
+
+	/* Normalize the cache count. */
+	ncache = arg_ncache <= 0 ? 1 : (u_int)arg_ncache;
+
+	/*
+	 * You can only store 4GB-1 in an unsigned 32-bit value, so correct for
+	 * applications that specify 4GB cache sizes -- we know what they meant.
+	 */
+	if (sizeof(roff_t) == 4 && gbytes / ncache == 4 && bytes == 0) {
+		--gbytes;
+		bytes = GIGABYTE - 1;
+	} else {
+		gbytes += bytes / GIGABYTE;
+		bytes %= GIGABYTE;
+	}
+
+	/*
+	 * !!!
+	 * With 32-bit region offsets, individual cache regions must be smaller
+	 * than 4GB.  Also, cache sizes larger than 10TB would cause 32-bit
+	 * wrapping in the calculation of the number of hash buckets.  See
+	 * __memp_open for details.
+	 */
+	if (!F_ISSET(env, ENV_OPEN_CALLED)) {
+		if (sizeof(roff_t) <= 4 && gbytes / ncache >= 4) {
+			__db_errx(env, DB_STR("3003",
+		    "individual cache size too large: maximum is 4GB"));
+			return (EINVAL);
+		}
+		if (gbytes / ncache > 10000) {
+			__db_errx(env, DB_STR("3004",
+		    "individual cache size too large: maximum is 10TB"));
+			return (EINVAL);
+		}
+	}
+
+	/*
+	 * If the application requested less than 500Mb, increase the cachesize
+	 * by 25% and factor in the size of the hash buckets to account for our
+	 * overhead.  (I'm guessing caches over 500Mb are specifically sized,
+	 * that is, it's a large server and the application actually knows how
+	 * much memory is available.  We only document the 25% overhead number,
+	 * not the hash buckets, but I don't see a reason to confuse the issue,
+	 * it shouldn't matter to an application.)
+	 *
+	 * There is a minimum cache size, regardless.
+	 */
+	if (gbytes == 0) {
+		if (bytes < 500 * MEGABYTE)
+			bytes += (bytes / 4) + 37 * sizeof(DB_MPOOL_HASH);
+		if (bytes / ncache < DB_CACHESIZE_MIN)
+			bytes = ncache * DB_CACHESIZE_MIN;
+	}
+
+	if (F_ISSET(env, ENV_OPEN_CALLED)) {
+		ENV_ENTER(env, ip);
+		ret = __memp_resize(env->mp_handle, gbytes, bytes);
+		ENV_LEAVE(env, ip);
+		return ret;
+	}
+
+	dbenv->mp_gbytes = gbytes;
+	dbenv->mp_bytes = bytes;
+	dbenv->mp_ncache = ncache;
+
+	return (0);
+}
+
+/*
+ * __memp_set_config --
+ *	Set the cache subsystem configuration.
+ *
+ * PUBLIC: int __memp_set_config __P((DB_ENV *, u_int32_t, int));
+ */
+int
+__memp_set_config(dbenv, which, on)
+	DB_ENV *dbenv;
+	u_int32_t which;
+	int on;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->memp_set_config", DB_INIT_MPOOL);
+
+	switch (which) {
+	case DB_MEMP_SUPPRESS_WRITE:
+	case DB_MEMP_SYNC_INTERRUPT:
+		if (MPOOL_ON(env)) {
+			dbmp = env->mp_handle;
+			mp = dbmp->reginfo[0].primary;
+			if (on)
+				FLD_SET(mp->config_flags, which);
+			else
+				FLD_CLR(mp->config_flags, which);
+		}
+		break;
+	default:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+/*
+ * __memp_get_config --
+ *	Return the cache subsystem configuration.
+ *
+ * PUBLIC: int __memp_get_config __P((DB_ENV *, u_int32_t, int *));
+ */
+int
+__memp_get_config(dbenv, which, onp)
+	DB_ENV *dbenv;
+	u_int32_t which;
+	int *onp;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_REQUIRES_CONFIG(env,
+	    env->mp_handle, "DB_ENV->memp_get_config", DB_INIT_MPOOL);
+
+	switch (which) {
+	case DB_MEMP_SUPPRESS_WRITE:
+	case DB_MEMP_SYNC_INTERRUPT:
+		if (MPOOL_ON(env)) {
+			dbmp = env->mp_handle;
+			mp = dbmp->reginfo[0].primary;
+			*onp = FLD_ISSET(mp->config_flags, which) ? 1 : 0;
+		} else
+			*onp = 0;
+		break;
+	default:
+		return (EINVAL);
+	}
+	return (0);
+}
+
+/*
+ * PUBLIC: int __memp_get_mp_max_openfd __P((DB_ENV *, int *));
+ */
+int
+__memp_get_mp_max_openfd(dbenv, maxopenfdp)
+	DB_ENV *dbenv;
+	int *maxopenfdp;
+{
+	DB_MPOOL *dbmp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_mp_max_openfd", DB_INIT_MPOOL);
+
+	if (MPOOL_ON(env)) {
+		dbmp = env->mp_handle;
+		mp = dbmp->reginfo[0].primary;
+		ENV_ENTER(env, ip);
+		MPOOL_SYSTEM_LOCK(env);
+		*maxopenfdp = mp->mp_maxopenfd;
+		MPOOL_SYSTEM_UNLOCK(env);
+		ENV_LEAVE(env, ip);
+	} else
+		*maxopenfdp = dbenv->mp_maxopenfd;
+	return (0);
+}
+
+/*
+ * __memp_set_mp_max_openfd --
+ *	Set the maximum number of open fd's when flushing the cache.
+ * PUBLIC: int __memp_set_mp_max_openfd __P((DB_ENV *, int));
+ */
+int
+__memp_set_mp_max_openfd(dbenv, maxopenfd)
+	DB_ENV *dbenv;
+	int maxopenfd;
+{
+	DB_MPOOL *dbmp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->set_mp_max_openfd", DB_INIT_MPOOL);
+
+	if (MPOOL_ON(env)) {
+		dbmp = env->mp_handle;
+		mp = dbmp->reginfo[0].primary;
+		ENV_ENTER(env, ip);
+		MPOOL_SYSTEM_LOCK(env);
+		mp->mp_maxopenfd = maxopenfd;
+		MPOOL_SYSTEM_UNLOCK(env);
+		ENV_LEAVE(env, ip);
+	} else
+		dbenv->mp_maxopenfd = maxopenfd;
+	return (0);
+}
+
+/*
+ * PUBLIC: int __memp_get_mp_max_write __P((DB_ENV *, int *, db_timeout_t *));
+ */
+int
+__memp_get_mp_max_write(dbenv, maxwritep, maxwrite_sleepp)
+	DB_ENV *dbenv;
+	int *maxwritep;
+	db_timeout_t *maxwrite_sleepp;
+{
+	DB_MPOOL *dbmp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_mp_max_write", DB_INIT_MPOOL);
+
+	if (MPOOL_ON(env)) {
+		dbmp = env->mp_handle;
+		mp = dbmp->reginfo[0].primary;
+		ENV_ENTER(env, ip);
+		MPOOL_SYSTEM_LOCK(env);
+		*maxwritep = mp->mp_maxwrite;
+		*maxwrite_sleepp = mp->mp_maxwrite_sleep;
+		MPOOL_SYSTEM_UNLOCK(env);
+		ENV_LEAVE(env, ip);
+	} else {
+		*maxwritep = dbenv->mp_maxwrite;
+		*maxwrite_sleepp = dbenv->mp_maxwrite_sleep;
+	}
+	return (0);
+}
+
+/*
+ * __memp_set_mp_max_write --
+ *	Set the maximum continuous I/O count.
+ *
+ * PUBLIC: int __memp_set_mp_max_write __P((DB_ENV *, int, db_timeout_t));
+ */
+int
+__memp_set_mp_max_write(dbenv, maxwrite, maxwrite_sleep)
+	DB_ENV *dbenv;
+	int maxwrite;
+	db_timeout_t maxwrite_sleep;
+{
+	DB_MPOOL *dbmp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_mp_max_write", DB_INIT_MPOOL);
+
+	if (MPOOL_ON(env)) {
+		dbmp = env->mp_handle;
+		mp = dbmp->reginfo[0].primary;
+		ENV_ENTER(env, ip);
+		MPOOL_SYSTEM_LOCK(env);
+		mp->mp_maxwrite = maxwrite;
+		mp->mp_maxwrite_sleep = maxwrite_sleep;
+		MPOOL_SYSTEM_UNLOCK(env);
+		ENV_LEAVE(env, ip);
+	} else {
+		dbenv->mp_maxwrite = maxwrite;
+		dbenv->mp_maxwrite_sleep = maxwrite_sleep;
+	}
+	return (0);
+}
+
+/*
+ * PUBLIC: int __memp_get_mp_mmapsize __P((DB_ENV *, size_t *));
+ */
+int
+__memp_get_mp_mmapsize(dbenv, mp_mmapsizep)
+	DB_ENV *dbenv;
+	size_t *mp_mmapsizep;
+{
+	DB_MPOOL *dbmp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_mp_max_mmapsize", DB_INIT_MPOOL);
+
+	if (MPOOL_ON(env)) {
+		dbmp = env->mp_handle;
+		mp = dbmp->reginfo[0].primary;
+		ENV_ENTER(env, ip);
+		MPOOL_SYSTEM_LOCK(env);
+		*mp_mmapsizep = mp->mp_mmapsize;
+		MPOOL_SYSTEM_UNLOCK(env);
+		ENV_LEAVE(env, ip);
+	} else
+		*mp_mmapsizep = dbenv->mp_mmapsize;
+	return (0);
+}
+
+/*
+ * __memp_set_mp_mmapsize --
+ *	DB_ENV->set_mp_mmapsize.
+ *
+ * PUBLIC: int __memp_set_mp_mmapsize __P((DB_ENV *, size_t));
+ */
+int
+__memp_set_mp_mmapsize(dbenv, mp_mmapsize)
+	DB_ENV *dbenv;
+	size_t mp_mmapsize;
+{
+	DB_MPOOL *dbmp;
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->set_mp_max_mmapsize", DB_INIT_MPOOL);
+
+	if (MPOOL_ON(env)) {
+		dbmp = env->mp_handle;
+		mp = dbmp->reginfo[0].primary;
+		ENV_ENTER(env, ip);
+		MPOOL_SYSTEM_LOCK(env);
+		/*
+		 * We need to cast here because size_t and db_size_t can be
+		 * different on a 64 bit build, when building in 32 bit
+		 * compatibility mode. The cast is safe, because we check for
+		 * overflow when the fields are assigned.
+		 */
+		mp->mp_mmapsize = (db_size_t)mp_mmapsize;
+		MPOOL_SYSTEM_UNLOCK(env);
+		ENV_LEAVE(env, ip);
+	} else
+		dbenv->mp_mmapsize = (db_size_t)mp_mmapsize;
+	return (0);
+}
+
+/*
+ * PUBLIC: int __memp_get_mp_pagesize __P((DB_ENV *, u_int32_t *));
+ */
+int
+__memp_get_mp_pagesize(dbenv, mp_pagesizep)
+	DB_ENV *dbenv;
+	u_int32_t *mp_pagesizep;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_mp_max_pagesize", DB_INIT_MPOOL);
+
+	if (MPOOL_ON(env)) {
+		dbmp = env->mp_handle;
+		mp = dbmp->reginfo[0].primary;
+		*mp_pagesizep = mp->pagesize;
+	} else {
+		*mp_pagesizep = dbenv->mp_pagesize;
+	}
+	return (0);
+}
+
+/*
+ * __memp_set_mp_pagesize --
+ *	DB_ENV->set_mp_pagesize.
+ *
+ * PUBLIC: int __memp_set_mp_pagesize __P((DB_ENV *, u_int32_t));
+ */
+int
+__memp_set_mp_pagesize(dbenv, mp_pagesize)
+	DB_ENV *dbenv;
+	u_int32_t mp_pagesize;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_mp_max_mmapsize", DB_INIT_MPOOL);
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_mp_pagesize");
+
+	dbenv->mp_pagesize = mp_pagesize;
+	return (0);
+}
+
+/*
+ * PUBLIC: int __memp_get_mp_tablesize __P((DB_ENV *, u_int32_t *));
+ */
+int
+__memp_get_mp_tablesize(dbenv, mp_tablesizep)
+	DB_ENV *dbenv;
+	u_int32_t *mp_tablesizep;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_mp_max_tablesize", DB_INIT_MPOOL);
+
+	if (MPOOL_ON(env)) {
+		dbmp = env->mp_handle;
+		mp = dbmp->reginfo[0].primary;
+		*mp_tablesizep = mp->htab_buckets;
+	} else
+		*mp_tablesizep = dbenv->mp_tablesize;
+	return (0);
+}
+
+/*
+ * __memp_set_mp_tablesize --
+ *	DB_ENV->set_mp_tablesize.
+ *
+ * PUBLIC: int __memp_set_mp_tablesize __P((DB_ENV *, u_int32_t));
+ */
+int
+__memp_set_mp_tablesize(dbenv, mp_tablesize)
+	DB_ENV *dbenv;
+	u_int32_t mp_tablesize;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_mp_max_mmapsize", DB_INIT_MPOOL);
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_mp_tablesize");
+
+	dbenv->mp_tablesize = mp_tablesize;
+	return (0);
+}
+
+/*
+ * PUBLIC: int __memp_get_mp_mtxcount __P((DB_ENV *, u_int32_t *));
+ */
+int
+__memp_get_mp_mtxcount(dbenv, mp_mtxcountp)
+	DB_ENV *dbenv;
+	u_int32_t *mp_mtxcountp;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOL *mp;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_mp_max_mtxcount", DB_INIT_MPOOL);
+
+	if (MPOOL_ON(env)) {
+		dbmp = env->mp_handle;
+		mp = dbmp->reginfo[0].primary;
+		*mp_mtxcountp = mp->htab_mutexes;
+	} else
+		*mp_mtxcountp = dbenv->mp_mtxcount;
+	return (0);
+}
+
+/*
+ * __memp_set_mp_mtxcount --
+ *	DB_ENV->set_mp_mtxcount.
+ *
+ * PUBLIC: int __memp_set_mp_mtxcount __P((DB_ENV *, u_int32_t));
+ */
+int
+__memp_set_mp_mtxcount(dbenv, mp_mtxcount)
+	DB_ENV *dbenv;
+	u_int32_t mp_mtxcount;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_mp_max_mmapsize", DB_INIT_MPOOL);
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_mp_mtxcount");
+
+	dbenv->mp_mtxcount = mp_mtxcount;
+	return (0);
+}
+
+/*
+ * __memp_nameop
+ *	Remove or rename a file in the pool.
+ *
+ * PUBLIC: int __memp_nameop __P((ENV *,
+ * PUBLIC:     u_int8_t *, const char *, const char *, const char *, int));
+ *
+ * XXX
+ * Undocumented interface: DB private.
+ */
+int
+__memp_nameop(env, fileid, newname, fullold, fullnew, inmem)
+	ENV *env;
+	u_int8_t *fileid;
+	const char *newname, *fullold, *fullnew;
+	int inmem;
+{
+	DB_MPOOL *dbmp;
+	DB_MPOOL_HASH *hp, *nhp;
+	MPOOL *mp;
+	MPOOLFILE *mfp;
+	roff_t newname_off;
+	u_int32_t bucket;
+	int locked, ret;
+	size_t nlen;
+	void *p;
+
+#undef	op_is_remove
+#define	op_is_remove	(newname == NULL)
+
+	COMPQUIET(bucket, 0);
+	COMPQUIET(hp, NULL);
+	COMPQUIET(newname_off, 0);
+	COMPQUIET(nlen, 0);
+
+	dbmp = NULL;
+	mfp = NULL;
+	nhp = NULL;
+	p = NULL;
+	locked = ret = 0;
+
+	if (!MPOOL_ON(env))
+		goto fsop;
+
+	dbmp = env->mp_handle;
+	mp = dbmp->reginfo[0].primary;
+	hp = R_ADDR(dbmp->reginfo, mp->ftab);
+
+	if (!op_is_remove) {
+		nlen = strlen(newname);
+		if ((ret = __memp_alloc(dbmp, dbmp->reginfo,
+		    NULL,  nlen + 1, &newname_off, &p)) != 0)
+			return (ret);
+		memcpy(p, newname, nlen + 1);
+	}
+
+	/*
+	 * Remove or rename a file that the mpool might know about.  We assume
+	 * that the fop layer has the file locked for exclusive access, so we
+	 * don't worry about locking except for the mpool mutexes.  Checkpoint
+	 * can happen at any time, independent of file locking, so we have to
+	 * do the actual unlink or rename system call while holding
+	 * all affected buckets locked.
+	 *
+	 * If this is a rename and this is a memory file then we need
+	 * to make sure that the new name does not exist.  Since we
+	 * are locking two buckets lock them in ascending order.
+	 */
+	if (inmem) {
+		DB_ASSERT(env, fullold != NULL);
+		hp += FNBUCKET(fullold, strlen(fullold));
+		if (!op_is_remove) {
+			bucket = FNBUCKET(newname, nlen);
+			nhp = R_ADDR(dbmp->reginfo, mp->ftab);
+			nhp += bucket;
+		}
+	} else
+		hp += FNBUCKET(fileid, DB_FILE_ID_LEN);
+
+	if (nhp != NULL && nhp < hp)
+		MUTEX_LOCK(env, nhp->mtx_hash);
+	MUTEX_LOCK(env, hp->mtx_hash);
+	if (nhp != NULL && nhp > hp)
+		MUTEX_LOCK(env, nhp->mtx_hash);
+	locked = 1;
+
+	if (!op_is_remove && inmem) {
+		SH_TAILQ_FOREACH(mfp, &nhp->hash_bucket, q, __mpoolfile)
+			if (!mfp->deadfile &&
+			    mfp->no_backing_file && strcmp(newname,
+			    R_ADDR(dbmp->reginfo, mfp->path_off)) == 0)
+				break;
+		if (mfp != NULL) {
+			ret = EEXIST;
+			goto err;
+		}
+	}
+
+	/*
+	 * Find the file -- if mpool doesn't know about this file, that may
+	 * not be an error.
+	 */
+	SH_TAILQ_FOREACH(mfp, &hp->hash_bucket, q, __mpoolfile) {
+		/* Ignore non-active files. */
+		if (mfp->deadfile || F_ISSET(mfp, MP_TEMP))
+			continue;
+
+		/* Try to match on fileid. */
+		if (memcmp(fileid, R_ADDR(
+		    dbmp->reginfo, mfp->fileid_off), DB_FILE_ID_LEN) != 0)
+			continue;
+
+		break;
+	}
+
+	if (mfp == NULL) {
+		if (inmem) {
+			ret = ENOENT;
+			goto err;
+		}
+		goto fsop;
+	}
+
+	if (op_is_remove) {
+		MUTEX_LOCK(env, mfp->mutex);
+		/*
+		 * In-memory dbs have an artificially incremented ref count so
+		 * they do not get reclaimed as long as they exist.  Since we
+		 * are now deleting the database, we need to dec that count.
+		 */
+		if (mfp->no_backing_file)
+			mfp->mpf_cnt--;
+		mfp->deadfile = 1;
+		MUTEX_UNLOCK(env, mfp->mutex);
+	} else {
+		/*
+		 * Else, it's a rename.  We've allocated memory for the new
+		 * name.  Swap it with the old one.  If it's in memory we
+		 * need to move it the right bucket.
+		 */
+		p = R_ADDR(dbmp->reginfo, mfp->path_off);
+		mfp->path_off = newname_off;
+
+		if (inmem && hp != nhp) {
+			DB_ASSERT(env, nhp != NULL);
+			SH_TAILQ_REMOVE(&hp->hash_bucket, mfp, q, __mpoolfile);
+			mfp->bucket = bucket;
+			SH_TAILQ_INSERT_TAIL(&nhp->hash_bucket, mfp, q);
+		}
+	}
+
+fsop:	/*
+	 * If this is a real file, then mfp could be NULL, because
+	 * mpool isn't turned on, and we still need to do the file ops.
+	 */
+	if (mfp == NULL || !mfp->no_backing_file) {
+		if (op_is_remove) {
+			/*
+			 * !!!
+			 * Replication may ask us to unlink a file that's been
+			 * renamed.  Don't complain if it doesn't exist.
+			 */
+			if ((ret = __os_unlink(env, fullold, 0)) == ENOENT)
+				ret = 0;
+		} else {
+			/*
+			 * Defensive only, fullnew should never be
+			 * NULL.
+			 */
+			DB_ASSERT(env, fullnew != NULL);
+			if (fullnew == NULL) {
+				ret = EINVAL;
+				goto err;
+			}
+			ret = __os_rename(env, fullold, fullnew, 1);
+		}
+	}
+
+	/* Delete the memory we no longer need. */
+err:	if (p != NULL) {
+		MPOOL_REGION_LOCK(env, &dbmp->reginfo[0]);
+		__memp_free(&dbmp->reginfo[0], p);
+		MPOOL_REGION_UNLOCK(env, &dbmp->reginfo[0]);
+	}
+
+	/* If we have buckets locked, unlock them when done moving files. */
+	if (locked == 1) {
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+		if (nhp != NULL && nhp != hp)
+			MUTEX_UNLOCK(env, nhp->mtx_hash);
+	}
+	return (ret);
+}
+
+/*
+ * __memp_ftruncate __
+ *	Truncate the file.
+ *
+ * PUBLIC: int __memp_ftruncate __P((DB_MPOOLFILE *, DB_TXN *,
+ * PUBLIC:     DB_THREAD_INFO *, db_pgno_t, u_int32_t));
+ */
+int
+__memp_ftruncate(dbmfp, txn, ip, pgno, flags)
+	DB_MPOOLFILE *dbmfp;
+	DB_TXN *txn;
+	DB_THREAD_INFO *ip;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	ENV *env;
+	MPOOLFILE *mfp;
+	void *pagep;
+	db_pgno_t last_pgno, pg;
+	int ret;
+
+	env = dbmfp->env;
+	mfp = dbmfp->mfp;
+	ret = 0;
+
+	MUTEX_LOCK(env, mfp->mutex);
+	last_pgno = mfp->last_pgno;
+	MUTEX_UNLOCK(env, mfp->mutex);
+
+	if (pgno > last_pgno) {
+		if (LF_ISSET(MP_TRUNC_RECOVER))
+			return (0);
+		__db_errx(env, DB_STR("3005",
+		    "Truncate beyond the end of file"));
+		return (EINVAL);
+	}
+
+	pg = pgno;
+	if (!LF_ISSET(MP_TRUNC_NOCACHE))
+		do {
+			if (mfp->block_cnt == 0)
+				break;
+			if ((ret = __memp_fget(dbmfp, &pg,
+			    ip, txn, DB_MPOOL_FREE, &pagep)) != 0)
+				return (ret);
+		} while (pg++ < last_pgno);
+
+	/*
+	 * If we are aborting an extend of a file, the call to __os_truncate
+	 * could extend the file if the new page(s) had not yet been
+	 * written to disk.  We do not want to extend the file to pages
+	 * whose log records are not yet flushed [#14031].  In addition if
+	 * we are out of disk space we can generate an error [#12743].
+	 */
+	MUTEX_LOCK(env, mfp->mutex);
+	if (!F_ISSET(mfp, MP_TEMP) &&
+	    !mfp->no_backing_file && pgno <= mfp->last_flushed_pgno)
+#ifdef HAVE_FTRUNCATE
+		ret = __os_truncate(env,
+		    dbmfp->fhp, pgno, mfp->pagesize);
+#else
+		ret = __db_zero_extend(env,
+		    dbmfp->fhp, pgno, mfp->last_pgno, mfp->pagesize);
+#endif
+
+	/*
+	 * This set could race with another thread of control that extending
+	 * the file.  It's not a problem because we should have the page
+	 * locked at a higher level of the system.
+	 */
+	if (ret == 0) {
+		mfp->last_pgno = pgno - 1;
+		if (mfp->last_flushed_pgno > mfp->last_pgno)
+			mfp->last_flushed_pgno = mfp->last_pgno;
+	}
+	MUTEX_UNLOCK(env, mfp->mutex);
+
+	return (ret);
+}
+
+#ifdef HAVE_FTRUNCATE
+/*
+ * Support routines for maintaining a sorted freelist while we try to rearrange
+ * and truncate the file.
+ */
+
+/*
+ * __memp_alloc_freelist --
+ *	Allocate mpool space for the freelist.
+ *
+ * PUBLIC: int __memp_alloc_freelist __P((DB_MPOOLFILE *,
+ * PUBLIC:	 u_int32_t, db_pgno_t **));
+ */
+int
+__memp_alloc_freelist(dbmfp, nelems, listp)
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t nelems;
+	db_pgno_t **listp;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOLFILE *mfp;
+	void *retp;
+	int ret;
+
+	env = dbmfp->env;
+	dbmp = env->mp_handle;
+	mfp = dbmfp->mfp;
+
+	*listp = NULL;
+
+	/*
+	 * These fields are protected because the database layer
+	 * has the metapage locked while manipulating them.
+	 */
+	mfp->free_ref++;
+	if (mfp->free_size != 0)
+		return (EBUSY);
+
+	/* Allocate at least a few slots. */
+	mfp->free_cnt = nelems;
+	if (nelems == 0)
+		nelems = 50;
+
+	if ((ret = __memp_alloc(dbmp, dbmp->reginfo,
+	    NULL, nelems * sizeof(db_pgno_t), &mfp->free_list, &retp)) != 0)
+		return (ret);
+
+	mfp->free_size = nelems * sizeof(db_pgno_t);
+	*listp = retp;
+	return (0);
+}
+
+/*
+ * __memp_free_freelist --
+ *	Free the list.
+ *
+ * PUBLIC: int __memp_free_freelist __P((DB_MPOOLFILE *));
+ */
+int
+__memp_free_freelist(dbmfp)
+	DB_MPOOLFILE *dbmfp;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOLFILE *mfp;
+
+	env = dbmfp->env;
+	dbmp = env->mp_handle;
+	mfp = dbmfp->mfp;
+
+	DB_ASSERT(env, mfp->free_ref > 0);
+	if (--mfp->free_ref > 0)
+		return (0);
+
+	DB_ASSERT(env, mfp->free_size != 0);
+
+	MPOOL_SYSTEM_LOCK(env);
+	__memp_free(dbmp->reginfo, R_ADDR(dbmp->reginfo, mfp->free_list));
+	MPOOL_SYSTEM_UNLOCK(env);
+
+	mfp->free_cnt = 0;
+	mfp->free_list = 0;
+	mfp->free_size = 0;
+	return (0);
+}
+
+/*
+ * __memp_get_freelst --
+ *	Return current list.
+ *
+ * PUBLIC: int __memp_get_freelist __P((
+ * PUBLIC:	DB_MPOOLFILE *, u_int32_t *, db_pgno_t **));
+ */
+int
+__memp_get_freelist(dbmfp, nelemp, listp)
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t *nelemp;
+	db_pgno_t **listp;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOLFILE *mfp;
+
+	env = dbmfp->env;
+	dbmp = env->mp_handle;
+	mfp = dbmfp->mfp;
+
+	if (mfp->free_size == 0) {
+		*nelemp = 0;
+		*listp = NULL;
+	} else {
+		*nelemp = mfp->free_cnt;
+		*listp = R_ADDR(dbmp->reginfo, mfp->free_list);
+	}
+
+	return (0);
+}
+
+/*
+ * __memp_extend_freelist --
+ *	Extend the list.
+ *
+ * PUBLIC: int __memp_extend_freelist __P((
+ * PUBLIC:	DB_MPOOLFILE *, u_int32_t , db_pgno_t **));
+ */
+int
+__memp_extend_freelist(dbmfp, count, listp)
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t count;
+	db_pgno_t **listp;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOLFILE *mfp;
+	int ret;
+	size_t size;
+	void *retp;
+
+	env = dbmfp->env;
+	dbmp = env->mp_handle;
+	mfp = dbmfp->mfp;
+
+	if (mfp->free_size == 0)
+		return (EINVAL);
+
+	if (count * sizeof(db_pgno_t) > mfp->free_size) {
+		size = (size_t)DB_ALIGN(count * sizeof(db_pgno_t), 512);
+#ifdef HAVE_MIXED_SIZE_ADDRESSING
+		if (size >= 0xFFFFFFFF) {
+			__db_errx(env, DB_STR("3006",
+			    "Can't get the required free size while"
+			    "operating in mixed-size-addressing mode"));
+			return EINVAL;
+		}
+#endif
+		*listp = R_ADDR(dbmp->reginfo, mfp->free_list);
+		if ((ret = __memp_alloc(dbmp, dbmp->reginfo,
+		    NULL, size, &mfp->free_list, &retp)) != 0)
+			return (ret);
+		mfp->free_size = (db_size_t)size;
+
+		memcpy(retp, *listp, mfp->free_cnt * sizeof(db_pgno_t));
+
+		MPOOL_SYSTEM_LOCK(env);
+		__memp_free(dbmp->reginfo, *listp);
+		MPOOL_SYSTEM_UNLOCK(env);
+	}
+
+	mfp->free_cnt = count;
+	*listp = R_ADDR(dbmp->reginfo, mfp->free_list);
+
+	return (0);
+}
+#endif
+
+/*
+ * __memp_set_last_pgno -- set the last page of the file
+ *
+ * PUBLIC: int __memp_set_last_pgno __P((DB_MPOOLFILE *, db_pgno_t));
+ */
+int
+__memp_set_last_pgno(dbmfp, pgno)
+	DB_MPOOLFILE *dbmfp;
+	db_pgno_t pgno;
+{
+	MPOOLFILE *mfp;
+
+	mfp = dbmfp->mfp;
+
+	if (mfp->mpf_cnt == 1) {
+		MUTEX_LOCK(dbmfp->env, mfp->mutex);
+		if (mfp->mpf_cnt == 1)
+			dbmfp->mfp->last_pgno = pgno;
+		MUTEX_UNLOCK(dbmfp->env, mfp->mutex);
+	}
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_region.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,642 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/mp.h"
+
+static int	__memp_init_config __P((ENV *, MPOOL *));
+static void	__memp_region_size __P((ENV *, roff_t *, u_int32_t *));
+
+#define	MPOOL_DEFAULT_PAGESIZE	(4 * 1024)
+
+/*
+ * __memp_open --
+ *	Internal version of memp_open: only called from ENV->open.
+ *
+ * PUBLIC: int __memp_open __P((ENV *, int));
+ */
+int
+__memp_open(env, create_ok)
+	ENV *env;
+	int create_ok;
+{
+	DB_ENV *dbenv;
+	DB_MPOOL *dbmp;
+	MPOOL *mp, *mp_i;
+	REGINFO reginfo;
+	roff_t cache_size, max_size, reg_size;
+	u_int i, max_nreg;
+	u_int32_t htab_buckets, *regids;
+	int ret;
+
+	dbenv = env->dbenv;
+	cache_size = 0;
+
+	/* Calculate the region size and hash bucket count. */
+	__memp_region_size(env, &max_size, &htab_buckets);
+
+	/* Create and initialize the DB_MPOOL structure. */
+	if ((ret = __os_calloc(env, 1, sizeof(*dbmp), &dbmp)) != 0)
+		return (ret);
+	LIST_INIT(&dbmp->dbregq);
+	TAILQ_INIT(&dbmp->dbmfq);
+	dbmp->env = env;
+
+	/* Join/create the first mpool region. */
+	memset(&reginfo, 0, sizeof(REGINFO));
+	reginfo.env = env;
+	reginfo.type = REGION_TYPE_MPOOL;
+	reginfo.id = INVALID_REGION_ID;
+	reginfo.flags = REGION_JOIN_OK;
+
+	/* Calculate the minimum allocation. */
+	reg_size = sizeof(MPOOL);
+	reg_size += MPOOL_FILE_BUCKETS * sizeof(DB_MPOOL_HASH);
+	reg_size += htab_buckets * sizeof(DB_MPOOL_HASH);
+	reg_size += (dbenv->mp_pagesize == 0 ?
+		MPOOL_DEFAULT_PAGESIZE : dbenv->mp_pagesize) * 10;
+	if (reg_size > max_size)
+		reg_size = max_size;
+
+	if (create_ok)
+		F_SET(&reginfo, REGION_CREATE_OK);
+	if ((ret = __env_region_attach(env, &reginfo, reg_size, max_size)) != 0)
+		goto err;
+	cache_size = reginfo.rp->max;
+	if (F_ISSET(env, ENV_PRIVATE))
+		reginfo.max_alloc = reginfo.rp->max;
+
+	/*
+	 * If we created the region, initialize it.  Create or join any
+	 * additional regions.
+	 */
+	if (F_ISSET(&reginfo, REGION_CREATE)) {
+		/*
+		 * We define how many regions there are going to be, allocate
+		 * the REGINFO structures and create them.  Make sure we don't
+		 * clear the wrong entries on error.
+		 */
+		max_nreg = __memp_max_regions(env);
+		if ((ret = __os_calloc(env,
+		    max_nreg, sizeof(REGINFO), &dbmp->reginfo)) != 0)
+			goto err;
+		/* Make sure we don't clear the wrong entries on error. */
+		dbmp->reginfo[0] = reginfo;
+		for (i = 1; i < max_nreg; ++i)
+			dbmp->reginfo[i].id = INVALID_REGION_ID;
+
+		/* Initialize the first region. */
+		if ((ret = __memp_init(env, dbmp,
+		    0, htab_buckets, max_nreg)) != 0)
+			goto err;
+
+		/*
+		 * Create/initialize remaining regions and copy their IDs into
+		 * the first region.
+		 */
+		mp = R_ADDR(dbmp->reginfo, dbmp->reginfo[0].rp->primary);
+		regids = R_ADDR(dbmp->reginfo, mp->regids);
+		regids[0] = dbmp->reginfo[0].id;
+		for (i = 1; i < dbenv->mp_ncache; ++i) {
+			dbmp->reginfo[i].env = env;
+			dbmp->reginfo[i].type = REGION_TYPE_MPOOL;
+			dbmp->reginfo[i].id = INVALID_REGION_ID;
+			dbmp->reginfo[i].flags = REGION_CREATE_OK;
+			if ((ret = __env_region_attach(
+			    env, &dbmp->reginfo[i], reg_size, max_size)) != 0)
+				goto err;
+			if (F_ISSET(env, ENV_PRIVATE))
+				dbmp->reginfo[i].max_alloc = max_size;
+			cache_size += dbmp->reginfo[i].rp->max;
+			if ((ret = __memp_init(env, dbmp,
+			    i, htab_buckets, max_nreg)) != 0)
+				goto err;
+
+			regids[i] = dbmp->reginfo[i].id;
+		}
+		mp->gbytes = (u_int32_t) (cache_size / GIGABYTE);
+		mp->bytes = (u_int32_t) (cache_size % GIGABYTE);
+	} else {
+		/*
+		 * Determine how many regions there are going to be, allocate
+		 * the REGINFO structures and fill in local copies of that
+		 * information.
+		 */
+		mp = R_ADDR(&reginfo, reginfo.rp->primary);
+		dbenv->mp_ncache = mp->nreg;
+		if ((ret = __os_calloc(env,
+		    mp->max_nreg, sizeof(REGINFO), &dbmp->reginfo)) != 0)
+			goto err;
+		/* Make sure we don't clear the wrong entries on error. */
+		for (i = 0; i < dbenv->mp_ncache; ++i)
+			dbmp->reginfo[i].id = INVALID_REGION_ID;
+		dbmp->reginfo[0] = reginfo;
+
+		/* Join remaining regions. */
+		regids = R_ADDR(dbmp->reginfo, mp->regids);
+		for (i = 1; i < dbenv->mp_ncache; ++i) {
+			dbmp->reginfo[i].env = env;
+			dbmp->reginfo[i].type = REGION_TYPE_MPOOL;
+			dbmp->reginfo[i].id = regids[i];
+			dbmp->reginfo[i].flags = REGION_JOIN_OK;
+			if ((ret = __env_region_attach(
+			    env, &dbmp->reginfo[i], 0, 0)) != 0)
+				goto err;
+		}
+	}
+
+	/* Set the local addresses for the regions. */
+	for (i = 0; i < dbenv->mp_ncache; ++i) {
+		mp_i = dbmp->reginfo[i].primary =
+		    R_ADDR(&dbmp->reginfo[i], dbmp->reginfo[i].rp->primary);
+		dbmp->reginfo[i].mtx_alloc = mp_i->mtx_region;
+	}
+
+	/* If the region is threaded, allocate a mutex to lock the handles. */
+	if ((ret = __mutex_alloc(env,
+	    MTX_MPOOL_HANDLE, DB_MUTEX_PROCESS_ONLY, &dbmp->mutex)) != 0)
+		goto err;
+
+	env->mp_handle = dbmp;
+
+	/* A process joining the region may reset the mpool configuration. */
+	if ((ret = __memp_init_config(env, mp)) != 0)
+		return (ret);
+
+	return (0);
+
+err:	env->mp_handle = NULL;
+	if (dbmp->reginfo != NULL && dbmp->reginfo[0].addr != NULL) {
+		for (i = 0; i < dbenv->mp_ncache; ++i)
+			if (dbmp->reginfo[i].id != INVALID_REGION_ID)
+				(void)__env_region_detach(
+				    env, &dbmp->reginfo[i], 0);
+		__os_free(env, dbmp->reginfo);
+	}
+
+	(void)__mutex_free(env, &dbmp->mutex);
+	__os_free(env, dbmp);
+	return (ret);
+}
+
+/*
+ * __memp_init --
+ *	Initialize a MPOOL structure in shared memory.
+ *
+ * PUBLIC: int	__memp_init
+ * PUBLIC:     __P((ENV *, DB_MPOOL *, u_int, u_int32_t, u_int));
+ */
+int
+__memp_init(env, dbmp, reginfo_off, htab_buckets, max_nreg)
+	ENV *env;
+	DB_MPOOL *dbmp;
+	u_int reginfo_off, max_nreg;
+	u_int32_t htab_buckets;
+{
+	BH *frozen_bhp;
+	BH_FROZEN_ALLOC *frozen;
+	DB_ENV *dbenv;
+	DB_MPOOL_HASH *htab, *hp;
+	MPOOL *mp, *main_mp;
+	REGINFO *infop;
+	db_mutex_t mtx_base, mtx_discard, mtx_prev;
+	u_int32_t i;
+	int ret;
+	void *p;
+
+	dbenv = env->dbenv;
+
+	infop = &dbmp->reginfo[reginfo_off];
+	if ((ret = __env_alloc(infop, sizeof(MPOOL), &infop->primary)) != 0)
+		goto mem_err;
+	infop->rp->primary = R_OFFSET(infop, infop->primary);
+	mp = infop->primary;
+	memset(mp, 0, sizeof(*mp));
+
+	if ((ret =
+	    __mutex_alloc(env, MTX_MPOOL_REGION, 0, &mp->mtx_region)) != 0)
+		return (ret);
+
+	if (reginfo_off == 0) {
+		ZERO_LSN(mp->lsn);
+
+		mp->nreg = dbenv->mp_ncache;
+		mp->max_nreg = max_nreg;
+		if ((ret = __env_alloc(&dbmp->reginfo[0],
+		    max_nreg * sizeof(u_int32_t), &p)) != 0)
+			goto mem_err;
+		mp->regids = R_OFFSET(dbmp->reginfo, p);
+		mp->nbuckets = dbenv->mp_ncache * htab_buckets;
+
+		/* Allocate file table space and initialize it. */
+		if ((ret = __env_alloc(infop,
+		    MPOOL_FILE_BUCKETS * sizeof(DB_MPOOL_HASH), &htab)) != 0)
+			goto mem_err;
+		mp->ftab = R_OFFSET(infop, htab);
+		for (i = 0; i < MPOOL_FILE_BUCKETS; i++) {
+			if ((ret = __mutex_alloc(env,
+			     MTX_MPOOL_FILE_BUCKET, 0, &htab[i].mtx_hash)) != 0)
+				return (ret);
+			SH_TAILQ_INIT(&htab[i].hash_bucket);
+			atomic_init(&htab[i].hash_page_dirty, 0);
+		}
+
+		/*
+		 * Allocate all of the hash bucket mutexes up front.  We do
+		 * this so that we don't need to free and reallocate mutexes as
+		 * the cache is resized.
+		 */
+		mtx_base = mtx_prev = MUTEX_INVALID;
+		if (!MUTEX_ON(env) || F_ISSET(env, ENV_PRIVATE))
+			goto no_prealloc;
+		for (i = 0; i < mp->max_nreg * dbenv->mp_mtxcount; i++) {
+			if ((ret = __mutex_alloc(env, MTX_MPOOL_HASH_BUCKET,
+			    DB_MUTEX_SHARED, &mtx_discard)) != 0)
+				return (ret);
+			if (i == 0)
+				mtx_base = mtx_discard;
+			else
+				DB_ASSERT(env, mtx_base == MUTEX_INVALID ||
+				    mtx_discard == mtx_prev + 1);
+			mtx_prev = mtx_discard;
+		}
+	} else {
+		main_mp = dbmp->reginfo[0].primary;
+		htab = R_ADDR(&dbmp->reginfo[0], main_mp->htab);
+		mtx_base = htab[0].mtx_hash;
+	}
+
+	/*
+	 * We preallocated all of the mutexes in a block, so for regions after
+	 * the first, we skip mutexes in use in earlier regions.  Each region
+	 * has the same number of buckets
+	 */
+no_prealloc:
+	if (MUTEX_ON(env))
+		mtx_base += reginfo_off * dbenv->mp_mtxcount;
+
+	/* Allocate hash table space and initialize it. */
+	if ((ret = __env_alloc(infop,
+	    htab_buckets * sizeof(DB_MPOOL_HASH), &htab)) != 0)
+		goto mem_err;
+	mp->htab = R_OFFSET(infop, htab);
+	for (i = 0; i < htab_buckets; i++) {
+		hp = &htab[i];
+		if (!MUTEX_ON(env) || dbenv->mp_mtxcount == 0)
+			hp->mtx_hash = MUTEX_INVALID;
+		else if (F_ISSET(env, ENV_PRIVATE)) {
+			if (i >= dbenv->mp_mtxcount)
+				hp->mtx_hash =
+				    htab[i % dbenv->mp_mtxcount].mtx_hash;
+			else if
+			    ((ret = __mutex_alloc(env, MTX_MPOOL_HASH_BUCKET,
+			    DB_MUTEX_SHARED, &hp->mtx_hash)) != 0)
+				return (ret);
+		} else
+			hp->mtx_hash = mtx_base + (i % dbenv->mp_mtxcount);
+		SH_TAILQ_INIT(&hp->hash_bucket);
+		atomic_init(&hp->hash_page_dirty, 0);
+#ifdef HAVE_STATISTICS
+		hp->hash_io_wait = 0;
+		hp->hash_frozen = hp->hash_thawed = hp->hash_frozen_freed = 0;
+#endif
+		hp->flags = 0;
+		ZERO_LSN(hp->old_reader);
+	}
+	mp->htab_buckets = htab_buckets;
+	mp->htab_mutexes = dbenv->mp_mtxcount;
+	mp->pagesize = dbenv->mp_pagesize == 0 ?
+		MPOOL_DEFAULT_PAGESIZE : dbenv->mp_pagesize;
+
+	SH_TAILQ_INIT(&mp->free_frozen);
+	SH_TAILQ_INIT(&mp->alloc_frozen);
+
+	/*
+	 * Pre-allocate one frozen buffer header.  This avoids situations where
+	 * the cache becomes full of pages and we don't even have the 28 bytes
+	 * (or so) available to allocate a frozen buffer header.
+	 */
+	if ((ret = __env_alloc(infop,
+	    sizeof(BH_FROZEN_ALLOC) + sizeof(BH_FROZEN_PAGE), &frozen)) != 0)
+		goto mem_err;
+	SH_TAILQ_INSERT_TAIL(&mp->alloc_frozen, frozen, links);
+	frozen_bhp = (BH *)(frozen + 1);
+	frozen_bhp->mtx_buf = MUTEX_INVALID;
+	SH_TAILQ_INSERT_TAIL(&mp->free_frozen, frozen_bhp, hq);
+
+	/*
+	 * Only the environment creator knows the total cache size,
+	 * fill in those fields now.
+	 */
+	mp->gbytes = dbenv->mp_gbytes;
+	mp->bytes = dbenv->mp_bytes;
+	infop->mtx_alloc = mp->mtx_region;
+	return (0);
+
+mem_err:__db_errx(env, DB_STR("3026",
+	    "Unable to allocate memory for mpool region"));
+	return (ret);
+}
+
+/*
+ * PUBLIC: u_int32_t __memp_max_regions __P((ENV *));
+ */
+u_int32_t
+__memp_max_regions(env)
+	ENV *env;
+{
+	DB_ENV *dbenv;
+	roff_t reg_size, max_size;
+	size_t max_nreg;
+
+	dbenv = env->dbenv;
+
+	if (dbenv->mp_max_gbytes == 0 && dbenv->mp_max_bytes == 0)
+		return (dbenv->mp_ncache);
+	__memp_region_size(env, &reg_size, NULL);
+	max_size =
+	    (roff_t)dbenv->mp_max_gbytes * GIGABYTE + dbenv->mp_max_bytes;
+	max_nreg = (max_size + reg_size / 2) / reg_size;
+
+	/* Sanity check that the number of regions fits in 32 bits. */
+	DB_ASSERT(env, max_nreg == (u_int32_t)max_nreg);
+
+	if (max_nreg <= dbenv->mp_ncache)
+		max_nreg = dbenv->mp_ncache;
+	return ((u_int32_t)max_nreg);
+}
+
+/*
+ * __memp_region_size --
+ *	Size the region and figure out how many hash buckets we'll have.
+ */
+static void
+__memp_region_size(env, reg_sizep, htab_bucketsp)
+	ENV *env;
+	roff_t *reg_sizep;
+	u_int32_t *htab_bucketsp;
+{
+	DB_ENV *dbenv;
+	roff_t reg_size, cache_size;
+	u_int32_t pgsize;
+
+	dbenv = env->dbenv;
+
+	/*
+	 * Figure out how big each cache region is.  Cast an operand to roff_t
+	 * so we do 64-bit arithmetic as appropriate.
+	 */
+	cache_size = (roff_t)dbenv->mp_gbytes * GIGABYTE + dbenv->mp_bytes;
+	reg_size = cache_size / dbenv->mp_ncache;
+	if (reg_sizep != NULL)
+		*reg_sizep = reg_size;
+
+	/*
+	 * Figure out how many hash buckets each region will have.  Assume we
+	 * want to keep the hash chains with under 3 pages on each chain.  We
+	 * don't know the pagesize in advance, and it may differ for different
+	 * files.  Use a pagesize of 4K for the calculation -- we walk these
+	 * chains a lot, they must be kept short.  We use 2.5 as this maintains
+	 * compatibility with previous releases.
+	 *
+	 * XXX
+	 * Cache sizes larger than 10TB would cause 32-bit wrapping in the
+	 * calculation of the number of hash buckets.  This probably isn't
+	 * something we need to worry about right now, but is checked when the
+	 * cache size is set.
+	 */
+	if (htab_bucketsp != NULL) {
+		if (dbenv->mp_tablesize != 0)
+			*htab_bucketsp = __db_tablesize(dbenv->mp_tablesize);
+		else {
+			if ((pgsize = dbenv->mp_pagesize) == 0)
+				pgsize = MPOOL_DEFAULT_PAGESIZE;
+			*htab_bucketsp = __db_tablesize(
+				(u_int32_t)(reg_size / (2.5 * pgsize)));
+		}
+	}
+
+}
+
+/*
+ * __memp_region_mutex_count --
+ *	Return the number of mutexes the mpool region will need.
+ *
+ * PUBLIC: u_int32_t __memp_region_mutex_count __P((ENV *));
+ */
+u_int32_t
+__memp_region_mutex_count(env)
+	ENV *env;
+{
+	DB_ENV *dbenv;
+	u_int32_t htab_buckets;
+	roff_t reg_size;
+	u_int32_t max_region, num_per_cache, pgsize;
+
+	dbenv = env->dbenv;
+
+	__memp_region_size(env, &reg_size, &htab_buckets);
+	if (F_ISSET(env->dbenv, DB_ENV_MULTIVERSION))
+		pgsize = sizeof(BH_FROZEN_ALLOC) + sizeof(BH_FROZEN_PAGE);
+	if ((pgsize = dbenv->mp_pagesize) == 0)
+		pgsize = MPOOL_DEFAULT_PAGESIZE;
+	max_region = __memp_max_regions(env);
+
+	/*
+	 * We need a couple of mutexes for the region itself, one for each
+	 * file handle (MPOOLFILE) the application allocates, one for each
+	 * of the MPOOL_FILE_BUCKETS, and each cache has one mutex per
+	 * hash bucket. We then need one mutex per page in the cache,
+	 * the worst case is really big if the pages are 512 bytes.
+	 */
+	if (dbenv->mp_mtxcount != 0)
+		htab_buckets = dbenv->mp_mtxcount;
+	else
+		dbenv->mp_mtxcount = htab_buckets;
+	num_per_cache = htab_buckets + (u_int32_t)(reg_size / pgsize);
+	return ((max_region * num_per_cache) + 50 + MPOOL_FILE_BUCKETS);
+}
+
+/*
+ * __memp_init_config --
+ *	Initialize shared configuration information.
+ */
+static int
+__memp_init_config(env, mp)
+	ENV *env;
+	MPOOL *mp;
+{
+	DB_ENV *dbenv;
+
+	dbenv = env->dbenv;
+
+	MPOOL_SYSTEM_LOCK(env);
+	if (dbenv->mp_mmapsize != 0)
+		mp->mp_mmapsize = (db_size_t)dbenv->mp_mmapsize;
+	if (dbenv->mp_maxopenfd != 0)
+		mp->mp_maxopenfd = dbenv->mp_maxopenfd;
+	if (dbenv->mp_maxwrite != 0)
+		mp->mp_maxwrite = dbenv->mp_maxwrite;
+	if (dbenv->mp_maxwrite_sleep != 0)
+		mp->mp_maxwrite_sleep = dbenv->mp_maxwrite_sleep;
+	MPOOL_SYSTEM_UNLOCK(env);
+
+	return (0);
+}
+
+/*
+ * __memp_env_refresh --
+ *	Clean up after the mpool system on a close or failed open.
+ *
+ * PUBLIC: int __memp_env_refresh __P((ENV *));
+ */
+int
+__memp_env_refresh(env)
+	ENV *env;
+{
+	BH *bhp;
+	BH_FROZEN_ALLOC *frozen_alloc;
+	DB_MPOOL *dbmp;
+	DB_MPOOLFILE *dbmfp;
+	DB_MPOOL_HASH *hp;
+	DB_MPREG *mpreg;
+	MPOOL *mp, *c_mp;
+	REGINFO *infop;
+	u_int32_t bucket, i, nreg;
+	int ret, t_ret;
+
+	ret = 0;
+	dbmp = env->mp_handle;
+	mp = dbmp->reginfo[0].primary;
+	nreg = mp->nreg;
+	hp = R_ADDR(&dbmp->reginfo[0], mp->htab);
+
+	/*
+	 * If a private region, return the memory to the heap.  Not needed for
+	 * filesystem-backed or system shared memory regions, that memory isn't
+	 * owned by any particular process.
+	 */
+	if (!F_ISSET(env, ENV_PRIVATE))
+		goto not_priv;
+
+	/* Discard buffers. */
+	for (i = 0; i < nreg; ++i) {
+		infop = &dbmp->reginfo[i];
+		c_mp = infop->primary;
+		for (hp = R_ADDR(infop, c_mp->htab), bucket = 0;
+		    bucket < c_mp->htab_buckets; ++hp, ++bucket) {
+			while ((bhp = SH_TAILQ_FIRST(
+			    &hp->hash_bucket, __bh)) != NULL)
+				if (F_ISSET(bhp, BH_FROZEN))
+					SH_TAILQ_REMOVE(
+					    &hp->hash_bucket, bhp,
+					    hq, __bh);
+				else {
+					if (F_ISSET(bhp, BH_DIRTY)) {
+						atomic_dec(env,
+						     &hp->hash_page_dirty);
+						F_CLR(bhp,
+						    BH_DIRTY | BH_DIRTY_CREATE);
+					}
+					atomic_inc(env, &bhp->ref);
+					if ((t_ret = __memp_bhfree(dbmp, infop,
+					    R_ADDR(dbmp->reginfo,
+					    bhp->mf_offset), hp, bhp,
+					    BH_FREE_FREEMEM |
+					    BH_FREE_UNLOCKED)) != 0 && ret == 0)
+						ret = t_ret;
+				}
+		}
+		MPOOL_REGION_LOCK(env, infop);
+		while ((frozen_alloc = SH_TAILQ_FIRST(
+		    &c_mp->alloc_frozen, __bh_frozen_a)) != NULL) {
+			SH_TAILQ_REMOVE(&c_mp->alloc_frozen, frozen_alloc,
+			    links, __bh_frozen_a);
+			__env_alloc_free(infop, frozen_alloc);
+		}
+		MPOOL_REGION_UNLOCK(env, infop);
+	}
+
+not_priv:
+	/* Discard DB_MPOOLFILEs. */
+	while ((dbmfp = TAILQ_FIRST(&dbmp->dbmfq)) != NULL)
+		if ((t_ret = __memp_fclose(dbmfp, DB_FLUSH)) != 0 && ret == 0)
+			ret = t_ret;
+
+	/* Discard DB_MPREGs. */
+	if (dbmp->pg_inout != NULL)
+		__os_free(env, dbmp->pg_inout);
+	while ((mpreg = LIST_FIRST(&dbmp->dbregq)) != NULL) {
+		LIST_REMOVE(mpreg, q);
+		__os_free(env, mpreg);
+	}
+
+	/* Discard the DB_MPOOL thread mutex. */
+	if ((t_ret = __mutex_free(env, &dbmp->mutex)) != 0 && ret == 0)
+		ret = t_ret;
+
+	if (F_ISSET(env, ENV_PRIVATE)) {
+		/* Discard REGION IDs. */
+		infop = &dbmp->reginfo[0];
+		infop->mtx_alloc = MUTEX_INVALID;
+		__memp_free(infop, R_ADDR(infop, mp->regids));
+
+		/* Discard all the MPOOLFILEs. */
+		if ((t_ret = __memp_discard_all_mpfs(env, mp)) != 0 && ret == 0)
+			ret = t_ret;
+		/* Discard the File table. */
+		__memp_free(infop, R_ADDR(infop, mp->ftab));
+
+		/* Discard Hash tables. */
+		for (i = 0; i < nreg; ++i) {
+			infop = &dbmp->reginfo[i];
+			c_mp = infop->primary;
+			infop->mtx_alloc = MUTEX_INVALID;
+			__memp_free(infop, R_ADDR(infop, c_mp->htab));
+		}
+	}
+
+	/* Detach from the region. */
+	for (i = 0; i < nreg; ++i) {
+		infop = &dbmp->reginfo[i];
+		if ((t_ret =
+		    __env_region_detach(env, infop, 0)) != 0 && ret == 0)
+			ret = t_ret;
+	}
+
+	/* Discard DB_MPOOL. */
+	__os_free(env, dbmp->reginfo);
+	__os_free(env, dbmp);
+
+	env->mp_handle = NULL;
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_register.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,138 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/log.h"
+#include "dbinc/mp.h"
+
+/*
+ * memp_register_pp --
+ *	ENV->memp_register pre/post processing.
+ *
+ * PUBLIC: int __memp_register_pp __P((DB_ENV *, int,
+ * PUBLIC:     int (*)(DB_ENV *, db_pgno_t, void *, DBT *),
+ * PUBLIC:     int (*)(DB_ENV *, db_pgno_t, void *, DBT *)));
+ */
+int
+__memp_register_pp(dbenv, ftype, pgin, pgout)
+	DB_ENV *dbenv;
+	int ftype;
+	int (*pgin) __P((DB_ENV *, db_pgno_t, void *, DBT *));
+	int (*pgout) __P((DB_ENV *, db_pgno_t, void *, DBT *));
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_REQUIRES_CONFIG(env,
+	    env->mp_handle, "DB_ENV->memp_register", DB_INIT_MPOOL);
+
+	if (REP_ON(env)) {
+		__db_errx(env, DB_STR_A("3001",
+		    "%smethod not permitted when replication is configured",
+		    "%s"), "DB_ENV->memp_register: ");
+		return (EINVAL);
+	}
+
+	ENV_ENTER(env, ip);
+	ret = __memp_register(env, ftype, pgin, pgout);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * memp_register --
+ *	ENV->memp_register.
+ *
+ * PUBLIC: int __memp_register __P((ENV *, int,
+ * PUBLIC:     int (*)(DB_ENV *, db_pgno_t, void *, DBT *),
+ * PUBLIC:     int (*)(DB_ENV *, db_pgno_t, void *, DBT *)));
+ */
+int
+__memp_register(env, ftype, pgin, pgout)
+	ENV *env;
+	int ftype;
+	int (*pgin) __P((DB_ENV *, db_pgno_t, void *, DBT *));
+	int (*pgout) __P((DB_ENV *, db_pgno_t, void *, DBT *));
+{
+	DB_MPOOL *dbmp;
+	DB_MPREG *mpreg;
+	int ret;
+
+	dbmp = env->mp_handle;
+
+	/*
+	 * We keep the DB pgin/pgout functions outside of the linked list
+	 * to avoid locking/unlocking the linked list on every page I/O.
+	 *
+	 * The Berkeley DB I/O conversion functions are registered when the
+	 * environment is first created, so there's no need for locking here.
+	 */
+	if (ftype == DB_FTYPE_SET) {
+		if (dbmp->pg_inout != NULL)
+			return (0);
+		if ((ret =
+		    __os_malloc(env, sizeof(DB_MPREG), &dbmp->pg_inout)) != 0)
+			return (ret);
+		dbmp->pg_inout->ftype = ftype;
+		dbmp->pg_inout->pgin = pgin;
+		dbmp->pg_inout->pgout = pgout;
+		return (0);
+	}
+
+	/*
+	 * The item may already have been registered.  If already registered,
+	 * just update the entry, although it's probably unchanged.
+	 */
+	MUTEX_LOCK(env, dbmp->mutex);
+	LIST_FOREACH(mpreg, &dbmp->dbregq, q)
+		if (mpreg->ftype == ftype) {
+			mpreg->pgin = pgin;
+			mpreg->pgout = pgout;
+			break;
+		}
+
+	if (mpreg == NULL) {			/* New entry. */
+		if ((ret = __os_malloc(env, sizeof(DB_MPREG), &mpreg)) != 0)
+			return (ret);
+		mpreg->ftype = ftype;
+		mpreg->pgin = pgin;
+		mpreg->pgout = pgout;
+
+		LIST_INSERT_HEAD(&dbmp->dbregq, mpreg, q);
+	}
+	MUTEX_UNLOCK(env, dbmp->mutex);
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_resize.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,583 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2006, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+static int __memp_add_bucket __P((DB_MPOOL *));
+static int __memp_add_region __P((DB_MPOOL *));
+static int __memp_map_regions __P((DB_MPOOL *));
+static int __memp_merge_buckets
+    __P((DB_MPOOL *, u_int32_t, u_int32_t, u_int32_t));
+static int __memp_remove_bucket __P((DB_MPOOL *));
+static int __memp_remove_region __P((DB_MPOOL *));
+
+/*
+ * PUBLIC: int __memp_get_bucket __P((ENV *, MPOOLFILE *,
+ * PUBLIC:     db_pgno_t, REGINFO **, DB_MPOOL_HASH **, u_int32_t *));
+ */
+int
+__memp_get_bucket(env, mfp, pgno, infopp, hpp, bucketp)
+	ENV *env;
+	MPOOLFILE *mfp;
+	db_pgno_t pgno;
+	REGINFO **infopp;
+	DB_MPOOL_HASH **hpp;
+	u_int32_t *bucketp;
+{
+	DB_MPOOL *dbmp;
+	DB_MPOOL_HASH *hp;
+	MPOOL *c_mp, *mp;
+	REGINFO *infop;
+	roff_t mf_offset;
+	u_int32_t bucket, nbuckets, new_bucket, new_nbuckets, region;
+	u_int32_t *regids;
+	int ret;
+
+	dbmp = env->mp_handle;
+	mf_offset = R_OFFSET(dbmp->reginfo, mfp);
+	mp = dbmp->reginfo[0].primary;
+	ret = 0;
+
+	for (;;) {
+		nbuckets = mp->nbuckets;
+		MP_BUCKET(mf_offset, pgno, nbuckets, bucket);
+
+		/*
+		 * Once we work out which region we are looking in, we have to
+		 * check that we have that region mapped, and that the version
+		 * we have matches the ID in the main mpool region.  Otherwise
+		 * we have to go and map in any regions that don't match and
+		 * retry.
+		 */
+		region = NREGION(mp, bucket);
+		regids = R_ADDR(dbmp->reginfo, mp->regids);
+
+		for (;;) {
+			infop = *infopp = &dbmp->reginfo[region];
+			c_mp = infop->primary;
+
+			/* If we have the correct region mapped, we're done. */
+			if (c_mp != NULL && regids[region] == infop->id)
+				break;
+			if ((ret = __memp_map_regions(dbmp)) != 0)
+				return (ret);
+		}
+
+		/* If our caller wants the hash bucket, lock it here. */
+		if (hpp != NULL) {
+			hp = R_ADDR(infop, c_mp->htab);
+			hp = &hp[bucket - region * mp->htab_buckets];
+
+			MUTEX_READLOCK(env, hp->mtx_hash);
+
+			/*
+			 * Check that we still have the correct region mapped.
+			 */
+			if (regids[region] != infop->id) {
+				MUTEX_UNLOCK(env, hp->mtx_hash);
+				continue;
+			}
+
+			/*
+			 * Now that the bucket is locked, we need to check that
+			 * the cache has not been resized while we waited.
+			 */
+			new_nbuckets = mp->nbuckets;
+			if (nbuckets != new_nbuckets) {
+				MP_BUCKET(mf_offset, pgno, new_nbuckets,
+				    new_bucket);
+
+				if (new_bucket != bucket) {
+					MUTEX_UNLOCK(env, hp->mtx_hash);
+					continue;
+				}
+			}
+
+			*hpp = hp;
+		}
+
+		break;
+	}
+
+	if (bucketp != NULL)
+		*bucketp = bucket - region * mp->htab_buckets;
+	return (ret);
+}
+
+static int
+__memp_merge_buckets(dbmp, new_nbuckets, old_bucket, new_bucket)
+	DB_MPOOL *dbmp;
+	u_int32_t new_nbuckets, old_bucket, new_bucket;
+{
+	BH *alloc_bhp, *bhp, *current_bhp, *new_bhp, *next_bhp;
+	DB_MPOOL_HASH *new_hp, *old_hp;
+	ENV *env;
+	MPOOL *mp, *new_mp, *old_mp;
+	MPOOLFILE *mfp;
+	REGINFO *new_infop, *old_infop;
+	u_int32_t bucket, high_mask, new_region, old_region;
+	int ret;
+
+	env = dbmp->env;
+	mp = dbmp->reginfo[0].primary;
+	new_bhp = NULL;
+	ret = 0;
+
+	MP_MASK(new_nbuckets, high_mask);
+
+	old_region = NREGION(mp, old_bucket);
+	old_infop = &dbmp->reginfo[old_region];
+	old_mp = old_infop->primary;
+	old_hp = R_ADDR(old_infop, old_mp->htab);
+	old_hp = &old_hp[old_bucket - old_region * mp->htab_buckets];
+
+	new_region = NREGION(mp, new_bucket);
+	new_infop = &dbmp->reginfo[new_region];
+	new_mp = new_infop->primary;
+	new_hp = R_ADDR(new_infop, new_mp->htab);
+	new_hp = &new_hp[new_bucket - new_region * mp->htab_buckets];
+
+	/*
+	 * Before merging, we need to check that there are no old buffers left
+	 * in the target hash bucket after a previous split.
+	 */
+free_old:
+	MUTEX_LOCK(env, new_hp->mtx_hash);
+	SH_TAILQ_FOREACH(bhp, &new_hp->hash_bucket, hq, __bh) {
+		MP_BUCKET(bhp->mf_offset, bhp->pgno, mp->nbuckets, bucket);
+
+		if (bucket != new_bucket) {
+			/*
+			 * There is no way that an old buffer can be locked
+			 * after a split, since everyone will look for it in
+			 * the new hash bucket.
+			 */
+			DB_ASSERT(env, !F_ISSET(bhp, BH_DIRTY) &&
+			    atomic_read(&bhp->ref) == 0);
+			atomic_inc(env, &bhp->ref);
+			mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
+			if ((ret = __memp_bhfree(dbmp, new_infop,
+			    mfp, new_hp, bhp, BH_FREE_FREEMEM)) != 0) {
+				MUTEX_UNLOCK(env, new_hp->mtx_hash);
+				return (ret);
+			}
+
+			/*
+			 * The free has modified the list of buffers and
+			 * dropped the mutex.  We need to start again.
+			 */
+			goto free_old;
+		}
+	}
+	MUTEX_UNLOCK(env, new_hp->mtx_hash);
+
+	/*
+	 * Before we begin, make sure that all of the buffers we care about are
+	 * not in use and not frozen.  We do this because we can't drop the old
+	 * hash bucket mutex once we start moving buffers around.
+	 */
+retry:	MUTEX_LOCK(env, old_hp->mtx_hash);
+	SH_TAILQ_FOREACH(bhp, &old_hp->hash_bucket, hq, __bh) {
+		MP_HASH_BUCKET(MP_HASH(bhp->mf_offset, bhp->pgno),
+		    new_nbuckets, high_mask, bucket);
+
+		if (bucket == new_bucket && atomic_read(&bhp->ref) != 0) {
+			MUTEX_UNLOCK(env, old_hp->mtx_hash);
+			__os_yield(env, 0, 0);
+			goto retry;
+		}
+	}
+
+	/*
+	 * We now know that all of the buffers we care about are unlocked and
+	 * unreferenced.  Go ahead and copy them.
+	 */
+	SH_TAILQ_FOREACH(bhp, &old_hp->hash_bucket, hq, __bh) {
+		MP_HASH_BUCKET(MP_HASH(bhp->mf_offset, bhp->pgno),
+		    new_nbuckets, high_mask, bucket);
+		mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
+
+		/*
+		 * We ignore buffers that don't hash to the new bucket.  We
+		 * could also ignore clean buffers which are not part of a
+		 * multiversion chain as long as they have a backing file.
+		 */
+		if (bucket != new_bucket || (!F_ISSET(bhp, BH_DIRTY) &&
+		    SH_CHAIN_SINGLETON(bhp, vc) && !mfp->no_backing_file))
+			continue;
+
+		for (current_bhp = bhp, next_bhp = NULL;
+		    current_bhp != NULL;
+		    current_bhp = SH_CHAIN_PREV(current_bhp, vc, __bh),
+		    next_bhp = alloc_bhp) {
+			/* Allocate in the new region. */
+			if ((ret = __memp_alloc(dbmp,
+			    new_infop, mfp, 0, NULL, &alloc_bhp)) != 0)
+				break;
+
+			alloc_bhp->ref = current_bhp->ref;
+			alloc_bhp->priority = current_bhp->priority;
+			alloc_bhp->pgno = current_bhp->pgno;
+			alloc_bhp->mf_offset = current_bhp->mf_offset;
+			alloc_bhp->flags = current_bhp->flags;
+			alloc_bhp->td_off = current_bhp->td_off;
+
+			/*
+			 * We've duplicated the buffer, so now we need to
+			 * update reference counts, including the counts in the
+			 * per-MPOOLFILE and the transaction detail (for MVCC
+			 * buffers).
+			 */
+			MUTEX_LOCK(env, mfp->mutex);
+			++mfp->block_cnt;
+			MUTEX_UNLOCK(env, mfp->mutex);
+
+			if (alloc_bhp->td_off != INVALID_ROFF &&
+			    (ret = __txn_add_buffer(env,
+			    R_ADDR(&env->tx_handle->reginfo,
+			    alloc_bhp->td_off))) != 0)
+				break;
+
+			memcpy(alloc_bhp->buf, bhp->buf, mfp->pagesize);
+
+			/*
+			 * We build up the MVCC chain first, then insert the
+			 * head (stored in new_bhp) once.
+			 */
+			if (next_bhp == NULL) {
+				SH_CHAIN_INIT(alloc_bhp, vc);
+				new_bhp = alloc_bhp;
+			} else
+				SH_CHAIN_INSERT_BEFORE(
+				    next_bhp, alloc_bhp, vc, __bh);
+		}
+
+		DB_ASSERT(env, new_hp->mtx_hash != old_hp->mtx_hash);
+		MUTEX_LOCK(env, new_hp->mtx_hash);
+		SH_TAILQ_INSERT_TAIL(&new_hp->hash_bucket, new_bhp, hq);
+		if (F_ISSET(new_bhp, BH_DIRTY))
+			atomic_inc(env, &new_hp->hash_page_dirty);
+
+		if (F_ISSET(bhp, BH_DIRTY)) {
+			F_CLR(bhp, BH_DIRTY);
+			atomic_dec(env, &old_hp->hash_page_dirty);
+		}
+		MUTEX_UNLOCK(env, new_hp->mtx_hash);
+	}
+
+	if (ret == 0)
+		mp->nbuckets = new_nbuckets;
+	MUTEX_UNLOCK(env, old_hp->mtx_hash);
+
+	return (ret);
+}
+
+static int
+__memp_add_bucket(dbmp)
+	DB_MPOOL *dbmp;
+{
+	ENV *env;
+	MPOOL *mp;
+	u_int32_t high_mask, new_bucket, old_bucket;
+
+	env = dbmp->env;
+	mp = dbmp->reginfo[0].primary;
+
+	new_bucket = mp->nbuckets;
+	/* We should always be adding buckets to the last region. */
+	DB_ASSERT(env, NREGION(mp, new_bucket) == mp->nreg - 1);
+	MP_MASK(mp->nbuckets, high_mask);
+	old_bucket = new_bucket & (high_mask >> 1);
+
+	/*
+	 * With fixed-sized regions, the new region is always smaller than the
+	 * existing total cache size, so buffers always need to be copied.  If
+	 * we implement variable region sizes, it's possible that we will be
+	 * splitting a hash bucket in the new region.  Catch that here.
+	 */
+	DB_ASSERT(env, NREGION(mp, old_bucket) != NREGION(mp, new_bucket));
+
+	return (__memp_merge_buckets(dbmp, mp->nbuckets + 1,
+	    old_bucket, new_bucket));
+}
+
+static int
+__memp_add_region(dbmp)
+	DB_MPOOL *dbmp;
+{
+	ENV *env;
+	MPOOL *mp;
+	REGINFO *infop;
+	int ret;
+	roff_t cache_size, reg_size;
+	u_int i;
+	u_int32_t *regids;
+
+	env = dbmp->env;
+	mp = dbmp->reginfo[0].primary;
+	cache_size = (roff_t)mp->gbytes * GIGABYTE + mp->bytes;
+
+	/* All cache regions are the same size. */
+	reg_size = dbmp->reginfo[0].rp->size;
+	ret = 0;
+
+	infop = &dbmp->reginfo[mp->nreg];
+	infop->env = env;
+	infop->type = REGION_TYPE_MPOOL;
+	infop->id = INVALID_REGION_ID;
+	infop->flags = REGION_CREATE_OK;
+	if ((ret = __env_region_attach(env, infop, reg_size, reg_size)) != 0)
+		return (ret);
+	if ((ret = __memp_init(env,
+	    dbmp, mp->nreg, mp->htab_buckets, mp->max_nreg)) != 0)
+		return (ret);
+	cache_size += reg_size;
+	mp->gbytes = (u_int32_t)(cache_size / GIGABYTE);
+	mp->bytes = (u_int32_t)(cache_size % GIGABYTE);
+	regids = R_ADDR(dbmp->reginfo, mp->regids);
+	regids[mp->nreg++] = infop->id;
+
+	for (i = 0; i < mp->htab_buckets; i++)
+		if ((ret = __memp_add_bucket(dbmp)) != 0)
+			break;
+
+	return (ret);
+}
+
+static int
+__memp_remove_bucket(dbmp)
+	DB_MPOOL *dbmp;
+{
+	ENV *env;
+	MPOOL *mp;
+	u_int32_t high_mask, new_bucket, old_bucket;
+
+	env = dbmp->env;
+	mp = dbmp->reginfo[0].primary;
+
+	old_bucket = mp->nbuckets - 1;
+
+	/* We should always be removing buckets from the last region. */
+	DB_ASSERT(env, NREGION(mp, old_bucket) == mp->nreg - 1);
+	MP_MASK(mp->nbuckets - 1, high_mask);
+	new_bucket = old_bucket & (high_mask >> 1);
+
+	return (__memp_merge_buckets(dbmp, mp->nbuckets - 1,
+	    old_bucket, new_bucket));
+}
+
+static int
+__memp_remove_region(dbmp)
+	DB_MPOOL *dbmp;
+{
+	DB_MPOOL_HASH *hp;
+	ENV *env;
+	MPOOL *mp;
+	REGINFO *infop;
+	int ret;
+	roff_t cache_size, reg_size;
+	u_int i;
+
+	env = dbmp->env;
+	mp = dbmp->reginfo[0].primary;
+	reg_size = dbmp->reginfo[0].rp->size;
+	cache_size = (roff_t)mp->gbytes * GIGABYTE + mp->bytes;
+	ret = 0;
+
+	if (mp->nreg == 1) {
+		__db_errx(env, DB_STR("3019",
+		    "cannot remove the last cache"));
+		return (EINVAL);
+	}
+
+	for (i = 0; i < mp->htab_buckets; i++)
+		if ((ret = __memp_remove_bucket(dbmp)) != 0)
+			return (ret);
+
+	/* Detach from the region then destroy it. */
+	infop = &dbmp->reginfo[mp->nreg];
+	if (F_ISSET(env, ENV_PRIVATE)) {
+		hp = R_ADDR(infop, ((MPOOL*)infop->primary)->htab);
+		for (i = 0; i < env->dbenv->mp_mtxcount; i++)
+			if ((ret = __mutex_free(env, &hp[i].mtx_hash)) != 0)
+				return (ret);
+	}
+
+	ret = __env_region_detach(env, infop, 1);
+	if  (ret == 0) {
+		mp->nreg--;
+		cache_size -= reg_size;
+		mp->gbytes = (u_int32_t)(cache_size / GIGABYTE);
+		mp->bytes = (u_int32_t)(cache_size % GIGABYTE);
+	}
+
+	return (ret);
+}
+
+static int
+__memp_map_regions(dbmp)
+	DB_MPOOL *dbmp;
+{
+	ENV *env;
+	MPOOL *mp;
+	int ret;
+	u_int i;
+	u_int32_t *regids;
+
+	env = dbmp->env;
+	mp = dbmp->reginfo[0].primary;
+	regids = R_ADDR(dbmp->reginfo, mp->regids);
+	ret = 0;
+
+	for (i = 1; i < mp->nreg; ++i) {
+		if (dbmp->reginfo[i].primary != NULL &&
+		    dbmp->reginfo[i].id == regids[i])
+			continue;
+
+		if (dbmp->reginfo[i].primary != NULL)
+			ret = __env_region_detach(env, &dbmp->reginfo[i], 0);
+
+		dbmp->reginfo[i].env = env;
+		dbmp->reginfo[i].type = REGION_TYPE_MPOOL;
+		dbmp->reginfo[i].id = regids[i];
+		dbmp->reginfo[i].flags = REGION_JOIN_OK;
+		if ((ret =
+		    __env_region_attach(env, &dbmp->reginfo[i], 0, 0)) != 0)
+			return (ret);
+		dbmp->reginfo[i].primary = R_ADDR(&dbmp->reginfo[i],
+		    dbmp->reginfo[i].rp->primary);
+	}
+
+	for (; i < mp->max_nreg; i++)
+		if (dbmp->reginfo[i].primary != NULL &&
+		    (ret = __env_region_detach(env,
+		    &dbmp->reginfo[i], 0)) != 0)
+			break;
+
+	return (ret);
+}
+
+/*
+ * PUBLIC: int __memp_resize __P((DB_MPOOL *, u_int32_t, u_int32_t));
+ */
+int
+__memp_resize(dbmp, gbytes, bytes)
+	DB_MPOOL *dbmp;
+	u_int32_t gbytes, bytes;
+{
+	ENV *env;
+	MPOOL *mp;
+	int ret;
+	u_int32_t ncache;
+	roff_t reg_size, total_size;
+
+	env = dbmp->env;
+	mp = dbmp->reginfo[0].primary;
+	reg_size = dbmp->reginfo[0].rp->size;
+	total_size = (roff_t)gbytes * GIGABYTE + bytes;
+	ncache = (u_int32_t)((total_size + reg_size / 2) / reg_size);
+
+	if (ncache < 1)
+		ncache = 1;
+	else if (ncache > mp->max_nreg) {
+		__db_errx(env, DB_STR_A("3020",
+		    "cannot resize to %lu cache regions: maximum is %lu",
+		    "%lu %lu"), (u_long)ncache, (u_long)mp->max_nreg);
+		return (EINVAL);
+	}
+
+	ret = 0;
+	MUTEX_LOCK(env, mp->mtx_resize);
+	while (mp->nreg != ncache)
+		if ((ret = (mp->nreg < ncache ?
+		    __memp_add_region(dbmp) :
+		    __memp_remove_region(dbmp))) != 0)
+			break;
+	MUTEX_UNLOCK(env, mp->mtx_resize);
+
+	return (ret);
+}
+
+/*
+ * PUBLIC: int __memp_get_cache_max __P((DB_ENV *, u_int32_t *, u_int32_t *));
+ */
+int
+__memp_get_cache_max(dbenv, max_gbytesp, max_bytesp)
+	DB_ENV *dbenv;
+	u_int32_t *max_gbytesp, *max_bytesp;
+{
+	DB_MPOOL *dbmp;
+	ENV *env;
+	MPOOL *mp;
+	roff_t reg_size, max_size;
+
+	env = dbenv->env;
+
+	ENV_NOT_CONFIGURED(env,
+	    env->mp_handle, "DB_ENV->get_mp_max_ncache", DB_INIT_MPOOL);
+
+	if (MPOOL_ON(env)) {
+		/* Cannot be set after open, no lock required to read. */
+		dbmp = env->mp_handle;
+		mp = dbmp->reginfo[0].primary;
+		reg_size = dbmp->reginfo[0].rp->size;
+		max_size = mp->max_nreg * reg_size;
+		*max_gbytesp = (u_int32_t)(max_size / GIGABYTE);
+		*max_bytesp = (u_int32_t)(max_size % GIGABYTE);
+	} else {
+		*max_gbytesp = dbenv->mp_max_gbytes;
+		*max_bytesp = dbenv->mp_max_bytes;
+	}
+
+	return (0);
+}
+
+/*
+ * PUBLIC: int __memp_set_cache_max __P((DB_ENV *, u_int32_t, u_int32_t));
+ */
+int
+__memp_set_cache_max(dbenv, max_gbytes, max_bytes)
+	DB_ENV *dbenv;
+	u_int32_t max_gbytes, max_bytes;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_cache_max");
+	dbenv->mp_max_gbytes = max_gbytes;
+	dbenv->mp_max_bytes = max_bytes;
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_stat.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,931 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+#ifdef HAVE_STATISTICS
+static void __memp_print_bh __P((ENV *,
+		DB_MPOOL *, const char *, BH *, roff_t *));
+static int  __memp_print_all __P((ENV *, u_int32_t));
+static int  __memp_print_stats __P((ENV *, u_int32_t));
+static int __memp_print_hash __P((ENV *,
+		DB_MPOOL *, REGINFO *, roff_t *, u_int32_t));
+static int  __memp_stat __P((ENV *,
+		DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t));
+static void __memp_stat_wait
+		__P((ENV *, REGINFO *, MPOOL *, DB_MPOOL_STAT *, u_int32_t));
+static int __memp_file_stats __P((ENV *,
+		MPOOLFILE *, void *, u_int32_t *, u_int32_t));
+static int __memp_count_files __P((ENV *,
+		MPOOLFILE *, void *, u_int32_t *, u_int32_t));
+static int __memp_get_files __P((ENV *,
+		MPOOLFILE *, void *, u_int32_t *, u_int32_t));
+static int __memp_print_files __P((ENV *,
+		MPOOLFILE *, void *, u_int32_t *, u_int32_t));
+
+/*
+ * __memp_stat_pp --
+ *	DB_ENV->memp_stat pre/post processing.
+ *
+ * PUBLIC: int __memp_stat_pp
+ * PUBLIC:     __P((DB_ENV *, DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t));
+ */
+int
+__memp_stat_pp(dbenv, gspp, fspp, flags)
+	DB_ENV *dbenv;
+	DB_MPOOL_STAT **gspp;
+	DB_MPOOL_FSTAT ***fspp;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_REQUIRES_CONFIG(env,
+	    env->mp_handle, "DB_ENV->memp_stat", DB_INIT_MPOOL);
+
+	if ((ret = __db_fchk(env,
+	    "DB_ENV->memp_stat", flags, DB_STAT_CLEAR)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env, (__memp_stat(env, gspp, fspp, flags)), 0, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __memp_stat --
+ *	ENV->memp_stat
+ */
+static int
+__memp_stat(env, gspp, fspp, flags)
+	ENV *env;
+	DB_MPOOL_STAT **gspp;
+	DB_MPOOL_FSTAT ***fspp;
+	u_int32_t flags;
+{
+	DB_MPOOL *dbmp;
+	DB_MPOOL_FSTAT **tfsp;
+	DB_MPOOL_STAT *sp;
+	MPOOL *c_mp, *mp;
+	size_t len;
+	int ret;
+	u_int32_t i;
+	uintmax_t tmp_wait, tmp_nowait;
+
+	dbmp = env->mp_handle;
+	mp = dbmp->reginfo[0].primary;
+
+	/* Global statistics. */
+	if (gspp != NULL) {
+		*gspp = NULL;
+
+		if ((ret = __os_umalloc(env, sizeof(**gspp), gspp)) != 0)
+			return (ret);
+		memset(*gspp, 0, sizeof(**gspp));
+		sp = *gspp;
+
+		/*
+		 * Initialization and information that is not maintained on
+		 * a per-cache basis.  Note that configuration information
+		 * may be modified at any time, and so we have to lock.
+		 */
+		sp->st_gbytes = mp->gbytes;
+		sp->st_bytes = mp->bytes;
+		sp->st_pagesize = mp->pagesize;
+		sp->st_ncache = mp->nreg;
+		sp->st_max_ncache = mp->max_nreg;
+		sp->st_regsize = dbmp->reginfo[0].rp->size;
+		sp->st_regmax = dbmp->reginfo[0].rp->max;
+		sp->st_sync_interrupted = mp->stat.st_sync_interrupted;
+
+		MPOOL_SYSTEM_LOCK(env);
+		sp->st_mmapsize = mp->mp_mmapsize;
+		sp->st_maxopenfd = mp->mp_maxopenfd;
+		sp->st_maxwrite = mp->mp_maxwrite;
+		sp->st_maxwrite_sleep = mp->mp_maxwrite_sleep;
+		MPOOL_SYSTEM_UNLOCK(env);
+
+		/* Walk the cache list and accumulate the global information. */
+		for (i = 0; i < mp->nreg; ++i) {
+			c_mp = dbmp->reginfo[i].primary;
+
+			sp->st_map += c_mp->stat.st_map;
+			sp->st_cache_hit += c_mp->stat.st_cache_hit;
+			sp->st_cache_miss += c_mp->stat.st_cache_miss;
+			sp->st_page_create += c_mp->stat.st_page_create;
+			sp->st_page_in += c_mp->stat.st_page_in;
+			sp->st_page_out += c_mp->stat.st_page_out;
+			sp->st_ro_evict += c_mp->stat.st_ro_evict;
+			sp->st_rw_evict += c_mp->stat.st_rw_evict;
+			sp->st_page_trickle += c_mp->stat.st_page_trickle;
+			sp->st_pages += c_mp->pages;
+			sp->st_oddfsize_detect +=
+			    c_mp->stat.st_oddfsize_detect;
+			sp->st_oddfsize_resolve +=
+			    c_mp->stat.st_oddfsize_resolve;
+			/*
+			 * st_page_dirty	calculated by __memp_stat_hash
+			 * st_page_clean	calculated here
+			 */
+			__memp_stat_hash(
+			    &dbmp->reginfo[i], c_mp, &sp->st_page_dirty);
+			sp->st_page_clean = sp->st_pages - sp->st_page_dirty;
+			sp->st_hash_buckets += c_mp->htab_buckets;
+			sp->st_hash_mutexes += c_mp->htab_mutexes;
+			sp->st_hash_searches += c_mp->stat.st_hash_searches;
+			sp->st_hash_longest += c_mp->stat.st_hash_longest;
+			sp->st_hash_examined += c_mp->stat.st_hash_examined;
+			/*
+			 * st_hash_nowait	calculated by __memp_stat_wait
+			 * st_hash_wait
+			 */
+			__memp_stat_wait(
+			    env, &dbmp->reginfo[i], c_mp, sp, flags);
+			__mutex_set_wait_info(env,
+			    c_mp->mtx_region, &tmp_wait, &tmp_nowait);
+			sp->st_region_nowait += tmp_nowait;
+			sp->st_region_wait += tmp_wait;
+			sp->st_alloc += c_mp->stat.st_alloc;
+			sp->st_alloc_buckets += c_mp->stat.st_alloc_buckets;
+			if (sp->st_alloc_max_buckets <
+			    c_mp->stat.st_alloc_max_buckets)
+				sp->st_alloc_max_buckets =
+				    c_mp->stat.st_alloc_max_buckets;
+			sp->st_alloc_pages += c_mp->stat.st_alloc_pages;
+			if (sp->st_alloc_max_pages <
+			    c_mp->stat.st_alloc_max_pages)
+				sp->st_alloc_max_pages =
+				    c_mp->stat.st_alloc_max_pages;
+
+			if (LF_ISSET(DB_STAT_CLEAR)) {
+				if (!LF_ISSET(DB_STAT_SUBSYSTEM))
+					__mutex_clear(env, c_mp->mtx_region);
+
+				memset(&c_mp->stat, 0, sizeof(c_mp->stat));
+			}
+		}
+
+		/*
+		 * We have duplicate statistics fields in per-file structures
+		 * and the cache.  The counters are only incremented in the
+		 * per-file structures, except if a file is flushed from the
+		 * mpool, at which time we copy its information into the cache
+		 * statistics.  We added the cache information above, now we
+		 * add the per-file information.
+		 */
+		if ((ret = __memp_walk_files(env, mp, __memp_file_stats,
+		    sp, NULL, fspp == NULL ? LF_ISSET(DB_STAT_CLEAR) : 0)) != 0)
+			return (ret);
+	}
+
+	/* Per-file statistics. */
+	if (fspp != NULL) {
+		*fspp = NULL;
+
+		/* Count the MPOOLFILE structures. */
+		i = 0;
+		len = 0;
+		if ((ret = __memp_walk_files(env,
+		     mp, __memp_count_files, &len, &i, flags)) != 0)
+			return (ret);
+
+		if (i == 0)
+			return (0);
+		len += sizeof(DB_MPOOL_FSTAT *);	/* Trailing NULL */
+
+		/* Allocate space */
+		if ((ret = __os_umalloc(env, len, fspp)) != 0)
+			return (ret);
+
+		tfsp = *fspp;
+		*tfsp = NULL;
+
+		/*
+		 * Files may have been opened since we counted, don't walk
+		 * off the end of the allocated space.
+		 */
+		if ((ret = __memp_walk_files(env,
+		    mp, __memp_get_files, &tfsp, &i, flags)) != 0)
+			return (ret);
+
+		*++tfsp = NULL;
+	}
+
+	return (0);
+}
+
+static int
+__memp_file_stats(env, mfp, argp, countp, flags)
+	ENV *env;
+	MPOOLFILE *mfp;
+	void *argp;
+	u_int32_t *countp;
+	u_int32_t flags;
+{
+	DB_MPOOL_STAT *sp;
+
+	COMPQUIET(env, NULL);
+	COMPQUIET(countp, NULL);
+
+	sp = argp;
+
+	sp->st_map += mfp->stat.st_map;
+	sp->st_cache_hit += mfp->stat.st_cache_hit;
+	sp->st_cache_miss += mfp->stat.st_cache_miss;
+	sp->st_page_create += mfp->stat.st_page_create;
+	sp->st_page_in += mfp->stat.st_page_in;
+	sp->st_page_out += mfp->stat.st_page_out;
+	if (LF_ISSET(DB_STAT_CLEAR))
+		memset(&mfp->stat, 0, sizeof(mfp->stat));
+
+	return (0);
+}
+
+static int
+__memp_count_files(env, mfp, argp, countp, flags)
+	ENV *env;
+	MPOOLFILE *mfp;
+	void *argp;
+	u_int32_t *countp;
+	u_int32_t flags;
+{
+	DB_MPOOL *dbmp;
+	size_t len;
+
+	COMPQUIET(flags, 0);
+	dbmp = env->mp_handle;
+	len = *(size_t *)argp;
+
+	(*countp)++;
+	len += sizeof(DB_MPOOL_FSTAT *) +
+	    sizeof(DB_MPOOL_FSTAT) + strlen(__memp_fns(dbmp, mfp)) + 1;
+
+	*(size_t *)argp = len;
+	return (0);
+}
+
+/*
+ * __memp_get_files --
+ *	get file specific statistics
+ *
+ * Build each individual entry.  We assume that an array of pointers are
+ * aligned correctly to be followed by an array of structures, which should
+ * be safe (in this particular case, the first element of the structure
+ * is a pointer, so we're doubly safe).  The array is followed by space
+ * for the text file names.
+ */
+static int
+__memp_get_files(env, mfp, argp, countp, flags)
+	ENV *env;
+	MPOOLFILE *mfp;
+	void *argp;
+	u_int32_t *countp;
+	u_int32_t flags;
+{
+	DB_MPOOL *dbmp;
+	DB_MPOOL_FSTAT **tfsp, *tstruct;
+	char *name, *tname;
+	size_t nlen;
+
+	if (*countp == 0)
+		return (0);
+
+	dbmp = env->mp_handle;
+	tfsp = *(DB_MPOOL_FSTAT ***)argp;
+
+	if (*tfsp == NULL) {
+		/* Add 1 to count because we need to skip over the NULL. */
+		tstruct = (DB_MPOOL_FSTAT *)(tfsp + *countp + 1);
+		tname = (char *)(tstruct + *countp);
+		*tfsp = tstruct;
+	} else {
+		tstruct = *tfsp + 1;
+		tname = (*tfsp)->file_name + strlen((*tfsp)->file_name) + 1;
+		*++tfsp = tstruct;
+	}
+
+	name = __memp_fns(dbmp, mfp);
+	nlen = strlen(name) + 1;
+	memcpy(tname, name, nlen);
+	memcpy(tstruct, &mfp->stat, sizeof(mfp->stat));
+	tstruct->file_name = tname;
+
+	/* Grab the pagesize from the mfp. */
+	tstruct->st_pagesize = mfp->pagesize;
+
+	*(DB_MPOOL_FSTAT ***)argp = tfsp;
+	(*countp)--;
+
+	if (LF_ISSET(DB_STAT_CLEAR))
+		memset(&mfp->stat, 0, sizeof(mfp->stat));
+
+	return (0);
+}
+
+/*
+ * __memp_stat_print_pp --
+ *	ENV->memp_stat_print pre/post processing.
+ *
+ * PUBLIC: int __memp_stat_print_pp __P((DB_ENV *, u_int32_t));
+ */
+int
+__memp_stat_print_pp(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_REQUIRES_CONFIG(env,
+	    env->mp_handle, "DB_ENV->memp_stat_print", DB_INIT_MPOOL);
+
+#define	DB_STAT_MEMP_FLAGS						\
+	(DB_STAT_ALL | DB_STAT_ALLOC | DB_STAT_CLEAR | DB_STAT_MEMP_HASH)
+	if ((ret = __db_fchk(env,
+	    "DB_ENV->memp_stat_print", flags, DB_STAT_MEMP_FLAGS)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env, (__memp_stat_print(env, flags)), 0, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+#define	FMAP_ENTRIES	200			/* Files we map. */
+
+/*
+ * __memp_stat_print --
+ *	ENV->memp_stat_print method.
+ *
+ * PUBLIC: int  __memp_stat_print __P((ENV *, u_int32_t));
+ */
+int
+__memp_stat_print(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	u_int32_t orig_flags;
+	int ret;
+
+	orig_flags = flags;
+	LF_CLR(DB_STAT_CLEAR | DB_STAT_SUBSYSTEM);
+	if (flags == 0 || LF_ISSET(DB_STAT_ALL)) {
+		ret = __memp_print_stats(env,
+		    LF_ISSET(DB_STAT_ALL) ? flags : orig_flags);
+		if (flags == 0 || ret != 0)
+			return (ret);
+	}
+
+	if (LF_ISSET(DB_STAT_ALL | DB_STAT_MEMP_HASH) &&
+	    (ret = __memp_print_all(env, orig_flags)) != 0)
+		return (ret);
+
+	return (0);
+}
+
+/*
+ * __memp_print_stats --
+ *	Display default mpool region statistics.
+ */
+static int
+__memp_print_stats(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	DB_MPOOL_FSTAT **fsp, **tfsp;
+	DB_MPOOL_STAT *gsp;
+	int ret;
+
+	if ((ret = __memp_stat(env, &gsp, &fsp, flags)) != 0)
+		return (ret);
+
+	if (LF_ISSET(DB_STAT_ALL))
+		__db_msg(env, "Default cache region information:");
+	__db_dlbytes(env, "Total cache size",
+	    (u_long)gsp->st_gbytes, (u_long)0, (u_long)gsp->st_bytes);
+	__db_dl(env, "Number of caches", (u_long)gsp->st_ncache);
+	__db_dl(env, "Maximum number of caches", (u_long)gsp->st_max_ncache);
+	__db_dlbytes(env, "Pool individual cache size",
+	    (u_long)0, (u_long)0, (u_long)gsp->st_regsize);
+	__db_dlbytes(env, "Pool individual cache max",
+	    (u_long)0, (u_long)0, (u_long)gsp->st_regmax);
+	__db_dlbytes(env, "Maximum memory-mapped file size",
+	    (u_long)0, (u_long)0, (u_long)gsp->st_mmapsize);
+	STAT_LONG("Maximum open file descriptors", gsp->st_maxopenfd);
+	STAT_LONG("Maximum sequential buffer writes", gsp->st_maxwrite);
+	STAT_LONG("Sleep after writing maximum sequential buffers",
+	    gsp->st_maxwrite_sleep);
+	__db_dl(env,
+	    "Requested pages mapped into the process' address space",
+	    (u_long)gsp->st_map);
+	__db_dl_pct(env, "Requested pages found in the cache",
+	    (u_long)gsp->st_cache_hit, DB_PCT(
+	    gsp->st_cache_hit, gsp->st_cache_hit + gsp->st_cache_miss), NULL);
+	__db_dl(env, "Requested pages not found in the cache",
+	    (u_long)gsp->st_cache_miss);
+	__db_dl(env,
+	    "Pages created in the cache", (u_long)gsp->st_page_create);
+	__db_dl(env, "Pages read into the cache", (u_long)gsp->st_page_in);
+	__db_dl(env, "Pages written from the cache to the backing file",
+	    (u_long)gsp->st_page_out);
+	__db_dl(env, "Clean pages forced from the cache",
+	    (u_long)gsp->st_ro_evict);
+	__db_dl(env, "Dirty pages forced from the cache",
+	    (u_long)gsp->st_rw_evict);
+	__db_dl(env, "Dirty pages written by trickle-sync thread",
+	    (u_long)gsp->st_page_trickle);
+	__db_dl(env, "Current total page count",
+	    (u_long)gsp->st_pages);
+	__db_dl(env, "Current clean page count",
+	    (u_long)gsp->st_page_clean);
+	__db_dl(env, "Current dirty page count",
+	    (u_long)gsp->st_page_dirty);
+	__db_dl(env, "Number of hash buckets used for page location",
+	    (u_long)gsp->st_hash_buckets);
+	__db_dl(env, "Number of mutexes for the hash buckets",
+	    (u_long)gsp->st_hash_mutexes);
+	__db_dl(env, "Assumed page size used",
+	    (u_long)gsp->st_pagesize);
+	__db_dl(env,
+	    "Total number of times hash chains searched for a page",
+	    (u_long)gsp->st_hash_searches);
+	__db_dl(env, "The longest hash chain searched for a page",
+	    (u_long)gsp->st_hash_longest);
+	__db_dl(env,
+	    "Total number of hash chain entries checked for page",
+	    (u_long)gsp->st_hash_examined);
+	__db_dl_pct(env,
+	    "The number of hash bucket locks that required waiting",
+	    (u_long)gsp->st_hash_wait, DB_PCT(
+	    gsp->st_hash_wait, gsp->st_hash_wait + gsp->st_hash_nowait), NULL);
+	__db_dl_pct(env,
+    "The maximum number of times any hash bucket lock was waited for",
+	    (u_long)gsp->st_hash_max_wait, DB_PCT(gsp->st_hash_max_wait,
+	    gsp->st_hash_max_wait + gsp->st_hash_max_nowait), NULL);
+	__db_dl_pct(env,
+	    "The number of region locks that required waiting",
+	    (u_long)gsp->st_region_wait, DB_PCT(gsp->st_region_wait,
+	    gsp->st_region_wait + gsp->st_region_nowait), NULL);
+	__db_dl(env, "The number of buffers frozen",
+	    (u_long)gsp->st_mvcc_frozen);
+	__db_dl(env, "The number of buffers thawed",
+	    (u_long)gsp->st_mvcc_thawed);
+	__db_dl(env, "The number of frozen buffers freed",
+	    (u_long)gsp->st_mvcc_freed);
+	__db_dl(env, "The number of page allocations", (u_long)gsp->st_alloc);
+	__db_dl(env,
+	    "The number of hash buckets examined during allocations",
+	    (u_long)gsp->st_alloc_buckets);
+	__db_dl(env,
+	    "The maximum number of hash buckets examined for an allocation",
+	    (u_long)gsp->st_alloc_max_buckets);
+	__db_dl(env, "The number of pages examined during allocations",
+	    (u_long)gsp->st_alloc_pages);
+	__db_dl(env, "The max number of pages examined for an allocation",
+	    (u_long)gsp->st_alloc_max_pages);
+	__db_dl(env, "Threads waited on page I/O", (u_long)gsp->st_io_wait);
+	__db_dl(env, "The number of times a sync is interrupted",
+	    (u_long)gsp->st_sync_interrupted);
+
+	for (tfsp = fsp; fsp != NULL && *tfsp != NULL; ++tfsp) {
+		if (LF_ISSET(DB_STAT_ALL))
+			__db_msg(env, "%s", DB_GLOBAL(db_line));
+		__db_msg(env, "Pool File: %s", (*tfsp)->file_name);
+		__db_dl(env, "Page size", (u_long)(*tfsp)->st_pagesize);
+		__db_dl(env,
+		    "Requested pages mapped into the process' address space",
+		    (u_long)(*tfsp)->st_map);
+		__db_dl_pct(env, "Requested pages found in the cache",
+		    (u_long)(*tfsp)->st_cache_hit, DB_PCT((*tfsp)->st_cache_hit,
+		    (*tfsp)->st_cache_hit + (*tfsp)->st_cache_miss), NULL);
+		__db_dl(env, "Requested pages not found in the cache",
+		    (u_long)(*tfsp)->st_cache_miss);
+		__db_dl(env, "Pages created in the cache",
+		    (u_long)(*tfsp)->st_page_create);
+		__db_dl(env, "Pages read into the cache",
+		    (u_long)(*tfsp)->st_page_in);
+		__db_dl(env,
+		    "Pages written from the cache to the backing file",
+		    (u_long)(*tfsp)->st_page_out);
+		if ((*tfsp)->st_backup_spins != 0)
+			__db_dl(env,
+			    "Spins while trying to backup the file",
+			    (u_long)(*tfsp)->st_backup_spins);
+	}
+
+	__os_ufree(env, fsp);
+	__os_ufree(env, gsp);
+	return (0);
+}
+
+/*
+ * __memp_print_all --
+ *	Display debugging mpool region statistics.
+ */
+static int
+__memp_print_all(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	static const FN cfn[] = {
+		{ DB_MPOOL_NOFILE,	"DB_MPOOL_NOFILE" },
+		{ DB_MPOOL_UNLINK,	"DB_MPOOL_UNLINK" },
+		{ 0,			NULL }
+	};
+	DB_MPOOL *dbmp;
+	DB_MPOOLFILE *dbmfp;
+	MPOOL *mp;
+	roff_t fmap[FMAP_ENTRIES + 1];
+	u_int32_t i, cnt;
+	int ret;
+
+	dbmp = env->mp_handle;
+	mp = dbmp->reginfo[0].primary;
+	ret = 0;
+
+	MPOOL_SYSTEM_LOCK(env);
+
+	__db_print_reginfo(env, dbmp->reginfo, "Mpool", flags);
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+
+	__db_msg(env, "MPOOL structure:");
+	__mutex_print_debug_single(
+	    env, "MPOOL region mutex", mp->mtx_region, flags);
+	STAT_LSN("Maximum checkpoint LSN", &mp->lsn);
+	STAT_ULONG("Hash table entries", mp->htab_buckets);
+	STAT_ULONG("Hash table mutexes", mp->htab_mutexes);
+
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	__db_msg(env, "DB_MPOOL handle information:");
+	__mutex_print_debug_single(
+	    env, "DB_MPOOL handle mutex", dbmp->mutex, flags);
+	STAT_ULONG("Underlying cache regions", mp->nreg);
+
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	__db_msg(env, "DB_MPOOLFILE structures:");
+	for (cnt = 0, dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
+	    dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q), ++cnt) {
+		__db_msg(env, "File #%lu: %s: per-process, %s",
+		    (u_long)cnt + 1, __memp_fn(dbmfp),
+		    F_ISSET(dbmfp, MP_READONLY) ? "readonly" : "read/write");
+		STAT_ULONG("Reference count", dbmfp->ref);
+		STAT_ULONG("Pinned block reference count", dbmfp->ref);
+		STAT_ULONG("Clear length", dbmfp->clear_len);
+		__db_print_fileid(env, dbmfp->fileid, "\tID");
+		STAT_ULONG("File type", dbmfp->ftype);
+		STAT_ULONG("LSN offset", dbmfp->lsn_offset);
+		STAT_ULONG("Max gbytes", dbmfp->gbytes);
+		STAT_ULONG("Max bytes", dbmfp->bytes);
+		STAT_ULONG("Cache priority", dbmfp->priority);
+		STAT_POINTER("mmap address", dbmfp->addr);
+		STAT_ULONG("mmap length", dbmfp->len);
+		__db_prflags(env, NULL, dbmfp->flags, cfn, NULL, "\tFlags");
+		__db_print_fh(env, "File handle", dbmfp->fhp, flags);
+	}
+
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	__db_msg(env, "MPOOLFILE structures:");
+	cnt = 0;
+	ret = __memp_walk_files(env, mp, __memp_print_files, fmap, &cnt, flags);
+	MPOOL_SYSTEM_UNLOCK(env);
+	if (ret != 0)
+		return (ret);
+
+	if (cnt < FMAP_ENTRIES)
+		fmap[cnt] = INVALID_ROFF;
+	else
+		fmap[FMAP_ENTRIES] = INVALID_ROFF;
+
+	/* Dump the individual caches. */
+	for (i = 0; i < mp->nreg; ++i) {
+		__db_msg(env, "%s", DB_GLOBAL(db_line));
+		__db_msg(env, "Cache #%d:", i + 1);
+		if (i > 0)
+			__env_alloc_print(&dbmp->reginfo[i], flags);
+		if ((ret = __memp_print_hash(
+		    env, dbmp, &dbmp->reginfo[i], fmap, flags)) != 0)
+			break;
+	}
+
+	return (ret);
+}
+
+static int
+__memp_print_files(env, mfp, argp, countp, flags)
+	ENV *env;
+	MPOOLFILE *mfp;
+	void *argp;
+	u_int32_t *countp;
+	u_int32_t flags;
+{
+	roff_t *fmap;
+	DB_MPOOL *dbmp;
+	u_int32_t mfp_flags;
+	static const FN fn[] = {
+		{ MP_CAN_MMAP,		"MP_CAN_MMAP" },
+		{ MP_DIRECT,		"MP_DIRECT" },
+		{ MP_EXTENT,		"MP_EXTENT" },
+		{ MP_FAKE_DEADFILE,	"deadfile" },
+		{ MP_FAKE_FILEWRITTEN,	"file written" },
+		{ MP_FAKE_NB,		"no backing file" },
+		{ MP_FAKE_UOC,		"unlink on close" },
+		{ MP_NOT_DURABLE,	"not durable" },
+		{ MP_TEMP,		"MP_TEMP" },
+		{ 0,			NULL }
+	};
+
+	dbmp = env->mp_handle;
+	fmap = argp;
+
+	__db_msg(env, "File #%d: %s", *countp + 1, __memp_fns(dbmp, mfp));
+	__mutex_print_debug_single(env, "Mutex", mfp->mutex, flags);
+
+	MUTEX_LOCK(env, mfp->mutex);
+	STAT_ULONG("Revision count", mfp->revision);
+	STAT_ULONG("Reference count", mfp->mpf_cnt);
+	STAT_ULONG("Sync/read only open count", mfp->neutral_cnt);
+	STAT_ULONG("Block count", mfp->block_cnt);
+	STAT_ULONG("Last page number", mfp->last_pgno);
+	STAT_ULONG("Original last page number", mfp->orig_last_pgno);
+	STAT_ULONG("Maximum page number", mfp->maxpgno);
+	STAT_LONG("Type", mfp->ftype);
+	STAT_LONG("Priority", mfp->priority);
+	STAT_LONG("Page's LSN offset", mfp->lsn_off);
+	STAT_LONG("Page's clear length", mfp->clear_len);
+
+	__db_print_fileid(env,
+	    R_ADDR(dbmp->reginfo, mfp->fileid_off), "\tID");
+
+	mfp_flags = 0;
+	if (mfp->deadfile)
+		FLD_SET(mfp_flags, MP_FAKE_DEADFILE);
+	if (mfp->file_written)
+		FLD_SET(mfp_flags, MP_FAKE_FILEWRITTEN);
+	if (mfp->no_backing_file)
+		FLD_SET(mfp_flags, MP_FAKE_NB);
+	if (mfp->unlink_on_close)
+		FLD_SET(mfp_flags, MP_FAKE_UOC);
+	__db_prflags(env, NULL, mfp_flags, fn, NULL, "\tFlags");
+
+	if (*countp < FMAP_ENTRIES)
+		fmap[*countp] = R_OFFSET(dbmp->reginfo, mfp);
+	(*countp)++;
+	MUTEX_UNLOCK(env, mfp->mutex);
+	return (0);
+}
+
+/*
+ * __memp_print_hash --
+ *	Display hash bucket statistics for a cache.
+ */
+static int
+__memp_print_hash(env, dbmp, reginfo, fmap, flags)
+	ENV *env;
+	DB_MPOOL *dbmp;
+	REGINFO *reginfo;
+	roff_t *fmap;
+	u_int32_t flags;
+{
+	BH *bhp, *vbhp;
+	DB_MPOOL_HASH *hp;
+	DB_MSGBUF mb;
+	MPOOL *c_mp;
+	u_int32_t bucket;
+
+	c_mp = reginfo->primary;
+	DB_MSGBUF_INIT(&mb);
+	STAT_ULONG("Hash table last-checked", c_mp->last_checked);
+	STAT_ULONG("Hash table LRU priority", c_mp->lru_priority);
+	STAT_ULONG("Hash table LRU generation", c_mp->lru_generation);
+	STAT_ULONG("Put counter", c_mp->put_counter);
+
+	/* Display the hash table list of BH's. */
+	__db_msg(env,
+	    "BH hash table (%lu hash slots)", (u_long)c_mp->htab_buckets);
+	__db_msg(env, "bucket #: priority, I/O wait, [mutex]");
+	__db_msg(env, "\tpageno, file, ref, LSN, address, priority, flags");
+
+	for (hp = R_ADDR(reginfo, c_mp->htab),
+	    bucket = 0; bucket < c_mp->htab_buckets; ++hp, ++bucket) {
+		MUTEX_READLOCK(env, hp->mtx_hash);
+		if ((bhp = SH_TAILQ_FIRST(&hp->hash_bucket, __bh)) != NULL) {
+			__db_msgadd(env, &mb,
+			    "bucket %lu: %lu (%lu dirty)",
+			    (u_long)bucket, (u_long)hp->hash_io_wait,
+			    (u_long)atomic_read(&hp->hash_page_dirty));
+			if (hp->hash_frozen != 0)
+				__db_msgadd(env, &mb, "(MVCC %lu/%lu/%lu) ",
+				    (u_long)hp->hash_frozen,
+				    (u_long)hp->hash_thawed,
+				    (u_long)hp->hash_frozen_freed);
+			__mutex_print_debug_stats(
+			    env, &mb, hp->mtx_hash, flags);
+			DB_MSGBUF_FLUSH(env, &mb);
+		}
+		for (; bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh)) {
+			__memp_print_bh(env, dbmp, NULL, bhp, fmap);
+
+			/* Print the version chain, if it exists. */
+			for (vbhp = SH_CHAIN_PREV(bhp, vc, __bh);
+			    vbhp != NULL;
+			    vbhp = SH_CHAIN_PREV(vbhp, vc, __bh)) {
+				__memp_print_bh(env, dbmp,
+				    " next:\t", vbhp, fmap);
+			}
+		}
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+	}
+
+	return (0);
+}
+
+/*
+ * __memp_print_bh --
+ *	Display a BH structure.
+ */
+static void
+__memp_print_bh(env, dbmp, prefix, bhp, fmap)
+	ENV *env;
+	DB_MPOOL *dbmp;
+	const char *prefix;
+	BH *bhp;
+	roff_t *fmap;
+{
+	static const FN fn[] = {
+		{ BH_CALLPGIN,		"callpgin" },
+		{ BH_DIRTY,		"dirty" },
+		{ BH_DIRTY_CREATE,	"created" },
+		{ BH_DISCARD,		"discard" },
+		{ BH_EXCLUSIVE,		"exclusive" },
+		{ BH_FREED,		"freed" },
+		{ BH_FROZEN,		"frozen" },
+		{ BH_TRASH,		"trash" },
+		{ BH_THAWED,		"thawed" },
+		{ 0,			NULL }
+	};
+	DB_MSGBUF mb;
+	int i;
+
+	DB_MSGBUF_INIT(&mb);
+
+	if (prefix != NULL)
+		__db_msgadd(env, &mb, "%s", prefix);
+	else
+		__db_msgadd(env, &mb, "\t");
+
+	for (i = 0; i < FMAP_ENTRIES; ++i)
+		if (fmap[i] == INVALID_ROFF || fmap[i] == bhp->mf_offset)
+			break;
+
+	if (fmap[i] == INVALID_ROFF)
+		__db_msgadd(env, &mb, "%5lu, %lu, ",
+		    (u_long)bhp->pgno, (u_long)bhp->mf_offset);
+	else
+		__db_msgadd(
+		    env, &mb, "%5lu, #%d, ", (u_long)bhp->pgno, i + 1);
+
+	__db_msgadd(env, &mb, "%2lu, %lu/%lu", (u_long)atomic_read(&bhp->ref),
+	    F_ISSET(bhp, BH_FROZEN) ? 0 : (u_long)LSN(bhp->buf).file,
+	    F_ISSET(bhp, BH_FROZEN) ? 0 : (u_long)LSN(bhp->buf).offset);
+	if (bhp->td_off != INVALID_ROFF)
+		__db_msgadd(env, &mb, " (@%lu/%lu 0x%x)",
+		    (u_long)VISIBLE_LSN(env, bhp)->file,
+		    (u_long)VISIBLE_LSN(env, bhp)->offset,
+		    BH_OWNER(env, bhp)->txnid);
+	__db_msgadd(env, &mb, ", %#08lx, %lu",
+	    (u_long)R_OFFSET(dbmp->reginfo, bhp), (u_long)bhp->priority);
+	__db_prflags(env, &mb, bhp->flags, fn, " (", ")");
+	DB_MSGBUF_FLUSH(env, &mb);
+}
+
+/*
+ * __memp_stat_wait --
+ *	Total hash bucket wait stats into the region.
+ */
+static void
+__memp_stat_wait(env, reginfo, mp, mstat, flags)
+	ENV *env;
+	REGINFO *reginfo;
+	MPOOL *mp;
+	DB_MPOOL_STAT *mstat;
+	u_int32_t flags;
+{
+	DB_MPOOL_HASH *hp;
+	u_int32_t i;
+	uintmax_t tmp_nowait, tmp_wait;
+
+	mstat->st_hash_max_wait = 0;
+	hp = R_ADDR(reginfo, mp->htab);
+	for (i = 0; i < mp->htab_buckets; i++, hp++) {
+		__mutex_set_wait_info(
+		    env, hp->mtx_hash, &tmp_wait, &tmp_nowait);
+		mstat->st_hash_nowait += tmp_nowait;
+		mstat->st_hash_wait += tmp_wait;
+		if (tmp_wait > mstat->st_hash_max_wait) {
+			mstat->st_hash_max_wait = tmp_wait;
+			mstat->st_hash_max_nowait = tmp_nowait;
+		}
+		if (LF_ISSET(DB_STAT_CLEAR |
+		    DB_STAT_SUBSYSTEM) == DB_STAT_CLEAR)
+			__mutex_clear(env, hp->mtx_hash);
+
+		mstat->st_io_wait += hp->hash_io_wait;
+		mstat->st_mvcc_frozen += hp->hash_frozen;
+		mstat->st_mvcc_thawed += hp->hash_thawed;
+		mstat->st_mvcc_freed += hp->hash_frozen_freed;
+		if (LF_ISSET(DB_STAT_CLEAR)) {
+			hp->hash_io_wait = 0;
+			hp->hash_frozen = 0;
+			hp->hash_thawed = 0;
+			hp->hash_frozen_freed = 0;
+		}
+	}
+}
+
+#else /* !HAVE_STATISTICS */
+
+int
+__memp_stat_pp(dbenv, gspp, fspp, flags)
+	DB_ENV *dbenv;
+	DB_MPOOL_STAT **gspp;
+	DB_MPOOL_FSTAT ***fspp;
+	u_int32_t flags;
+{
+	COMPQUIET(gspp, NULL);
+	COMPQUIET(fspp, NULL);
+	COMPQUIET(flags, 0);
+
+	return (__db_stat_not_built(dbenv->env));
+}
+
+int
+__memp_stat_print_pp(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+
+	return (__db_stat_not_built(dbenv->env));
+}
+#endif
+
+/*
+ * __memp_stat_hash --
+ *	Total hash bucket stats (other than mutex wait) into the region.
+ *
+ * PUBLIC: void __memp_stat_hash __P((REGINFO *, MPOOL *, u_int32_t *));
+ */
+void
+__memp_stat_hash(reginfo, mp, dirtyp)
+	REGINFO *reginfo;
+	MPOOL *mp;
+	u_int32_t *dirtyp;
+{
+	DB_MPOOL_HASH *hp;
+	u_int32_t dirty, i;
+
+	hp = R_ADDR(reginfo, mp->htab);
+	for (i = 0, dirty = 0; i < mp->htab_buckets; i++, hp++)
+		dirty += (u_int32_t)atomic_read(&hp->hash_page_dirty);
+	*dirtyp = dirty;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_sync.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,987 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/log.h"
+#include "dbinc/mp.h"
+#include "dbinc/db_page.h"
+#include "dbinc/hash.h"
+
+typedef struct {
+	DB_MPOOL_HASH *track_hp;	/* Hash bucket. */
+
+	roff_t	  track_off;		/* Page file offset. */
+	db_pgno_t track_pgno;		/* Page number. */
+} BH_TRACK;
+
+static int __bhcmp __P((const void *, const void *));
+static int __memp_close_flush_files __P((ENV *, int));
+static int __memp_sync_files __P((ENV *));
+static int __memp_sync_file __P((ENV *,
+		MPOOLFILE *, void *, u_int32_t *, u_int32_t));
+
+/*
+ * __memp_walk_files --
+ * PUBLIC: int __memp_walk_files __P((ENV *, MPOOL *,
+ * PUBLIC:	int (*) __P((ENV *, MPOOLFILE *, void *,
+ * PUBLIC:	u_int32_t *, u_int32_t)), void *, u_int32_t *, u_int32_t));
+ */
+int
+__memp_walk_files(env, mp, func, arg, countp, flags)
+	ENV *env;
+	MPOOL *mp;
+	int (*func)__P((ENV *, MPOOLFILE *, void *, u_int32_t *, u_int32_t));
+	void *arg;
+	u_int32_t *countp;
+	u_int32_t flags;
+{
+	DB_MPOOL *dbmp;
+	DB_MPOOL_HASH *hp;
+	MPOOLFILE *mfp;
+	int i, ret, t_ret;
+
+	dbmp = env->mp_handle;
+	ret = 0;
+
+	hp = R_ADDR(dbmp->reginfo, mp->ftab);
+	for (i = 0; i < MPOOL_FILE_BUCKETS; i++, hp++) {
+		MUTEX_LOCK(env, hp->mtx_hash);
+		SH_TAILQ_FOREACH(mfp, &hp->hash_bucket, q, __mpoolfile) {
+			if ((t_ret = func(env,
+			    mfp, arg, countp, flags)) != 0 && ret == 0)
+				ret = t_ret;
+			if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
+				break;
+		}
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+		if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
+			break;
+	}
+	return (ret);
+}
+
+/*
+ * __memp_discard_all_mpfs --
+ *	Force discard all mpoolfiles. When closing a private environment, we
+ *	always want to discard all mpoolfiles to avoid memory leak.
+ *
+ * PUBLIC: int __memp_discard_all_mpfs __P((ENV *, MPOOL *));
+ */
+int
+__memp_discard_all_mpfs (env, mp)
+	ENV *env;
+	MPOOL *mp;
+{
+	DB_MPOOL *dbmp;
+	DB_MPOOL_HASH *hp;
+	MPOOLFILE *mfp;
+	int i, ret, t_ret;
+
+	ret = t_ret = 0;
+	mfp = NULL;
+	hp = NULL;
+	dbmp = env->mp_handle;
+
+	hp = R_ADDR(dbmp->reginfo, mp->ftab);
+	for (i = 0; i < MPOOL_FILE_BUCKETS; i++, hp++) {
+		MUTEX_LOCK(env, hp->mtx_hash);
+		while ((mfp = SH_TAILQ_FIRST(
+		    &hp->hash_bucket, __mpoolfile)) != NULL) {
+			MUTEX_LOCK(env, mfp->mutex);
+			if ((t_ret = __memp_mf_discard(dbmp, mfp, 1)) != 0 &&
+			    ret == 0)
+				ret = t_ret;
+		}
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+	}
+	return (ret);
+}
+
+/*
+ * __memp_sync_pp --
+ *	ENV->memp_sync pre/post processing.
+ *
+ * PUBLIC: int __memp_sync_pp __P((DB_ENV *, DB_LSN *));
+ */
+int
+__memp_sync_pp(dbenv, lsnp)
+	DB_ENV *dbenv;
+	DB_LSN *lsnp;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_REQUIRES_CONFIG(env,
+	    env->mp_handle, "memp_sync", DB_INIT_MPOOL);
+
+	/*
+	 * If no LSN is provided, flush the entire cache (reasonable usage
+	 * even if there's no log subsystem configured).
+	 */
+	if (lsnp != NULL)
+		ENV_REQUIRES_CONFIG(env,
+		    env->lg_handle, "memp_sync", DB_INIT_LOG);
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env, (__memp_sync(env, DB_SYNC_CACHE, lsnp)), 0, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __memp_sync --
+ *	ENV->memp_sync.
+ *
+ * PUBLIC: int __memp_sync __P((ENV *, u_int32_t, DB_LSN *));
+ */
+int
+__memp_sync(env, flags, lsnp)
+	ENV *env;
+	u_int32_t flags;
+	DB_LSN *lsnp;
+{
+	DB_MPOOL *dbmp;
+	MPOOL *mp;
+	int interrupted, ret;
+
+	dbmp = env->mp_handle;
+	mp = dbmp->reginfo[0].primary;
+
+	/* If we've flushed to the requested LSN, return that information. */
+	if (lsnp != NULL) {
+		MPOOL_SYSTEM_LOCK(env);
+		if (LOG_COMPARE(lsnp, &mp->lsn) <= 0) {
+			*lsnp = mp->lsn;
+
+			MPOOL_SYSTEM_UNLOCK(env);
+			return (0);
+		}
+		MPOOL_SYSTEM_UNLOCK(env);
+	}
+
+	if ((ret =
+	    __memp_sync_int(env, NULL, 0, flags, NULL, &interrupted)) != 0)
+		return (ret);
+
+	if (!interrupted && lsnp != NULL) {
+		MPOOL_SYSTEM_LOCK(env);
+		if (LOG_COMPARE(lsnp, &mp->lsn) > 0)
+			mp->lsn = *lsnp;
+		MPOOL_SYSTEM_UNLOCK(env);
+	}
+
+	return (0);
+}
+
+/*
+ * __memp_fsync_pp --
+ *	DB_MPOOLFILE->sync pre/post processing.
+ *
+ * PUBLIC: int __memp_fsync_pp __P((DB_MPOOLFILE *));
+ */
+int
+__memp_fsync_pp(dbmfp)
+	DB_MPOOLFILE *dbmfp;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbmfp->env;
+
+	MPF_ILLEGAL_BEFORE_OPEN(dbmfp, "DB_MPOOLFILE->sync");
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env, (__memp_fsync(dbmfp)), 0, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __memp_fsync --
+ *	DB_MPOOLFILE->sync.
+ *
+ * PUBLIC: int __memp_fsync __P((DB_MPOOLFILE *));
+ */
+int
+__memp_fsync(dbmfp)
+	DB_MPOOLFILE *dbmfp;
+{
+	MPOOLFILE *mfp;
+
+	mfp = dbmfp->mfp;
+
+	/*
+	 * If this handle doesn't have a file descriptor that's open for
+	 * writing, or if the file is a temporary, or if the file hasn't
+	 * been written since it was flushed, there's no reason to proceed
+	 * further.
+	 */
+	if (F_ISSET(dbmfp, MP_READONLY))
+		return (0);
+
+	if (F_ISSET(dbmfp->mfp, MP_TEMP) || dbmfp->mfp->no_backing_file)
+		return (0);
+
+	if (mfp->file_written == 0)
+		return (0);
+
+	return (__memp_sync_int(
+	    dbmfp->env, dbmfp, 0, DB_SYNC_FILE, NULL, NULL));
+}
+
+/*
+ * __mp_xxx_fh --
+ *	Return a file descriptor for DB 1.85 compatibility locking.
+ *
+ * PUBLIC: int __mp_xxx_fh __P((DB_MPOOLFILE *, DB_FH **));
+ */
+int
+__mp_xxx_fh(dbmfp, fhp)
+	DB_MPOOLFILE *dbmfp;
+	DB_FH **fhp;
+{
+	int ret;
+
+	/*
+	 * This is a truly spectacular layering violation, intended ONLY to
+	 * support compatibility for the DB 1.85 DB->fd call.
+	 *
+	 * Sync the database file to disk, creating the file as necessary.
+	 *
+	 * We skip the MP_READONLY and MP_TEMP tests done by memp_fsync(3).
+	 * The MP_READONLY test isn't interesting because we will either
+	 * already have a file descriptor (we opened the database file for
+	 * reading) or we aren't readonly (we created the database which
+	 * requires write privileges).  The MP_TEMP test isn't interesting
+	 * because we want to write to the backing file regardless so that
+	 * we get a file descriptor to return.
+	 */
+	if ((*fhp = dbmfp->fhp) != NULL)
+		return (0);
+
+	if ((ret = __memp_sync_int(
+	    dbmfp->env, dbmfp, 0, DB_SYNC_FILE, NULL, NULL)) == 0)
+		*fhp = dbmfp->fhp;
+	return (ret);
+}
+
+/*
+ * __memp_sync_int --
+ *	Mpool sync internal function.
+ *
+ * PUBLIC: int __memp_sync_int __P((ENV *,
+ * PUBLIC:     DB_MPOOLFILE *, u_int32_t, u_int32_t, u_int32_t *, int *));
+ */
+int
+__memp_sync_int(env, dbmfp, trickle_max, flags, wrote_totalp, interruptedp)
+	ENV *env;
+	DB_MPOOLFILE *dbmfp;
+	u_int32_t trickle_max, flags, *wrote_totalp;
+	int *interruptedp;
+{
+	BH *bhp;
+	BH_TRACK *bharray;
+	DB_MPOOL *dbmp;
+	DB_MPOOL_HASH *hp;
+	MPOOL *c_mp, *mp;
+	MPOOLFILE *mfp;
+	db_mutex_t mutex;
+	roff_t last_mf_offset;
+	u_int32_t ar_cnt, ar_max, i, n_cache, remaining, wrote_total;
+	int32_t wrote_cnt;
+	int dirty, filecnt, maxopenfd, required_write, ret, t_ret;
+
+	dbmp = env->mp_handle;
+	mp = dbmp->reginfo[0].primary;
+	last_mf_offset = INVALID_ROFF;
+	filecnt = wrote_total = 0;
+
+	if (wrote_totalp != NULL)
+		*wrote_totalp = 0;
+	if (interruptedp != NULL)
+		*interruptedp = 0;
+
+	/*
+	 * If we're flushing the cache, it's a checkpoint or we're flushing a
+	 * specific file, we really have to write the blocks and we have to
+	 * confirm they made it to disk.  Otherwise, we can skip a block if
+	 * it's hard to get.
+	 */
+	required_write = LF_ISSET(DB_SYNC_CACHE |
+	    DB_SYNC_CHECKPOINT | DB_SYNC_FILE | DB_SYNC_QUEUE_EXTENT);
+
+	/* Get shared configuration information. */
+	MPOOL_SYSTEM_LOCK(env);
+	maxopenfd = mp->mp_maxopenfd;
+	MPOOL_SYSTEM_UNLOCK(env);
+
+	/* Assume one dirty page per bucket. */
+	ar_max = mp->nreg * mp->htab_buckets;
+	if ((ret =
+	    __os_malloc(env, ar_max * sizeof(BH_TRACK), &bharray)) != 0)
+		return (ret);
+
+	/*
+	 * Walk each cache's list of buffers and mark all dirty buffers to be
+	 * written and all dirty buffers to be potentially written, depending
+	 * on our flags.
+	 */
+	for (ar_cnt = 0, n_cache = 0; n_cache < mp->nreg; ++n_cache) {
+		c_mp = dbmp->reginfo[n_cache].primary;
+
+		hp = R_ADDR(&dbmp->reginfo[n_cache], c_mp->htab);
+		for (i = 0; i < c_mp->htab_buckets; i++, hp++) {
+			/*
+			 * We can check for empty buckets before locking as
+			 * we only care if the pointer is zero or non-zero.
+			 * We can ignore empty or clean buckets because we
+			 * only need write buffers that were dirty before
+			 * we started.
+			 */
+#ifdef DIAGNOSTIC
+			if (SH_TAILQ_FIRST(&hp->hash_bucket, __bh) == NULL)
+#else
+			if (atomic_read(&hp->hash_page_dirty) == 0)
+#endif
+				continue;
+
+			dirty = 0;
+			MUTEX_LOCK(env, hp->mtx_hash);
+			SH_TAILQ_FOREACH(bhp, &hp->hash_bucket, hq, __bh) {
+				/* Always ignore clean pages. */
+				if (!F_ISSET(bhp, BH_DIRTY))
+					continue;
+
+				dirty++;
+				mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
+
+				/*
+				 * Ignore in-memory files, unless the file is
+				 * specifically being flushed.
+				 */
+				if (mfp->no_backing_file)
+					continue;
+				if (!LF_ISSET(DB_SYNC_FILE) &&
+				    F_ISSET(mfp, MP_TEMP))
+					continue;
+
+				/*
+				 * Ignore files that aren't involved in DB's
+				 * transactional operations during checkpoints.
+				 */
+				if (LF_ISSET(DB_SYNC_CHECKPOINT) &&
+				    mfp->lsn_off == DB_LSN_OFF_NOTSET)
+					continue;
+
+				/*
+				 * Ignore files that aren't Queue extent files
+				 * if we're flushing a Queue file with extents.
+				 */
+				if (LF_ISSET(DB_SYNC_QUEUE_EXTENT) &&
+				    !F_ISSET(mfp, MP_EXTENT))
+					continue;
+
+				/*
+				 * If we're flushing a specific file, see if
+				 * this page is from that file.
+				 */
+				if (dbmfp != NULL && mfp != dbmfp->mfp)
+					continue;
+
+				/* Track the buffer, we want it. */
+				bharray[ar_cnt].track_hp = hp;
+				bharray[ar_cnt].track_pgno = bhp->pgno;
+				bharray[ar_cnt].track_off = bhp->mf_offset;
+				ar_cnt++;
+
+				/*
+				 * If we run out of space, double and continue.
+				 * Don't stop at trickle_max, we want to sort
+				 * as large a sample set as possible in order
+				 * to minimize disk seeks.
+				 */
+				if (ar_cnt >= ar_max) {
+					if ((ret = __os_realloc(env,
+					    (ar_max * 2) * sizeof(BH_TRACK),
+					    &bharray)) != 0)
+						break;
+					ar_max *= 2;
+				}
+			}
+
+			if (ret != 0)
+				goto err;
+			/*
+			 * We are only checking this in diagnostic mode
+			 * since it requires extra latching to keep the count
+			 * in sync with the number of bits counted.
+			 */
+			DB_ASSERT(env,
+			    dirty == (int)atomic_read(&hp->hash_page_dirty));
+			MUTEX_UNLOCK(env, hp->mtx_hash);
+
+			/* Check if the call has been interrupted. */
+			if (LF_ISSET(DB_SYNC_INTERRUPT_OK) && FLD_ISSET(
+			    mp->config_flags, DB_MEMP_SYNC_INTERRUPT)) {
+				STAT(++mp->stat.st_sync_interrupted);
+				if (interruptedp != NULL)
+					*interruptedp = 1;
+				goto err;
+			}
+		}
+	}
+
+	/* If there no buffers to write, we're done. */
+	if (ar_cnt == 0)
+		goto done;
+
+	/*
+	 * Write the buffers in file/page order, trying to reduce seeks by the
+	 * filesystem and, when pages are smaller than filesystem block sizes,
+	 * reduce the actual number of writes.
+	 */
+	if (ar_cnt > 1)
+		qsort(bharray, ar_cnt, sizeof(BH_TRACK), __bhcmp);
+
+	/*
+	 * If we're trickling buffers, only write enough to reach the correct
+	 * percentage.
+	 */
+	if (LF_ISSET(DB_SYNC_TRICKLE) && ar_cnt > trickle_max)
+		ar_cnt = trickle_max;
+
+	/*
+	 * Flush the log.  We have to ensure the log records reflecting the
+	 * changes on the database pages we're writing have already made it
+	 * to disk.  We still have to check the log each time we write a page
+	 * (because pages we are about to write may be modified after we have
+	 * flushed the log), but in general this will at least avoid any I/O
+	 * on the log's part.
+	 */
+	if (LOGGING_ON(env) && (ret = __log_flush(env, NULL)) != 0)
+		goto err;
+
+	/*
+	 * Walk the array, writing buffers.  When we write a buffer, we NULL
+	 * out its hash bucket pointer so we don't process a slot more than
+	 * once.
+	 */
+	for (i = wrote_cnt = 0, remaining = ar_cnt; remaining > 0; ++i) {
+		if (i >= ar_cnt) {
+			i = 0;
+			__os_yield(env, 1, 0);
+		}
+		if ((hp = bharray[i].track_hp) == NULL)
+			continue;
+
+		/* Lock the hash bucket and find the buffer. */
+		mutex = hp->mtx_hash;
+		MUTEX_READLOCK(env, mutex);
+		SH_TAILQ_FOREACH(bhp, &hp->hash_bucket, hq, __bh)
+			if (bhp->pgno == bharray[i].track_pgno &&
+			    bhp->mf_offset == bharray[i].track_off)
+				break;
+
+		/*
+		 * If we can't find the buffer we're done, somebody else had
+		 * to have written it.
+		 *
+		 * If the buffer isn't dirty, we're done, there's no work
+		 * needed.
+		 */
+		if (bhp == NULL || !F_ISSET(bhp, BH_DIRTY)) {
+			MUTEX_UNLOCK(env, mutex);
+			--remaining;
+			bharray[i].track_hp = NULL;
+			continue;
+		}
+
+		/*
+		 * If the buffer is locked by another thread, ignore it, we'll
+		 * come back to it.
+		 */
+		if (F_ISSET(bhp, BH_EXCLUSIVE)) {
+			MUTEX_UNLOCK(env, mutex);
+			if (!required_write) {
+				--remaining;
+				bharray[i].track_hp = NULL;
+			}
+			continue;
+		}
+
+		/* Pin the buffer into memory. */
+		atomic_inc(env, &bhp->ref);
+		MUTEX_UNLOCK(env, mutex);
+		MUTEX_READLOCK(env, bhp->mtx_buf);
+		DB_ASSERT(env, !F_ISSET(bhp, BH_EXCLUSIVE));
+
+		/*
+		 * When swapping the hash bucket mutex for the buffer mutex,
+		 * we may have raced with an MVCC update.  In that case, we
+		 * no longer have the most recent version, and need to retry
+		 * (the buffer header we have pinned will no longer be marked
+		 * dirty, so we can't just write it).
+		 */
+		if (SH_CHAIN_HASNEXT(bhp, vc)) {
+			atomic_dec(env, &bhp->ref);
+			MUTEX_UNLOCK(env, bhp->mtx_buf);
+			continue;
+		}
+
+		/*
+		 * If we've switched files, check to see if we're configured
+		 * to close file descriptors.
+		 */
+		if (maxopenfd != 0 && bhp->mf_offset != last_mf_offset) {
+			if (++filecnt >= maxopenfd) {
+				filecnt = 0;
+				if ((t_ret = __memp_close_flush_files(
+				    env, 1)) != 0 && ret == 0)
+					ret = t_ret;
+			}
+			last_mf_offset = bhp->mf_offset;
+		}
+
+		/*
+		 * If the buffer is dirty, we write it.  We only try to
+		 * write the buffer once.
+		 */
+		if (F_ISSET(bhp, BH_DIRTY)) {
+			mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
+			if ((t_ret =
+			    __memp_bhwrite(dbmp, hp, mfp, bhp, 1)) == 0) {
+				++wrote_cnt;
+				++wrote_total;
+			} else {
+				/* The buffer is being backed up, try again. */
+				if (t_ret == EAGAIN) {
+					atomic_dec(env, &bhp->ref);
+					MUTEX_UNLOCK(env, bhp->mtx_buf);
+					continue;
+				}
+				if (ret == 0)
+					ret = t_ret;
+				__db_errx(env, DB_STR_A("3027",
+				    "%s: unable to flush page: %lu", "%s %lu"),
+				    __memp_fns(dbmp, mfp), (u_long)bhp->pgno);
+
+			}
+		}
+
+		/* we disposed of this buffer. */
+		--remaining;
+		bharray[i].track_hp = NULL;
+
+		/* Discard our buffer reference. */
+		DB_ASSERT(env, atomic_read(&bhp->ref) > 0);
+		atomic_dec(env, &bhp->ref);
+		MUTEX_UNLOCK(env, bhp->mtx_buf);
+
+		/* Check if the call has been interrupted. */
+		if (LF_ISSET(DB_SYNC_INTERRUPT_OK) &&
+		    FLD_ISSET(mp->config_flags, DB_MEMP_SYNC_INTERRUPT)) {
+			STAT(++mp->stat.st_sync_interrupted);
+			if (interruptedp != NULL)
+				*interruptedp = 1;
+			goto err;
+		}
+
+		/*
+		 * Sleep after some number of writes to avoid disk saturation.
+		 * Don't cache the max writes value, an application shutting
+		 * down might reset the value in order to do a fast flush or
+		 * checkpoint.
+		 */
+		if (!LF_ISSET(DB_SYNC_SUPPRESS_WRITE) &&
+		    !FLD_ISSET(mp->config_flags, DB_MEMP_SUPPRESS_WRITE) &&
+		    mp->mp_maxwrite != 0 && wrote_cnt >= mp->mp_maxwrite) {
+			wrote_cnt = 0;
+			__os_yield(env, 0, (u_long)mp->mp_maxwrite_sleep);
+		}
+	}
+
+done:	/*
+	 * If a write is required, we have to force the pages to disk.  We
+	 * don't do this as we go along because we want to give the OS as
+	 * much time as possible to lazily flush, and because we have to flush
+	 * files that might not even have had dirty buffers in the cache, so
+	 * we have to walk the files list.
+	 */
+	if (ret == 0 && required_write) {
+		if (dbmfp == NULL)
+			ret = __memp_sync_files(env);
+		else
+			ret = __os_fsync(env, dbmfp->fhp);
+	}
+
+	/* If we've opened files to flush pages, close them. */
+	if ((t_ret = __memp_close_flush_files(env, 0)) != 0 && ret == 0)
+		ret = t_ret;
+
+err:	__os_free(env, bharray);
+	if (wrote_totalp != NULL)
+		*wrote_totalp = wrote_total;
+
+	return (ret);
+}
+
+static int
+__memp_sync_file(env, mfp, argp, countp, flags)
+	ENV *env;
+	MPOOLFILE *mfp;
+	void *argp;
+	u_int32_t *countp;
+	u_int32_t flags;
+{
+	DB_MPOOL *dbmp;
+	DB_MPOOLFILE *dbmfp;
+	int ret, t_ret;
+
+	COMPQUIET(countp, NULL);
+	COMPQUIET(flags, 0);
+
+	if (!mfp->file_written || mfp->no_backing_file ||
+	    mfp->deadfile || F_ISSET(mfp, MP_TEMP))
+		return (0);
+	/*
+	 * Pin the MPOOLFILE structure into memory, and release the
+	 * region mutex allowing us to walk the linked list.  We'll
+	 * re-acquire that mutex to move to the next entry in the list.
+	 *
+	 * This works because we only need to flush current entries,
+	 * we don't care about new entries being added, and the linked
+	 * list is never re-ordered, a single pass is sufficient.  It
+	 * requires MPOOLFILE structures removed before we get to them
+	 * be flushed to disk, but that's nothing new, they could have
+	 * been removed while checkpoint was running, too.
+	 *
+	 * Once we have the MPOOLFILE lock, re-check the MPOOLFILE is
+	 * not being discarded.  (A thread removing the MPOOLFILE
+	 * will: hold the MPOOLFILE mutex, set deadfile, drop the
+	 * MPOOLFILE mutex and then acquire the region MUTEX to walk
+	 * the linked list and remove the MPOOLFILE structure.  Make
+	 * sure the MPOOLFILE wasn't marked dead while we waited for
+	 * the mutex.
+	 */
+	MUTEX_LOCK(env, mfp->mutex);
+	if (!mfp->file_written || mfp->deadfile) {
+		MUTEX_UNLOCK(env, mfp->mutex);
+		return (0);
+	}
+	++mfp->mpf_cnt;
+	++mfp->neutral_cnt;
+	MUTEX_UNLOCK(env, mfp->mutex);
+
+	/*
+	 * Look for an already open, writable handle (fsync doesn't
+	 * work on read-only Windows handles).
+	 */
+	dbmp = env->mp_handle;
+	MUTEX_LOCK(env, dbmp->mutex);
+	TAILQ_FOREACH(dbmfp, &dbmp->dbmfq, q) {
+		if (dbmfp->mfp != mfp || F_ISSET(dbmfp, MP_READONLY))
+			continue;
+		/*
+		 * We don't want to hold the mutex while calling sync.
+		 * Increment the DB_MPOOLFILE handle ref count to pin
+		 * it into memory.
+		 */
+		++dbmfp->ref;
+		break;
+	}
+	MUTEX_UNLOCK(env, dbmp->mutex);
+
+	/* If we don't find a handle we can use, open one. */
+	if (dbmfp == NULL) {
+		if ((ret = __memp_mf_sync(dbmp, mfp, 1)) != 0) {
+			__db_err(env, ret, DB_STR_A("3028",
+			    "%s: unable to flush", "%s"), (char *)
+			    R_ADDR(dbmp->reginfo, mfp->path_off));
+		}
+	} else
+		ret = __os_fsync(env, dbmfp->fhp);
+
+	/*
+	 * Re-acquire the MPOOLFILE mutex, we need it to modify the
+	 * reference count.
+	 */
+	MUTEX_LOCK(env, mfp->mutex);
+
+	/*
+	 * If we wrote the file and there are no other references (or there
+	 * is a single reference, and it's the one we opened to write
+	 * buffers during checkpoint), clear the file_written flag.  We
+	 * do this so that applications opening thousands of files don't
+	 * loop here opening and flushing those files during checkpoint.
+	 *
+	 * The danger here is if a buffer were to be written as part of
+	 * a checkpoint, and then not be flushed to disk.  This cannot
+	 * happen because we only clear file_written when there are no
+	 * other users of the MPOOLFILE in the system, and, as we hold
+	 * the region lock, no possibility of another thread of control
+	 * racing with us to open a MPOOLFILE.
+	 */
+	if (mfp->mpf_cnt == 1 || (mfp->mpf_cnt == 2 &&
+	    dbmfp != NULL && F_ISSET(dbmfp, MP_FLUSH))) {
+		mfp->file_written = 0;
+
+		/*
+		 * We may be the last reference for a MPOOLFILE, as we
+		 * weren't holding the MPOOLFILE mutex when flushing
+		 * it's buffers to disk.  If we can discard it, set
+		 * a flag to schedule a clean-out pass.   (Not likely,
+		 * I mean, what are the chances that there aren't any
+		 * buffers in the pool?  Regardless, it might happen.)
+		 */
+		if (mfp->mpf_cnt == 1 && mfp->block_cnt == 0)
+			*(int *)argp = 1;
+	}
+
+	/*
+	 * If we found the file we must close it in case we are the last
+	 * reference to the dbmfp.  NOTE: since we have incremented
+	 * mfp->mpf_cnt this cannot be the last reference to the mfp.
+	 * This is important since we are called with the hash bucket
+	 * locked.  The mfp will get freed via the cleanup pass.
+	 */
+	if (dbmfp != NULL &&
+	    (t_ret = __memp_fclose(dbmfp, DB_MPOOL_NOLOCK)) != 0 && ret == 0)
+		ret = t_ret;
+
+	--mfp->mpf_cnt;
+	DB_ASSERT(env, mfp->neutral_cnt != 0);
+	--mfp->neutral_cnt;
+
+	/* Unlock the MPOOLFILE. */
+	MUTEX_UNLOCK(env, mfp->mutex);
+	return (ret);
+}
+
+/*
+ * __memp_sync_files --
+ *	Sync all the files in the environment, open or not.
+ */
+static int
+__memp_sync_files(env)
+	ENV *env;
+{
+	DB_MPOOL *dbmp;
+	DB_MPOOL_HASH *hp;
+	MPOOL *mp;
+	MPOOLFILE *mfp, *next_mfp;
+	int i, need_discard_pass, ret;
+
+	dbmp = env->mp_handle;
+	mp = dbmp->reginfo[0].primary;
+	need_discard_pass = ret = 0;
+
+	ret = __memp_walk_files(env,
+	    mp, __memp_sync_file, &need_discard_pass, 0, DB_STAT_MEMP_NOERROR);
+
+	/*
+	 * We may need to do a last pass through the MPOOLFILE list -- if we
+	 * were the last reference to an MPOOLFILE, we need to clean it out.
+	 */
+	if (!need_discard_pass)
+		return (ret);
+
+	hp = R_ADDR(dbmp->reginfo, mp->ftab);
+	for (i = 0; i < MPOOL_FILE_BUCKETS; i++, hp++) {
+retry:		MUTEX_LOCK(env, hp->mtx_hash);
+		for (mfp = SH_TAILQ_FIRST(&hp->hash_bucket,
+		    __mpoolfile); mfp != NULL; mfp = next_mfp) {
+			next_mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile);
+			/*
+			 * Do a fast check -- we can check for zero/non-zero
+			 * without a mutex on the MPOOLFILE.  If likely to
+			 * succeed, lock the MPOOLFILE down and look for real.
+			 */
+			if (mfp->deadfile ||
+			    mfp->block_cnt != 0 || mfp->mpf_cnt != 0)
+				continue;
+
+			MUTEX_LOCK(env, mfp->mutex);
+			if (!mfp->deadfile &&
+			    mfp->block_cnt == 0 && mfp->mpf_cnt == 0) {
+				MUTEX_UNLOCK(env, hp->mtx_hash);
+				(void)__memp_mf_discard(dbmp, mfp, 0);
+				goto retry;
+			} else
+				MUTEX_UNLOCK(env, mfp->mutex);
+		}
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+	}
+	return (ret);
+}
+
+/*
+ * __memp_mf_sync --
+ *	Flush an MPOOLFILE, when no currently open handle is available.
+ *
+ * PUBLIC: int __memp_mf_sync __P((DB_MPOOL *, MPOOLFILE *, int));
+ */
+int
+__memp_mf_sync(dbmp, mfp, locked)
+	DB_MPOOL *dbmp;
+	MPOOLFILE *mfp;
+	int locked;
+{
+	DB_FH *fhp;
+	DB_MPOOL_HASH *hp;
+	ENV *env;
+	MPOOL *mp;
+	int ret, t_ret;
+	char *rpath;
+
+	COMPQUIET(hp, NULL);
+	env = dbmp->env;
+
+	/*
+	 * We need to be holding the hash lock: we're using the path name
+	 * and __memp_nameop might try and rename the file.
+	 */
+	if (!locked) {
+		mp = dbmp->reginfo[0].primary;
+		hp = R_ADDR(dbmp->reginfo, mp->ftab);
+		hp += FNBUCKET(
+		    R_ADDR(dbmp->reginfo, mfp->fileid_off), DB_FILE_ID_LEN);
+		MUTEX_LOCK(env, hp->mtx_hash);
+	}
+
+	if ((ret = __db_appname(env, DB_APP_DATA,
+	    R_ADDR(dbmp->reginfo, mfp->path_off), NULL, &rpath)) == 0) {
+		if ((ret = __os_open(env, rpath, 0, 0, 0, &fhp)) == 0) {
+			ret = __os_fsync(env, fhp);
+			if ((t_ret =
+			    __os_closehandle(env, fhp)) != 0 && ret == 0)
+				ret = t_ret;
+		}
+		__os_free(env, rpath);
+	}
+
+	if (!locked)
+		MUTEX_UNLOCK(env, hp->mtx_hash);
+
+	return (ret);
+}
+
+/*
+ * __memp_close_flush_files --
+ *	Close files opened only to flush buffers.
+ */
+static int
+__memp_close_flush_files(env, dosync)
+	ENV *env;
+	int dosync;
+{
+	DB_MPOOL *dbmp;
+	DB_MPOOLFILE *dbmfp;
+	MPOOLFILE *mfp;
+	int ret;
+
+	dbmp = env->mp_handle;
+
+	/*
+	 * The routine exists because we must close files opened by sync to
+	 * flush buffers.  There are two cases: first, extent files have to
+	 * be closed so they may be removed when empty.  Second, regular
+	 * files have to be closed so we don't run out of descriptors (for
+	 * example, an application partitioning its data into databases
+	 * based on timestamps, so there's a continually increasing set of
+	 * files).
+	 *
+	 * We mark files opened in the __memp_bhwrite() function with the
+	 * MP_FLUSH flag.  Here we walk through our file descriptor list,
+	 * and, if a file was opened by __memp_bhwrite(), we close it.
+	 */
+retry:	MUTEX_LOCK(env, dbmp->mutex);
+	TAILQ_FOREACH(dbmfp, &dbmp->dbmfq, q)
+		if (F_ISSET(dbmfp, MP_FLUSH)) {
+			F_CLR(dbmfp, MP_FLUSH);
+			MUTEX_UNLOCK(env, dbmp->mutex);
+			if (dosync) {
+				/*
+				 * If we have the only open handle on the file,
+				 * clear the dirty flag so we don't re-open and
+				 * sync it again when discarding the MPOOLFILE
+				 * structure.  Clear the flag before the sync
+				 * so can't race with a thread writing the file.
+				 */
+				mfp = dbmfp->mfp;
+				if (mfp->mpf_cnt == 1) {
+					MUTEX_LOCK(env, mfp->mutex);
+					if (mfp->mpf_cnt == 1)
+						mfp->file_written = 0;
+					MUTEX_UNLOCK(env, mfp->mutex);
+				}
+				if ((ret = __os_fsync(env, dbmfp->fhp)) != 0)
+					return (ret);
+			}
+			if ((ret = __memp_fclose(dbmfp, DB_FLUSH)) != 0)
+				return (ret);
+			goto retry;
+		}
+	MUTEX_UNLOCK(env, dbmp->mutex);
+
+	return (0);
+}
+
+static int
+__bhcmp(p1, p2)
+	const void *p1, *p2;
+{
+	BH_TRACK *bhp1, *bhp2;
+
+	bhp1 = (BH_TRACK *)p1;
+	bhp2 = (BH_TRACK *)p2;
+
+	/* Sort by file (shared memory pool offset). */
+	if (bhp1->track_off < bhp2->track_off)
+		return (-1);
+	if (bhp1->track_off > bhp2->track_off)
+		return (1);
+
+	/*
+	 * !!!
+	 * Defend against badly written quicksort code calling the comparison
+	 * function with two identical pointers (e.g., WATCOM C++ (Power++)).
+	 */
+	if (bhp1->track_pgno < bhp2->track_pgno)
+		return (-1);
+	if (bhp1->track_pgno > bhp2->track_pgno)
+		return (1);
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mp/mp_trickle.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,134 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/log.h"
+#include "dbinc/mp.h"
+
+static int __memp_trickle __P((ENV *, int, int *));
+
+/*
+ * __memp_trickle_pp --
+ *	ENV->memp_trickle pre/post processing.
+ *
+ * PUBLIC: int __memp_trickle_pp __P((DB_ENV *, int, int *));
+ */
+int
+__memp_trickle_pp(dbenv, pct, nwrotep)
+	DB_ENV *dbenv;
+	int pct, *nwrotep;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_REQUIRES_CONFIG(env,
+	    env->mp_handle, "memp_trickle", DB_INIT_MPOOL);
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env, (__memp_trickle(env, pct, nwrotep)), 0, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __memp_trickle --
+ *	ENV->memp_trickle.
+ */
+static int
+__memp_trickle(env, pct, nwrotep)
+	ENV *env;
+	int pct, *nwrotep;
+{
+	DB_MPOOL *dbmp;
+	MPOOL *c_mp, *mp;
+	u_int32_t clean, dirty, i, need_clean, total, dtmp, wrote;
+	int ret;
+
+	dbmp = env->mp_handle;
+	mp = dbmp->reginfo[0].primary;
+
+	if (nwrotep != NULL)
+		*nwrotep = 0;
+
+	if (pct < 1 || pct > 100) {
+		__db_errx(env, DB_STR_A("3007",
+	    "DB_ENV->memp_trickle: %d: percent must be between 1 and 100",
+		    "%d"), pct);
+		return (EINVAL);
+	}
+
+	/*
+	 * Loop through the caches counting total/dirty buffers.
+	 *
+	 * XXX
+	 * Using hash_page_dirty is our only choice at the moment, but it's not
+	 * as correct as we might like in the presence of pools having more
+	 * than one page size, as a free 512B buffer may not be equivalent to
+	 * having a free 8KB buffer.
+	 */
+	for (ret = 0, i = dirty = total = 0; i < mp->nreg; ++i) {
+		c_mp = dbmp->reginfo[i].primary;
+		total += c_mp->pages;
+		__memp_stat_hash(&dbmp->reginfo[i], c_mp, &dtmp);
+		dirty += dtmp;
+	}
+
+	/*
+	 * If there are sufficient clean buffers, no buffers or no dirty
+	 * buffers, we're done.
+	 */
+	if (total == 0 || dirty == 0)
+		return (0);
+
+	/*
+	 * The total number of pages is an exact number, but the dirty page
+	 * count can change while we're walking the hash buckets, and it's
+	 * even possible the dirty page count ends up larger than the total
+	 * number of pages.
+	 */
+	clean = total > dirty ? total - dirty : 0;
+	need_clean = (total * (u_int)pct) / 100;
+	if (clean >= need_clean)
+		return (0);
+
+	need_clean -= clean;
+	ret = __memp_sync_int(env, NULL,
+	    need_clean, DB_SYNC_TRICKLE | DB_SYNC_INTERRUPT_OK, &wrote, NULL);
+	STAT((mp->stat.st_page_trickle += wrote));
+	if (nwrotep != NULL)
+		*nwrotep = (int)wrote;
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mutex/mut_alloc.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,313 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __mutex_alloc --
+ *	Allocate a mutex from the mutex region.
+ *
+ * PUBLIC: int __mutex_alloc __P((ENV *, int, u_int32_t, db_mutex_t *));
+ */
+int
+__mutex_alloc(env, alloc_id, flags, indxp)
+	ENV *env;
+	int alloc_id;
+	u_int32_t flags;
+	db_mutex_t *indxp;
+{
+	/* The caller may depend on us to initialize. */
+	*indxp = MUTEX_INVALID;
+
+	/*
+	 * If this is not an application lock, and we've turned off locking,
+	 * or the ENV handle isn't thread-safe, and this is a thread lock
+	 * or the environment isn't multi-process by definition, there's no
+	 * need to mutex at all.
+	 */
+	if (alloc_id != MTX_APPLICATION && alloc_id != MTX_MUTEX_TEST &&
+	    (F_ISSET(env->dbenv, DB_ENV_NOLOCKING) ||
+	    (!F_ISSET(env, ENV_THREAD) &&
+	    (LF_ISSET(DB_MUTEX_PROCESS_ONLY) ||
+	    F_ISSET(env, ENV_PRIVATE)))))
+		return (0);
+
+	/* Private environments never share mutexes. */
+	if (F_ISSET(env, ENV_PRIVATE))
+		LF_SET(DB_MUTEX_PROCESS_ONLY);
+
+	/*
+	 * If we have a region in which to allocate the mutexes, lock it and
+	 * do the allocation.
+	 */
+	if (!MUTEX_ON(env)) {
+		__db_errx(env, DB_STR("2033",
+		    "Mutex allocated before mutex region."));
+		return (__env_panic(env, EINVAL));
+	}
+	return (__mutex_alloc_int(env, 1, alloc_id, flags, indxp));
+}
+
+/*
+ * __mutex_alloc_int --
+ *	Internal routine to allocate a mutex.
+ *
+ * PUBLIC: int __mutex_alloc_int
+ * PUBLIC:	__P((ENV *, int, int, u_int32_t, db_mutex_t *));
+ */
+int
+__mutex_alloc_int(env, locksys, alloc_id, flags, indxp)
+	ENV *env;
+	int locksys, alloc_id;
+	u_int32_t flags;
+	db_mutex_t *indxp;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	DB_MUTEXMGR *mtxmgr;
+	DB_MUTEXREGION *mtxregion;
+	db_mutex_t i;
+	size_t len;
+	u_int32_t cnt;
+	int ret;
+
+	dbenv = env->dbenv;
+	mtxmgr = env->mutex_handle;
+	mtxregion = mtxmgr->reginfo.primary;
+	ret = 0;
+
+	/*
+	 * If we're not initializing the mutex region, then lock the region to
+	 * allocate new mutexes.  Drop the lock before initializing the mutex,
+	 * mutex initialization may require a system call.
+	 */
+	if (locksys)
+		MUTEX_SYSTEM_LOCK(env);
+
+	if (mtxregion->mutex_next == MUTEX_INVALID) {
+		if (mtxregion->stat.st_mutex_max != 0 &&
+		    mtxregion->stat.st_mutex_cnt >=
+		    mtxregion->stat.st_mutex_max) {
+nomem:			__db_errx(env, DB_STR("2034",
+	    "unable to allocate memory for mutex; resize mutex region"));
+			if (locksys)
+				MUTEX_SYSTEM_UNLOCK(env);
+			return (ret == 0 ? ENOMEM : ret);
+		}
+		cnt = mtxregion->stat.st_mutex_cnt / 2;
+		if (cnt < 8)
+			cnt = 8;
+		if (mtxregion->stat.st_mutex_max != 0 &&
+		    mtxregion->stat.st_mutex_cnt + cnt >
+		    mtxregion->stat.st_mutex_max)
+			cnt = mtxregion->stat.st_mutex_max -
+			    mtxregion->stat.st_mutex_cnt;
+		if (F_ISSET(env, ENV_PRIVATE)) {
+			F_SET(&mtxmgr->reginfo, REGION_TRACKED);
+			while (__env_alloc(&mtxmgr->reginfo,
+			    (cnt * mtxregion->mutex_size) +
+			    mtxregion->stat.st_mutex_align, &i) != 0)
+				if ((cnt >> 1) == 0)
+					break;
+			F_CLR(&mtxmgr->reginfo, REGION_TRACKED);
+			i = (db_mutex_t)ALIGNP_INC(i,
+			    mtxregion->stat.st_mutex_align);
+		} else {
+			len = cnt * mtxregion->mutex_size;
+			if ((ret = __env_alloc_extend(&mtxmgr->reginfo,
+			    R_ADDR(&mtxmgr->reginfo,
+			    mtxregion->mutex_off_alloc), &len)) != 0)
+				goto nomem;
+			cnt = (u_int32_t)(len / mtxregion->mutex_size);
+			i = mtxregion->stat.st_mutex_cnt + 1;
+		}
+		if (cnt == 0)
+			goto nomem;
+		mutexp = MUTEXP_SET(env, i);
+		mtxregion->stat.st_mutex_free = cnt;
+		mtxregion->mutex_next = i;
+		mtxregion->stat.st_mutex_cnt += cnt;
+		while (--cnt > 0) {
+			mutexp->flags = 0;
+			if (F_ISSET(env, ENV_PRIVATE))
+				mutexp->mutex_next_link =
+				    (uintptr_t)(mutexp + 1);
+			else
+				mutexp->mutex_next_link = ++i;
+			mutexp++;
+		}
+		mutexp->flags = 0;
+		mutexp->mutex_next_link = MUTEX_INVALID;
+	}
+
+	*indxp = mtxregion->mutex_next;
+	mutexp = MUTEXP_SET(env, *indxp);
+	DB_ASSERT(env,
+	    ((uintptr_t)mutexp & (dbenv->mutex_align - 1)) == 0);
+	mtxregion->mutex_next = mutexp->mutex_next_link;
+
+	--mtxregion->stat.st_mutex_free;
+	++mtxregion->stat.st_mutex_inuse;
+	if (mtxregion->stat.st_mutex_inuse > mtxregion->stat.st_mutex_inuse_max)
+		mtxregion->stat.st_mutex_inuse_max =
+		    mtxregion->stat.st_mutex_inuse;
+	if (locksys)
+		MUTEX_SYSTEM_UNLOCK(env);
+
+	/* Initialize the mutex. */
+	memset(mutexp, 0, sizeof(*mutexp));
+	F_SET(mutexp, DB_MUTEX_ALLOCATED |
+	    LF_ISSET(DB_MUTEX_LOGICAL_LOCK |
+		DB_MUTEX_PROCESS_ONLY | DB_MUTEX_SHARED));
+
+	/*
+	 * If the mutex is associated with a single process, set the process
+	 * ID.  If the application ever calls DbEnv::failchk, we'll need the
+	 * process ID to know if the mutex is still in use.
+	 */
+	if (LF_ISSET(DB_MUTEX_PROCESS_ONLY))
+		dbenv->thread_id(dbenv, &mutexp->pid, NULL);
+
+#ifdef HAVE_STATISTICS
+	mutexp->alloc_id = alloc_id;
+#else
+	COMPQUIET(alloc_id, 0);
+#endif
+
+	if ((ret = __mutex_init(env, *indxp, flags)) != 0)
+		(void)__mutex_free_int(env, locksys, indxp);
+
+	return (ret);
+}
+
+/*
+ * __mutex_free --
+ *	Free a mutex.
+ *
+ * PUBLIC: int __mutex_free __P((ENV *, db_mutex_t *));
+ */
+int
+__mutex_free(env, indxp)
+	ENV *env;
+	db_mutex_t *indxp;
+{
+	/*
+	 * There is no explicit ordering in how the regions are cleaned up
+	 * up and/or discarded when an environment is destroyed (either a
+	 * private environment is closed or a public environment is removed).
+	 * The way we deal with mutexes is to clean up all remaining mutexes
+	 * when we close the mutex environment (because we have to be able to
+	 * do that anyway, after a crash), which means we don't have to deal
+	 * with region cleanup ordering on normal environment destruction.
+	 * All that said, what it really means is we can get here without a
+	 * mpool region.  It's OK, the mutex has been, or will be, destroyed.
+	 *
+	 * If the mutex has never been configured, we're done.
+	 */
+	if (!MUTEX_ON(env) || *indxp == MUTEX_INVALID)
+		return (0);
+
+	return (__mutex_free_int(env, 1, indxp));
+}
+
+/*
+ * __mutex_free_int --
+ *	Internal routine to free a mutex.
+ *
+ * PUBLIC: int __mutex_free_int __P((ENV *, int, db_mutex_t *));
+ */
+int
+__mutex_free_int(env, locksys, indxp)
+	ENV *env;
+	int locksys;
+	db_mutex_t *indxp;
+{
+	DB_MUTEX *mutexp;
+	DB_MUTEXMGR *mtxmgr;
+	DB_MUTEXREGION *mtxregion;
+	db_mutex_t mutex;
+	int ret;
+
+	mutex = *indxp;
+	*indxp = MUTEX_INVALID;
+
+	mtxmgr = env->mutex_handle;
+	mtxregion = mtxmgr->reginfo.primary;
+	mutexp = MUTEXP_SET(env, mutex);
+
+	DB_ASSERT(env, F_ISSET(mutexp, DB_MUTEX_ALLOCATED));
+	F_CLR(mutexp, DB_MUTEX_ALLOCATED);
+
+	ret = __mutex_destroy(env, mutex);
+
+	if (locksys)
+		MUTEX_SYSTEM_LOCK(env);
+
+	/* Link the mutex on the head of the free list. */
+	mutexp->mutex_next_link = mtxregion->mutex_next;
+	mtxregion->mutex_next = mutex;
+	++mtxregion->stat.st_mutex_free;
+	--mtxregion->stat.st_mutex_inuse;
+
+	if (locksys)
+		MUTEX_SYSTEM_UNLOCK(env);
+
+	return (ret);
+}
+
+/*
+ * __mutex_refresh --
+ *	Reinitialize a mutex, if we are not sure of its state.
+ *
+ * PUBLIC: int __mutex_refresh __P((ENV *, db_mutex_t));
+ */
+int
+__mutex_refresh(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	DB_MUTEX *mutexp;
+	u_int32_t flags;
+	int ret;
+
+	mutexp = MUTEXP_SET(env, mutex);
+	flags = mutexp->flags;
+	if ((ret = __mutex_destroy(env, mutex)) == 0) {
+		memset(mutexp, 0, sizeof(*mutexp));
+		F_SET(mutexp, DB_MUTEX_ALLOCATED |
+		    LF_ISSET(DB_MUTEX_LOGICAL_LOCK |
+			DB_MUTEX_PROCESS_ONLY | DB_MUTEX_SHARED));
+		LF_CLR(DB_MUTEX_LOCKED);
+		ret = __mutex_init(env, mutex, flags);
+	}
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mutex/mut_method.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,504 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __mutex_alloc_pp --
+ *	Allocate a mutex, application method.
+ *
+ * PUBLIC: int __mutex_alloc_pp __P((DB_ENV *, u_int32_t, db_mutex_t *));
+ */
+int
+__mutex_alloc_pp(dbenv, flags, indxp)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+	db_mutex_t *indxp;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	if ((ret = __db_fchk(env, "DB_ENV->mutex_alloc",
+	    flags, DB_MUTEX_PROCESS_ONLY | DB_MUTEX_SELF_BLOCK)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+	ret = __mutex_alloc(env, MTX_APPLICATION, flags, indxp);
+	ENV_LEAVE(env, ip);
+
+	return (ret);
+}
+
+/*
+ * __mutex_free_pp --
+ *	Destroy a mutex, application method.
+ *
+ * PUBLIC: int __mutex_free_pp __P((DB_ENV *, db_mutex_t));
+ */
+int
+__mutex_free_pp(dbenv, indx)
+	DB_ENV *dbenv;
+	db_mutex_t indx;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	if (indx == MUTEX_INVALID)
+		return (EINVAL);
+
+	/*
+	 * Internally Berkeley DB passes around the db_mutex_t address on
+	 * free, because we want to make absolutely sure the slot gets
+	 * overwritten with MUTEX_INVALID.  We don't export MUTEX_INVALID,
+	 * so we don't export that part of the API, either.
+	 */
+	ENV_ENTER(env, ip);
+	ret = __mutex_free(env, &indx);
+	ENV_LEAVE(env, ip);
+
+	return (ret);
+}
+
+/*
+ * __mutex_lock --
+ *	Lock a mutex, application method.
+ *
+ * PUBLIC: int __mutex_lock_pp __P((DB_ENV *, db_mutex_t));
+ */
+int
+__mutex_lock_pp(dbenv, indx)
+	DB_ENV *dbenv;
+	db_mutex_t indx;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	if (indx == MUTEX_INVALID)
+		return (EINVAL);
+
+	ENV_ENTER(env, ip);
+	ret = __mutex_lock(env, indx);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __mutex_unlock --
+ *	Unlock a mutex, application method.
+ *
+ * PUBLIC: int __mutex_unlock_pp __P((DB_ENV *, db_mutex_t));
+ */
+int
+__mutex_unlock_pp(dbenv, indx)
+	DB_ENV *dbenv;
+	db_mutex_t indx;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	if (indx == MUTEX_INVALID)
+		return (EINVAL);
+
+	ENV_ENTER(env, ip);
+	ret = __mutex_unlock(env, indx);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __mutex_get_align --
+ *	DB_ENV->mutex_get_align.
+ *
+ * PUBLIC: int __mutex_get_align __P((DB_ENV *, u_int32_t *));
+ */
+int
+__mutex_get_align(dbenv, alignp)
+	DB_ENV *dbenv;
+	u_int32_t *alignp;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	if (MUTEX_ON(env)) {
+		/* Cannot be set after open, no lock required to read. */
+		*alignp = ((DB_MUTEXREGION *)
+		    env->mutex_handle->reginfo.primary)->stat.st_mutex_align;
+	} else
+		*alignp = dbenv->mutex_align;
+	return (0);
+}
+
+/*
+ * __mutex_set_align --
+ *	DB_ENV->mutex_set_align.
+ *
+ * PUBLIC: int __mutex_set_align __P((DB_ENV *, u_int32_t));
+ */
+int
+__mutex_set_align(dbenv, align)
+	DB_ENV *dbenv;
+	u_int32_t align;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_mutex_align");
+
+	if (align == 0 || !POWER_OF_TWO(align)) {
+		__db_errx(env, DB_STR("2018",
+"DB_ENV->mutex_set_align: alignment value must be a non-zero power-of-two"));
+		return (EINVAL);
+	}
+
+	dbenv->mutex_align = align;
+	return (0);
+}
+
+/*
+ * __mutex_get_increment --
+ *	DB_ENV->mutex_get_increment.
+ *
+ * PUBLIC: int __mutex_get_increment __P((DB_ENV *, u_int32_t *));
+ */
+int
+__mutex_get_increment(dbenv, incrementp)
+	DB_ENV *dbenv;
+	u_int32_t *incrementp;
+{
+	/*
+	 * We don't maintain the increment in the region (it just makes
+	 * no sense).  Return whatever we have configured on this handle,
+	 * nobody is ever going to notice.
+	 */
+	*incrementp = dbenv->mutex_inc;
+	return (0);
+}
+
+/*
+ * __mutex_set_increment --
+ *	DB_ENV->mutex_set_increment.
+ *
+ * PUBLIC: int __mutex_set_increment __P((DB_ENV *, u_int32_t));
+ */
+int
+__mutex_set_increment(dbenv, increment)
+	DB_ENV *dbenv;
+	u_int32_t increment;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_mutex_increment");
+
+	dbenv->mutex_cnt = 0;
+	dbenv->mutex_inc = increment;
+	return (0);
+}
+
+/*
+ * __mutex_get_init --
+ *	DB_ENV->mutex_get_init.
+ *
+ * PUBLIC: int __mutex_get_init __P((DB_ENV *, u_int32_t *));
+ */
+int
+__mutex_get_init(dbenv, initp)
+	DB_ENV *dbenv;
+	u_int32_t *initp;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	if (MUTEX_ON(env)) {
+		/* Cannot be set after open, no lock required to read. */
+		*initp = ((DB_MUTEXREGION *)
+		    env->mutex_handle->reginfo.primary)->stat.st_mutex_init;
+	} else
+		*initp = dbenv->mutex_cnt;
+	return (0);
+}
+
+/*
+ * __mutex_set_init --
+ *	DB_ENV->mutex_set_init.
+ *
+ * PUBLIC: int __mutex_set_init __P((DB_ENV *, u_int32_t));
+ */
+int
+__mutex_set_init(dbenv, init)
+	DB_ENV *dbenv;
+	u_int32_t init;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_mutex_init");
+
+	dbenv->mutex_cnt = init;
+	dbenv->mutex_inc = 0;
+	return (0);
+}
+
+/*
+ * __mutex_get_max --
+ *	DB_ENV->mutex_get_max.
+ *
+ * PUBLIC: int __mutex_get_max __P((DB_ENV *, u_int32_t *));
+ */
+int
+__mutex_get_max(dbenv, maxp)
+	DB_ENV *dbenv;
+	u_int32_t *maxp;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	if (MUTEX_ON(env)) {
+		/* Cannot be set after open, no lock required to read. */
+		*maxp = ((DB_MUTEXREGION *)
+		    env->mutex_handle->reginfo.primary)->stat.st_mutex_max;
+	} else
+		*maxp = dbenv->mutex_max;
+	return (0);
+}
+
+/*
+ * __mutex_set_max --
+ *	DB_ENV->mutex_set_max.
+ *
+ * PUBLIC: int __mutex_set_max __P((DB_ENV *, u_int32_t));
+ */
+int
+__mutex_set_max(dbenv, max)
+	DB_ENV *dbenv;
+	u_int32_t max;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_mutex_max");
+
+	dbenv->mutex_max = max;
+	dbenv->mutex_inc = 0;
+	return (0);
+}
+
+/*
+ * __mutex_get_tas_spins --
+ *	DB_ENV->mutex_get_tas_spins.
+ *
+ * PUBLIC: int __mutex_get_tas_spins __P((DB_ENV *, u_int32_t *));
+ */
+int
+__mutex_get_tas_spins(dbenv, tas_spinsp)
+	DB_ENV *dbenv;
+	u_int32_t *tas_spinsp;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	if (MUTEX_ON(env)) {
+		/* Cannot be set after open, no lock required to read. */
+		*tas_spinsp = ((DB_MUTEXREGION *)env->
+		    mutex_handle->reginfo.primary)->stat.st_mutex_tas_spins;
+	} else
+		*tas_spinsp = dbenv->mutex_tas_spins;
+	return (0);
+}
+
+/*
+ * __mutex_set_tas_spins --
+ *	DB_ENV->mutex_set_tas_spins.
+ *
+ * PUBLIC: int __mutex_set_tas_spins __P((DB_ENV *, u_int32_t));
+ */
+int
+__mutex_set_tas_spins(dbenv, tas_spins)
+	DB_ENV *dbenv;
+	u_int32_t tas_spins;
+{
+	ENV *env;
+
+	env = dbenv->env;
+
+	/*
+	 * Bound the value -- less than 1 makes no sense, greater than 1M
+	 * makes no sense.
+	 */
+	if (tas_spins == 0)
+		tas_spins = 1;
+	else if (tas_spins > 1000000)
+		tas_spins = 1000000;
+
+	/*
+	 * There's a theoretical race here, but I'm not interested in locking
+	 * the test-and-set spin count.  The worst possibility is a thread
+	 * reads out a bad spin count and spins until it gets the lock, but
+	 * that's awfully unlikely.
+	 */
+	if (MUTEX_ON(env))
+		((DB_MUTEXREGION *)env->mutex_handle
+		    ->reginfo.primary)->stat.st_mutex_tas_spins = tas_spins;
+	else
+		dbenv->mutex_tas_spins = tas_spins;
+	return (0);
+}
+
+#if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT)
+/*
+ * Provide atomic operations for platforms which have mutexes yet do not have
+ * native atomic operations configured. They are emulated by protected the
+ * operation with a mutex.  The address of the atomic value selects which
+ * mutex to use.
+ */
+/*
+ * atomic_get_mutex -
+ *	Map an address to the mutex to use to atomically modify it
+ */
+static inline db_mutex_t atomic_get_mutex(env, v)
+	ENV *env;
+	db_atomic_t *v;
+{
+	u_int	index;
+	DB_MUTEXREGION *mtxreg;
+
+	if (!MUTEX_ON(env))
+		return (MUTEX_INVALID);
+	index = (u_int)(((uintptr_t) (v)) >> 6) % MAX_ATOMIC_MUTEXES;
+	mtxreg = (DB_MUTEXREGION *)env->mutex_handle->reginfo.primary;
+	return (mtxreg->mtx_atomic[index]);
+}
+
+/*
+ * __atomic_inc
+ *	Use a mutex to provide an atomic increment function
+ *
+ * PUBLIC: #if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT)
+ * PUBLIC: atomic_value_t __atomic_inc __P((ENV *, db_atomic_t *));
+ * PUBLIC: #endif
+ */
+atomic_value_t
+__atomic_inc(env, v)
+	ENV *env;
+	db_atomic_t *v;
+{
+	db_mutex_t mtx;
+	int ret;
+
+	mtx = atomic_get_mutex(env, v);
+	MUTEX_LOCK(env, mtx);
+	ret = ++v->value;
+	MUTEX_UNLOCK(env, mtx);
+
+	return (ret);
+}
+
+/*
+ * __atomic_dec
+ *	Use a mutex to provide an atomic decrement function
+ *
+ * PUBLIC: #if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT)
+ * PUBLIC: atomic_value_t __atomic_dec __P((ENV *, db_atomic_t *));
+ * PUBLIC: #endif
+ */
+atomic_value_t
+__atomic_dec(env, v)
+	ENV *env;
+	db_atomic_t *v;
+{
+	db_mutex_t mtx;
+	int ret;
+
+	mtx = atomic_get_mutex(env, v);
+	MUTEX_LOCK(env, mtx);
+	ret = --v->value;
+	MUTEX_UNLOCK(env, mtx);
+
+	return (ret);
+}
+
+/*
+ * atomic_compare_exchange
+ *	Use a mutex to provide an atomic decrement function
+ *
+ * PUBLIC: #if !defined(HAVE_ATOMIC_SUPPORT) && defined(HAVE_MUTEX_SUPPORT)
+ * PUBLIC: int atomic_compare_exchange
+ * PUBLIC:     __P((ENV *, db_atomic_t *, atomic_value_t, atomic_value_t));
+ * PUBLIC: #endif
+ *	Returns 1 if the *v was equal to oldval, else 0
+ *
+ *	Side Effect:
+ *		Sets the value to newval if and only if returning 1
+ */
+int
+atomic_compare_exchange(env, v, oldval, newval)
+	ENV *env;
+	db_atomic_t *v;
+	atomic_value_t oldval;
+	atomic_value_t newval;
+{
+	db_mutex_t mtx;
+	int ret;
+
+	if (atomic_read(v) != oldval)
+		return (0);
+
+	mtx = atomic_get_mutex(env, v);
+	MUTEX_LOCK(env, mtx);
+	ret = atomic_read(v) == oldval;
+	if (ret)
+		atomic_init(v, newval);
+	MUTEX_UNLOCK(env, mtx);
+
+	return (ret);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mutex/mut_pthread.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,792 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/lock.h"
+
+/*
+ * This is where we load in architecture/compiler specific mutex code.
+ */
+#define	LOAD_ACTUAL_MUTEX_CODE
+
+#ifdef HAVE_MUTEX_SOLARIS_LWP
+#define	pthread_cond_destroy(x)		0
+#define	pthread_cond_signal		_lwp_cond_signal
+#define	pthread_cond_broadcast		_lwp_cond_broadcast
+#define	pthread_cond_wait		_lwp_cond_wait
+#define	pthread_mutex_destroy(x)	0
+#define	pthread_mutex_lock		_lwp_mutex_lock
+#define	pthread_mutex_trylock		_lwp_mutex_trylock
+#define	pthread_mutex_unlock		_lwp_mutex_unlock
+#endif
+#ifdef HAVE_MUTEX_UI_THREADS
+#define	pthread_cond_destroy(x)		cond_destroy
+#define	pthread_cond_broadcast		cond_broadcast
+#define	pthread_cond_wait		cond_wait
+#define	pthread_mutex_destroy		mutex_destroy
+#define	pthread_mutex_lock		mutex_lock
+#define	pthread_mutex_trylock		mutex_trylock
+#define	pthread_mutex_unlock		mutex_unlock
+#endif
+
+/*
+ * According to HP-UX engineers contacted by Netscape,
+ * pthread_mutex_unlock() will occasionally return EFAULT for no good reason
+ * on mutexes in shared memory regions, and the correct caller behavior
+ * is to try again.  Do so, up to EFAULT_RETRY_ATTEMPTS consecutive times.
+ * Note that we don't bother to restrict this to HP-UX;
+ * it should be harmless elsewhere. [#2471]
+ */
+#define	EFAULT_RETRY_ATTEMPTS	5
+#define	RETRY_ON_EFAULT(func_invocation, ret) do {	\
+	int i;						\
+	i = EFAULT_RETRY_ATTEMPTS;			\
+	do {						\
+		RET_SET((func_invocation), ret);	\
+	} while (ret == EFAULT && --i > 0);		\
+} while (0)
+
+/*
+ * IBM's MVS pthread mutex implementation returns -1 and sets errno rather than
+ * returning errno itself.  As -1 is not a valid errno value, assume functions
+ * returning -1 have set errno.  If they haven't, return a random error value.
+ */
+#define	RET_SET(f, ret) do {						\
+	if (((ret) = (f)) == -1 && ((ret) = errno) == 0)		\
+		(ret) = EAGAIN;						\
+} while (0)
+
+/*
+ * __db_pthread_mutex_init --
+ *	Initialize a pthread mutex: either a native one or
+ *	just the mutex for block/wakeup of a hybrid test-and-set mutex
+ *
+ *
+ * PUBLIC: int __db_pthread_mutex_init __P((ENV *, db_mutex_t, u_int32_t));
+ */
+int
+__db_pthread_mutex_init(env, mutex, flags)
+	ENV *env;
+	db_mutex_t mutex;
+	u_int32_t flags;
+{
+	DB_MUTEX *mutexp;
+	int ret;
+
+	mutexp = MUTEXP_SET(env, mutex);
+	ret = 0;
+
+#ifndef HAVE_MUTEX_HYBRID
+	/* Can't have self-blocking shared latches.  */
+	DB_ASSERT(env, !LF_ISSET(DB_MUTEX_SELF_BLOCK) ||
+	    !LF_ISSET(DB_MUTEX_SHARED));
+#endif
+
+#ifdef HAVE_MUTEX_PTHREADS
+	{
+#ifndef HAVE_MUTEX_THREAD_ONLY
+	pthread_condattr_t condattr;
+	pthread_mutexattr_t mutexattr;
+#endif
+	pthread_condattr_t *condattrp = NULL;
+	pthread_mutexattr_t *mutexattrp = NULL;
+
+#ifndef HAVE_MUTEX_HYBRID
+	if (LF_ISSET(DB_MUTEX_SHARED)) {
+#if defined(HAVE_SHARED_LATCHES)
+		pthread_rwlockattr_t rwlockattr, *rwlockattrp = NULL;
+#ifndef HAVE_MUTEX_THREAD_ONLY
+		if (!LF_ISSET(DB_MUTEX_PROCESS_ONLY)) {
+			RET_SET((pthread_rwlockattr_init(&rwlockattr)), ret);
+			if (ret != 0)
+				goto err;
+			RET_SET((pthread_rwlockattr_setpshared(
+			    &rwlockattr, PTHREAD_PROCESS_SHARED)), ret);
+			rwlockattrp = &rwlockattr;
+		}
+#endif
+
+		if (ret == 0)
+			RET_SET((pthread_rwlock_init(&mutexp->u.rwlock,
+			    rwlockattrp)), ret);
+		if (rwlockattrp != NULL)
+			(void)pthread_rwlockattr_destroy(rwlockattrp);
+
+		F_SET(mutexp, DB_MUTEX_SHARED);
+		/* For rwlocks, we're done - cannot use the mutex or cond */
+		goto err;
+#endif
+	}
+#endif
+#ifndef HAVE_MUTEX_THREAD_ONLY
+	if (!LF_ISSET(DB_MUTEX_PROCESS_ONLY)) {
+		RET_SET((pthread_mutexattr_init(&mutexattr)), ret);
+		if (ret != 0)
+			goto err;
+		RET_SET((pthread_mutexattr_setpshared(
+		    &mutexattr, PTHREAD_PROCESS_SHARED)), ret);
+		mutexattrp = &mutexattr;
+	}
+#endif
+
+	if (ret == 0)
+		RET_SET(
+		    (pthread_mutex_init(&mutexp->u.m.mutex, mutexattrp)), ret);
+
+	if (mutexattrp != NULL)
+		(void)pthread_mutexattr_destroy(mutexattrp);
+	if (ret != 0)
+		goto err;
+	if (LF_ISSET(DB_MUTEX_SELF_BLOCK)) {
+#ifndef HAVE_MUTEX_THREAD_ONLY
+		if (!LF_ISSET(DB_MUTEX_PROCESS_ONLY)) {
+			RET_SET((pthread_condattr_init(&condattr)), ret);
+			if (ret != 0)
+				goto err;
+
+			condattrp = &condattr;
+			RET_SET((pthread_condattr_setpshared(
+			    &condattr, PTHREAD_PROCESS_SHARED)), ret);
+		}
+#endif
+
+		if (ret == 0)
+			RET_SET((pthread_cond_init(
+			    &mutexp->u.m.cond, condattrp)), ret);
+
+		F_SET(mutexp, DB_MUTEX_SELF_BLOCK);
+		if (condattrp != NULL)
+			(void)pthread_condattr_destroy(condattrp);
+	}
+
+	}
+#endif
+#ifdef HAVE_MUTEX_SOLARIS_LWP
+	/*
+	 * XXX
+	 * Gcc complains about missing braces in the static initializations of
+	 * lwp_cond_t and lwp_mutex_t structures because the structures contain
+	 * sub-structures/unions and the Solaris include file that defines the
+	 * initialization values doesn't have surrounding braces.  There's not
+	 * much we can do.
+	 */
+	if (LF_ISSET(DB_MUTEX_PROCESS_ONLY)) {
+		static lwp_mutex_t mi = DEFAULTMUTEX;
+
+		mutexp->mutex = mi;
+	} else {
+		static lwp_mutex_t mi = SHAREDMUTEX;
+
+		mutexp->mutex = mi;
+	}
+	if (LF_ISSET(DB_MUTEX_SELF_BLOCK)) {
+		if (LF_ISSET(DB_MUTEX_PROCESS_ONLY)) {
+			static lwp_cond_t ci = DEFAULTCV;
+
+			mutexp->cond = ci;
+		} else {
+			static lwp_cond_t ci = SHAREDCV;
+
+			mutexp->cond = ci;
+		}
+		F_SET(mutexp, DB_MUTEX_SELF_BLOCK);
+	}
+#endif
+#ifdef HAVE_MUTEX_UI_THREADS
+	{
+	int type;
+
+	type = LF_ISSET(DB_MUTEX_PROCESS_ONLY) ? USYNC_THREAD : USYNC_PROCESS;
+
+	ret = mutex_init(&mutexp->mutex, type, NULL);
+	if (ret == 0 && LF_ISSET(DB_MUTEX_SELF_BLOCK)) {
+		ret = cond_init(&mutexp->cond, type, NULL);
+
+		F_SET(mutexp, DB_MUTEX_SELF_BLOCK);
+	}}
+#endif
+
+err:	if (ret != 0) {
+		__db_err(env, ret, DB_STR("2021",
+		    "unable to initialize mutex"));
+	}
+	return (ret);
+}
+
+/*
+ * __db_pthread_mutex_prep
+ *	Prepare to use a pthread-based DB_MUTEX.
+ *
+ *	This exclusively locks a DB_MUTEX's pthread_mutex_t or pthread_rwlock_t,
+ *	before locking, unlocking, or waiting for the DB mutex to be become
+ *	available in the requested mode (exclusive == 1, shared == 0).
+ *
+ *	Test for failchk concerns here too, to avoid hanging on a dead pid/tid.
+ */
+inline static int
+__db_pthread_mutex_prep(env, mutex, mutexp, exclusive)
+	ENV *env;
+	db_mutex_t mutex;
+	DB_MUTEX *mutexp;
+	int exclusive;
+{
+	DB_ENV *dbenv;
+	DB_THREAD_INFO *ip;
+	int ret;
+
+	dbenv = env->dbenv;
+	PERFMON4(env,
+	    mutex, suspend, mutex, exclusive, mutexp->alloc_id, mutexp);
+	if (F_ISSET(dbenv, DB_ENV_FAILCHK)) {
+		for (;;) {
+			RET_SET_PTHREAD_TRYLOCK(mutexp, ret);
+			if (ret != EBUSY)
+				break;
+			if (dbenv->is_alive(dbenv,
+			    mutexp->pid, mutexp->tid, 0) == 0) {
+				ret = __env_set_state(env, &ip, THREAD_VERIFY);
+				if (ret != 0 ||
+				    ip->dbth_state == THREAD_FAILCHK) {
+					ret = DB_RUNRECOVERY;
+				} else {
+					/*
+					 * Some thread other than the true
+					 * FAILCHK thread in this process is
+					 * asking for the mutex held by the
+					 * dead process/thread.  We will block
+					 * here until someone else does the
+					 * cleanup.  Same behavior as if we
+					 * hadn't gone down the 'if
+					 * DB_ENV_FAILCHK' path to start with.
+					 */
+				    RET_SET_PTHREAD_LOCK(mutexp, ret);
+				    break;
+				}
+			}
+		}
+	} else
+		RET_SET_PTHREAD_LOCK(mutexp, ret);
+
+	PERFMON4(env,
+	    mutex, resume, mutex, exclusive, mutexp->alloc_id, mutexp);
+	COMPQUIET(mutex, 0);
+	COMPQUIET(exclusive, 0);
+	return (ret);
+}
+
+/*
+ * __db_pthread_mutex_condwait
+ *	Perform a pthread condition wait for a DB_MUTEX.
+ *
+ *	This will be a timed wait when a timespec has been specified. EINTR and
+ *	spurious ETIME* values are mapped to 0, and hence success.  The
+ *	mutexp->u.m.mutex must be locked upon entry. When returning a success
+ *	or timeout status it will have been locked again.
+ *
+ *	Returns:
+ *		0 if it is safe to retry to get the mutex
+ *		DB_TIMEOUT if the timeout exceeded
+ *		<other> a fatal error. The mutexp->u.m.mutex has been unlocked.
+ */
+inline static int
+__db_pthread_mutex_condwait(env, mutex, mutexp, timespec)
+	ENV *env;
+	db_mutex_t mutex;
+	DB_MUTEX *mutexp;
+	db_timespec *timespec;
+{
+	int ret;
+
+#ifdef MUTEX_DIAG
+	printf("condwait %ld %x wait busy %x count %d\n",
+	    mutex, pthread_self(), MUTEXP_BUSY_FIELD(mutexp), mutexp->wait);
+#endif
+	PERFMON4(env, mutex, suspend, mutex, TRUE, mutexp->alloc_id, mutexp);
+
+	if (timespec != NULL) {
+		RET_SET((pthread_cond_timedwait(&mutexp->u.m.cond,
+		    &mutexp->u.m.mutex, (struct timespec *) timespec)), ret);
+		if (ret == ETIMEDOUT) {
+			ret = DB_TIMEOUT;
+			goto ret;
+		}
+	} else
+		RET_SET((pthread_cond_wait(&mutexp->u.m.cond,
+		    &mutexp->u.m.mutex)), ret);
+#ifdef MUTEX_DIAG
+	printf("condwait %ld %x wait returns %d busy %x\n",
+	    mutex, pthread_self(), ret, MUTEXP_BUSY_FIELD(mutexp));
+#endif
+	/*
+	 * !!!
+	 * Solaris bug workaround: pthread_cond_wait() sometimes returns ETIME
+	 * -- out  of sheer paranoia, check both ETIME and ETIMEDOUT.  We
+	 * believe this happens when the application uses SIGALRM for some
+	 * purpose, e.g., the C library sleep call, and Solaris delivers the
+	 * signal to the wrong  LWP.
+	 */
+	if (ret != 0) {
+		if (ret == ETIMEDOUT ||
+#ifdef ETIME
+		    ret == ETIME ||
+#endif
+		    ret == EINTR)
+			ret = 0;
+		else
+			/* Failure, caller shouldn't condwait again. */
+			(void)pthread_mutex_unlock(&mutexp->u.m.mutex);
+	}
+
+ret:
+	PERFMON4(env, mutex, resume, mutex, TRUE, mutexp->alloc_id, mutexp);
+
+	COMPQUIET(mutex, 0);
+	COMPQUIET(env, 0);
+	return (ret);
+}
+
+#ifndef HAVE_MUTEX_HYBRID
+/*
+ * __db_pthread_mutex_lock
+ *	Lock on a mutex, blocking if necessary.
+ *	Timeouts are supported only for self-blocking mutexes.
+ *
+ *	Self-blocking shared latches are not supported.
+ *
+ * PUBLIC: #ifndef HAVE_MUTEX_HYBRID
+ * PUBLIC: int __db_pthread_mutex_lock __P((ENV *, db_mutex_t, db_timeout_t));
+ * PUBLIC: #endif
+ */
+int
+__db_pthread_mutex_lock(env, mutex, timeout)
+	ENV *env;
+	db_mutex_t mutex;
+	db_timeout_t timeout;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	db_timespec timespec;
+	int ret, t_ret;
+
+	dbenv = env->dbenv;
+
+	if (!MUTEX_ON(env) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
+		return (0);
+
+	t_ret = 0;
+	mutexp = MUTEXP_SET(env, mutex);
+
+	CHECK_MTX_THREAD(env, mutexp);
+
+#if defined(HAVE_STATISTICS)
+	/*
+	 * We want to know which mutexes are contentious, but don't want to
+	 * do an interlocked test here -- that's slower when the underlying
+	 * system has adaptive mutexes and can perform optimizations like
+	 * spinning only if the thread holding the mutex is actually running
+	 * on a CPU.  Make a guess, using a normal load instruction.
+	 */
+	if (F_ISSET(mutexp, DB_MUTEX_LOCKED))
+		STAT_INC(env, mutex, set_wait, mutexp->mutex_set_wait, mutex);
+	else
+		STAT_INC(env,
+		    mutex, set_nowait, mutexp->mutex_set_nowait, mutex);
+#endif
+
+	/* Single-thread the next block, except during the possible condwait. */
+	if ((ret = __db_pthread_mutex_prep(env, mutex, mutexp, TRUE)) != 0)
+		goto err;
+
+	if (F_ISSET(mutexp, DB_MUTEX_SELF_BLOCK)) {
+		if (timeout != 0)
+			timespecclear(&timespec);
+		while (MUTEXP_IS_BUSY(mutexp)) {
+			/* Set expiration timer upon first need. */
+			if (timeout != 0 && !timespecisset(&timespec)) {
+				timespecclear(&timespec);
+				__clock_set_expires(env, &timespec, timeout);
+			}
+			t_ret = __db_pthread_mutex_condwait(env,
+			    mutex, mutexp, timeout == 0 ? NULL : &timespec);
+			if (t_ret != 0) {
+				if (t_ret == DB_TIMEOUT)
+					goto out;
+				ret = t_ret;
+				goto err;
+			}
+		}
+
+		F_SET(mutexp, DB_MUTEX_LOCKED);
+		dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid);
+out:
+		/* #2471: HP-UX can sporadically return EFAULT. See above */
+		RETRY_ON_EFAULT(pthread_mutex_unlock(&mutexp->u.m.mutex), ret);
+		if (ret != 0)
+			goto err;
+	} else {
+#ifdef DIAGNOSTIC
+		if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) {
+			char buf[DB_THREADID_STRLEN];
+			(void)dbenv->thread_id_string(dbenv,
+			    mutexp->pid, mutexp->tid, buf);
+			__db_errx(env, DB_STR_A("2022",
+		    "pthread lock failed: lock currently in use: pid/tid: %s",
+			    "%s"), buf);
+			ret = EINVAL;
+			goto err;
+		}
+#endif
+		F_SET(mutexp, DB_MUTEX_LOCKED);
+		dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid);
+	}
+
+#ifdef DIAGNOSTIC
+	/*
+	 * We want to switch threads as often as possible.  Yield every time
+	 * we get a mutex to ensure contention.
+	 */
+	if (F_ISSET(dbenv, DB_ENV_YIELDCPU))
+		__os_yield(env, 0, 0);
+#endif
+	return (t_ret);
+
+err:
+	__db_err(env, ret, DB_STR("2023", "pthread lock failed"));
+	return (__env_panic(env, ret));
+}
+#endif
+
+#if defined(HAVE_SHARED_LATCHES) && !defined(HAVE_MUTEX_HYBRID)
+/*
+ * __db_pthread_mutex_readlock
+ *	Take a shared lock on a mutex, blocking if necessary.
+ *
+ * PUBLIC: #if defined(HAVE_SHARED_LATCHES)
+ * PUBLIC: int __db_pthread_mutex_readlock __P((ENV *, db_mutex_t));
+ * PUBLIC: #endif
+ */
+int
+__db_pthread_mutex_readlock(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	int ret;
+
+	dbenv = env->dbenv;
+
+	if (!MUTEX_ON(env) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
+		return (0);
+
+	mutexp = MUTEXP_SET(env, mutex);
+	DB_ASSERT(env, F_ISSET(mutexp, DB_MUTEX_SHARED));
+
+	CHECK_MTX_THREAD(env, mutexp);
+
+#if defined(HAVE_STATISTICS)
+	/*
+	 * We want to know which mutexes are contentious, but don't want to
+	 * do an interlocked test here -- that's slower when the underlying
+	 * system has adaptive mutexes and can perform optimizations like
+	 * spinning only if the thread holding the mutex is actually running
+	 * on a CPU.  Make a guess, using a normal load instruction.
+	 */
+	if (F_ISSET(mutexp, DB_MUTEX_LOCKED))
+		STAT_INC(env,
+		    mutex, set_rd_wait, mutexp->mutex_set_rd_wait, mutex);
+	else
+		STAT_INC(env,
+		    mutex, set_rd_nowait, mutexp->mutex_set_rd_nowait, mutex);
+#endif
+
+	PERFMON4(env, mutex, suspend, mutex, FALSE, mutexp->alloc_id, mutexp);
+	RET_SET((pthread_rwlock_rdlock(&mutexp->u.rwlock)), ret);
+	PERFMON4(env, mutex, resume, mutex, FALSE, mutexp->alloc_id, mutexp);
+	DB_ASSERT(env, !F_ISSET(mutexp, DB_MUTEX_LOCKED));
+	if (ret != 0)
+		goto err;
+
+#ifdef DIAGNOSTIC
+	/*
+	 * We want to switch threads as often as possible.  Yield every time
+	 * we get a mutex to ensure contention.
+	 */
+	if (F_ISSET(dbenv, DB_ENV_YIELDCPU))
+		__os_yield(env, 0, 0);
+#endif
+	return (0);
+
+err:	__db_err(env, ret, DB_STR("2024", "pthread readlock failed"));
+	return (__env_panic(env, ret));
+}
+#endif
+
+#ifdef HAVE_MUTEX_HYBRID
+/*
+ * __db_hybrid_mutex_suspend
+ *	Suspend this thread until the mutex is free enough to give the caller a
+ *	good chance of getting the mutex in the requested exclusivity mode.
+ *
+ *	The major difference between this and the old __db_pthread_mutex_lock()
+ *	is the additional 'exclusive' parameter.
+ *
+ * PUBLIC: #ifdef HAVE_MUTEX_HYBRID
+ * PUBLIC: int __db_hybrid_mutex_suspend
+ * PUBLIC:	__P((ENV *, db_mutex_t, db_timespec *, int));
+ * PUBLIC: #endif
+ */
+int
+__db_hybrid_mutex_suspend(env, mutex, timespec, exclusive)
+	ENV *env;
+	db_mutex_t mutex;
+	db_timespec *timespec;
+	int exclusive;
+{
+	DB_MUTEX *mutexp;
+	int ret, t_ret;
+
+	t_ret = 0;
+	mutexp = MUTEXP_SET(env, mutex);
+
+	if (!exclusive)
+		DB_ASSERT(env, F_ISSET(mutexp, DB_MUTEX_SHARED));
+	DB_ASSERT(env, F_ISSET(mutexp, DB_MUTEX_SELF_BLOCK));
+
+	if ((ret = __db_pthread_mutex_prep(env, mutex, mutexp, exclusive)) != 0)
+		goto err;
+
+	/*
+	 * Since this is only for hybrid mutexes the pthread mutex
+	 * is only used to wait after spinning on the TAS mutex.
+	 * Set the wait flag before checking to see if the mutex
+	 * is still locked.  The holder will clear DB_MUTEX_LOCKED
+	 * before checking the wait counter.
+	 */
+	mutexp->wait++;
+	MUTEX_MEMBAR(mutexp->wait);
+	while (exclusive ? MUTEXP_IS_BUSY(mutexp) :
+	    atomic_read(&mutexp->sharecount) == MUTEX_SHARE_ISEXCLUSIVE) {
+		t_ret = __db_pthread_mutex_condwait(env,
+		    mutex, mutexp, timespec);
+		if (t_ret != 0) {
+			if (t_ret == DB_TIMEOUT)
+				break;
+			ret = t_ret;
+			goto err;
+		}
+		MUTEX_MEMBAR(mutexp->flags);
+	}
+
+	mutexp->wait--;
+
+	/* #2471: HP-UX can sporadically return EFAULT. See above */
+	RETRY_ON_EFAULT(pthread_mutex_unlock(&mutexp->u.m.mutex), ret);
+	if (ret != 0)
+		goto err;
+
+	PERFMON4(env,
+	    mutex, resume, mutex, exclusive, mutexp->alloc_id, mutexp);
+
+#ifdef DIAGNOSTIC
+	/*
+	 * We want to switch threads as often as possible.  Yield every time
+	 * we get a mutex to ensure contention.
+	 */
+	if (F_ISSET(env->dbenv, DB_ENV_YIELDCPU))
+		__os_yield(env, 0, 0);
+#endif
+	return (t_ret);
+
+err:
+	PERFMON4(env,
+	    mutex, resume, mutex, exclusive, mutexp->alloc_id, mutexp);
+	__db_err(env, ret, "pthread suspend failed");
+	return (__env_panic(env, ret));
+}
+#endif
+
+/*
+ * __db_pthread_mutex_unlock --
+ *	Release a mutex, or, if hybrid, wake a thread up from a suspend.
+ *
+ * PUBLIC: int __db_pthread_mutex_unlock __P((ENV *, db_mutex_t));
+ */
+int
+__db_pthread_mutex_unlock(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	int ret;
+#if defined(MUTEX_DIAG) && defined(HAVE_MUTEX_HYBRID)
+	int waiters;
+#endif
+
+	dbenv = env->dbenv;
+
+	if (!MUTEX_ON(env) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
+		return (0);
+
+	mutexp = MUTEXP_SET(env, mutex);
+#if defined(MUTEX_DIAG) && defined(HAVE_MUTEX_HYBRID)
+	waiters = mutexp->wait;
+#endif
+
+#if !defined(HAVE_MUTEX_HYBRID) && defined(DIAGNOSTIC)
+	if (!F_ISSET(mutexp, DB_MUTEX_LOCKED | DB_MUTEX_SHARED)) {
+		__db_errx(env, DB_STR("2025",
+		    "pthread unlock failed: lock already unlocked"));
+		return (__env_panic(env, EACCES));
+	}
+#endif
+	if (F_ISSET(mutexp, DB_MUTEX_SELF_BLOCK)) {
+		ret = __db_pthread_mutex_prep(env, mutex, mutexp, TRUE);
+		if (ret != 0)
+			goto err;
+
+#ifdef HAVE_MUTEX_HYBRID
+		STAT_INC(env,
+		    mutex, hybrid_wakeup, mutexp->hybrid_wakeup, mutex);
+#else
+		F_CLR(mutexp, DB_MUTEX_LOCKED);	/* nop if DB_MUTEX_SHARED */
+#endif
+
+		if (F_ISSET(mutexp, DB_MUTEX_SHARED))
+			RET_SET(
+			    (pthread_cond_broadcast(&mutexp->u.m.cond)), ret);
+		else
+			RET_SET((pthread_cond_signal(&mutexp->u.m.cond)), ret);
+		if (ret != 0)
+			goto err;
+	} else {
+#ifndef HAVE_MUTEX_HYBRID
+		F_CLR(mutexp, DB_MUTEX_LOCKED);
+#endif
+	}
+
+	/* See comment above; workaround for [#2471]. */
+#if defined(HAVE_SHARED_LATCHES) && !defined(HAVE_MUTEX_HYBRID)
+	if (F_ISSET(mutexp, DB_MUTEX_SHARED))
+		RETRY_ON_EFAULT(pthread_rwlock_unlock(&mutexp->u.rwlock), ret);
+	else
+#endif
+		RETRY_ON_EFAULT(pthread_mutex_unlock(&mutexp->u.m.mutex), ret);
+
+err:	if (ret != 0) {
+		__db_err(env, ret, "pthread unlock failed");
+		return (__env_panic(env, ret));
+	}
+#if defined(MUTEX_DIAG) && defined(HAVE_MUTEX_HYBRID)
+	if (!MUTEXP_IS_BUSY(mutexp) && mutexp->wait != 0)
+		printf("unlock %ld %x busy %x waiters %d/%d\n",
+		    mutex, pthread_self(), ret,
+		    MUTEXP_BUSY_FIELD(mutexp), waiters, mutexp->wait);
+#endif
+	return (ret);
+}
+
+/*
+ * __db_pthread_mutex_destroy --
+ *	Destroy a mutex.
+ *	If it is a native shared latch (not hybrid) then
+ *	destroy only one half of the rwlock/mutex&cond union,
+ *	depending whether it was allocated as shared
+ *
+ * PUBLIC: int __db_pthread_mutex_destroy __P((ENV *, db_mutex_t));
+ */
+int
+__db_pthread_mutex_destroy(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	DB_MUTEX *mutexp;
+	DB_THREAD_INFO *ip;
+	int ret, t_ret, failchk_thread;
+
+	if (!MUTEX_ON(env))
+		return (0);
+
+	mutexp = MUTEXP_SET(env, mutex);
+
+	ret = 0;
+	failchk_thread = FALSE;
+	/* Get information to determine if we are really the failchk thread. */
+	if (F_ISSET(env->dbenv, DB_ENV_FAILCHK)) {
+		ret = __env_set_state(env, &ip, THREAD_VERIFY);
+		if (ip != NULL && ip->dbth_state == THREAD_FAILCHK)
+			failchk_thread = TRUE;
+	}
+
+#ifndef HAVE_MUTEX_HYBRID
+	if (F_ISSET(mutexp, DB_MUTEX_SHARED)) {
+#if defined(HAVE_SHARED_LATCHES)
+		/*
+		 * If there were dead processes waiting on the condition
+		 * we may not be able to destroy it.  Let failchk thread skip
+		 * this, unless destroy is required.
+		 * XXX What operating system resources might this leak?
+		 */
+#ifdef HAVE_PTHREAD_RWLOCK_REINIT_OKAY
+		if (!failchk_thread)
+#endif
+			RET_SET(
+			    (pthread_rwlock_destroy(&mutexp->u.rwlock)), ret);
+		/* For rwlocks, we're done - must not destroy rest of union */
+		return (ret);
+#endif
+	}
+#endif
+	if (F_ISSET(mutexp, DB_MUTEX_SELF_BLOCK)) {
+		/*
+		 * If there were dead processes waiting on the condition
+		 * we may not be able to destroy it.  Let failchk thread
+		 * skip this, unless destroy is required.
+		 */
+#ifdef HAVE_PTHREAD_COND_REINIT_OKAY
+		if (!failchk_thread)
+#endif
+			RET_SET((pthread_cond_destroy(&mutexp->u.m.cond)), ret);
+		if (ret != 0)
+			__db_err(env, ret, DB_STR("2026",
+			    "unable to destroy cond"));
+	}
+	RET_SET((pthread_mutex_destroy(&mutexp->u.m.mutex)), t_ret);
+	if (t_ret != 0 && !failchk_thread) {
+		__db_err(env, t_ret, DB_STR("2027",
+		    "unable to destroy mutex"));
+		if (ret == 0)
+			ret = t_ret;
+	}
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mutex/mut_region.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,490 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/log.h"
+#include "dbinc/lock.h"
+#include "dbinc/mp.h"
+#include "dbinc/txn.h"
+
+static db_size_t __mutex_align_size __P((ENV *));
+static int __mutex_region_init __P((ENV *, DB_MUTEXMGR *));
+static size_t __mutex_region_size __P((ENV *));
+static size_t __mutex_region_max __P((ENV *));
+
+/*
+ * __mutex_open --
+ *	Open a mutex region.
+ *
+ * PUBLIC: int __mutex_open __P((ENV *, int));
+ */
+int
+__mutex_open(env, create_ok)
+	ENV *env;
+	int create_ok;
+{
+	DB_ENV *dbenv;
+	DB_MUTEXMGR *mtxmgr;
+	DB_MUTEXREGION *mtxregion;
+	size_t size;
+	u_int32_t cpu_count;
+	int ret;
+#ifndef HAVE_ATOMIC_SUPPORT
+	u_int i;
+#endif
+
+	dbenv = env->dbenv;
+	if (dbenv->mutex_max == 0 &&
+	    dbenv->mutex_cnt == 0 && dbenv->mutex_inc == 0 &&
+	    F_ISSET(env, ENV_PRIVATE | ENV_THREAD) == ENV_PRIVATE)
+		return (0);
+
+	/*
+	 * Initialize the ENV handle information if not already initialized.
+	 *
+	 * Align mutexes on the byte boundaries specified by the application.
+	 */
+	if (dbenv->mutex_align == 0)
+		dbenv->mutex_align = MUTEX_ALIGN;
+	if (dbenv->mutex_tas_spins == 0) {
+		cpu_count = __os_cpu_count();
+		if ((ret = __mutex_set_tas_spins(dbenv, cpu_count == 1 ?
+		    cpu_count : cpu_count * MUTEX_SPINS_PER_PROCESSOR)) != 0)
+			return (ret);
+	}
+
+	/*
+	 * If the user didn't set an absolute value on the number of mutexes
+	 * we'll need, figure it out.  We're conservative in our allocation,
+	 * we need mutexes for DB handles, group-commit queues and other things
+	 * applications allocate at run-time.  The application may have kicked
+	 * up our count to allocate its own mutexes, add that in.
+	 */
+	if (dbenv->mutex_cnt == 0 &&
+	    F_ISSET(env, ENV_PRIVATE | ENV_THREAD) != ENV_PRIVATE)
+		dbenv->mutex_cnt =
+		    __lock_region_mutex_count(env) +
+		    __log_region_mutex_count(env) +
+		    __memp_region_mutex_count(env) +
+		    __txn_region_mutex_count(env);
+
+	if (dbenv->mutex_max != 0 && dbenv->mutex_cnt > dbenv->mutex_max)
+		dbenv->mutex_cnt = dbenv->mutex_max;
+
+	/* Create/initialize the mutex manager structure. */
+	if ((ret = __os_calloc(env, 1, sizeof(DB_MUTEXMGR), &mtxmgr)) != 0)
+		return (ret);
+
+	/* Join/create the mutex region. */
+	mtxmgr->reginfo.env = env;
+	mtxmgr->reginfo.type = REGION_TYPE_MUTEX;
+	mtxmgr->reginfo.id = INVALID_REGION_ID;
+	mtxmgr->reginfo.flags = REGION_JOIN_OK;
+	size = __mutex_region_size(env);
+	if (create_ok)
+		F_SET(&mtxmgr->reginfo, REGION_CREATE_OK);
+	if ((ret = __env_region_attach(env,
+	    &mtxmgr->reginfo, size, size + __mutex_region_max(env))) != 0)
+		goto err;
+
+	/* If we created the region, initialize it. */
+	if (F_ISSET(&mtxmgr->reginfo, REGION_CREATE))
+		if ((ret = __mutex_region_init(env, mtxmgr)) != 0)
+			goto err;
+
+	/* Set the local addresses. */
+	mtxregion = mtxmgr->reginfo.primary =
+	    R_ADDR(&mtxmgr->reginfo, mtxmgr->reginfo.rp->primary);
+	mtxmgr->mutex_array = R_ADDR(&mtxmgr->reginfo, mtxregion->mutex_off);
+
+	env->mutex_handle = mtxmgr;
+
+#ifndef HAVE_ATOMIC_SUPPORT
+	/* If necessary allocate the atomic emulation mutexes.  */
+	if (F_ISSET(&mtxmgr->reginfo, REGION_CREATE))
+		for (i = 0; i != MAX_ATOMIC_MUTEXES; i++)
+			if ((ret = __mutex_alloc_int(
+			    env, 0, MTX_ATOMIC_EMULATION,
+			    0, &mtxregion->mtx_atomic[i])) != 0)
+				return (ret);
+#endif
+
+	return (0);
+
+err:	env->mutex_handle = NULL;
+	if (mtxmgr->reginfo.addr != NULL)
+		(void)__env_region_detach(env, &mtxmgr->reginfo, 0);
+
+	__os_free(env, mtxmgr);
+	return (ret);
+}
+
+/*
+ * __mutex_region_init --
+ *	Initialize a mutex region in shared memory.
+ */
+static int
+__mutex_region_init(env, mtxmgr)
+	ENV *env;
+	DB_MUTEXMGR *mtxmgr;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	DB_MUTEXREGION *mtxregion;
+	db_mutex_t mutex;
+	int ret;
+	void *mutex_array;
+
+	dbenv = env->dbenv;
+
+	COMPQUIET(mutexp, NULL);
+
+	if ((ret = __env_alloc(&mtxmgr->reginfo,
+	    sizeof(DB_MUTEXREGION), &mtxmgr->reginfo.primary)) != 0) {
+		__db_errx(env, DB_STR("2013",
+		    "Unable to allocate memory for the mutex region"));
+		return (ret);
+	}
+	mtxmgr->reginfo.rp->primary =
+	    R_OFFSET(&mtxmgr->reginfo, mtxmgr->reginfo.primary);
+	mtxregion = mtxmgr->reginfo.primary;
+	memset(mtxregion, 0, sizeof(*mtxregion));
+
+	mtxregion->mutex_size = __mutex_align_size(env);
+
+	mtxregion->stat.st_mutex_align = dbenv->mutex_align;
+	if (dbenv->mutex_cnt == 0)
+		dbenv->mutex_cnt = 1;
+	mtxregion->stat.st_mutex_init =
+	     mtxregion->stat.st_mutex_cnt = dbenv->mutex_cnt;
+	mtxregion->stat.st_mutex_max = dbenv->mutex_max;
+	if (mtxregion->stat.st_mutex_max != 0)
+		mtxregion->stat.st_mutex_max += dbenv->mutex_inc;
+	mtxregion->stat.st_mutex_tas_spins = dbenv->mutex_tas_spins;
+
+	/*
+	 * Get a chunk of memory to be used for the mutexes themselves.  Each
+	 * piece of the memory must be properly aligned, and that alignment
+	 * may be more restrictive than the memory alignment returned by the
+	 * underlying allocation code.  We already know how much memory each
+	 * mutex in the array will take up, but we need to offset the first
+	 * mutex in the array so the array begins properly aligned.
+	 *
+	 * The OOB mutex (MUTEX_INVALID) is 0.  To make this work, we ignore
+	 * the first allocated slot when we build the free list.  We have to
+	 * correct the count by 1 here, though, otherwise our counter will be
+	 * off by 1.
+	 */
+	if ((ret = __env_alloc(&mtxmgr->reginfo,
+	    mtxregion->stat.st_mutex_align +
+	    (mtxregion->stat.st_mutex_cnt + 1) * mtxregion->mutex_size,
+	    &mutex_array)) != 0) {
+		__db_errx(env, DB_STR("2014",
+		    "Unable to allocate memory for mutexes from the region"));
+		return (ret);
+	}
+
+	mtxregion->mutex_off_alloc = R_OFFSET(&mtxmgr->reginfo, mutex_array);
+	mutex_array = ALIGNP_INC(mutex_array, mtxregion->stat.st_mutex_align);
+	mtxregion->mutex_off = R_OFFSET(&mtxmgr->reginfo, mutex_array);
+	mtxmgr->mutex_array = mutex_array;
+
+	/*
+	 * Put the mutexes on a free list and clear the allocated flag.
+	 *
+	 * The OOB mutex (MUTEX_INVALID) is 0, skip it.
+	 *
+	 * The comparison is <, not <=, because we're looking ahead one
+	 * in each link.
+	 */
+	env->mutex_handle = mtxmgr;
+	if (F_ISSET(env, ENV_PRIVATE)) {
+		mutexp = (DB_MUTEX *)mutex_array;
+		mutexp++;
+		mutexp = ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align);
+		mtxregion->mutex_next = (db_mutex_t)mutexp;
+	} else {
+		mtxregion->mutex_next = 1;
+		mutexp = MUTEXP_SET(env, 1);
+	}
+	for (mutex = 1; mutex < mtxregion->stat.st_mutex_cnt; ++mutex) {
+		mutexp->flags = 0;
+		if (F_ISSET(env, ENV_PRIVATE))
+			mutexp->mutex_next_link = (db_mutex_t)(mutexp + 1);
+		else
+			mutexp->mutex_next_link = mutex + 1;
+		mutexp++;
+		mutexp = ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align);
+	}
+	mutexp->flags = 0;
+	mutexp->mutex_next_link = MUTEX_INVALID;
+	mtxregion->stat.st_mutex_free = mtxregion->stat.st_mutex_cnt;
+	mtxregion->stat.st_mutex_inuse = mtxregion->stat.st_mutex_inuse_max = 0;
+	if ((ret = __mutex_alloc(env, MTX_MUTEX_REGION, 0, &mutex)) != 0)
+		return (ret);
+	mtxmgr->reginfo.mtx_alloc = mtxregion->mtx_region = mutex;
+
+	/*
+	 * This is the first place we can test mutexes and we need to
+	 * know if they're working.  (They CAN fail, for example on
+	 * SunOS, when using fcntl(2) for locking and using an
+	 * in-memory filesystem as the database environment directory.
+	 * But you knew that, I'm sure -- it probably wasn't worth
+	 * mentioning.)
+	 */
+	mutex = MUTEX_INVALID;
+	if ((ret =
+	    __mutex_alloc(env, MTX_MUTEX_TEST, 0, &mutex) != 0) ||
+	    (ret = __mutex_lock(env, mutex)) != 0 ||
+	    (ret = __mutex_unlock(env, mutex)) != 0 ||
+	    (ret = __mutex_trylock(env, mutex)) != 0 ||
+	    (ret = __mutex_unlock(env, mutex)) != 0 ||
+	    (ret = __mutex_free(env, &mutex)) != 0) {
+		__db_errx(env, DB_STR("2015",
+	    "Unable to acquire/release a mutex; check configuration"));
+		return (ret);
+	}
+#ifdef HAVE_SHARED_LATCHES
+	if ((ret =
+	    __mutex_alloc(env,
+		MTX_MUTEX_TEST, DB_MUTEX_SHARED, &mutex) != 0) ||
+	    (ret = __mutex_lock(env, mutex)) != 0 ||
+	    (ret = __mutex_tryrdlock(env, mutex)) != DB_LOCK_NOTGRANTED ||
+	    (ret = __mutex_unlock(env, mutex)) != 0 ||
+	    (ret = __mutex_rdlock(env, mutex)) != 0 ||
+	    (ret = __mutex_rdlock(env, mutex)) != 0 ||
+	    (ret = __mutex_unlock(env, mutex)) != 0 ||
+	    (ret = __mutex_unlock(env, mutex)) != 0 ||
+	    (ret = __mutex_free(env, &mutex)) != 0) {
+		__db_errx(env, DB_STR("2016",
+    "Unable to acquire/release a shared latch; check configuration"));
+		return (ret);
+	}
+#endif
+
+	return (0);
+}
+
+/*
+ * __mutex_env_refresh --
+ *	Clean up after the mutex region on a close or failed open.
+ *
+ * PUBLIC: int __mutex_env_refresh __P((ENV *));
+ */
+int
+__mutex_env_refresh(env)
+	ENV *env;
+{
+	DB_MUTEXMGR *mtxmgr;
+	DB_MUTEXREGION *mtxregion;
+	REGINFO *reginfo;
+	int ret;
+
+	mtxmgr = env->mutex_handle;
+	reginfo = &mtxmgr->reginfo;
+	mtxregion = mtxmgr->reginfo.primary;
+
+	/*
+	 * If a private region, return the memory to the heap.  Not needed for
+	 * filesystem-backed or system shared memory regions, that memory isn't
+	 * owned by any particular process.
+	 */
+	if (F_ISSET(env, ENV_PRIVATE)) {
+		reginfo->mtx_alloc = MUTEX_INVALID;
+
+#ifdef HAVE_MUTEX_SYSTEM_RESOURCES
+		/*
+		 * If destroying the mutex region, return any system resources
+		 * to the system.
+		 */
+		__mutex_resource_return(env, reginfo);
+#endif
+		/* Discard the mutex array. */
+		__env_alloc_free(
+		    reginfo, R_ADDR(reginfo, mtxregion->mutex_off_alloc));
+	}
+
+	/* Detach from the region. */
+	ret = __env_region_detach(env, reginfo, 0);
+
+	__os_free(env, mtxmgr);
+
+	env->mutex_handle = NULL;
+
+	return (ret);
+}
+
+/*
+ * __mutex_align_size --
+ *	Return how much memory each mutex will take up if an array of them
+ *	are to be properly aligned, individually, within the array.
+ */
+static db_size_t
+__mutex_align_size(env)
+	ENV *env;
+{
+	DB_ENV *dbenv;
+
+	dbenv = env->dbenv;
+
+	return ((db_size_t)DB_ALIGN(sizeof(DB_MUTEX), dbenv->mutex_align));
+}
+
+/*
+ * __mutex_region_size --
+ *	 Return the amount of space needed for the mutex region.
+ */
+static size_t
+__mutex_region_size(env)
+	ENV *env;
+{
+	DB_ENV *dbenv;
+	size_t s;
+
+	dbenv = env->dbenv;
+
+	s = sizeof(DB_MUTEXMGR) + 1024;
+
+	/* We discard one mutex for the OOB slot. */
+	s += __env_alloc_size(
+	    (dbenv->mutex_cnt + 1) *__mutex_align_size(env));
+
+	return (s);
+}
+
+/*
+ * __mutex_region_max --
+ *	 Return the amount of space needed to reach the maximum size.
+ */
+static size_t
+__mutex_region_max(env)
+	ENV *env;
+{
+	DB_ENV *dbenv;
+	u_int32_t max;
+
+	dbenv = env->dbenv;
+
+	if ((max = dbenv->mutex_max) == 0) {
+		if (F_ISSET(env, ENV_PRIVATE | ENV_THREAD) == ENV_PRIVATE)
+			max = dbenv->mutex_inc + 1;
+		else
+			max = __lock_region_mutex_max(env) +
+			    __txn_region_mutex_max(env) +
+			    __log_region_mutex_max(env) +
+			    dbenv->mutex_inc + 100;
+	} else if (max <= dbenv->mutex_cnt)
+		return (0);
+	else
+		max -= dbenv->mutex_cnt;
+
+	return ( __env_alloc_size(max * __mutex_align_size(env)));
+}
+
+#ifdef	HAVE_MUTEX_SYSTEM_RESOURCES
+/*
+ * __mutex_resource_return
+ *	Return any system-allocated mutex resources to the system.
+ *
+ * PUBLIC: void __mutex_resource_return __P((ENV *, REGINFO *));
+ */
+void
+__mutex_resource_return(env, infop)
+	ENV *env;
+	REGINFO *infop;
+{
+	DB_MUTEX *mutexp;
+	DB_MUTEXMGR *mtxmgr, mtxmgr_st;
+	DB_MUTEXREGION *mtxregion;
+	db_mutex_t i, indx;
+	void *orig_handle, *chunk;
+	uintmax_t size;
+
+	/*
+	 * This routine is called in two cases: when discarding the regions
+	 * from a previous Berkeley DB run, during recovery, and two, when
+	 * discarding regions as we shut down the database environment.
+	 *
+	 * Walk the list of mutexes and destroy any live ones.
+	 *
+	 * This is just like joining a region -- the REGINFO we're handed is
+	 * the same as the one returned by __env_region_attach(), all we have
+	 * to do is fill in the links.
+	 *
+	 * !!!
+	 * The region may be corrupted, of course.  We're safe because the
+	 * only things we look at are things that are initialized when the
+	 * region is created, and never modified after that.
+	 */
+	memset(&mtxmgr_st, 0, sizeof(mtxmgr_st));
+	mtxmgr = &mtxmgr_st;
+	mtxmgr->reginfo = *infop;
+	mtxregion = mtxmgr->reginfo.primary =
+	    R_ADDR(&mtxmgr->reginfo, mtxmgr->reginfo.rp->primary);
+	mtxmgr->mutex_array = R_ADDR(&mtxmgr->reginfo, mtxregion->mutex_off);
+
+	/*
+	 * This is a little strange, but the mutex_handle is what all of the
+	 * underlying mutex routines will use to determine if they should do
+	 * any work and to find their information.  Save/restore the handle
+	 * around the work loop.
+	 *
+	 * The OOB mutex (MUTEX_INVALID) is 0, skip it.
+	 */
+	orig_handle = env->mutex_handle;
+	env->mutex_handle = mtxmgr;
+	if (F_ISSET(env, ENV_PRIVATE)) {
+		mutexp = (DB_MUTEX *)mtxmgr->mutex_array + 1;
+		chunk = NULL;
+		size = __env_elem_size(env,
+		    (void *)mtxregion->mutex_off_alloc);
+		size -= sizeof(*mutexp);
+	} else
+		mutexp = MUTEXP_SET(env, 1);
+	for (i = 1; i <= mtxregion->stat.st_mutex_cnt; ++i) {
+		if (F_ISSET(env, ENV_PRIVATE))
+			indx = (db_mutex_t)mutexp;
+		else
+			indx = i;
+		if (F_ISSET(mutexp, DB_MUTEX_ALLOCATED))
+			(void)__mutex_destroy(env, indx);
+		mutexp++;
+		if (F_ISSET(env, ENV_PRIVATE) &&
+		    (size -= sizeof(*mutexp)) < sizeof(*mutexp)) {
+			mutexp = __env_get_chunk(&mtxmgr->reginfo,
+			    &chunk, &size);
+		}
+		mutexp = ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align);
+	}
+	env->mutex_handle = orig_handle;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mutex/mut_stat.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,601 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+
+#ifdef HAVE_STATISTICS
+static int __mutex_print_all __P((ENV *, u_int32_t));
+static const char *__mutex_print_id __P((int));
+static int __mutex_print_stats __P((ENV *, u_int32_t));
+static void __mutex_print_summary __P((ENV *));
+static int __mutex_stat __P((ENV *, DB_MUTEX_STAT **, u_int32_t));
+
+/*
+ * __mutex_stat_pp --
+ *	ENV->mutex_stat pre/post processing.
+ *
+ * PUBLIC: int __mutex_stat_pp __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t));
+ */
+int
+__mutex_stat_pp(dbenv, statp, flags)
+	DB_ENV *dbenv;
+	DB_MUTEX_STAT **statp;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_REQUIRES_CONFIG(env,
+	    env->mutex_handle, "DB_ENV->mutex_stat", DB_INIT_MUTEX);
+
+	if ((ret = __db_fchk(env,
+	    "DB_ENV->mutex_stat", flags, DB_STAT_CLEAR)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env, (__mutex_stat(env, statp, flags)), 0, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __mutex_stat --
+ *	ENV->mutex_stat.
+ */
+static int
+__mutex_stat(env, statp, flags)
+	ENV *env;
+	DB_MUTEX_STAT **statp;
+	u_int32_t flags;
+{
+	DB_MUTEXMGR *mtxmgr;
+	DB_MUTEXREGION *mtxregion;
+	DB_MUTEX_STAT *stats;
+	int ret;
+
+	*statp = NULL;
+	mtxmgr = env->mutex_handle;
+	mtxregion = mtxmgr->reginfo.primary;
+
+	if ((ret = __os_umalloc(env, sizeof(DB_MUTEX_STAT), &stats)) != 0)
+		return (ret);
+
+	MUTEX_SYSTEM_LOCK(env);
+
+	/*
+	 * Most fields are maintained in the underlying region structure.
+	 * Region size and region mutex are not.
+	 */
+	*stats = mtxregion->stat;
+	stats->st_regsize = mtxmgr->reginfo.rp->size;
+	stats->st_regmax = mtxmgr->reginfo.rp->max;
+	__mutex_set_wait_info(env, mtxregion->mtx_region,
+	    &stats->st_region_wait, &stats->st_region_nowait);
+	if (LF_ISSET(DB_STAT_CLEAR))
+		__mutex_clear(env, mtxregion->mtx_region);
+
+	MUTEX_SYSTEM_UNLOCK(env);
+
+	*statp = stats;
+	return (0);
+}
+
+/*
+ * __mutex_stat_print_pp --
+ *	ENV->mutex_stat_print pre/post processing.
+ *
+ * PUBLIC: int __mutex_stat_print_pp __P((DB_ENV *, u_int32_t));
+ */
+int
+__mutex_stat_print_pp(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	DB_THREAD_INFO *ip;
+	ENV *env;
+	int ret;
+
+	env = dbenv->env;
+
+	ENV_REQUIRES_CONFIG(env,
+	    env->mutex_handle, "DB_ENV->mutex_stat_print", DB_INIT_MUTEX);
+
+	if ((ret = __db_fchk(env, "DB_ENV->mutex_stat_print",
+	    flags, DB_STAT_ALL | DB_STAT_ALLOC | DB_STAT_CLEAR)) != 0)
+		return (ret);
+
+	ENV_ENTER(env, ip);
+	REPLICATION_WRAP(env, (__mutex_stat_print(env, flags)), 0, ret);
+	ENV_LEAVE(env, ip);
+	return (ret);
+}
+
+/*
+ * __mutex_stat_print
+ *	ENV->mutex_stat_print method.
+ *
+ * PUBLIC: int __mutex_stat_print __P((ENV *, u_int32_t));
+ */
+int
+__mutex_stat_print(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	u_int32_t orig_flags;
+	int ret;
+
+	orig_flags = flags;
+	LF_CLR(DB_STAT_CLEAR | DB_STAT_SUBSYSTEM);
+	if (flags == 0 || LF_ISSET(DB_STAT_ALL)) {
+		ret = __mutex_print_stats(env, orig_flags);
+		__mutex_print_summary(env);
+		if (flags == 0 || ret != 0)
+			return (ret);
+	}
+
+	if (LF_ISSET(DB_STAT_ALL))
+		ret = __mutex_print_all(env, orig_flags);
+
+	return (0);
+}
+
+static void
+__mutex_print_summary(env)
+	ENV *env;
+{
+	DB_MUTEX *mutexp;
+	DB_MUTEXMGR *mtxmgr;
+	DB_MUTEXREGION *mtxregion;
+	void *chunk;
+	db_mutex_t i;
+	u_int32_t counts[MTX_MAX_ENTRY + 2];
+	uintmax_t size;
+	int alloc_id;
+
+	mtxmgr = env->mutex_handle;
+	mtxregion = mtxmgr->reginfo.primary;
+	memset(counts, 0, sizeof(counts));
+	size = 0;
+
+	if (F_ISSET(env, ENV_PRIVATE)) {
+		mutexp = (DB_MUTEX *)mtxmgr->mutex_array + 1;
+		chunk = NULL;
+		size = __env_elem_size(env,
+		    ROFF_TO_P(mtxregion->mutex_off_alloc));
+		size -= sizeof(*mutexp);
+	} else
+		mutexp = MUTEXP_SET(env, 1);
+	for (i = 1; i <= mtxregion->stat.st_mutex_cnt; ++i) {
+		if (!F_ISSET(mutexp, DB_MUTEX_ALLOCATED))
+			counts[0]++;
+		else if (mutexp->alloc_id > MTX_MAX_ENTRY)
+			counts[MTX_MAX_ENTRY + 1]++;
+		else
+			counts[mutexp->alloc_id]++;
+
+		mutexp++;
+		if (F_ISSET(env, ENV_PRIVATE) &&
+		    (size -= sizeof(*mutexp)) < sizeof(*mutexp)) {
+			mutexp =
+			    __env_get_chunk(&mtxmgr->reginfo, &chunk, &size);
+		}
+		mutexp = ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align);
+	}
+	__db_msg(env, "Mutex counts");
+	__db_msg(env, "%d\tUnallocated", counts[0]);
+	for (alloc_id = 1; alloc_id <= MTX_TXN_REGION + 1; alloc_id++)
+		if (counts[alloc_id] != 0)
+			__db_msg(env, "%lu\t%s",
+			    (u_long)counts[alloc_id],
+			    __mutex_print_id(alloc_id));
+
+}
+
+/*
+ * __mutex_print_stats --
+ *	Display default mutex region statistics.
+ */
+static int
+__mutex_print_stats(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	DB_MUTEX_STAT *sp;
+	int ret;
+
+	if ((ret = __mutex_stat(env, &sp, LF_ISSET(DB_STAT_CLEAR))) != 0)
+		return (ret);
+
+	if (LF_ISSET(DB_STAT_ALL))
+		__db_msg(env, "Default mutex region information:");
+
+	__db_dlbytes(env, "Mutex region size",
+	    (u_long)0, (u_long)0, (u_long)sp->st_regsize);
+	__db_dlbytes(env, "Mutex region max size",
+	    (u_long)0, (u_long)0, (u_long)sp->st_regmax);
+	__db_dl_pct(env,
+	    "The number of region locks that required waiting",
+	    (u_long)sp->st_region_wait, DB_PCT(sp->st_region_wait,
+	    sp->st_region_wait + sp->st_region_nowait), NULL);
+	STAT_ULONG("Mutex alignment", sp->st_mutex_align);
+	STAT_ULONG("Mutex test-and-set spins", sp->st_mutex_tas_spins);
+	STAT_ULONG("Mutex initial count", sp->st_mutex_init);
+	STAT_ULONG("Mutex total count", sp->st_mutex_cnt);
+	STAT_ULONG("Mutex max count", sp->st_mutex_max);
+	STAT_ULONG("Mutex free count", sp->st_mutex_free);
+	STAT_ULONG("Mutex in-use count", sp->st_mutex_inuse);
+	STAT_ULONG("Mutex maximum in-use count", sp->st_mutex_inuse_max);
+
+	__os_ufree(env, sp);
+
+	return (0);
+}
+
+/*
+ * __mutex_print_all --
+ *	Display debugging mutex region statistics.
+ */
+static int
+__mutex_print_all(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	static const FN fn[] = {
+		{ DB_MUTEX_ALLOCATED,		"alloc" },
+		{ DB_MUTEX_LOCKED,		"locked" },
+		{ DB_MUTEX_LOGICAL_LOCK,	"logical" },
+		{ DB_MUTEX_PROCESS_ONLY,	"process-private" },
+		{ DB_MUTEX_SELF_BLOCK,		"self-block" },
+		{ 0,				NULL }
+	};
+	DB_MSGBUF mb, *mbp;
+	DB_MUTEX *mutexp;
+	DB_MUTEXMGR *mtxmgr;
+	DB_MUTEXREGION *mtxregion;
+	db_mutex_t i;
+	uintmax_t size;
+	void *chunk;
+
+	DB_MSGBUF_INIT(&mb);
+	mbp = &mb;
+
+	mtxmgr = env->mutex_handle;
+	mtxregion = mtxmgr->reginfo.primary;
+
+	__db_print_reginfo(env, &mtxmgr->reginfo, "Mutex", flags);
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+
+	__db_msg(env, "DB_MUTEXREGION structure:");
+	__mutex_print_debug_single(env,
+	    "DB_MUTEXREGION region mutex", mtxregion->mtx_region, flags);
+	STAT_ULONG("Size of the aligned mutex", mtxregion->mutex_size);
+	STAT_ULONG("Next free mutex", mtxregion->mutex_next);
+
+	/*
+	 * The OOB mutex (MUTEX_INVALID) is 0, skip it.
+	 *
+	 * We're not holding the mutex region lock, so we're racing threads of
+	 * control allocating mutexes.  That's OK, it just means we display or
+	 * clear statistics while mutexes are moving.
+	 */
+	__db_msg(env, "%s", DB_GLOBAL(db_line));
+	__db_msg(env, "mutex\twait/nowait, pct wait, holder, flags");
+	size = 0;
+	if (F_ISSET(env, ENV_PRIVATE)) {
+		mutexp = (DB_MUTEX *)mtxmgr->mutex_array + 1;
+		chunk = NULL;
+		size = __env_elem_size(env,
+		    ROFF_TO_P(mtxregion->mutex_off_alloc));
+		size -= sizeof(*mutexp);
+	} else
+		mutexp = MUTEXP_SET(env, 1);
+	for (i = 1; i <= mtxregion->stat.st_mutex_cnt; ++i) {
+		if (F_ISSET(mutexp, DB_MUTEX_ALLOCATED)) {
+			__db_msgadd(env, mbp, "%5lu\t", (u_long)i);
+
+			__mutex_print_debug_stats(env, mbp,
+			    F_ISSET(env, ENV_PRIVATE) ?
+			    (db_mutex_t)mutexp : i, flags);
+
+			if (mutexp->alloc_id != 0)
+				__db_msgadd(env, mbp,
+				    ", %s", __mutex_print_id(mutexp->alloc_id));
+
+			__db_prflags(env, mbp, mutexp->flags, fn, " (", ")");
+
+			DB_MSGBUF_FLUSH(env, mbp);
+		}
+
+		mutexp++;
+		if (F_ISSET(env, ENV_PRIVATE) &&
+		    (size -= sizeof(*mutexp)) < sizeof(*mutexp)) {
+			mutexp =
+			    __env_get_chunk(&mtxmgr->reginfo, &chunk, &size);
+		}
+		mutexp = ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align);
+	}
+
+	return (0);
+}
+
+/*
+ * __mutex_print_debug_single --
+ *	Print mutex internal debugging statistics for a single mutex on a
+ *	single output line.
+ *
+ * PUBLIC: void __mutex_print_debug_single
+ * PUBLIC:          __P((ENV *, const char *, db_mutex_t, u_int32_t));
+ */
+void
+__mutex_print_debug_single(env, tag, mutex, flags)
+	ENV *env;
+	const char *tag;
+	db_mutex_t mutex;
+	u_int32_t flags;
+{
+	DB_MSGBUF mb, *mbp;
+
+	DB_MSGBUF_INIT(&mb);
+	mbp = &mb;
+
+	if (LF_ISSET(DB_STAT_SUBSYSTEM))
+		LF_CLR(DB_STAT_CLEAR);
+	__db_msgadd(env, mbp, "%lu\t%s ", (u_long)mutex, tag);
+	__mutex_print_debug_stats(env, mbp, mutex, flags);
+	DB_MSGBUF_FLUSH(env, mbp);
+}
+
+/*
+ * __mutex_print_debug_stats --
+ *	Print mutex internal debugging statistics, that is, the statistics
+ *	in the [] square brackets.
+ *
+ * PUBLIC: void __mutex_print_debug_stats
+ * PUBLIC:          __P((ENV *, DB_MSGBUF *, db_mutex_t, u_int32_t));
+ */
+void
+__mutex_print_debug_stats(env, mbp, mutex, flags)
+	ENV *env;
+	DB_MSGBUF *mbp;
+	db_mutex_t mutex;
+	u_int32_t flags;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	u_long value;
+	char buf[DB_THREADID_STRLEN];
+#if defined(HAVE_SHARED_LATCHES) && (defined(HAVE_MUTEX_HYBRID) || \
+    !defined(HAVE_MUTEX_PTHREADS))
+	int sharecount;
+#endif
+
+	if (mutex == MUTEX_INVALID) {
+		__db_msgadd(env, mbp, "[!Set]");
+		return;
+	}
+
+	dbenv = env->dbenv;
+	mutexp = MUTEXP_SET(env, mutex);
+
+	__db_msgadd(env, mbp, "[");
+	if ((value = mutexp->mutex_set_wait) < 10000000)
+		__db_msgadd(env, mbp, "%lu", value);
+	else
+		__db_msgadd(env, mbp, "%luM", value / 1000000);
+	if ((value = mutexp->mutex_set_nowait) < 10000000)
+		__db_msgadd(env, mbp, "/%lu", value);
+	else
+		__db_msgadd(env, mbp, "/%luM", value / 1000000);
+
+	__db_msgadd(env, mbp, " %d%% ",
+	    DB_PCT(mutexp->mutex_set_wait,
+	    mutexp->mutex_set_wait + mutexp->mutex_set_nowait));
+
+#if defined(HAVE_SHARED_LATCHES)
+	if (F_ISSET(mutexp, DB_MUTEX_SHARED)) {
+		__db_msgadd(env, mbp, " rd ");
+		if ((value = mutexp->mutex_set_rd_wait) < 10000000)
+			__db_msgadd(env, mbp, "%lu", value);
+		else
+			__db_msgadd(env, mbp, "%luM", value / 1000000);
+		if ((value = mutexp->mutex_set_rd_nowait) < 10000000)
+			__db_msgadd(env, mbp, "/%lu", value);
+		else
+			__db_msgadd(env, mbp, "/%luM", value / 1000000);
+		__db_msgadd(env, mbp, " %d%% ",
+		    DB_PCT(mutexp->mutex_set_rd_wait,
+		    mutexp->mutex_set_rd_wait + mutexp->mutex_set_rd_nowait));
+	}
+#endif
+
+	if (F_ISSET(mutexp, DB_MUTEX_LOCKED))
+		__db_msgadd(env, mbp, "%s]",
+		    dbenv->thread_id_string(dbenv,
+		    mutexp->pid, mutexp->tid, buf));
+	/* Pthreads-based shared latches do not expose the share count. */
+#if defined(HAVE_SHARED_LATCHES) && (defined(HAVE_MUTEX_HYBRID) || \
+    !defined(HAVE_MUTEX_PTHREADS))
+	else if (F_ISSET(mutexp, DB_MUTEX_SHARED) &&
+	    (sharecount = atomic_read(&mutexp->sharecount)) != 0) {
+		if (sharecount == 1)
+			__db_msgadd(env, mbp, "1 reader");
+		else
+			__db_msgadd(env, mbp, "%d readers", sharecount);
+		/* Show the thread which last acquired the latch. */
+		__db_msgadd(env, mbp, " %s]",
+		    dbenv->thread_id_string(dbenv,
+		    mutexp->pid, mutexp->tid, buf));
+	}
+#endif
+	else
+		__db_msgadd(env, mbp, "!Own]");
+
+#ifdef HAVE_MUTEX_HYBRID
+	if (mutexp->hybrid_wait != 0 || mutexp->hybrid_wakeup != 0)
+		__db_msgadd(env, mbp, " <wakeups %d/%d>",
+		    mutexp->hybrid_wait, mutexp->hybrid_wakeup);
+#endif
+
+	if (LF_ISSET(DB_STAT_CLEAR))
+		__mutex_clear(env, mutex);
+}
+
+static const char *
+__mutex_print_id(alloc_id)
+	int alloc_id;
+{
+	switch (alloc_id) {
+	case MTX_APPLICATION:		return ("application allocated");
+	case MTX_ATOMIC_EMULATION:	return ("atomic emulation");
+	case MTX_DB_HANDLE:		return ("db handle");
+	case MTX_ENV_DBLIST:		return ("env dblist");
+	case MTX_ENV_EXCLDBLIST:	return ("env exclusive dblist");
+	case MTX_ENV_HANDLE:		return ("env handle");
+	case MTX_ENV_REGION:		return ("env region");
+	case MTX_LOCK_REGION:		return ("lock region");
+	case MTX_LOGICAL_LOCK:		return ("logical lock");
+	case MTX_LOG_FILENAME:		return ("log filename");
+	case MTX_LOG_FLUSH:		return ("log flush");
+	case MTX_LOG_HANDLE:		return ("log handle");
+	case MTX_LOG_REGION:		return ("log region");
+	case MTX_MPOOLFILE_HANDLE:	return ("mpoolfile handle");
+	case MTX_MPOOL_BH:		return ("mpool buffer");
+	case MTX_MPOOL_FH:		return ("mpool filehandle");
+	case MTX_MPOOL_FILE_BUCKET:	return ("mpool file bucket");
+	case MTX_MPOOL_HANDLE:		return ("mpool handle");
+	case MTX_MPOOL_HASH_BUCKET:	return ("mpool hash bucket");
+	case MTX_MPOOL_REGION:		return ("mpool region");
+	case MTX_MUTEX_REGION:		return ("mutex region");
+	case MTX_MUTEX_TEST:		return ("mutex test");
+	case MTX_REPMGR:		return ("replication manager");
+	case MTX_REP_CHKPT:		return ("replication checkpoint");
+	case MTX_REP_DATABASE:		return ("replication database");
+	case MTX_REP_DIAG:		return ("replication diagnostics");
+	case MTX_REP_EVENT:		return ("replication event");
+	case MTX_REP_REGION:		return ("replication region");
+	case MTX_REP_START:		return ("replication role config");
+	case MTX_REP_WAITER:		return ("replication txn apply");
+	case MTX_SEQUENCE:		return ("sequence");
+	case MTX_TWISTER:		return ("twister");
+	case MTX_TCL_EVENTS:		return ("Tcl events");
+	case MTX_TXN_ACTIVE:		return ("txn active list");
+	case MTX_TXN_CHKPT:		return ("transaction checkpoint");
+	case MTX_TXN_COMMIT:		return ("txn commit");
+	case MTX_TXN_MVCC:		return ("txn mvcc");
+	case MTX_TXN_REGION:		return ("txn region");
+	default:			return ("unknown mutex type");
+	/* NOTREACHED */
+	}
+}
+
+/*
+ * __mutex_set_wait_info --
+ *	Return mutex statistics.
+ *
+ * PUBLIC: void __mutex_set_wait_info
+ * PUBLIC:	__P((ENV *, db_mutex_t, uintmax_t *, uintmax_t *));
+ */
+void
+__mutex_set_wait_info(env, mutex, waitp, nowaitp)
+	ENV *env;
+	db_mutex_t mutex;
+	uintmax_t *waitp, *nowaitp;
+{
+	DB_MUTEX *mutexp;
+
+	if (mutex == MUTEX_INVALID) {
+		*waitp = 0;
+		*nowaitp = 0;
+		return;
+	}
+	mutexp = MUTEXP_SET(env, mutex);
+
+	*waitp = mutexp->mutex_set_wait;
+	*nowaitp = mutexp->mutex_set_nowait;
+}
+
+/*
+ * __mutex_clear --
+ *	Clear mutex statistics.
+ *
+ * PUBLIC: void __mutex_clear __P((ENV *, db_mutex_t));
+ */
+void
+__mutex_clear(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	DB_MUTEX *mutexp;
+
+	if (!MUTEX_ON(env))
+		return;
+
+	mutexp = MUTEXP_SET(env, mutex);
+
+	mutexp->mutex_set_wait = mutexp->mutex_set_nowait = 0;
+#ifdef HAVE_SHARED_LATCHES
+	mutexp->mutex_set_rd_wait = mutexp->mutex_set_rd_nowait = 0;
+#endif
+#ifdef HAVE_MUTEX_HYBRID
+	mutexp->hybrid_wait = mutexp->hybrid_wakeup = 0;
+#endif
+}
+
+#else /* !HAVE_STATISTICS */
+
+int
+__mutex_stat_pp(dbenv, statp, flags)
+	DB_ENV *dbenv;
+	DB_MUTEX_STAT **statp;
+	u_int32_t flags;
+{
+	COMPQUIET(statp, NULL);
+	COMPQUIET(flags, 0);
+
+	return (__db_stat_not_built(dbenv->env));
+}
+
+int
+__mutex_stat_print_pp(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+
+	return (__db_stat_not_built(dbenv->env));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mutex/mut_tas.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,630 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/lock.h"
+
+static inline int __db_tas_mutex_lock_int
+	    __P((ENV *, db_mutex_t, db_timeout_t, int));
+static inline int __db_tas_mutex_readlock_int __P((ENV *, db_mutex_t, int));
+
+/*
+ * __db_tas_mutex_init --
+ *	Initialize a test-and-set mutex.
+ *
+ * PUBLIC: int __db_tas_mutex_init __P((ENV *, db_mutex_t, u_int32_t));
+ */
+int
+__db_tas_mutex_init(env, mutex, flags)
+	ENV *env;
+	db_mutex_t mutex;
+	u_int32_t flags;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	int ret;
+
+#ifndef HAVE_MUTEX_HYBRID
+	COMPQUIET(flags, 0);
+#endif
+
+	dbenv = env->dbenv;
+	mutexp = MUTEXP_SET(env, mutex);
+
+	/* Check alignment. */
+	if (((uintptr_t)mutexp & (dbenv->mutex_align - 1)) != 0) {
+		__db_errx(env, DB_STR("2028",
+		    "TAS: mutex not appropriately aligned"));
+		return (EINVAL);
+	}
+
+#ifdef HAVE_SHARED_LATCHES
+	if (F_ISSET(mutexp, DB_MUTEX_SHARED))
+		atomic_init(&mutexp->sharecount, 0);
+	else
+#endif
+	if (MUTEX_INIT(&mutexp->tas)) {
+		ret = __os_get_syserr();
+		__db_syserr(env, ret, DB_STR("2029",
+		    "TAS: mutex initialize"));
+		return (__os_posix_err(ret));
+	}
+#ifdef HAVE_MUTEX_HYBRID
+	if ((ret = __db_pthread_mutex_init(env,
+	     mutex, flags | DB_MUTEX_SELF_BLOCK)) != 0)
+		return (ret);
+#endif
+	return (0);
+}
+
+/*
+ * __db_tas_mutex_lock_int
+ *     Internal function to lock a mutex, or just try to lock it without waiting
+ */
+inline static int
+__db_tas_mutex_lock_int(env, mutex, timeout, nowait)
+	ENV *env;
+	db_mutex_t mutex;
+	db_timeout_t timeout;
+	int nowait;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	DB_MUTEXMGR *mtxmgr;
+	DB_MUTEXREGION *mtxregion;
+	DB_THREAD_INFO *ip;
+	db_timespec now, timespec;
+	u_int32_t nspins;
+	int ret;
+#ifdef HAVE_MUTEX_HYBRID
+	const u_long micros = 0;
+#else
+	u_long micros, max_micros;
+	db_timeout_t time_left;
+#endif
+
+	dbenv = env->dbenv;
+
+	if (!MUTEX_ON(env) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
+		return (0);
+
+	mtxmgr = env->mutex_handle;
+	mtxregion = mtxmgr->reginfo.primary;
+	mutexp = MUTEXP_SET(env, mutex);
+
+	CHECK_MTX_THREAD(env, mutexp);
+
+#ifdef HAVE_STATISTICS
+	if (F_ISSET(mutexp, DB_MUTEX_LOCKED))
+		STAT_INC(env, mutex, set_wait, mutexp->mutex_set_wait, mutex);
+	else
+		STAT_INC(env,
+		    mutex, set_nowait, mutexp->mutex_set_nowait, mutex);
+#endif
+
+#ifndef HAVE_MUTEX_HYBRID
+	/*
+	 * Wait 1ms initially, up to 10ms for mutexes backing logical database
+	 * locks, and up to 25 ms for mutual exclusion data structure mutexes.
+	 * SR: #7675
+	 */
+	micros = 1000;
+	max_micros = F_ISSET(mutexp, DB_MUTEX_LOGICAL_LOCK) ? 10000 : 25000;
+#endif
+
+	/* Clear the ending timespec so it'll be initialed upon first need. */
+	if (timeout != 0)
+		timespecclear(&timespec);
+
+	 /*
+	 * Only check the thread state once, by initializing the thread
+	 * control block pointer to null.  If it is not the failchk
+	 * thread, then ip will have a valid value subsequent times
+	 * in the loop.
+	 */
+	ip = NULL;
+
+loop:	/* Attempt to acquire the resource for N spins. */
+	for (nspins =
+	    mtxregion->stat.st_mutex_tas_spins; nspins > 0; --nspins) {
+#ifdef HAVE_MUTEX_S390_CC_ASSEMBLY
+		tsl_t zero;
+
+		zero = 0;
+#endif
+
+#ifdef HAVE_MUTEX_HPPA_MSEM_INIT
+	relock:
+#endif
+		/*
+		 * Avoid interlocked instructions until they're likely to
+		 * succeed by first checking whether it is held
+		 */
+		if (MUTEXP_IS_BUSY(mutexp) || !MUTEXP_ACQUIRE(mutexp)) {
+			if (F_ISSET(dbenv, DB_ENV_FAILCHK) &&
+			    ip == NULL && dbenv->is_alive(dbenv,
+			    mutexp->pid, mutexp->tid, 0) == 0) {
+				ret = __env_set_state(env, &ip, THREAD_VERIFY);
+				if (ret != 0 ||
+				    ip->dbth_state == THREAD_FAILCHK)
+					return (DB_RUNRECOVERY);
+			}
+			if (nowait)
+				return (DB_LOCK_NOTGRANTED);
+			/*
+			 * Some systems (notably those with newer Intel CPUs)
+			 * need a small pause here. [#6975]
+			 */
+			MUTEX_PAUSE
+			continue;
+		}
+
+		MEMBAR_ENTER();
+
+#ifdef HAVE_MUTEX_HPPA_MSEM_INIT
+		/*
+		 * HP semaphores are unlocked automatically when a holding
+		 * process exits.  If the mutex appears to be locked
+		 * (F_ISSET(DB_MUTEX_LOCKED)) but we got here, assume this
+		 * has happened.  Set the pid and tid into the mutex and
+		 * lock again.  (The default state of the mutexes used to
+		 * block in __lock_get_internal is locked, so exiting with
+		 * a locked mutex is reasonable behavior for a process that
+		 * happened to initialize or use one of them.)
+		 */
+		if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) {
+			dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid);
+			goto relock;
+		}
+		/*
+		 * If we make it here, the mutex isn't locked, the diagnostic
+		 * won't fire, and we were really unlocked by someone calling
+		 * the DB mutex unlock function.
+		 */
+#endif
+#ifdef DIAGNOSTIC
+		if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) {
+			char buf[DB_THREADID_STRLEN];
+			__db_errx(env, DB_STR_A("2030",
+		    "TAS lock failed: lock %ld currently in use: ID: %s",
+			    "%ld %s"), (long)mutex,
+			    dbenv->thread_id_string(dbenv,
+			    mutexp->pid, mutexp->tid, buf));
+			return (__env_panic(env, EACCES));
+		}
+#endif
+		F_SET(mutexp, DB_MUTEX_LOCKED);
+		dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid);
+
+#ifdef DIAGNOSTIC
+		/*
+		 * We want to switch threads as often as possible.  Yield
+		 * every time we get a mutex to ensure contention.
+		 */
+		if (F_ISSET(dbenv, DB_ENV_YIELDCPU))
+			__os_yield(env, 0, 0);
+#endif
+		return (0);
+	}
+
+	/*
+	 * We need to wait for the lock to become available.
+	 * Possibly setup timeouts if this is the first wait, or
+	 * check expiration times for the second and subsequent waits.
+	 */
+	if (timeout != 0) {
+		/* Set the expiration time if this is the first sleep . */
+		if (!timespecisset(&timespec))
+			__clock_set_expires(env, &timespec, timeout);
+		else {
+			timespecclear(&now);
+			if (__clock_expired(env, &now, &timespec))
+				return (DB_TIMEOUT);
+#ifndef HAVE_MUTEX_HYBRID
+			timespecsub(&now, &timespec);
+			DB_TIMESPEC_TO_TIMEOUT(time_left, &now, 0);
+			time_left = timeout - time_left;
+			if (micros > time_left)
+				micros = time_left;
+#endif
+		}
+	}
+
+	/*
+	 * This yields for a while for tas mutexes, and just gives up the
+	 * processor for hybrid mutexes.
+	 * By yielding here we can get the other thread to give up the
+	 * mutex before calling the more expensive library mutex call.
+	 * Tests have shown this to be a big win when there is contention.
+	 */
+	PERFMON4(env, mutex, suspend, mutex, TRUE, mutexp->alloc_id, mutexp);
+	__os_yield(env, 0, micros);
+	PERFMON4(env, mutex, resume, mutex, TRUE, mutexp->alloc_id, mutexp);
+
+#if defined(HAVE_MUTEX_HYBRID)
+	if (!MUTEXP_IS_BUSY(mutexp))
+		goto loop;
+	/* Wait until the mutex can be obtained exclusively or it times out. */
+	if ((ret = __db_hybrid_mutex_suspend(env,
+	    mutex, timeout == 0 ? NULL : &timespec, TRUE)) != 0)
+		return (ret);
+#else
+	if ((micros <<= 1) > max_micros)
+		micros = max_micros;
+#endif
+
+	/*
+	 * We're spinning.  The environment might be hung, and somebody else
+	 * has already recovered it.  The first thing recovery does is panic
+	 * the environment.  Check to see if we're never going to get this
+	 * mutex.
+	 */
+	PANIC_CHECK(env);
+
+	goto loop;
+}
+
+/*
+ * __db_tas_mutex_lock
+ *	Lock on a mutex, blocking if necessary.
+ *
+ * PUBLIC: int __db_tas_mutex_lock __P((ENV *, db_mutex_t, db_timeout_t));
+ */
+int
+__db_tas_mutex_lock(env, mutex, timeout)
+	ENV *env;
+	db_mutex_t mutex;
+	db_timeout_t timeout;
+{
+	return (__db_tas_mutex_lock_int(env, mutex, timeout, 0));
+}
+
+/*
+ * __db_tas_mutex_trylock
+ *	Try to exclusively lock a mutex without ever blocking - ever!
+ *
+ *	Returns 0 on success,
+ *		DB_LOCK_NOTGRANTED on timeout
+ *		Possibly DB_RUNRECOVERY if DB_ENV_FAILCHK or panic.
+ *
+ *	This will work for DB_MUTEX_SHARED, though it always tries
+ *	for exclusive access.
+ *
+ * PUBLIC: int __db_tas_mutex_trylock __P((ENV *, db_mutex_t));
+ */
+int
+__db_tas_mutex_trylock(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	return (__db_tas_mutex_lock_int(env, mutex, 0, 1));
+}
+
+#if defined(HAVE_SHARED_LATCHES)
+/*
+ * __db_tas_mutex_readlock_int
+ *    Internal function to get a shared lock on a latch, blocking if necessary.
+ *
+ */
+static inline int
+__db_tas_mutex_readlock_int(env, mutex, nowait)
+	ENV *env;
+	db_mutex_t mutex;
+	int nowait;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	DB_MUTEXMGR *mtxmgr;
+	DB_MUTEXREGION *mtxregion;
+	DB_THREAD_INFO *ip;
+	int lock;
+	u_int32_t nspins;
+	int ret;
+#ifndef HAVE_MUTEX_HYBRID
+	u_long micros, max_micros;
+#endif
+	dbenv = env->dbenv;
+
+	if (!MUTEX_ON(env) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
+		return (0);
+
+	mtxmgr = env->mutex_handle;
+	mtxregion = mtxmgr->reginfo.primary;
+	mutexp = MUTEXP_SET(env, mutex);
+
+	CHECK_MTX_THREAD(env, mutexp);
+
+	DB_ASSERT(env, F_ISSET(mutexp, DB_MUTEX_SHARED));
+#ifdef HAVE_STATISTICS
+	if (F_ISSET(mutexp, DB_MUTEX_LOCKED))
+		STAT_INC(env,
+		    mutex, set_rd_wait, mutexp->mutex_set_rd_wait, mutex);
+	else
+		STAT_INC(env,
+		    mutex, set_rd_nowait, mutexp->mutex_set_rd_nowait, mutex);
+#endif
+
+#ifndef HAVE_MUTEX_HYBRID
+	/*
+	 * Wait 1ms initially, up to 10ms for mutexes backing logical database
+	 * locks, and up to 25 ms for mutual exclusion data structure mutexes.
+	 * SR: #7675
+	 */
+	micros = 1000;
+	max_micros = F_ISSET(mutexp, DB_MUTEX_LOGICAL_LOCK) ? 10000 : 25000;
+#endif
+
+loop:	/* Attempt to acquire the resource for N spins. */
+	for (nspins =
+	    mtxregion->stat.st_mutex_tas_spins; nspins > 0; --nspins) {
+		lock = atomic_read(&mutexp->sharecount);
+		if (lock == MUTEX_SHARE_ISEXCLUSIVE ||
+		    !atomic_compare_exchange(env,
+			&mutexp->sharecount, lock, lock + 1)) {
+			/*
+			 * Some systems (notably those with newer Intel CPUs)
+			 * need a small pause here. [#6975]
+			 */
+			MUTEX_PAUSE
+			continue;
+		}
+
+		MEMBAR_ENTER();
+		/* For shared latches the threadid is the last requestor's id.
+		 */
+		dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid);
+
+		return (0);
+	}
+
+	/*
+	 * Waiting for the latched must be avoided when it could allow a
+	 * 'failchk'ing thread to hang.
+	 */
+	if (F_ISSET(dbenv, DB_ENV_FAILCHK) &&
+	    dbenv->is_alive(dbenv, mutexp->pid, mutexp->tid, 0) == 0) {
+		ret = __env_set_state(env, &ip, THREAD_VERIFY);
+		if (ret != 0 || ip->dbth_state == THREAD_FAILCHK)
+			return (DB_RUNRECOVERY);
+	}
+
+	/*
+	 * It is possible to spin out when the latch is just shared, due to
+	 * many threads or interrupts interfering with the compare&exchange.
+	 * Avoid spurious DB_LOCK_NOTGRANTED returns by retrying.
+	 */
+	if (nowait) {
+		if (atomic_read(&mutexp->sharecount) != MUTEX_SHARE_ISEXCLUSIVE)
+			goto loop;
+		return (DB_LOCK_NOTGRANTED);
+	}
+
+	/* Wait for the lock to become available. */
+#ifdef HAVE_MUTEX_HYBRID
+	/*
+	 * By yielding here we can get the other thread to give up the
+	 * mutex before calling the more expensive library mutex call.
+	 * Tests have shown this to be a big win when there is contention.
+	 */
+	PERFMON4(env, mutex, suspend, mutex, FALSE, mutexp->alloc_id, mutexp);
+	__os_yield(env, 0, 0);
+	PERFMON4(env, mutex, resume, mutex, FALSE, mutexp->alloc_id, mutexp);
+	if (atomic_read(&mutexp->sharecount) != MUTEX_SHARE_ISEXCLUSIVE)
+		goto loop;
+	/* Wait until the mutex is no longer exclusively locked. */
+	if ((ret = __db_hybrid_mutex_suspend(env, mutex, NULL, FALSE)) != 0)
+		return (ret);
+#else
+	PERFMON4(env, mutex, suspend, mutex, FALSE, mutexp->alloc_id, mutexp);
+	__os_yield(env, 0, micros);
+	PERFMON4(env, mutex, resume, mutex, FALSE, mutexp->alloc_id, mutexp);
+	if ((micros <<= 1) > max_micros)
+		micros = max_micros;
+#endif
+
+	/*
+	 * We're spinning.  The environment might be hung, and somebody else
+	 * has already recovered it.  The first thing recovery does is panic
+	 * the environment.  Check to see if we're never going to get this
+	 * mutex.
+	 */
+	PANIC_CHECK(env);
+
+	goto loop;
+}
+
+/*
+ * __db_tas_mutex_readlock
+ *	Get a shared lock on a latch, waiting if necessary.
+ *
+ * PUBLIC: #if defined(HAVE_SHARED_LATCHES)
+ * PUBLIC: int __db_tas_mutex_readlock __P((ENV *, db_mutex_t));
+ * PUBLIC: #endif
+ */
+int
+__db_tas_mutex_readlock(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	return (__db_tas_mutex_readlock_int(env, mutex, 0));
+}
+
+/*
+ * __db_tas_mutex_tryreadlock
+ *	Try to get a shared lock on a latch; don't wait when busy.
+ *
+ * PUBLIC: #if defined(HAVE_SHARED_LATCHES)
+ * PUBLIC: int __db_tas_mutex_tryreadlock __P((ENV *, db_mutex_t));
+ * PUBLIC: #endif
+ */
+int
+__db_tas_mutex_tryreadlock(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	return (__db_tas_mutex_readlock_int(env, mutex, 1));
+}
+#endif
+
+/*
+ * __db_tas_mutex_unlock --
+ *	Release a mutex.
+ *
+ * PUBLIC: int __db_tas_mutex_unlock __P((ENV *, db_mutex_t));
+ *
+ * Hybrid shared latch wakeup
+ *	When an exclusive requester waits for the last shared holder to
+ *	release, it increments mutexp->wait and pthread_cond_wait()'s. The
+ *	last shared unlock calls __db_pthread_mutex_unlock() to wake it.
+ */
+int
+__db_tas_mutex_unlock(env, mutex)
+    ENV *env;
+	db_mutex_t mutex;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+#ifdef HAVE_MUTEX_HYBRID
+	int ret;
+#ifdef MUTEX_DIAG
+	int waiters;
+#endif
+#endif
+#ifdef HAVE_SHARED_LATCHES
+	int sharecount;
+#endif
+	dbenv = env->dbenv;
+
+	if (!MUTEX_ON(env) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
+		return (0);
+
+	mutexp = MUTEXP_SET(env, mutex);
+#if defined(HAVE_MUTEX_HYBRID) && defined(MUTEX_DIAG)
+	waiters = mutexp->wait;
+#endif
+
+#if defined(DIAGNOSTIC)
+#if defined(HAVE_SHARED_LATCHES)
+	if (F_ISSET(mutexp, DB_MUTEX_SHARED)) {
+		if (atomic_read(&mutexp->sharecount) == 0) {
+			__db_errx(env, DB_STR_A("2031",
+			    "shared unlock %ld already unlocked", "%ld"),
+			    (long)mutex);
+			return (__env_panic(env, EACCES));
+		}
+	} else
+#endif
+	if (!F_ISSET(mutexp, DB_MUTEX_LOCKED)) {
+		__db_errx(env, DB_STR_A("2032",
+		    "unlock %ld already unlocked", "%ld"), (long)mutex);
+		return (__env_panic(env, EACCES));
+	}
+#endif
+
+#ifdef HAVE_SHARED_LATCHES
+	if (F_ISSET(mutexp, DB_MUTEX_SHARED)) {
+		sharecount = atomic_read(&mutexp->sharecount);
+		/*MUTEX_MEMBAR(mutexp->sharecount);*/		/* XXX why? */
+		if (sharecount == MUTEX_SHARE_ISEXCLUSIVE) {
+			F_CLR(mutexp, DB_MUTEX_LOCKED);
+			/* Flush flag update before zeroing count */
+			MEMBAR_EXIT();
+			atomic_init(&mutexp->sharecount, 0);
+		} else {
+			DB_ASSERT(env, sharecount > 0);
+			MEMBAR_EXIT();
+			sharecount = atomic_dec(env, &mutexp->sharecount);
+			DB_ASSERT(env, sharecount >= 0);
+			if (sharecount > 0)
+				return (0);
+		}
+	} else
+#endif
+	{
+		F_CLR(mutexp, DB_MUTEX_LOCKED);
+		MUTEX_UNSET(&mutexp->tas);
+	}
+
+#ifdef HAVE_MUTEX_HYBRID
+#ifdef DIAGNOSTIC
+	if (F_ISSET(dbenv, DB_ENV_YIELDCPU))
+		__os_yield(env, 0, 0);
+#endif
+
+	/* Prevent the load of wait from being hoisted before MUTEX_UNSET */
+	MUTEX_MEMBAR(mutexp->flags);
+	if (mutexp->wait &&
+	    (ret = __db_pthread_mutex_unlock(env, mutex)) != 0)
+		    return (ret);
+
+#ifdef MUTEX_DIAG
+	if (mutexp->wait)
+		printf("tas_unlock %ld %x waiters! busy %x waiters %d/%d\n",
+		    mutex, pthread_self(),
+		    MUTEXP_BUSY_FIELD(mutexp), waiters, mutexp->wait);
+#endif
+#endif
+
+	return (0);
+}
+
+/*
+ * __db_tas_mutex_destroy --
+ *	Destroy a mutex.
+ *
+ * PUBLIC: int __db_tas_mutex_destroy __P((ENV *, db_mutex_t));
+ */
+int
+__db_tas_mutex_destroy(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	DB_MUTEX *mutexp;
+#ifdef HAVE_MUTEX_HYBRID
+	int ret;
+#endif
+
+	if (!MUTEX_ON(env))
+		return (0);
+
+	mutexp = MUTEXP_SET(env, mutex);
+
+	MUTEX_DESTROY(&mutexp->tas);
+
+#ifdef HAVE_MUTEX_HYBRID
+	if ((ret = __db_pthread_mutex_destroy(env, mutex)) != 0)
+		return (ret);
+#endif
+
+	COMPQUIET(mutexp, NULL);	/* MUTEX_DESTROY may not be defined. */
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mutex/mut_win32.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,611 @@
+/*
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2002, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#define	LOAD_ACTUAL_MUTEX_CODE
+#include "db_int.h"
+
+#include "dbinc/atomic.h"
+/*
+ * This is where we load in the actual mutex declarations.
+ */
+#include "dbinc/mutex_int.h"
+
+/*
+ * Common code to get an event handle.  This is executed whenever a mutex
+ * blocks, or when unlocking a mutex that a thread is waiting on.  We can't
+ * keep these handles around, since the mutex structure is in shared memory,
+ * and each process gets its own handle value.
+ *
+ * We pass security attributes so that the created event is accessible by all
+ * users, in case a Windows service is sharing an environment with a local
+ * process run as a different user.
+ */
+static _TCHAR hex_digits[] = _T("0123456789abcdef");
+
+static __inline int get_handle(env, mutexp, eventp)
+	ENV *env;
+	DB_MUTEX *mutexp;
+	HANDLE *eventp;
+{
+	_TCHAR idbuf[] = _T("db.m00000000");
+	_TCHAR *p = idbuf + 12;
+	int ret = 0;
+	u_int32_t id;
+
+	for (id = (mutexp)->id; id != 0; id >>= 4)
+		*--p = hex_digits[id & 0xf];
+
+#ifndef DB_WINCE
+	if (DB_GLOBAL(win_sec_attr) == NULL) {
+		InitializeSecurityDescriptor(&DB_GLOBAL(win_default_sec_desc),
+		    SECURITY_DESCRIPTOR_REVISION);
+		SetSecurityDescriptorDacl(&DB_GLOBAL(win_default_sec_desc),
+		    TRUE, 0, FALSE);
+		DB_GLOBAL(win_default_sec_attr).nLength =
+		    sizeof(SECURITY_ATTRIBUTES);
+		DB_GLOBAL(win_default_sec_attr).bInheritHandle = FALSE;
+		DB_GLOBAL(win_default_sec_attr).lpSecurityDescriptor =
+		    &DB_GLOBAL(win_default_sec_desc);
+		DB_GLOBAL(win_sec_attr) = &DB_GLOBAL(win_default_sec_attr);
+	}
+#endif
+
+	if ((*eventp = CreateEvent(DB_GLOBAL(win_sec_attr),
+	    FALSE, FALSE, idbuf)) == NULL) {
+		ret = __os_get_syserr();
+		__db_syserr(env, ret, DB_STR("2002",
+		    "Win32 create event failed"));
+	}
+
+	return (ret);
+}
+
+/*
+ * __db_win32_mutex_lock_int
+ *	Internal function to lock a win32 mutex
+ *
+ *	If the wait parameter is 0, this function will return DB_LOCK_NOTGRANTED
+ *	rather than wait.
+ *
+ */
+static __inline int
+__db_win32_mutex_lock_int(env, mutex, timeout, wait)
+	ENV *env;
+	db_mutex_t mutex;
+	db_timeout_t timeout;
+	int wait;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	DB_MUTEXMGR *mtxmgr;
+	DB_MUTEXREGION *mtxregion;
+	DB_THREAD_INFO *ip;
+	HANDLE event;
+	u_int32_t ms, nspins;
+	db_timespec now, tempspec, timeoutspec;
+	db_timeout_t time_left;
+	int ret;
+#ifdef MUTEX_DIAG
+	LARGE_INTEGER now;
+#endif
+	dbenv = env->dbenv;
+
+	if (!MUTEX_ON(env) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
+		return (0);
+
+	mtxmgr = env->mutex_handle;
+	mtxregion = mtxmgr->reginfo.primary;
+	mutexp = MUTEXP_SET(env, mutex);
+
+	CHECK_MTX_THREAD(env, mutexp);
+
+	if (timeout != 0) {
+		timespecclear(&timeoutspec);
+		__clock_set_expires(env, &timeoutspec, timeout);
+	}
+
+	/*
+	 * See WINCE_ATOMIC_MAGIC definition for details.
+	 * Use sharecount, because the value just needs to be a db_atomic_t
+	 * memory mapped onto the same page as those being Interlocked*.
+	 */
+	WINCE_ATOMIC_MAGIC(&mutexp->sharecount);
+
+	event = NULL;
+	ms = 50;
+	ret = 0;
+
+	/*
+	 * Only check the thread state once, by initializing the thread
+	 * control block pointer to null.  If it is not the failchk
+	 * thread, then ip will have a valid value subsequent times
+	 * in the loop.
+	 */
+	ip = NULL;
+
+loop:	/* Attempt to acquire the mutex mutex_tas_spins times, if waiting. */
+	for (nspins =
+	    mtxregion->stat.st_mutex_tas_spins; nspins > 0; --nspins) {
+		/*
+		 * We can avoid the (expensive) interlocked instructions if
+		 * the mutex is already busy.
+		 */
+		if (MUTEXP_IS_BUSY(mutexp) || !MUTEXP_ACQUIRE(mutexp)) {
+			if (F_ISSET(dbenv, DB_ENV_FAILCHK) &&
+			    ip == NULL && dbenv->is_alive(dbenv,
+			    mutexp->pid, mutexp->tid, 0) == 0) {
+				ret = __env_set_state(env, &ip, THREAD_VERIFY);
+				if (ret != 0 ||
+				    ip->dbth_state == THREAD_FAILCHK)
+					return (DB_RUNRECOVERY);
+			}
+			if (!wait)
+				return (DB_LOCK_NOTGRANTED);
+			/*
+			 * Some systems (notably those with newer Intel CPUs)
+			 * need a small pause before retrying. [#6975]
+			 */
+			MUTEX_PAUSE
+			continue;
+		}
+
+#ifdef DIAGNOSTIC
+		if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) {
+			char buf[DB_THREADID_STRLEN];
+			__db_errx(env, DB_STR_A("2003",
+			    "Win32 lock failed: mutex already locked by %s",
+			    "%s"), dbenv->thread_id_string(dbenv,
+			    mutexp->pid, mutexp->tid, buf));
+			return (__env_panic(env, EACCES));
+		}
+#endif
+		F_SET(mutexp, DB_MUTEX_LOCKED);
+		dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid);
+
+#ifdef HAVE_STATISTICS
+		if (event == NULL)
+			++mutexp->mutex_set_nowait;
+		else
+			++mutexp->mutex_set_wait;
+#endif
+		if (event != NULL) {
+			CloseHandle(event);
+			InterlockedDecrement(&mutexp->nwaiters);
+#ifdef MUTEX_DIAG
+			if (ret != WAIT_OBJECT_0) {
+				QueryPerformanceCounter(&diag_now);
+				printf(DB_STR_A("2004",
+				    "[%I64d]: Lost signal on mutex %p, "
+				    "id %d, ms %d\n", "%I64d %p %d %d"),
+				    diag_now.QuadPart, mutexp, mutexp->id, ms);
+			}
+#endif
+		}
+
+#ifdef DIAGNOSTIC
+		/*
+		 * We want to switch threads as often as possible.  Yield
+		 * every time we get a mutex to ensure contention.
+		 */
+		if (F_ISSET(dbenv, DB_ENV_YIELDCPU))
+			__os_yield(env, 0, 0);
+#endif
+
+		return (0);
+	}
+
+	/*
+	 * Yield the processor; wait 50 ms initially, up to 1 second.  This
+	 * loop is needed to work around a race where the signal from the
+	 * unlocking thread gets lost.  We start at 50 ms because it's unlikely
+	 * to happen often and we want to avoid wasting CPU.
+	 */
+	if (timeout != 0) {
+		timespecclear(&now);
+		if (__clock_expired(env, &now, &timeoutspec)) {
+			if (event != NULL) {
+				CloseHandle(event);
+				InterlockedDecrement(&mutexp->nwaiters);
+			}
+			return (DB_TIMEOUT);
+		}
+		/* Reduce the event wait if the timeout would happen first. */
+		tempspec = timeoutspec;
+		timespecsub(&tempspec, &now);
+		DB_TIMESPEC_TO_TIMEOUT(time_left, &tempspec, 0);
+		time_left /= US_PER_MS;
+		if (ms > time_left)
+			ms = time_left;
+	}
+	if (event == NULL) {
+#ifdef MUTEX_DIAG
+		QueryPerformanceCounter(&diag_now);
+		printf(DB_STR_A("2005",
+		    "[%I64d]: Waiting on mutex %p, id %d\n",
+		    "%I64d %p %d"), diag_now.QuadPart, mutexp, mutexp->id);
+#endif
+		InterlockedIncrement(&mutexp->nwaiters);
+		if ((ret = get_handle(env, mutexp, &event)) != 0)
+			goto err;
+	}
+	if ((ret = WaitForSingleObject(event, ms)) == WAIT_FAILED) {
+		ret = __os_get_syserr();
+		goto err;
+	}
+	if ((ms <<= 1) > MS_PER_SEC)
+		ms = MS_PER_SEC;
+
+	PANIC_CHECK(env);
+	goto loop;
+
+err:	__db_syserr(env, ret, DB_STR("2006", "Win32 lock failed"));
+	return (__env_panic(env, __os_posix_err(ret)));
+}
+
+/*
+ * __db_win32_mutex_init --
+ *	Initialize a Win32 mutex.
+ *
+ * PUBLIC: int __db_win32_mutex_init __P((ENV *, db_mutex_t, u_int32_t));
+ */
+int
+__db_win32_mutex_init(env, mutex, flags)
+	ENV *env;
+	db_mutex_t mutex;
+	u_int32_t flags;
+{
+	DB_MUTEX *mutexp;
+
+	mutexp = MUTEXP_SET(env, mutex);
+	mutexp->id = ((getpid() & 0xffff) << 16) ^ P_TO_UINT32(mutexp);
+	F_SET(mutexp, flags);
+
+	return (0);
+}
+
+/*
+ * __db_win32_mutex_lock
+ *	Lock on a mutex, blocking if necessary.
+ *
+ * PUBLIC: int __db_win32_mutex_lock __P((ENV *, db_mutex_t, db_timeout_t));
+ */
+int
+__db_win32_mutex_lock(env, mutex, timeout)
+	ENV *env;
+	db_mutex_t mutex;
+	db_timeout_t timeout;
+{
+	return (__db_win32_mutex_lock_int(env, mutex, timeout, 1));
+}
+
+/*
+ * __db_win32_mutex_trylock
+ *	Try to lock a mutex, returning without waiting if it is busy
+ *
+ * PUBLIC: int __db_win32_mutex_trylock __P((ENV *, db_mutex_t));
+ */
+int
+__db_win32_mutex_trylock(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	return (__db_win32_mutex_lock_int(env, mutex, 0));
+}
+
+#if defined(HAVE_SHARED_LATCHES)
+/*
+ * __db_win32_mutex_readlock_int
+ *	Try to lock a mutex, possibly waiting if requested and necessary.
+ */
+int
+__db_win32_mutex_readlock_int(env, mutex, nowait)
+	ENV *env;
+	db_mutex_t mutex;
+	int nowait;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	DB_MUTEXMGR *mtxmgr;
+	DB_MUTEXREGION *mtxregion;
+	HANDLE event;
+	u_int32_t nspins;
+	int ms, ret;
+	long exch_ret, mtx_val;
+#ifdef MUTEX_DIAG
+	LARGE_INTEGER diag_now;
+#endif
+	dbenv = env->dbenv;
+
+	if (!MUTEX_ON(env) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
+		return (0);
+
+	mtxmgr = env->mutex_handle;
+	mtxregion = mtxmgr->reginfo.primary;
+	mutexp = MUTEXP_SET(env, mutex);
+
+	CHECK_MTX_THREAD(env, mutexp);
+
+	/*
+	 * See WINCE_ATOMIC_MAGIC definition for details.
+	 * Use sharecount, because the value just needs to be a db_atomic_t
+	 * memory mapped onto the same page as those being Interlocked*.
+	 */
+	WINCE_ATOMIC_MAGIC(&mutexp->sharecount);
+
+	event = NULL;
+	ms = 50;
+	ret = 0;
+	/*
+	 * This needs to be initialized, since if mutexp->tas
+	 * is write locked on the first pass, it needs a value.
+	 */
+	exch_ret = 0;
+
+loop:	/* Attempt to acquire the resource for N spins. */
+	for (nspins =
+	    mtxregion->stat.st_mutex_tas_spins; nspins > 0; --nspins) {
+		/*
+		 * We can avoid the (expensive) interlocked instructions if
+		 * the mutex is already "set".
+		 */
+retry:		mtx_val = atomic_read(&mutexp->sharecount);
+		if (mtx_val == MUTEX_SHARE_ISEXCLUSIVE) {
+			if (nowait)
+				return (DB_LOCK_NOTGRANTED);
+
+			continue;
+		} else if (!atomic_compare_exchange(env, &mutexp->sharecount,
+		    mtx_val, mtx_val + 1)) {
+			/*
+			 * Some systems (notably those with newer Intel CPUs)
+			 * need a small pause here. [#6975]
+			 */
+			MUTEX_PAUSE
+			goto retry;
+		}
+
+#ifdef HAVE_STATISTICS
+		if (event == NULL)
+			++mutexp->mutex_set_rd_nowait;
+		else
+			++mutexp->mutex_set_rd_wait;
+#endif
+		if (event != NULL) {
+			CloseHandle(event);
+			InterlockedDecrement(&mutexp->nwaiters);
+#ifdef MUTEX_DIAG
+			if (ret != WAIT_OBJECT_0) {
+				QueryPerformanceCounter(&diag_now);
+				printf(DB_STR_A("2007",
+				    "[%I64d]: Lost signal on mutex %p, "
+				    "id %d, ms %d\n", "%I64d %p %d %d"),
+				    diag_now.QuadPart, mutexp, mutexp->id, ms);
+			}
+#endif
+		}
+
+#ifdef DIAGNOSTIC
+		/*
+		 * We want to switch threads as often as possible.  Yield
+		 * every time we get a mutex to ensure contention.
+		 */
+		if (F_ISSET(dbenv, DB_ENV_YIELDCPU))
+			__os_yield(env, 0, 0);
+#endif
+
+		return (0);
+	}
+
+	/*
+	 * Yield the processor; wait 50 ms initially, up to 1 second.  This
+	 * loop is needed to work around a race where the signal from the
+	 * unlocking thread gets lost.  We start at 50 ms because it's unlikely
+	 * to happen often and we want to avoid wasting CPU.
+	 */
+	if (event == NULL) {
+#ifdef MUTEX_DIAG
+		QueryPerformanceCounter(&diag_now);
+		printf(DB_STR_A("2008",
+		    "[%I64d]: Waiting on mutex %p, id %d\n",
+		    "%I64d %p %d"), diag_now.QuadPart, mutexp, mutexp->id);
+#endif
+		InterlockedIncrement(&mutexp->nwaiters);
+		if ((ret = get_handle(env, mutexp, &event)) != 0)
+			goto err;
+	}
+	if ((ret = WaitForSingleObject(event, ms)) == WAIT_FAILED) {
+		ret = __os_get_syserr();
+		goto err;
+	}
+	if ((ms <<= 1) > MS_PER_SEC)
+		ms = MS_PER_SEC;
+
+	PANIC_CHECK(env);
+	goto loop;
+
+err:	__db_syserr(env, ret, DB_STR("2009",
+	    "Win32 read lock failed"));
+	return (__env_panic(env, __os_posix_err(ret)));
+}
+
+/*
+ * __db_win32_mutex_readlock
+ *	Get a shared lock on a latch
+ *
+ * PUBLIC: #if defined(HAVE_SHARED_LATCHES)
+ * PUBLIC: int __db_win32_mutex_readlock __P((ENV *, db_mutex_t));
+ * PUBLIC: #endif
+ */
+int
+__db_win32_mutex_readlock(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	return (__db_win32_mutex_readlock_int(env, mutex, 0));
+}
+
+/*
+ * __db_win32_mutex_tryreadlock
+ *	Try to a shared lock on a latch
+ *
+ * PUBLIC: #if defined(HAVE_SHARED_LATCHES)
+ * PUBLIC: int __db_win32_mutex_tryreadlock __P((ENV *, db_mutex_t));
+ * PUBLIC: #endif
+ */
+int
+__db_win32_mutex_tryreadlock(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	return (__db_win32_mutex_readlock_int(env, mutex, 1));
+}
+#endif
+
+/*
+ * __db_win32_mutex_unlock --
+ *	Release a mutex.
+ *
+ * PUBLIC: int __db_win32_mutex_unlock __P((ENV *, db_mutex_t));
+ */
+int
+__db_win32_mutex_unlock(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	DB_ENV *dbenv;
+	DB_MUTEX *mutexp;
+	HANDLE event;
+	int ret;
+#ifdef MUTEX_DIAG
+	LARGE_INTEGER diag_now;
+#endif
+	dbenv = env->dbenv;
+
+	if (!MUTEX_ON(env) || F_ISSET(dbenv, DB_ENV_NOLOCKING))
+		return (0);
+
+	mutexp = MUTEXP_SET(env, mutex);
+
+#ifdef DIAGNOSTIC
+	if (!MUTEXP_IS_BUSY(mutexp) || !(F_ISSET(mutexp, DB_MUTEX_SHARED) ||
+	    F_ISSET(mutexp, DB_MUTEX_LOCKED))) {
+		__db_errx(env, DB_STR_A("2010",
+	    "Win32 unlock failed: lock already unlocked: mutex %d busy %d",
+		    "%d %d"), mutex, MUTEXP_BUSY_FIELD(mutexp));
+		return (__env_panic(env, EACCES));
+	}
+#endif
+	/*
+	 * If we have a shared latch, and a read lock (DB_MUTEX_LOCKED is only
+	 * set for write locks), then decrement the latch. If the readlock is
+	 * still held by other threads, just return. Otherwise go ahead and
+	 * notify any waiting threads.
+	 */
+#ifdef HAVE_SHARED_LATCHES
+	if (F_ISSET(mutexp, DB_MUTEX_SHARED)) {
+		if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) {
+			F_CLR(mutexp, DB_MUTEX_LOCKED);
+			if ((ret = InterlockedExchange(
+			    (interlocked_val)(&atomic_read(
+			    &mutexp->sharecount)), 0)) !=
+			    MUTEX_SHARE_ISEXCLUSIVE) {
+				ret = DB_RUNRECOVERY;
+				goto err;
+			}
+		} else if (InterlockedDecrement(
+		    (interlocked_val)(&atomic_read(&mutexp->sharecount))) > 0)
+			return (0);
+	} else
+#endif
+	{
+		F_CLR(mutexp, DB_MUTEX_LOCKED);
+		MUTEX_UNSET(&mutexp->tas);
+	}
+
+	if (mutexp->nwaiters > 0) {
+		if ((ret = get_handle(env, mutexp, &event)) != 0)
+			goto err;
+
+#ifdef MUTEX_DIAG
+		QueryPerformanceCounter(&diag_now);
+		printf(DB_STR_A("2011",
+		    "[%I64d]: Signalling mutex %p, id %d\n",
+		    "%I64d %p %d"), diag_now.QuadPart, mutexp, mutexp->id);
+#endif
+		if (!PulseEvent(event)) {
+			ret = __os_get_syserr();
+			CloseHandle(event);
+			goto err;
+		}
+
+		CloseHandle(event);
+	}
+
+	return (0);
+
+err:	__db_syserr(env, ret, DB_STR("2012", "Win32 unlock failed"));
+	return (__env_panic(env, __os_posix_err(ret)));
+}
+
+/*
+ * __db_win32_mutex_destroy --
+ *	Destroy a mutex.
+ *
+ * PUBLIC: int __db_win32_mutex_destroy __P((ENV *, db_mutex_t));
+ */
+int
+__db_win32_mutex_destroy(env, mutex)
+	ENV *env;
+	db_mutex_t mutex;
+{
+	return (0);
+}
+
+#ifndef DB_WINCE
+/*
+ * db_env_set_win_security
+ *
+ *	Set the SECURITY_ATTRIBUTES to be used by BDB on Windows.
+ *	It should not be called while any BDB mutexes are locked.
+ *
+ * EXTERN: #if defined(DB_WIN32) && !defined(DB_WINCE)
+ * EXTERN: int db_env_set_win_security __P((SECURITY_ATTRIBUTES *sa));
+ * EXTERN: #endif
+ */
+int
+db_env_set_win_security(sa)
+	SECURITY_ATTRIBUTES *sa;
+{
+	DB_GLOBAL(win_sec_attr) = sa;
+	return (0);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_abort.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,55 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2005, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_abort --
+ *
+ * PUBLIC: void __os_abort __P((ENV *));
+ */
+void
+__os_abort(env)
+	ENV *env;
+{
+	__os_stack(env);		/* Try and get a stack trace. */
+
+#ifdef HAVE_ABORT
+	abort();			/* Try and drop core. */
+	/* NOTREACHED */
+#endif
+#ifdef SIGABRT
+	(void)raise(SIGABRT);		/* Try and drop core. */
+#endif
+	exit(1);			/* Quit anyway. */
+	/* NOTREACHED */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_abs.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,46 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_abspath --
+ *	Return if a path is an absolute path.
+ *
+ * PUBLIC: int __os_abspath __P((const char *));
+ */
+int
+__os_abspath(path)
+	const char *path;
+{
+	return (path[0] == '/');
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_addrinfo.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,201 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2006, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_getaddrinfo and __os_freeaddrinfo wrap the getaddrinfo and freeaddrinfo
+ * calls, as well as the associated platform dependent error handling, mapping
+ * the error return to a ANSI C/POSIX error return.
+ */
+
+/*
+ * __os_getaddrinfo --
+ *
+ * PUBLIC: #if defined(HAVE_REPLICATION_THREADS)
+ * PUBLIC: int __os_getaddrinfo __P((ENV *, const char *, u_int,
+ * PUBLIC:    const char *, const ADDRINFO *, ADDRINFO **));
+ * PUBLIC: #endif
+ */
+int
+__os_getaddrinfo(env, nodename, port, servname, hints, res)
+	ENV *env;
+	const char *nodename, *servname;
+	u_int port;
+	const ADDRINFO *hints;
+	ADDRINFO **res;
+{
+#ifdef HAVE_GETADDRINFO
+	int ret;
+
+	if ((ret = getaddrinfo(nodename, servname, hints, res)) == 0)
+		return (0);
+
+	__db_errx(env, DB_STR_A("0153",
+	    "%s(%u): host lookup failed: %s", "%s %u %s"),
+	    nodename == NULL ? "" : nodename, port,
+#ifdef DB_WIN32
+	    gai_strerrorA(ret));
+#else
+	    gai_strerror(ret));
+#endif
+	return (__os_posix_err(ret));
+#else
+	ADDRINFO *answer;
+	struct hostent *hostaddr;
+	struct sockaddr_in sin;
+	u_int32_t tmpaddr;
+	int ret;
+
+	COMPQUIET(hints, NULL);
+	COMPQUIET(servname, NULL);
+
+	/* INADDR_NONE is not defined on Solaris 2.6, 2.7 or 2.8. */
+#ifndef	INADDR_NONE
+#define	INADDR_NONE	((u_long)0xffffffff)
+#endif
+
+	/*
+	 * Basic implementation of IPv4 component of getaddrinfo.
+	 * Limited to the functionality used by repmgr.
+	 */
+	memset(&sin, 0, sizeof(sin));
+	sin.sin_family = AF_INET;
+	if (nodename) {
+		if (nodename[0] == '\0')
+			sin.sin_addr.s_addr = htonl(INADDR_ANY);
+		else if ((tmpaddr = inet_addr(CHAR_STAR_CAST nodename)) !=
+		    INADDR_NONE) {
+			sin.sin_addr.s_addr = tmpaddr;
+		} else {
+			hostaddr = gethostbyname(nodename);
+			if (hostaddr == NULL) {
+#ifdef DB_WIN32
+				ret = __os_get_neterr();
+				__db_syserr(env, ret, DB_STR_A("0154",
+				    "%s(%u): host lookup failed", "%s %u"),
+				    nodename == NULL ? "" : nodename, port);
+				return (__os_posix_err(ret));
+#else
+				/*
+				 * Historic UNIX systems used the h_errno
+				 * global variable to return gethostbyname
+				 * errors.  The only function we currently
+				 * use that needs h_errno is gethostbyname,
+				 * so we deal with it here.
+				 *
+				 * hstrerror is not available on Solaris 2.6
+				 * (it is in libresolv but is a private,
+				 * unexported symbol).
+				 */
+#ifdef HAVE_HSTRERROR
+				__db_errx(env, DB_STR_A("0155",
+				    "%s(%u): host lookup failed: %s",
+				    "%s %u %s"),
+				    nodename == NULL ? "" : nodename, port,
+				    hstrerror(h_errno));
+#else
+				__db_errx(env, DB_STR_A("0156",
+				    "%s(%u): host lookup failed: %d",
+				    "%s %u %d"),
+				    nodename == NULL ? "" : nodename, port,
+				    h_errno);
+#endif
+				switch (h_errno) {
+				case HOST_NOT_FOUND:
+				case NO_DATA:
+					return (EHOSTUNREACH);
+				case TRY_AGAIN:
+					return (EAGAIN);
+				case NO_RECOVERY:
+				default:
+					return (EFAULT);
+				}
+				/* NOTREACHED */
+#endif
+			}
+			memcpy(&(sin.sin_addr),
+			    hostaddr->h_addr, (size_t)hostaddr->h_length);
+		}
+	} else					/* No host specified. */
+		sin.sin_addr.s_addr = htonl(INADDR_ANY);
+	sin.sin_port = htons((u_int16_t)port);
+
+	if ((ret = __os_calloc(env, 1, sizeof(ADDRINFO), &answer)) != 0)
+		return (ret);
+	if ((ret = __os_malloc(env, sizeof(sin), &answer->ai_addr)) != 0) {
+		__os_free(env, answer);
+		return (ret);
+	}
+
+	answer->ai_family = AF_INET;
+	answer->ai_protocol = IPPROTO_TCP;
+	answer->ai_socktype = SOCK_STREAM;
+	answer->ai_addrlen = sizeof(sin);
+	memcpy(answer->ai_addr, &sin, sizeof(sin));
+	*res = answer;
+
+	return (0);
+#endif /* HAVE_GETADDRINFO */
+}
+
+/*
+ * __os_freeaddrinfo --
+ *
+ * PUBLIC: #if defined(HAVE_REPLICATION_THREADS)
+ * PUBLIC: void __os_freeaddrinfo __P((ENV *, ADDRINFO *));
+ * PUBLIC: #endif
+ */
+void
+__os_freeaddrinfo(env, ai)
+	ENV *env;
+	ADDRINFO *ai;
+{
+#ifdef HAVE_GETADDRINFO
+	COMPQUIET(env, NULL);
+
+	freeaddrinfo(ai);
+#else
+	ADDRINFO *next, *tmpaddr;
+
+	for (next = ai; next != NULL; next = tmpaddr) {
+		if (next->ai_canonname != NULL)
+			__os_free(env, next->ai_canonname);
+
+		if (next->ai_addr != NULL)
+			__os_free(env, next->ai_addr);
+
+		tmpaddr = next->ai_next;
+		__os_free(env, next);
+	}
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_alloc.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,486 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+#ifdef DIAGNOSTIC
+static void __os_guard __P((ENV *));
+
+typedef union {
+	size_t size;
+	uintmax_t align;
+} db_allocinfo_t;
+#endif
+
+/*
+ * !!!
+ * Correct for systems that return NULL when you allocate 0 bytes of memory.
+ * There are several places in DB where we allocate the number of bytes held
+ * by the key/data item, and it can be 0.  Correct here so that malloc never
+ * returns a NULL for that reason (which behavior is permitted by ANSI).  We
+ * could make these calls macros on non-Alpha architectures (that's where we
+ * saw the problem), but it's probably not worth the autoconf complexity.
+ *
+ * !!!
+ * Correct for systems that don't set errno when malloc and friends fail.
+ *
+ *	Out of memory.
+ *	We wish to hold the whole sky,
+ *	But we never will.
+ */
+
+/*
+ * __os_umalloc --
+ *	Allocate memory to be used by the application.
+ *
+ *	Use, in order of preference, the allocation function specified to the
+ *	ENV handle, the allocation function specified as a replacement for
+ *	the library malloc, or the library malloc().
+ *
+ * PUBLIC: int __os_umalloc __P((ENV *, size_t, void *));
+ */
+int
+__os_umalloc(env, size, storep)
+	ENV *env;
+	size_t size;
+	void *storep;
+{
+	DB_ENV *dbenv;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	/* Never allocate 0 bytes -- some C libraries don't like it. */
+	if (size == 0)
+		++size;
+
+	if (dbenv == NULL || dbenv->db_malloc == NULL) {
+		if (DB_GLOBAL(j_malloc) != NULL)
+			*(void **)storep = DB_GLOBAL(j_malloc)(size);
+		else
+			*(void **)storep = malloc(size);
+		if (*(void **)storep == NULL) {
+			/*
+			 *  Correct error return, see __os_malloc.
+			 */
+			if ((ret = __os_get_errno_ret_zero()) == 0) {
+				ret = ENOMEM;
+				__os_set_errno(ENOMEM);
+			}
+			__db_err(env, ret, DB_STR_A("0143", "malloc: %lu",
+			    "%lu"), (u_long)size);
+			return (ret);
+		}
+		return (0);
+	}
+
+	if ((*(void **)storep = dbenv->db_malloc(size)) == NULL) {
+		__db_errx(env, DB_STR("0144",
+		    "user-specified malloc function returned NULL"));
+		return (ENOMEM);
+	}
+
+	return (0);
+}
+
+/*
+ * __os_urealloc --
+ *	Allocate memory to be used by the application.
+ *
+ *	A realloc(3) counterpart to __os_umalloc's malloc(3).
+ *
+ * PUBLIC: int __os_urealloc __P((ENV *, size_t, void *));
+ */
+int
+__os_urealloc(env, size, storep)
+	ENV *env;
+	size_t size;
+	void *storep;
+{
+	DB_ENV *dbenv;
+	int ret;
+	void *ptr;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+	ptr = *(void **)storep;
+
+	/* Never allocate 0 bytes -- some C libraries don't like it. */
+	if (size == 0)
+		++size;
+
+	if (dbenv == NULL || dbenv->db_realloc == NULL) {
+		if (ptr == NULL)
+			return (__os_umalloc(env, size, storep));
+
+		if (DB_GLOBAL(j_realloc) != NULL)
+			*(void **)storep = DB_GLOBAL(j_realloc)(ptr, size);
+		else
+			*(void **)storep = realloc(ptr, size);
+		if (*(void **)storep == NULL) {
+			/*
+			 * Correct errno, see __os_realloc.
+			 */
+			if ((ret = __os_get_errno_ret_zero()) == 0) {
+				ret = ENOMEM;
+				__os_set_errno(ENOMEM);
+			}
+			__db_err(env, ret, DB_STR_A("0145",
+			    "realloc: %lu", "%lu"), (u_long)size);
+			return (ret);
+		}
+		return (0);
+	}
+
+	if ((*(void **)storep = dbenv->db_realloc(ptr, size)) == NULL) {
+		__db_errx(env, DB_STR("0146",
+		    "User-specified realloc function returned NULL"));
+		return (ENOMEM);
+	}
+
+	return (0);
+}
+
+/*
+ * __os_ufree --
+ *	Free memory used by the application.
+ *
+ *	A free(3) counterpart to __os_umalloc's malloc(3).
+ *
+ * PUBLIC: void __os_ufree __P((ENV *, void *));
+ */
+void
+__os_ufree(env, ptr)
+	ENV *env;
+	void *ptr;
+{
+	DB_ENV *dbenv;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	if (dbenv != NULL && dbenv->db_free != NULL)
+		dbenv->db_free(ptr);
+	else if (DB_GLOBAL(j_free) != NULL)
+		DB_GLOBAL(j_free)(ptr);
+	else
+		free(ptr);
+}
+
+/*
+ * __os_strdup --
+ *	The strdup(3) function for DB.
+ *
+ * PUBLIC: int __os_strdup __P((ENV *, const char *, void *));
+ */
+int
+__os_strdup(env, str, storep)
+	ENV *env;
+	const char *str;
+	void *storep;
+{
+	size_t size;
+	int ret;
+	void *p;
+
+	*(void **)storep = NULL;
+
+	size = strlen(str) + 1;
+	if ((ret = __os_malloc(env, size, &p)) != 0)
+		return (ret);
+
+	memcpy(p, str, size);
+
+	*(void **)storep = p;
+	return (0);
+}
+
+/*
+ * __os_calloc --
+ *	The calloc(3) function for DB.
+ *
+ * PUBLIC: int __os_calloc __P((ENV *, size_t, size_t, void *));
+ */
+int
+__os_calloc(env, num, size, storep)
+	ENV *env;
+	size_t num, size;
+	void *storep;
+{
+	int ret;
+
+	size *= num;
+	if ((ret = __os_malloc(env, size, storep)) != 0)
+		return (ret);
+
+	memset(*(void **)storep, 0, size);
+
+	return (0);
+}
+
+/*
+ * __os_malloc --
+ *	The malloc(3) function for DB.
+ *
+ * PUBLIC: int __os_malloc __P((ENV *, size_t, void *));
+ */
+int
+__os_malloc(env, size, storep)
+	ENV *env;
+	size_t size;
+	void *storep;
+{
+	int ret;
+	void *p;
+
+	*(void **)storep = NULL;
+
+	/* Never allocate 0 bytes -- some C libraries don't like it. */
+	if (size == 0)
+		++size;
+
+#ifdef DIAGNOSTIC
+	/* Add room for size and a guard byte. */
+	size += sizeof(db_allocinfo_t) + 1;
+#endif
+
+	if (DB_GLOBAL(j_malloc) != NULL)
+		p = DB_GLOBAL(j_malloc)(size);
+	else
+		p = malloc(size);
+	if (p == NULL) {
+		/*
+		 * Some C libraries don't correctly set errno when malloc(3)
+		 * fails.  We'd like to 0 out errno before calling malloc,
+		 * but it turns out that setting errno is quite expensive on
+		 * Windows/NT in an MT environment.
+		 */
+		if ((ret = __os_get_errno_ret_zero()) == 0) {
+			ret = ENOMEM;
+			__os_set_errno(ENOMEM);
+		}
+		__db_err(env, ret, DB_STR_A("0147", "malloc: %lu", "%lu"),
+		    (u_long)size);
+		return (ret);
+	}
+
+#ifdef DIAGNOSTIC
+	/* Overwrite memory. */
+	memset(p, CLEAR_BYTE, size);
+
+	/*
+	 * Guard bytes: if #DIAGNOSTIC is defined, we allocate an additional
+	 * byte after the memory and set it to a special value that we check
+	 * for when the memory is free'd.
+	 */
+	((u_int8_t *)p)[size - 1] = CLEAR_BYTE;
+
+	((db_allocinfo_t *)p)->size = size;
+	p = &((db_allocinfo_t *)p)[1];
+#endif
+	*(void **)storep = p;
+
+	return (0);
+}
+
+/*
+ * __os_realloc --
+ *	The realloc(3) function for DB.
+ *
+ * PUBLIC: int __os_realloc __P((ENV *, size_t, void *));
+ */
+int
+__os_realloc(env, size, storep)
+	ENV *env;
+	size_t size;
+	void *storep;
+{
+	int ret;
+	void *p, *ptr;
+
+	ptr = *(void **)storep;
+
+	/* Never allocate 0 bytes -- some C libraries don't like it. */
+	if (size == 0)
+		++size;
+
+	/* If we haven't yet allocated anything yet, simply call malloc. */
+	if (ptr == NULL)
+		return (__os_malloc(env, size, storep));
+
+#ifdef DIAGNOSTIC
+	/* Add room for size and a guard byte. */
+	size += sizeof(db_allocinfo_t) + 1;
+
+	/* Back up to the real beginning */
+	ptr = &((db_allocinfo_t *)ptr)[-1];
+
+	{
+		size_t s;
+
+		s = ((db_allocinfo_t *)ptr)->size;
+		if (((u_int8_t *)ptr)[s - 1] != CLEAR_BYTE)
+			 __os_guard(env);
+	}
+#endif
+
+	/*
+	 * Don't overwrite the original pointer, there are places in DB we
+	 * try to continue after realloc fails.
+	 */
+	if (DB_GLOBAL(j_realloc) != NULL)
+		p = DB_GLOBAL(j_realloc)(ptr, size);
+	else
+		p = realloc(ptr, size);
+	if (p == NULL) {
+		/*
+		 * Some C libraries don't correctly set errno when malloc(3)
+		 * fails.  We'd like to 0 out errno before calling malloc,
+		 * but it turns out that setting errno is quite expensive on
+		 * Windows/NT in an MT environment.
+		 */
+		if ((ret = __os_get_errno_ret_zero()) == 0) {
+			ret = ENOMEM;
+			__os_set_errno(ENOMEM);
+		}
+		__db_err(env, ret, DB_STR_A("0148", "realloc: %lu", "%lu"),
+		    (u_long)size);
+		return (ret);
+	}
+#ifdef DIAGNOSTIC
+	((u_int8_t *)p)[size - 1] = CLEAR_BYTE;	/* Initialize guard byte. */
+
+	((db_allocinfo_t *)p)->size = size;
+	p = &((db_allocinfo_t *)p)[1];
+#endif
+
+	*(void **)storep = p;
+
+	return (0);
+}
+
+/*
+ * __os_free --
+ *	The free(3) function for DB.
+ *
+ * PUBLIC: void __os_free __P((ENV *, void *));
+ */
+void
+__os_free(env, ptr)
+	ENV *env;
+	void *ptr;
+{
+#ifdef DIAGNOSTIC
+	size_t size;
+#endif
+
+	/*
+	 * ANSI C requires free(NULL) work.  Don't depend on the underlying
+	 * library.
+	 */
+	if (ptr == NULL)
+		return;
+
+#ifdef DIAGNOSTIC
+	/*
+	 * Check that the guard byte (one past the end of the memory) is
+	 * still CLEAR_BYTE.
+	 */
+	ptr = &((db_allocinfo_t *)ptr)[-1];
+	size = ((db_allocinfo_t *)ptr)->size;
+	if (((u_int8_t *)ptr)[size - 1] != CLEAR_BYTE)
+		 __os_guard(env);
+
+	/* Overwrite memory. */
+	if (size != 0)
+		memset(ptr, CLEAR_BYTE, size);
+#else
+	COMPQUIET(env, NULL);
+#endif
+
+	if (DB_GLOBAL(j_free) != NULL)
+		DB_GLOBAL(j_free)(ptr);
+	else
+		free(ptr);
+}
+
+#ifdef DIAGNOSTIC
+/*
+ * __os_guard --
+ *	Complain and abort.
+ */
+static void
+__os_guard(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("0149",
+	    "Guard byte incorrect during free"));
+	__os_abort(env);
+	/* NOTREACHED */
+}
+#endif
+
+/*
+ * __ua_memcpy --
+ *	Copy memory to memory without relying on any kind of alignment.
+ *
+ *	There are places in DB that we have unaligned data, for example,
+ *	when we've stored a structure in a log record as a DBT, and now
+ *	we want to look at it.  Unfortunately, if you have code like:
+ *
+ *		struct a {
+ *			int x;
+ *		} *p;
+ *
+ *		void *func_argument;
+ *		int local;
+ *
+ *		p = (struct a *)func_argument;
+ *		memcpy(&local, p->x, sizeof(local));
+ *
+ *	compilers optimize to use inline instructions requiring alignment,
+ *	and records in the log don't have any particular alignment.  (This
+ *	isn't a compiler bug, because it's a structure they're allowed to
+ *	assume alignment.)
+ *
+ *	Casting the memcpy arguments to (u_int8_t *) appears to work most
+ *	of the time, but we've seen examples where it wasn't sufficient
+ *	and there's nothing in ANSI C that requires that work.
+ *
+ * PUBLIC: void *__ua_memcpy __P((void *, const void *, size_t));
+ */
+void *
+__ua_memcpy(dst, src, len)
+	void *dst;
+	const void *src;
+	size_t len;
+{
+	return ((void *)memcpy(dst, src, len));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_clock.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,94 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_gettime --
+ *	Return the current time-of-day clock in seconds and nanoseconds.
+ *
+ * PUBLIC: void __os_gettime __P((ENV *, db_timespec *, int));
+ */
+void
+__os_gettime(env, tp, monotonic)
+	ENV *env;
+	db_timespec *tp;
+	int monotonic;
+{
+	const char *sc;
+	int ret;
+
+#if defined(HAVE_CLOCK_GETTIME)
+#if defined(HAVE_CLOCK_MONOTONIC)
+	if (monotonic)
+		RETRY_CHK((clock_gettime(
+		    CLOCK_MONOTONIC, (struct timespec *)tp)), ret);
+	else
+#endif
+		RETRY_CHK((clock_gettime(
+		    CLOCK_REALTIME, (struct timespec *)tp)), ret);
+
+	if (ret != 0) {
+		sc = "clock_gettime";
+		goto err;
+	}
+#elif defined(HAVE_GETTIMEOFDAY)
+	struct timeval v;
+
+	RETRY_CHK((gettimeofday(&v, NULL)), ret);
+	if (ret != 0) {
+		sc = "gettimeofday";
+		goto err;
+	}
+
+	tp->tv_sec = v.tv_sec;
+	tp->tv_nsec = v.tv_usec * NS_PER_US;
+#elif defined(HAVE_TIME)
+	time_t now;
+
+	RETRY_CHK((time(&now) == (time_t)-1 ? 1 : 0), ret);
+	if (ret != 0) {
+		sc = "time";
+		goto err;
+	}
+
+	tp->tv_sec = now;
+	tp->tv_nsec = 0;
+#else
+	NO AVAILABLE CLOCK IMPLEMENTATION
+#endif
+	COMPQUIET(monotonic, 0);
+	return;
+
+err:	__db_syserr(env, ret, "%s", sc);
+	(void)__env_panic(env, __os_posix_err(ret));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_config.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,92 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_fs_notzero --
+ *	Return 1 if allocated filesystem blocks are not zeroed.
+ *
+ * PUBLIC: int __os_fs_notzero __P((void));
+ */
+int
+__os_fs_notzero()
+{
+	/* Most filesystems zero out implicitly created pages. */
+	return (0);
+}
+
+/*
+ * __os_support_direct_io --
+ *	Return 1 if we support direct I/O.
+ *
+ * PUBLIC: int __os_support_direct_io __P((void));
+ */
+int
+__os_support_direct_io()
+{
+	int ret;
+
+	ret = 0;
+
+#ifdef HAVE_O_DIRECT
+	ret = 1;
+#endif
+#if defined(HAVE_DIRECTIO) && defined(DIRECTIO_ON)
+	ret = 1;
+#endif
+	return (ret);
+}
+
+/*
+ * __os_support_db_register --
+ *	Return 1 if the system supports DB_REGISTER.
+ *
+ * PUBLIC: int __os_support_db_register __P((void));
+ */
+int
+__os_support_db_register()
+{
+	return (1);
+}
+
+/*
+ * __os_support_replication --
+ *	Return 1 if the system supports replication.
+ *
+ * PUBLIC: int __os_support_replication __P((void));
+ */
+int
+__os_support_replication()
+{
+	return (1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_cpu.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,69 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+#ifdef HAVE_SYSTEM_INCLUDE_FILES
+#if defined(HAVE_PSTAT_GETDYNAMIC)
+#include <sys/pstat.h>
+#endif
+#endif
+
+/*
+ * __os_cpu_count --
+ *	Return the number of CPUs.
+ *
+ * PUBLIC: u_int32_t __os_cpu_count __P((void));
+ */
+u_int32_t
+__os_cpu_count()
+{
+#if defined(HAVE_PSTAT_GETDYNAMIC)
+	/*
+	 * HP/UX.
+	 */
+	struct pst_dynamic psd;
+
+	return ((u_int32_t)pstat_getdynamic(&psd,
+	    sizeof(psd), (size_t)1, 0) == -1 ? 1 : psd.psd_proc_cnt);
+#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
+	/*
+	 * Solaris, Linux.
+	 */
+	long nproc;
+
+	nproc = sysconf(_SC_NPROCESSORS_ONLN);
+	return ((u_int32_t)(nproc > 1 ? nproc : 1));
+#else
+	return (1);
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_ctime.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,69 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_ctime --
+ *	Format a time-stamp.
+ *
+ * PUBLIC: char *__os_ctime __P((const time_t *, char *));
+ */
+char *
+__os_ctime(tod, time_buf)
+	const time_t *tod;
+	char *time_buf;
+{
+	time_buf[CTIME_BUFLEN - 1] = '\0';
+
+	/*
+	 * The ctime_r interface is the POSIX standard, thread-safe version of
+	 * ctime.  However, it was implemented in three different ways (with
+	 * and without a buffer length argument, and where the buffer length
+	 * argument was an int vs. a size_t *).  Also, you can't depend on a
+	 * return of (char *) from ctime_r, HP-UX 10.XX's version returned an
+	 * int.
+	 */
+#if defined(HAVE_VXWORKS)
+	{
+	size_t buflen = CTIME_BUFLEN;
+	(void)ctime_r(tod, time_buf, &buflen);
+	}
+#elif defined(HAVE_CTIME_R_3ARG)
+	(void)ctime_r(tod, time_buf, CTIME_BUFLEN);
+#elif defined(HAVE_CTIME_R)
+	(void)ctime_r(tod, time_buf);
+#else
+	(void)strncpy(time_buf, ctime(tod), CTIME_BUFLEN - 1);
+#endif
+	return (time_buf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_dir.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,162 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
+
+#include "db_int.h"
+
+/*
+ * __os_dirlist --
+ *	Return a list of the files in a directory.
+ *
+ * PUBLIC: int __os_dirlist __P((ENV *, const char *, int, char ***, int *));
+ */
+int
+__os_dirlist(env, dir, returndir, namesp, cntp)
+	ENV *env;
+	const char *dir;
+	int returndir, *cntp;
+	char ***namesp;
+{
+	DB_ENV *dbenv;
+	struct dirent *dp;
+	DIR *dirp;
+	struct stat sb;
+	int arraysz, cnt, ret;
+	char **names, buf[DB_MAXPATHLEN];
+
+	*namesp = NULL;
+	*cntp = 0;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0159",
+		    "fileops: directory list %s", "%s"), dir);
+
+	if (DB_GLOBAL(j_dirlist) != NULL)
+		return (DB_GLOBAL(j_dirlist)(dir, namesp, cntp));
+
+	if ((dirp = opendir(CHAR_STAR_CAST dir)) == NULL)
+		return (__os_get_errno());
+	names = NULL;
+	for (arraysz = cnt = 0; (dp = readdir(dirp)) != NULL;) {
+		snprintf(buf, sizeof(buf), "%s/%s", dir, dp->d_name);
+
+		RETRY_CHK(stat(buf, &sb), ret);
+		if (ret != 0) {
+			ret = __os_posix_err(ret);
+			/* Ignore entries that no longer exist. */
+			if (ret == ENOENT)
+				continue;
+
+			goto err;
+		}
+
+		/*
+		 * We return regular files, and optionally return directories
+		 * (except for dot and dot-dot).
+		 *
+		 * Shared memory files are of a different type on QNX, and we
+		 * return those as well.
+		 */
+#ifdef HAVE_QNX
+		if (!S_ISREG(sb.st_mode) && !S_TYPEISSHM(&sb)) {
+#else
+		if (!S_ISREG(sb.st_mode)) {
+#endif
+			if (!returndir || !S_ISDIR(sb.st_mode))
+				continue;
+			if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' ||
+			    (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
+				continue;
+		}
+
+		if (cnt >= arraysz) {
+			arraysz += 100;
+			if ((ret = __os_realloc(env,
+			    (u_int)arraysz * sizeof(names[0]), &names)) != 0)
+				goto err;
+		}
+		if ((ret = __os_strdup(env, dp->d_name, &names[cnt])) != 0)
+			goto err;
+		cnt++;
+	}
+	(void)closedir(dirp);
+
+	*namesp = names;
+	*cntp = cnt;
+	return (0);
+
+err:	if (names != NULL)
+		__os_dirfree(env, names, cnt);
+	if (dirp != NULL)
+		(void)closedir(dirp);
+	return (ret);
+}
+
+/*
+ * __os_dirfree --
+ *	Free the list of files.
+ *
+ * PUBLIC: void __os_dirfree __P((ENV *, char **, int));
+ */
+void
+__os_dirfree(env, names, cnt)
+	ENV *env;
+	char **names;
+	int cnt;
+{
+	if (DB_GLOBAL(j_dirfree) != NULL)
+		DB_GLOBAL(j_dirfree)(names, cnt);
+	else {
+		while (cnt > 0)
+			__os_free(env, names[--cnt]);
+		__os_free(env, names);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_errno.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,151 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_get_errno_ret_zero --
+ *	Return the last system error, including an error of zero.
+ *
+ * PUBLIC: int __os_get_errno_ret_zero __P((void));
+ */
+int
+__os_get_errno_ret_zero()
+{
+	/* This routine must be able to return the same value repeatedly. */
+	return (errno);
+}
+
+/*
+ * We've seen cases where system calls failed but errno was never set.  For
+ * that reason, __os_get_errno() and __os_get_syserr set errno to EAGAIN if
+ * it's not already set, to work around the problem.  For obvious reasons,
+ * we can only call this function if we know an error has occurred, that
+ * is, we can't test the return for a non-zero value after the get call.
+ *
+ * __os_get_errno --
+ *	Return the last ANSI C "errno" value or EAGAIN if the last error
+ *	is zero.
+ *
+ * PUBLIC: int __os_get_errno __P((void));
+ */
+int
+__os_get_errno()
+{
+	/* This routine must be able to return the same value repeatedly. */
+	return (__os_get_syserr());
+}
+
+#if 0
+/*
+ * __os_get_neterr --
+ *      Return the last network-related error or EAGAIN if the last
+ *	error is zero.
+ *
+ * PUBLIC: int __os_get_neterr __P((void));
+ */
+int
+__os_get_neterr()
+{
+	/* This routine must be able to return the same value repeatedly. */
+	return (__os_get_syserr());
+}
+#endif
+
+/*
+ * __os_get_syserr --
+ *	Return the last system error or EAGAIN if the last error is zero.
+ *
+ * PUBLIC: int __os_get_syserr __P((void));
+ */
+int
+__os_get_syserr()
+{
+	/* This routine must be able to return the same value repeatedly. */
+	if (errno == 0)
+		__os_set_errno(EAGAIN);
+	return (errno);
+}
+
+/*
+ * __os_set_errno --
+ *	Set the value of errno.
+ *
+ * PUBLIC: void __os_set_errno __P((int));
+ */
+void
+__os_set_errno(evalue)
+	int evalue;
+{
+	/*
+	 * This routine is called by the compatibility interfaces (DB 1.85,
+	 * dbm and hsearch).  Force values > 0, that is, not one of DB 2.X
+	 * and later's public error returns.  If something bad has happened,
+	 * default to EFAULT -- a nasty return.  Otherwise, default to EINVAL.
+	 * As the compatibility APIs aren't included on Windows, the Windows
+	 * version of this routine doesn't need this behavior.
+	 */
+	errno =
+	    evalue >= 0 ? evalue : (evalue == DB_RUNRECOVERY ? EFAULT : EINVAL);
+}
+
+/*
+ * __os_strerror --
+ *	Return a string associated with the system error.
+ *
+ * PUBLIC: char *__os_strerror __P((int, char *, size_t));
+ */
+char *
+__os_strerror(error, buf, len)
+	int error;
+	char *buf;
+	size_t len;
+{
+	/* No translation is needed in the POSIX layer. */
+	(void)strncpy(buf, strerror(error), len - 1);
+	buf[len - 1] = '\0';
+
+	return (buf);
+}
+
+/*
+ * __os_posix_err
+ *	Convert a system error to a POSIX error.
+ *
+ * PUBLIC: int __os_posix_err __P((int));
+ */
+int
+__os_posix_err(error)
+	int error;
+{
+	return (error);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_fid.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,157 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_fileid --
+ *	Return a unique identifier for a file.
+ *
+ * PUBLIC: int __os_fileid __P((ENV *, const char *, int, u_int8_t *));
+ */
+int
+__os_fileid(env, fname, unique_okay, fidp)
+	ENV *env;
+	const char *fname;
+	int unique_okay;
+	u_int8_t *fidp;
+{
+	pid_t pid;
+	size_t i;
+	u_int32_t tmp;
+	u_int8_t *p;
+
+#ifdef HAVE_STAT
+	struct stat sb;
+	int ret;
+
+	/*
+	 * The structure of a fileid on a POSIX/UNIX system is:
+	 *
+	 *	ino[4] dev[4] unique-ID[4] serial-counter[4] empty[4].
+	 *
+	 * For real files, which have a backing inode and device, the first
+	 * 8 bytes are filled in and the following bytes are left 0.  For
+	 * temporary files, the following 12 bytes are filled in.
+	 *
+	 * Clear the buffer.
+	 */
+	memset(fidp, 0, DB_FILE_ID_LEN);
+	RETRY_CHK((stat(CHAR_STAR_CAST fname, &sb)), ret);
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR_A("0158",
+		    "stat: %s", "%s"), fname);
+		return (__os_posix_err(ret));
+	}
+
+	/*
+	 * !!!
+	 * Nothing is ever big enough -- on Sparc V9, st_ino, st_dev and the
+	 * time_t types are all 8 bytes.  As DB_FILE_ID_LEN is only 20 bytes,
+	 * we convert to a (potentially) smaller fixed-size type and use it.
+	 *
+	 * We don't worry about byte sexing or the actual variable sizes.
+	 *
+	 * When this routine is called from the DB access methods, it's only
+	 * called once -- whatever ID is generated when a database is created
+	 * is stored in the database file's metadata, and that is what is
+	 * saved in the mpool region's information to uniquely identify the
+	 * file.
+	 *
+	 * When called from the mpool layer this routine will be called each
+	 * time a new thread of control wants to share the file, which makes
+	 * things tougher.  As far as byte sexing goes, since the mpool region
+	 * lives on a single host, there's no issue of that -- the entire
+	 * region is byte sex dependent.  As far as variable sizes go, we make
+	 * the simplifying assumption that 32-bit and 64-bit processes will
+	 * get the same 32-bit values if we truncate any returned 64-bit value
+	 * to a 32-bit value.  When we're called from the mpool layer, though,
+	 * we need to be careful not to include anything that isn't
+	 * reproducible for a given file, such as the timestamp or serial
+	 * number.
+	 */
+	tmp = (u_int32_t)sb.st_ino;
+	for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
+		*fidp++ = *p++;
+
+	tmp = (u_int32_t)sb.st_dev;
+	for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
+		*fidp++ = *p++;
+#else
+	 /*
+	  * Use the file name.
+	  *
+	  * XXX
+	  * Cast the first argument, the BREW ARM compiler is unhappy if
+	  * we don't.
+	  */
+	 (void)strncpy((char *)fidp, fname, DB_FILE_ID_LEN);
+#endif /* HAVE_STAT */
+
+	if (unique_okay) {
+		/* Add in 32-bits of (hopefully) unique number. */
+		__os_unique_id(env, &tmp);
+		for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
+			*fidp++ = *p++;
+
+		/*
+		 * Initialize/increment the serial number we use to help
+		 * avoid fileid collisions.  Note we don't bother with
+		 * locking; it's unpleasant to do from down in here, and
+		 * if we race on this no real harm will be done, since the
+		 * finished fileid has so many other components.
+		 *
+		 * We use the bottom 32-bits of the process ID, hoping they
+		 * are more random than the top 32-bits (should we be on a
+		 * machine with 64-bit process IDs).
+		 *
+		 * We increment by 100000 on each call as a simple way of
+		 * randomizing; simply incrementing seems potentially less
+		 * useful if pids are also simply incremented, since this
+		 * is process-local and we may be one of a set of processes
+		 * starting up.  100000 pushes us out of pid space on most
+		 * 32-bit platforms, and has few interesting properties in
+		 * base 2.
+		 */
+		if (DB_GLOBAL(fid_serial) == 0) {
+			__os_id(env->dbenv, &pid, NULL);
+			DB_GLOBAL(fid_serial) = (u_int32_t)pid;
+		} else
+			DB_GLOBAL(fid_serial) += 100000;
+
+		for (p = (u_int8_t *)
+		    &DB_GLOBAL(fid_serial), i = sizeof(u_int32_t); i > 0; --i)
+			*fidp++ = *p++;
+	}
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_flock.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,86 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_fdlock --
+ *	Acquire/release a lock on a byte in a file.
+ *
+ * PUBLIC: int __os_fdlock __P((ENV *, DB_FH *, off_t, int, int));
+ */
+int
+__os_fdlock(env, fhp, offset, acquire, nowait)
+	ENV *env;
+	DB_FH *fhp;
+	int acquire, nowait;
+	off_t offset;
+{
+#ifdef HAVE_FCNTL
+	DB_ENV *dbenv;
+	struct flock fl;
+	int ret, t_ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
+
+	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0138",
+		    "fileops: flock %s %s offset %lu", "%s %s %lu"), fhp->name,
+		    acquire ? DB_STR_P("acquire"): DB_STR_P("release"),
+		    (u_long)offset);
+
+	fl.l_start = offset;
+	fl.l_len = 1;
+	fl.l_type = acquire ? F_WRLCK : F_UNLCK;
+	fl.l_whence = SEEK_SET;
+
+	RETRY_CHK_EINTR_ONLY(
+	    (fcntl(fhp->fd, nowait ? F_SETLK : F_SETLKW, &fl)), ret);
+
+	if (ret == 0)
+		return (0);
+
+	if ((t_ret = __os_posix_err(ret)) != EACCES && t_ret != EAGAIN)
+		__db_syserr(env, ret, DB_STR("0139", "fcntl"));
+	return (t_ret);
+#else
+	COMPQUIET(fhp, NULL);
+	COMPQUIET(acquire, 0);
+	COMPQUIET(nowait, 0);
+	COMPQUIET(offset, 0);
+	__db_syserr(env, DB_OPNOTSUP, DB_STR("0140",
+	    "advisory file locking unavailable"));
+	return (DB_OPNOTSUP);
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_fsync.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,126 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+#ifdef	HAVE_VXWORKS
+#include "ioLib.h"
+
+#define	fsync(fd)	__vx_fsync(fd)
+
+int
+__vx_fsync(fd)
+	int fd;
+{
+	int ret;
+
+	/*
+	 * The results of ioctl are driver dependent.  Some will return the
+	 * number of bytes sync'ed.  Only if it returns 'ERROR' should we
+	 * flag it.
+	 */
+	if ((ret = ioctl(fd, FIOSYNC, 0)) != ERROR)
+		return (0);
+	return (ret);
+}
+#endif
+
+#ifdef __hp3000s900
+#define	fsync(fd)	__mpe_fsync(fd)
+
+int
+__mpe_fsync(fd)
+	int fd;
+{
+	extern FCONTROL(short, short, void *);
+
+	FCONTROL(_MPE_FILENO(fd), 2, NULL);	/* Flush the buffers */
+	FCONTROL(_MPE_FILENO(fd), 6, NULL);	/* Write the EOF */
+	return (0);
+}
+#endif
+
+/*
+ * __os_fsync --
+ *	Flush a file descriptor.
+ *
+ * PUBLIC: int __os_fsync __P((ENV *, DB_FH *));
+ */
+int
+__os_fsync(env, fhp)
+	ENV *env;
+	DB_FH *fhp;
+{
+	DB_ENV *dbenv;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
+
+	/*
+	 * Do nothing if the file descriptor has been marked as not requiring
+	 * any sync to disk.
+	 */
+	if (F_ISSET(fhp, DB_FH_NOSYNC))
+		return (0);
+
+	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0150", "fileops: flush %s", "%s"),
+		    fhp->name);
+
+	if (DB_GLOBAL(j_fsync) != NULL)
+		ret = DB_GLOBAL(j_fsync)(fhp->fd);
+	else {
+#if defined(F_FULLFSYNC)
+		RETRY_CHK((fcntl(fhp->fd, F_FULLFSYNC, 0)), ret);
+		/*
+		 * On OS X, F_FULLSYNC only works on HFS+, so we need to fall
+		 * back to regular fsync on other filesystems.
+		 */
+		if (ret == ENOTSUP)
+			RETRY_CHK((fsync(fhp->fd)), ret);
+#elif defined(HAVE_QNX)
+		ret = __qnx_fsync(fhp);
+#elif defined(HAVE_FDATASYNC)
+		RETRY_CHK((fdatasync(fhp->fd)), ret);
+#else
+		RETRY_CHK((fsync(fhp->fd)), ret);
+#endif
+	}
+
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR("0151", "fsync"));
+		ret = __os_posix_err(ret);
+	}
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_getenv.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,80 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_getenv --
+ *	Retrieve an environment variable.
+ *
+ * PUBLIC: int __os_getenv __P((ENV *, const char *, char **, size_t));
+ */
+int
+__os_getenv(env, name, bpp, buflen)
+	ENV *env;
+	const char *name;
+	char **bpp;
+	size_t buflen;
+{
+	/*
+	 * If we have getenv, there's a value and the buffer is large enough:
+	 *	copy value into the pointer, return 0
+	 * If we have getenv, there's a value  and the buffer is too short:
+	 *	set pointer to NULL, return EINVAL
+	 * If we have getenv and there's no value:
+	 *	set pointer to NULL, return 0
+	 * If we don't have getenv:
+	 *	set pointer to NULL, return 0
+	 */
+#ifdef HAVE_GETENV
+	char *p;
+
+	if ((p = getenv(name)) != NULL) {
+		if (strlen(p) < buflen) {
+			(void)strcpy(*bpp, p);
+			return (0);
+		}
+
+		*bpp = NULL;
+		__db_errx(env, DB_STR_A("0157",
+		    "%s: buffer too small to hold environment variable %s",
+		    "%s %s"), name, p);
+		return (EINVAL);
+	}
+#else
+	COMPQUIET(env, NULL);
+	COMPQUIET(name, NULL);
+	COMPQUIET(buflen, 0);
+#endif
+	*bpp = NULL;
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_handle.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,265 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_openhandle --
+ *	Open a file, using POSIX 1003.1 open flags.
+ *
+ * PUBLIC: int __os_openhandle
+ * PUBLIC:     __P((ENV *, const char *, int, int, DB_FH **));
+ */
+int
+__os_openhandle(env, name, flags, mode, fhpp)
+	ENV *env;
+	const char *name;
+	int flags, mode;
+	DB_FH **fhpp;
+{
+	DB_FH *fhp;
+	u_int nrepeat, retries;
+	int fcntl_flags, ret;
+#ifdef HAVE_VXWORKS
+	int newflags;
+#endif
+	/*
+	 * Allocate the file handle and copy the file name.  We generally only
+	 * use the name for verbose or error messages, but on systems where we
+	 * can't unlink temporary files immediately, we use the name to unlink
+	 * the temporary file when the file handle is closed.
+	 *
+	 * Lock the ENV handle and insert the new file handle on the list.
+	 */
+	if ((ret = __os_calloc(env, 1, sizeof(DB_FH), &fhp)) != 0)
+		return (ret);
+	if ((ret = __os_strdup(env, name, &fhp->name)) != 0)
+		goto err;
+	if (env != NULL) {
+		MUTEX_LOCK(env, env->mtx_env);
+		TAILQ_INSERT_TAIL(&env->fdlist, fhp, q);
+		MUTEX_UNLOCK(env, env->mtx_env);
+		F_SET(fhp, DB_FH_ENVLINK);
+	}
+
+	/* If the application specified an interface, use it. */
+	if (DB_GLOBAL(j_open) != NULL) {
+		if ((fhp->fd = DB_GLOBAL(j_open)(name, flags, mode)) == -1) {
+			ret = __os_posix_err(__os_get_syserr());
+			goto err;
+		}
+		goto done;
+	}
+
+	retries = 0;
+	for (nrepeat = 1; nrepeat < 4; ++nrepeat) {
+		ret = 0;
+#ifdef	HAVE_VXWORKS
+		/*
+		 * VxWorks does not support O_CREAT on open, you have to use
+		 * creat() instead.  (It does not support O_EXCL or O_TRUNC
+		 * either, even though they are defined "for future support".)
+		 * We really want the POSIX behavior that if O_CREAT is set,
+		 * we open if it exists, or create it if it doesn't exist.
+		 * If O_CREAT is specified, single thread and try to open the
+		 * file.  If successful, and O_EXCL return EEXIST.  If
+		 * unsuccessful call creat and then end single threading.
+		 */
+		if (LF_ISSET(O_CREAT)) {
+			DB_BEGIN_SINGLE_THREAD;
+			newflags = flags & ~(O_CREAT | O_EXCL);
+			if ((fhp->fd = open(name, newflags, mode)) != -1) {
+				/*
+				 * We need to mark the file opened at this
+				 * point so that if we get any error below
+				 * we will properly close the fd we just
+				 * opened on the error path.
+				 */
+				F_SET(fhp, DB_FH_OPENED);
+				if (LF_ISSET(O_EXCL)) {
+					/*
+					 * If we get here, want O_EXCL create,
+					 * and the file exists.  Close and
+					 * return EEXISTS.
+					 */
+					DB_END_SINGLE_THREAD;
+					ret = EEXIST;
+					goto err;
+				}
+				/*
+				 * XXX
+				 * Assume any error means non-existence.
+				 * Unfortunately return values (even for
+				 * non-existence) are driver specific so
+				 * there is no single error we can use to
+				 * verify we truly got the equivalent of
+				 * ENOENT.
+				 */
+			} else
+				fhp->fd = creat(name, newflags);
+			DB_END_SINGLE_THREAD;
+		} else
+		/* FALLTHROUGH */
+#endif
+#ifdef __VMS
+		/*
+		 * !!!
+		 * Open with full sharing on VMS.
+		 *
+		 * We use these flags because they are the ones set by the VMS
+		 * CRTL mmap() call when it opens a file, and we have to be
+		 * able to open files that mmap() has previously opened, e.g.,
+		 * when we're joining already existing DB regions.
+		 */
+		fhp->fd = open(name, flags, mode, "shr=get,put,upd,del,upi");
+#else
+		fhp->fd = open(name, flags, mode);
+#endif
+		if (fhp->fd != -1) {
+			ret = 0;
+			break;
+		}
+
+		switch (ret = __os_posix_err(__os_get_syserr())) {
+		case EMFILE:
+		case ENFILE:
+		case ENOSPC:
+			/*
+			 * If it's a "temporary" error, we retry up to 3 times,
+			 * waiting up to 12 seconds.  While it's not a problem
+			 * if we can't open a database, an inability to open a
+			 * log file is cause for serious dismay.
+			 */
+			__os_yield(env, nrepeat * 2, 0);
+			break;
+		case EAGAIN:
+		case EBUSY:
+		case EINTR:
+			/*
+			 * If an EAGAIN, EBUSY or EINTR, retry immediately for
+			 * DB_RETRY times.
+			 */
+			if (++retries < DB_RETRY)
+				--nrepeat;
+			break;
+		default:
+			/* Open is silent on error. */
+			goto err;
+		}
+	}
+
+	if (ret == 0) {
+#if defined(HAVE_FCNTL_F_SETFD)
+		/* Deny file descriptor access to any child process. */
+		if ((fcntl_flags = fcntl(fhp->fd, F_GETFD)) == -1 ||
+		    fcntl(fhp->fd, F_SETFD, fcntl_flags | FD_CLOEXEC) == -1) {
+			ret = __os_get_syserr();
+			__db_syserr(env, ret, DB_STR("0162",
+			    "fcntl(F_SETFD)"));
+			ret = __os_posix_err(ret);
+			goto err;
+		}
+#else
+		COMPQUIET(fcntl_flags, 0);
+#endif
+
+done:		F_SET(fhp, DB_FH_OPENED);
+		*fhpp = fhp;
+		return (0);
+	}
+
+err:	(void)__os_closehandle(env, fhp);
+	return (ret);
+}
+
+/*
+ * __os_closehandle --
+ *	Close a file.
+ *
+ * PUBLIC: int __os_closehandle __P((ENV *, DB_FH *));
+ */
+int
+__os_closehandle(env, fhp)
+	ENV *env;
+	DB_FH *fhp;
+{
+	DB_ENV *dbenv;
+	int ret;
+
+	ret = 0;
+
+	/*
+	 * If we linked the DB_FH handle into the ENV, it needs to be
+	 * unlinked.
+	 */
+	DB_ASSERT(env, env != NULL || !F_ISSET(fhp, DB_FH_ENVLINK));
+
+	if (env != NULL) {
+		dbenv = env->dbenv;
+		if (fhp->name != NULL && FLD_ISSET(
+		    dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+			__db_msg(env, DB_STR_A("0163",
+			    "fileops: close %s", "%s"), fhp->name);
+
+		if (F_ISSET(fhp, DB_FH_ENVLINK)) {
+			/*
+			 * Lock the ENV handle and remove this file
+			 * handle from the list.
+			 */
+			MUTEX_LOCK(env, env->mtx_env);
+			TAILQ_REMOVE(&env->fdlist, fhp, q);
+			MUTEX_UNLOCK(env, env->mtx_env);
+		}
+	}
+
+	/* Discard any underlying system file reference. */
+	if (F_ISSET(fhp, DB_FH_OPENED)) {
+		if (DB_GLOBAL(j_close) != NULL)
+			ret = DB_GLOBAL(j_close)(fhp->fd);
+		else
+			RETRY_CHK((close(fhp->fd)), ret);
+		if (ret != 0) {
+			__db_syserr(env, ret, DB_STR("0164", "close"));
+			ret = __os_posix_err(ret);
+		}
+	}
+
+	/* Unlink the file if we haven't already done so. */
+	if (F_ISSET(fhp, DB_FH_UNLINK))
+		(void)__os_unlink(env, fhp->name, 0);
+
+	if (fhp->name != NULL)
+		__os_free(env, fhp->name);
+	__os_free(env, fhp);
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_map.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,629 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+#ifdef HAVE_SYSTEM_INCLUDE_FILES
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#endif
+
+#ifdef HAVE_SHMGET
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif
+#endif
+
+#ifdef HAVE_MMAP
+static int __os_map __P((ENV *, char *, DB_FH *, size_t, int, int, void **));
+#endif
+#ifdef HAVE_SHMGET
+static int __shm_mode __P((ENV *));
+#else
+static int __no_system_mem __P((ENV *));
+#endif
+
+/*
+ * __os_attach --
+ *	Create/join a shared memory region.
+ *
+ * PUBLIC: int __os_attach __P((ENV *, REGINFO *, REGION *));
+ */
+int
+__os_attach(env, infop, rp)
+	ENV *env;
+	REGINFO *infop;
+	REGION *rp;
+{
+	DB_ENV *dbenv;
+	int create_ok, ret;
+
+	/*
+	 * We pass a DB_ENV handle to the user's replacement map function,
+	 * so there must be a valid handle.
+	 */
+	DB_ASSERT(env, env != NULL && env->dbenv != NULL);
+	dbenv = env->dbenv;
+
+	if (DB_GLOBAL(j_region_map) != NULL) {
+		/*
+		 * We have to find out if the region is being created.  Ask
+		 * the underlying map function, and use the REGINFO structure
+		 * to pass that information back to our caller.
+		 */
+		create_ok = F_ISSET(infop, REGION_CREATE) ? 1 : 0;
+		ret = DB_GLOBAL(j_region_map)
+		    (dbenv, infop->name, rp->max, &create_ok, &infop->addr);
+		if (create_ok)
+			F_SET(infop, REGION_CREATE);
+		else
+			F_CLR(infop, REGION_CREATE);
+		return (ret);
+	}
+
+	if (F_ISSET(env, ENV_SYSTEM_MEM)) {
+		/*
+		 * If the region is in system memory on UNIX, we use shmget(2).
+		 *
+		 * !!!
+		 * There exist spinlocks that don't work in shmget memory, e.g.,
+		 * the HP/UX msemaphore interface.  If we don't have locks that
+		 * will work in shmget memory, we better be private and not be
+		 * threaded.  If we reach this point, we know we're public, so
+		 * it's an error.
+		 */
+#if defined(HAVE_MUTEX_HPPA_MSEM_INIT)
+		__db_errx(env, DB_STR("0114",
+    "architecture does not support locks inside system shared memory"));
+		return (EINVAL);
+#endif
+#if defined(HAVE_SHMGET)
+		{
+		key_t segid;
+		int id, mode;
+
+		/*
+		 * We could potentially create based on REGION_CREATE_OK, but
+		 * that's dangerous -- we might get crammed in sideways if
+		 * some of the expected regions exist but others do not.  Also,
+		 * if the requested size differs from an existing region's
+		 * actual size, then all sorts of nasty things can happen.
+		 * Basing create solely on REGION_CREATE is much safer -- a
+		 * recovery will get us straightened out.
+		 */
+		if (F_ISSET(infop, REGION_CREATE)) {
+			/*
+			 * The application must give us a base System V IPC key
+			 * value.  Adjust that value based on the region's ID,
+			 * and correct so the user's original value appears in
+			 * the ipcs output.
+			 */
+			if (dbenv->shm_key == INVALID_REGION_SEGID) {
+				__db_errx(env, DB_STR("0115",
+			    "no base system shared memory ID specified"));
+				return (EINVAL);
+			}
+
+			/*
+			 * !!!
+			 * The BDB API takes a "long" as the base segment ID,
+			 * then adds an unsigned 32-bit value and stores it
+			 * in a key_t.  Wrong, admittedly, but not worth an
+			 * API change to fix.
+			 */
+			segid = (key_t)
+			    ((u_long)dbenv->shm_key + (infop->id - 1));
+
+			/*
+			 * If map to an existing region, assume the application
+			 * crashed and we're restarting.  Delete the old region
+			 * and re-try.  If that fails, return an error, the
+			 * application will have to select a different segment
+			 * ID or clean up some other way.
+			 */
+			if ((id = shmget(segid, 0, 0)) != -1) {
+				(void)shmctl(id, IPC_RMID, NULL);
+				if ((id = shmget(segid, 0, 0)) != -1) {
+					__db_errx(env, DB_STR_A("0116",
+		"shmget: key: %ld: shared system memory region already exists",
+					    "%ld"), (long)segid);
+					return (EAGAIN);
+				}
+			}
+
+			/*
+			 * Map the DbEnv::open method file mode permissions to
+			 * shmget call permissions.
+			 */
+			mode = IPC_CREAT | __shm_mode(env);
+			if ((id = shmget(segid, rp->max, mode)) == -1) {
+				ret = __os_get_syserr();
+				__db_syserr(env, ret, DB_STR_A("0117",
+	"shmget: key: %ld: unable to create shared system memory region",
+				    "%ld"), (long)segid);
+				return (__os_posix_err(ret));
+			}
+			rp->size = rp->max;
+			rp->segid = id;
+		} else
+			id = rp->segid;
+
+		if ((infop->addr = shmat(id, NULL, 0)) == (void *)-1) {
+			infop->addr = NULL;
+			ret = __os_get_syserr();
+			__db_syserr(env, ret, DB_STR_A("0118",
+	"shmat: id %d: unable to attach to shared system memory region",
+			    "%d"), id);
+			return (__os_posix_err(ret));
+		}
+
+		/* Optionally lock the memory down. */
+		if (F_ISSET(env, ENV_LOCKDOWN)) {
+#ifdef HAVE_SHMCTL_SHM_LOCK
+			ret = shmctl(
+			    id, SHM_LOCK, NULL) == 0 ? 0 : __os_get_syserr();
+#else
+			ret = DB_OPNOTSUP;
+#endif
+			if (ret != 0) {
+				__db_syserr(env, ret, DB_STR_A("0119",
+	"shmctl/SHM_LOCK: id %d: unable to lock down shared memory region",
+				   "%d"), id);
+				return (__os_posix_err(ret));
+			}
+		}
+
+		return (0);
+		}
+#else
+		return (__no_system_mem(env));
+#endif
+	}
+
+#ifdef HAVE_MMAP
+	{
+	infop->fhp = NULL;
+
+	/*
+	 * Try to open/create the shared region file.  We DO NOT need to ensure
+	 * that multiple threads/processes attempting to simultaneously create
+	 * the region are properly ordered, our caller has already taken care
+	 * of that.
+	 */
+	if ((ret = __os_open(env, infop->name, 0,
+	    DB_OSO_REGION |
+	    (F_ISSET(infop, REGION_CREATE_OK) ? DB_OSO_CREATE : 0),
+	    env->db_mode, &infop->fhp)) != 0)
+		__db_err(env, ret, "%s", infop->name);
+
+	/*
+	 * If we created the file, grow it before mapping it in. We really want
+	 * to avoid touching the buffer cache after mmap() is called, doing
+	 * anything else confuses the hell out of systems without merged
+	 * VM/buffer cache systems, or, more to the point, *badly* merged
+	 * VM/buffer cache systems.
+	 */
+	if (rp->max < rp->size)
+		rp->max = rp->size;
+	if (ret == 0 && F_ISSET(infop, REGION_CREATE)) {
+		if (F_ISSET(dbenv, DB_ENV_REGION_INIT))
+			ret = __db_file_write(env, infop->fhp,
+			    rp->size / MEGABYTE, rp->size % MEGABYTE, 0x00);
+		else
+			ret = __db_file_extend(env, infop->fhp, rp->size);
+	}
+
+	/* Map the file in. */
+	if (ret == 0)
+		ret = __os_map(env,
+		    infop->name, infop->fhp, rp->max, 1, 0, &infop->addr);
+
+	if (ret != 0 && infop->fhp != NULL) {
+		(void)__os_closehandle(env, infop->fhp);
+		infop->fhp = NULL;
+	}
+
+	return (ret);
+	}
+#else
+	COMPQUIET(infop, NULL);
+	COMPQUIET(rp, NULL);
+	__db_errx(env, DB_STR("0120",
+	    "architecture lacks mmap(2), shared environments not possible"));
+	return (DB_OPNOTSUP);
+#endif
+}
+
+/*
+ * __os_detach --
+ *	Detach from a shared memory region.
+ *
+ * PUBLIC: int __os_detach __P((ENV *, REGINFO *, int));
+ */
+int
+__os_detach(env, infop, destroy)
+	ENV *env;
+	REGINFO *infop;
+	int destroy;
+{
+	DB_ENV *dbenv;
+	REGION *rp;
+	int ret;
+
+	/*
+	 * We pass a DB_ENV handle to the user's replacement unmap function,
+	 * so there must be a valid handle.
+	 */
+	DB_ASSERT(env, env != NULL && env->dbenv != NULL);
+	dbenv = env->dbenv;
+
+	rp = infop->rp;
+
+	/* If the user replaced the unmap call, call through their interface. */
+	if (DB_GLOBAL(j_region_unmap) != NULL)
+		return (DB_GLOBAL(j_region_unmap)(dbenv, infop->addr));
+
+	if (F_ISSET(env, ENV_SYSTEM_MEM)) {
+#ifdef HAVE_SHMGET
+		int segid;
+
+		/*
+		 * We may be about to remove the memory referenced by rp,
+		 * save the segment ID, and (optionally) wipe the original.
+		 */
+		segid = rp->segid;
+		if (destroy)
+			rp->segid = INVALID_REGION_SEGID;
+
+		if (shmdt(infop->addr) != 0) {
+			ret = __os_get_syserr();
+			__db_syserr(env, ret, DB_STR("0121", "shmdt"));
+			return (__os_posix_err(ret));
+		}
+
+		if (destroy && shmctl(segid, IPC_RMID,
+		    NULL) != 0 && (ret = __os_get_syserr()) != EINVAL) {
+			__db_syserr(env, ret, DB_STR_A("0122",
+	    "shmctl: id %d: unable to delete system shared memory region",
+			    "%d"), segid);
+			return (__os_posix_err(ret));
+		}
+
+		return (0);
+#else
+		return (__no_system_mem(env));
+#endif
+	}
+
+#ifdef HAVE_MMAP
+#ifdef HAVE_MUNLOCK
+	if (F_ISSET(env, ENV_LOCKDOWN))
+		(void)munlock(infop->addr, rp->max);
+#endif
+	if (infop->fhp != NULL) {
+		ret = __os_closehandle(env, infop->fhp);
+		infop->fhp = NULL;
+		if (ret != 0)
+			return (ret);
+	}
+
+	if (munmap(infop->addr, rp->max) != 0) {
+		ret = __os_get_syserr();
+		__db_syserr(env, ret, DB_STR("0123", "munmap"));
+		return (__os_posix_err(ret));
+	}
+
+	if (destroy && (ret = __os_unlink(env, infop->name, 1)) != 0)
+		return (ret);
+
+	return (0);
+#else
+	COMPQUIET(destroy, 0);
+	COMPQUIET(ret, 0);
+	return (EINVAL);
+#endif
+}
+
+/*
+ * __os_mapfile --
+ *	Map in a shared memory file.
+ *
+ * PUBLIC: int __os_mapfile __P((ENV *, char *, DB_FH *, size_t, int, void **));
+ */
+int
+__os_mapfile(env, path, fhp, len, is_rdonly, addrp)
+	ENV *env;
+	char *path;
+	DB_FH *fhp;
+	int is_rdonly;
+	size_t len;
+	void **addrp;
+{
+#if defined(HAVE_MMAP) && !defined(HAVE_QNX)
+	DB_ENV *dbenv;
+
+	/* If the user replaced the map call, call through their interface. */
+	if (DB_GLOBAL(j_file_map) != NULL) {
+		/*
+		 * We pass a DB_ENV handle to the user's replacement map
+		 * function, so there must be a valid handle.
+		 */
+		DB_ASSERT(env, env != NULL && env->dbenv != NULL);
+		dbenv = env->dbenv;
+
+		return (
+		    DB_GLOBAL(j_file_map)(dbenv, path, len, is_rdonly, addrp));
+	}
+
+	return (__os_map(env, path, fhp, len, 0, is_rdonly, addrp));
+#else
+	COMPQUIET(env, NULL);
+	COMPQUIET(path, NULL);
+	COMPQUIET(fhp, NULL);
+	COMPQUIET(is_rdonly, 0);
+	COMPQUIET(len, 0);
+	COMPQUIET(addrp, NULL);
+	return (DB_OPNOTSUP);
+#endif
+}
+
+/*
+ * __os_unmapfile --
+ *	Unmap the shared memory file.
+ *
+ * PUBLIC: int __os_unmapfile __P((ENV *, void *, size_t));
+ */
+int
+__os_unmapfile(env, addr, len)
+	ENV *env;
+	void *addr;
+	size_t len;
+{
+	DB_ENV *dbenv;
+	int ret;
+
+	/*
+	 * We pass a DB_ENV handle to the user's replacement unmap function,
+	 * so there must be a valid handle.
+	 */
+	DB_ASSERT(env, env != NULL && env->dbenv != NULL);
+	dbenv = env->dbenv;
+
+	if (FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR("0124", "fileops: munmap"));
+
+	/* If the user replaced the map call, call through their interface. */
+	if (DB_GLOBAL(j_file_unmap) != NULL)
+		return (DB_GLOBAL(j_file_unmap)(dbenv, addr));
+
+#ifdef HAVE_MMAP
+#ifdef HAVE_MUNLOCK
+	if (F_ISSET(env, ENV_LOCKDOWN))
+		RETRY_CHK((munlock(addr, len)), ret);
+		/*
+		 * !!!
+		 * The return value is ignored.
+		 */
+#else
+	COMPQUIET(env, NULL);
+#endif
+	RETRY_CHK((munmap(addr, len)), ret);
+	ret = __os_posix_err(ret);
+#else
+	COMPQUIET(env, NULL);
+	ret = EINVAL;
+#endif
+	return (ret);
+}
+
+#ifdef HAVE_MMAP
+/*
+ * __os_map --
+ *	Call the mmap(2) function.
+ */
+static int
+__os_map(env, path, fhp, len, is_region, is_rdonly, addrp)
+	ENV *env;
+	char *path;
+	DB_FH *fhp;
+	int is_region, is_rdonly;
+	size_t len;
+	void **addrp;
+{
+	DB_ENV *dbenv;
+	int flags, prot, ret;
+	void *p;
+
+	/*
+	 * We pass a DB_ENV handle to the user's replacement map function,
+	 * so there must be a valid handle.
+	 */
+	DB_ASSERT(env, env != NULL && env->dbenv != NULL);
+	dbenv = env->dbenv;
+
+	if (FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0125", "fileops: mmap %s",
+		    "%s"), path);
+
+	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
+
+	/*
+	 * If it's read-only, it's private, and if it's not, it's shared.
+	 * Don't bother with an additional parameter.
+	 */
+	flags = is_rdonly ? MAP_PRIVATE : MAP_SHARED;
+
+#ifdef MAP_FILE
+	/*
+	 * Historically, MAP_FILE was required for mapping regular files,
+	 * even though it was the default.  Some systems have it, some
+	 * don't, some that have it set it to 0.
+	 */
+	flags |= MAP_FILE;
+#endif
+
+	/*
+	 * I know of no systems that implement the flag to tell the system
+	 * that the region contains semaphores, but it's not an unreasonable
+	 * thing to do, and has been part of the design since forever.  I
+	 * don't think anyone will object, but don't set it for read-only
+	 * files, it doesn't make sense.
+	 */
+#ifdef MAP_HASSEMAPHORE
+	if (is_region && !is_rdonly)
+		flags |= MAP_HASSEMAPHORE;
+#else
+	COMPQUIET(is_region, 0);
+#endif
+
+	/*
+	 * FreeBSD:
+	 * Causes data dirtied via this VM map to be flushed to physical media
+	 * only when necessary (usually by the pager) rather then gratuitously.
+	 * Typically this prevents the update daemons from flushing pages
+	 * dirtied through such maps and thus allows efficient sharing of
+	 * memory across unassociated processes using a file-backed shared
+	 * memory map.
+	 */
+#ifdef MAP_NOSYNC
+	flags |= MAP_NOSYNC;
+#endif
+
+	prot = PROT_READ | (is_rdonly ? 0 : PROT_WRITE);
+
+	/*
+	 * XXX
+	 * Work around a bug in the VMS V7.1 mmap() implementation.  To map
+	 * a file into memory on VMS it needs to be opened in a certain way,
+	 * originally.  To get the file opened in that certain way, the VMS
+	 * mmap() closes the file and re-opens it.  When it does this, it
+	 * doesn't flush any caches out to disk before closing.  The problem
+	 * this causes us is that when the memory cache doesn't get written
+	 * out, the file isn't big enough to match the memory chunk and the
+	 * mmap() call fails.  This call to fsync() fixes the problem.  DEC
+	 * thinks this isn't a bug because of language in XPG5 discussing user
+	 * responsibility for on-disk and in-memory synchronization.
+	 */
+#ifdef VMS
+	if (__os_fsync(env, fhp) == -1)
+		return (__os_posix_err(__os_get_syserr()));
+#endif
+
+	/* MAP_FAILED was not defined in early mmap implementations. */
+#ifndef MAP_FAILED
+#define	MAP_FAILED	-1
+#endif
+	if ((p = mmap(NULL,
+	    len, prot, flags, fhp->fd, (off_t)0)) == (void *)MAP_FAILED) {
+		ret = __os_get_syserr();
+		__db_syserr(env, ret, DB_STR("0126", "mmap"));
+		return (__os_posix_err(ret));
+	}
+
+	/*
+	 * If it's a region, we want to make sure that the memory isn't paged.
+	 * For example, Solaris will page large mpools because it thinks that
+	 * I/O buffer memory is more important than we are.  The mlock system
+	 * call may or may not succeed (mlock is restricted to the super-user
+	 * on some systems).  Currently, the only other use of mmap in DB is
+	 * to map read-only databases -- we don't want them paged, either, so
+	 * the call isn't conditional.
+	 */
+	if (F_ISSET(env, ENV_LOCKDOWN)) {
+#ifdef HAVE_MLOCK
+		ret = mlock(p, len) == 0 ? 0 : __os_get_syserr();
+#else
+		ret = DB_OPNOTSUP;
+#endif
+		if (ret != 0) {
+			__db_syserr(env, ret, DB_STR("0127", "mlock"));
+			return (__os_posix_err(ret));
+		}
+	}
+
+	*addrp = p;
+	return (0);
+}
+#endif
+
+#ifdef HAVE_SHMGET
+#ifndef SHM_R
+#define	SHM_R	0400
+#endif
+#ifndef SHM_W
+#define	SHM_W	0200
+#endif
+
+/*
+ * __shm_mode --
+ *	Map the DbEnv::open method file mode permissions to shmget call
+ *	permissions.
+ */
+static int
+__shm_mode(env)
+	ENV *env;
+{
+	int mode;
+
+	/* Default to r/w owner, r/w group. */
+	if (env->db_mode == 0)
+		return (SHM_R | SHM_W | SHM_R >> 3 | SHM_W >> 3);
+
+	mode = 0;
+	if (env->db_mode & S_IRUSR)
+		mode |= SHM_R;
+	if (env->db_mode & S_IWUSR)
+		mode |= SHM_W;
+	if (env->db_mode & S_IRGRP)
+		mode |= SHM_R >> 3;
+	if (env->db_mode & S_IWGRP)
+		mode |= SHM_W >> 3;
+	if (env->db_mode & S_IROTH)
+		mode |= SHM_R >> 6;
+	if (env->db_mode & S_IWOTH)
+		mode |= SHM_W >> 6;
+	return (mode);
+}
+#else
+/*
+ * __no_system_mem --
+ *	No system memory environments error message.
+ */
+static int
+__no_system_mem(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("0128",
+	    "architecture doesn't support environments in system memory"));
+	return (DB_OPNOTSUP);
+}
+#endif /* HAVE_SHMGET */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_mkdir.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,74 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_mkdir --
+ *	Create a directory.
+ *
+ * PUBLIC: int __os_mkdir __P((ENV *, const char *, int));
+ */
+int
+__os_mkdir(env, name, mode)
+	ENV *env;
+	const char *name;
+	int mode;
+{
+	DB_ENV *dbenv;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0129", "fileops: mkdir %s",
+		    "%s"), name);
+
+	/* Make the directory, with paranoid permissions. */
+#if defined(HAVE_VXWORKS)
+	RETRY_CHK((mkdir(CHAR_STAR_CAST name)), ret);
+#else
+	RETRY_CHK((mkdir(name, DB_MODE_700)), ret);
+#endif
+	if (ret != 0)
+		return (__os_posix_err(ret));
+
+	/* Set the absolute permissions, if specified. */
+#if !defined(HAVE_VXWORKS)
+	if (mode != 0) {
+		RETRY_CHK((chmod(name, mode)), ret);
+		if (ret != 0)
+			ret = __os_posix_err(ret);
+	}
+#endif
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_open.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,184 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_open --
+ *	Open a file descriptor (including page size and log size information).
+ *
+ * PUBLIC: int __os_open __P((ENV *,
+ * PUBLIC:     const char *, u_int32_t, u_int32_t, int, DB_FH **));
+ */
+int
+__os_open(env, name, page_size, flags, mode, fhpp)
+	ENV *env;
+	const char *name;
+	u_int32_t page_size, flags;
+	int mode;
+	DB_FH **fhpp;
+{
+	DB_ENV *dbenv;
+	DB_FH *fhp;
+	int oflags, ret;
+
+	COMPQUIET(page_size, 0);
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+	*fhpp = NULL;
+	oflags = 0;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0152",
+		    "fileops: open %s", "%s"), name);
+
+#undef	OKFLAGS
+#define	OKFLAGS								\
+	(DB_OSO_ABSMODE | DB_OSO_CREATE | DB_OSO_DIRECT | DB_OSO_DSYNC |\
+	DB_OSO_EXCL | DB_OSO_RDONLY | DB_OSO_REGION | DB_OSO_SEQ |	\
+	DB_OSO_TEMP | DB_OSO_TRUNC)
+	if ((ret = __db_fchk(env, "__os_open", flags, OKFLAGS)) != 0)
+		return (ret);
+
+#if defined(O_BINARY)
+	/*
+	 * If there's a binary-mode open flag, set it, we never want any
+	 * kind of translation.  Some systems do translations by default,
+	 * e.g., with Cygwin, the default mode for an open() is set by the
+	 * mode of the mount that underlies the file.
+	 */
+	oflags |= O_BINARY;
+#endif
+
+	/*
+	 * DB requires the POSIX 1003.1 semantic that two files opened at the
+	 * same time with DB_OSO_CREATE/O_CREAT and DB_OSO_EXCL/O_EXCL flags
+	 * set return an EEXIST failure in at least one.
+	 */
+	if (LF_ISSET(DB_OSO_CREATE))
+		oflags |= O_CREAT;
+
+	if (LF_ISSET(DB_OSO_EXCL))
+		oflags |= O_EXCL;
+
+#ifdef HAVE_O_DIRECT
+	if (LF_ISSET(DB_OSO_DIRECT))
+		oflags |= O_DIRECT;
+#endif
+#ifdef O_DSYNC
+	if (LF_ISSET(DB_OSO_DSYNC))
+		oflags |= O_DSYNC;
+#endif
+
+	if (LF_ISSET(DB_OSO_RDONLY))
+		oflags |= O_RDONLY;
+	else
+		oflags |= O_RDWR;
+
+	if (LF_ISSET(DB_OSO_TRUNC))
+		oflags |= O_TRUNC;
+
+	/*
+	 * Undocumented feature: allow applications to create intermediate
+	 * directories whenever a file is opened.
+	 */
+	if (dbenv != NULL &&
+	    env->dir_mode != 0 && LF_ISSET(DB_OSO_CREATE) &&
+	    (ret = __db_mkpath(env, name)) != 0)
+		return (ret);
+
+	/* Open the file. */
+#ifdef HAVE_QNX
+	if (LF_ISSET(DB_OSO_REGION))
+		ret = __os_qnx_region_open(env, name, oflags, mode, &fhp);
+	else
+#endif
+	ret = __os_openhandle(env, name, oflags, mode, &fhp);
+	if (ret != 0)
+		return (ret);
+
+	if (LF_ISSET(DB_OSO_REGION))
+		F_SET(fhp, DB_FH_REGION);
+#ifdef HAVE_FCHMOD
+	/*
+	 * If the code using Berkeley DB is a library, that code may not be able
+	 * to control the application's umask value.  Allow applications to set
+	 * absolute file modes.  We can't fix the race between file creation and
+	 * the fchmod call -- we can't modify the process' umask here since the
+	 * process may be multi-threaded and the umask value is per-process, not
+	 * per-thread.
+	 */
+	if (LF_ISSET(DB_OSO_CREATE) && LF_ISSET(DB_OSO_ABSMODE))
+		(void)fchmod(fhp->fd, mode);
+#endif
+
+#ifdef O_DSYNC
+	/*
+	 * If we can configure the file descriptor to flush on write, the
+	 * file descriptor does not need to be explicitly sync'd.
+	 */
+	if (LF_ISSET(DB_OSO_DSYNC))
+		F_SET(fhp, DB_FH_NOSYNC);
+#endif
+
+#if defined(HAVE_DIRECTIO) && defined(DIRECTIO_ON)
+	/*
+	 * The Solaris C library includes directio, but you have to set special
+	 * compile flags to #define DIRECTIO_ON.  Require both in order to call
+	 * directio.
+	 */
+	if (LF_ISSET(DB_OSO_DIRECT))
+		(void)directio(fhp->fd, DIRECTIO_ON);
+#endif
+
+	/*
+	 * Delete any temporary file.
+	 *
+	 * !!!
+	 * There's a race here, where we've created a file and we crash before
+	 * we can unlink it.  Temporary files aren't common in DB, regardless,
+	 * it's not a security problem because the file is empty.  There's no
+	 * reasonable way to avoid the race (playing signal games isn't worth
+	 * the portability nightmare), so we just live with it.
+	 */
+	if (LF_ISSET(DB_OSO_TEMP)) {
+#if defined(HAVE_UNLINK_WITH_OPEN_FAILURE) || defined(CONFIG_TEST)
+		F_SET(fhp, DB_FH_UNLINK);
+#else
+		(void)__os_unlink(env, name, 0);
+#endif
+	}
+
+	*fhpp = fhp;
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_path.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,49 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+/*
+ * __os_concat_path --
+ *	Concatenate two elements of a path.
+ * PUBLIC: int __os_concat_path __P((char *,
+ * PUBLIC:     size_t, const char *, const char *));
+ */
+int __os_concat_path(dest, destsize, path, file)
+	char *dest;
+	size_t destsize;
+	const char *path, *file;
+{
+	if ((size_t)snprintf(dest, destsize,
+	    "%s%c%s", path, PATH_SEPARATOR[0], file) >= destsize)
+		return (EINVAL);
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_pid.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,85 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_id --
+ *	Return the current process ID.
+ *
+ * PUBLIC: void __os_id __P((DB_ENV *, pid_t *, db_threadid_t*));
+ */
+void
+__os_id(dbenv, pidp, tidp)
+	DB_ENV *dbenv;
+	pid_t *pidp;
+	db_threadid_t *tidp;
+{
+	/*
+	 * We can't depend on dbenv not being NULL, this routine is called
+	 * from places where there's no DB_ENV handle.
+	 *
+	 * We cache the pid in the ENV handle, getting the process ID is a
+	 * fairly slow call on lots of systems.
+	 */
+	if (pidp != NULL) {
+		if (dbenv == NULL) {
+#if defined(HAVE_VXWORKS)
+			*pidp = taskIdSelf();
+#else
+			*pidp = getpid();
+#endif
+		} else
+			*pidp = dbenv->env->pid_cache;
+	}
+
+/* 
+ * When building on MinGW, we define both HAVE_PTHREAD_SELF and DB_WIN32,
+ * and we are using pthreads instead of Windows threads implementation.
+ * So here, we need to check the thread implementations before checking
+ * the platform.
+ */
+	if (tidp != NULL) {
+#if defined(HAVE_PTHREAD_SELF)
+		*tidp = pthread_self();
+#elif defined(HAVE_MUTEX_UI_THREADS)
+		*tidp = thr_self();
+#elif defined(DB_WIN32)
+		*tidp = GetCurrentThreadId();
+#else
+		/*
+		 * Default to just getpid.
+		 */
+		DB_THREADID_INIT(*tidp);
+#endif
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_rename.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,75 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_rename --
+ *	Rename a file.
+ *
+ * PUBLIC: int __os_rename __P((ENV *,
+ * PUBLIC:    const char *, const char *, u_int32_t));
+ */
+int
+__os_rename(env, oldname, newname, silent)
+	ENV *env;
+	const char *oldname, *newname;
+	u_int32_t silent;
+{
+	DB_ENV *dbenv;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0168", "fileops: rename %s to %s",
+		    "%s %s"), oldname, newname);
+
+	LAST_PANIC_CHECK_BEFORE_IO(env);
+
+	if (DB_GLOBAL(j_rename) != NULL)
+		ret = DB_GLOBAL(j_rename)(oldname, newname);
+	else
+		RETRY_CHK((rename(oldname, newname)), ret);
+
+	/*
+	 * If "silent" is not set, then errors are OK and we should not output
+	 * an error message.
+	 */
+	if (ret != 0) {
+		if (!silent)
+			__db_syserr(env, ret, DB_STR_A("0169",
+			    "rename %s %s", "%s %s"), oldname, newname);
+		ret = __os_posix_err(ret);
+	}
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_root.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,49 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_isroot --
+ *	Return if user has special permissions.
+ *
+ * PUBLIC: int __os_isroot __P((void));
+ */
+int
+__os_isroot()
+{
+#ifdef HAVE_GETUID
+	return (getuid() == 0);
+#else
+	return (0);
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_rpath.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,58 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __db_rpath --
+ *	Return the last path separator in the path or NULL if none found.
+ *
+ * PUBLIC: char *__db_rpath __P((const char *));
+ */
+char *
+__db_rpath(path)
+	const char *path;
+{
+	const char *s, *last;
+
+	s = path;
+	last = NULL;
+	if (PATH_SEPARATOR[1] != '\0') {
+		for (; s[0] != '\0'; ++s)
+			if (strchr(PATH_SEPARATOR, s[0]) != NULL)
+				last = s;
+	} else
+		for (; s[0] != '\0'; ++s)
+			if (s[0] == PATH_SEPARATOR[0])
+				last = s;
+	return ((char *)last);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_rw.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,313 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_io --
+ *	Do an I/O.
+ *
+ * PUBLIC: int __os_io __P((ENV *, int, DB_FH *, db_pgno_t,
+ * PUBLIC:     u_int32_t, u_int32_t, u_int32_t, u_int8_t *, size_t *));
+ */
+int
+__os_io(env, op, fhp, pgno, pgsize, relative, io_len, buf, niop)
+	ENV *env;
+	int op;
+	DB_FH *fhp;
+	db_pgno_t pgno;
+	u_int32_t pgsize, relative, io_len;
+	u_int8_t *buf;
+	size_t *niop;
+{
+#if defined(HAVE_PREAD) && defined(HAVE_PWRITE)
+	DB_ENV *dbenv;
+	off_t offset;
+	ssize_t nio;
+#endif
+	int ret;
+
+	/*
+	 * Check for illegal usage.
+	 *
+	 * This routine is used in one of two ways: reading bytes from an
+	 * absolute offset and reading a specific database page.  All of
+	 * our absolute offsets are known to fit into a u_int32_t, while
+	 * our database pages might be at offsets larger than a u_int32_t.
+	 */
+	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
+	DB_ASSERT(env, (pgno == 0 && pgsize == 0) || relative == 0);
+
+#if defined(HAVE_PREAD) && defined(HAVE_PWRITE)
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	if ((offset = relative) == 0)
+		offset = (off_t)pgno * pgsize;
+	switch (op) {
+	case DB_IO_READ:
+		if (DB_GLOBAL(j_read) != NULL)
+			goto slow;
+#if defined(HAVE_STATISTICS)
+		++fhp->read_count;
+#endif
+		if (dbenv != NULL &&
+		    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+			__db_msg(env, DB_STR_A("0130",
+			    "fileops: read %s: %lu bytes at offset %lu",
+			    "%s %lu %lu"), fhp->name, (u_long)io_len,
+			    (u_long)offset);
+
+		LAST_PANIC_CHECK_BEFORE_IO(env);
+		nio = DB_GLOBAL(j_pread) != NULL ?
+		    DB_GLOBAL(j_pread)(fhp->fd, buf, io_len, offset) :
+		    pread(fhp->fd, buf, io_len, offset);
+		break;
+	case DB_IO_WRITE:
+		if (DB_GLOBAL(j_write) != NULL)
+			goto slow;
+#ifdef HAVE_FILESYSTEM_NOTZERO
+		if (__os_fs_notzero())
+			goto slow;
+#endif
+#if defined(HAVE_STATISTICS)
+		++fhp->write_count;
+#endif
+		if (dbenv != NULL &&
+		    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+			__db_msg(env, DB_STR_A("0131",
+			    "fileops: write %s: %lu bytes at offset %lu",
+			    "%s %lu %lu"), fhp->name, (u_long)io_len,
+			    (u_long)offset);
+
+		LAST_PANIC_CHECK_BEFORE_IO(env);
+		nio = DB_GLOBAL(j_pwrite) != NULL ?
+		    DB_GLOBAL(j_pwrite)(fhp->fd, buf, io_len, offset) :
+		    pwrite(fhp->fd, buf, io_len, offset);
+		break;
+	default:
+		return (EINVAL);
+	}
+	if (nio == (ssize_t)io_len) {
+		*niop = io_len;
+		return (0);
+	}
+slow:
+#endif
+	MUTEX_LOCK(env, fhp->mtx_fh);
+
+	if ((ret = __os_seek(env, fhp, pgno, pgsize, relative)) != 0)
+		goto err;
+	switch (op) {
+	case DB_IO_READ:
+		ret = __os_read(env, fhp, buf, io_len, niop);
+		break;
+	case DB_IO_WRITE:
+		ret = __os_write(env, fhp, buf, io_len, niop);
+		break;
+	default:
+		ret = EINVAL;
+		break;
+	}
+
+err:	MUTEX_UNLOCK(env, fhp->mtx_fh);
+
+	return (ret);
+
+}
+
+/*
+ * __os_read --
+ *	Read from a file handle.
+ *
+ * PUBLIC: int __os_read __P((ENV *, DB_FH *, void *, size_t, size_t *));
+ */
+int
+__os_read(env, fhp, addr, len, nrp)
+	ENV *env;
+	DB_FH *fhp;
+	void *addr;
+	size_t len;
+	size_t *nrp;
+{
+	DB_ENV *dbenv;
+	size_t offset;
+	ssize_t nr;
+	int ret;
+	u_int8_t *taddr;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+	ret = 0;
+
+	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
+
+#if defined(HAVE_STATISTICS)
+	++fhp->read_count;
+#endif
+	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0132",
+		    "fileops: read %s: %lu bytes", "%s %lu"),
+		    fhp->name, (u_long)len);
+
+	if (DB_GLOBAL(j_read) != NULL) {
+		*nrp = len;
+		LAST_PANIC_CHECK_BEFORE_IO(env);
+		if (DB_GLOBAL(j_read)(fhp->fd, addr, len) != (ssize_t)len) {
+			ret = __os_get_syserr();
+			__db_syserr(env, ret, DB_STR_A("0133",
+			    "read: %#lx, %lu", "%#lx %lu"),
+			    P_TO_ULONG(addr), (u_long)len);
+			ret = __os_posix_err(ret);
+		}
+		return (ret);
+	}
+
+	for (taddr = addr, offset = 0;
+	    offset < len; taddr += nr, offset += (u_int32_t)nr) {
+		LAST_PANIC_CHECK_BEFORE_IO(env);
+		RETRY_CHK(((nr = read(fhp->fd,
+		    CHAR_STAR_CAST taddr, len - offset)) < 0 ? 1 : 0), ret);
+		if (nr == 0 || ret != 0)
+			break;
+	}
+	*nrp = (size_t)(taddr - (u_int8_t *)addr);
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR_A("0134",
+		    "read: %#lx, %lu", "%#lx %lu"),
+		    P_TO_ULONG(taddr), (u_long)len - offset);
+		ret = __os_posix_err(ret);
+	}
+	return (ret);
+}
+
+/*
+ * __os_write --
+ *	Write to a file handle.
+ *
+ * PUBLIC: int __os_write __P((ENV *, DB_FH *, void *, size_t, size_t *));
+ */
+int
+__os_write(env, fhp, addr, len, nwp)
+	ENV *env;
+	DB_FH *fhp;
+	void *addr;
+	size_t len;
+	size_t *nwp;
+{
+	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
+
+#ifdef HAVE_FILESYSTEM_NOTZERO
+	/* Zero-fill as necessary. */
+	if (__os_fs_notzero()) {
+		int ret;
+		if ((ret = __db_zero_fill(env, fhp)) != 0)
+			return (ret);
+	}
+#endif
+	return (__os_physwrite(env, fhp, addr, len, nwp));
+}
+
+/*
+ * __os_physwrite --
+ *	Physical write to a file handle.
+ *
+ * PUBLIC: int __os_physwrite
+ * PUBLIC:     __P((ENV *, DB_FH *, void *, size_t, size_t *));
+ */
+int
+__os_physwrite(env, fhp, addr, len, nwp)
+	ENV *env;
+	DB_FH *fhp;
+	void *addr;
+	size_t len;
+	size_t *nwp;
+{
+	DB_ENV *dbenv;
+	size_t offset;
+	ssize_t nw;
+	int ret;
+	u_int8_t *taddr;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+	ret = 0;
+
+#if defined(HAVE_STATISTICS)
+	++fhp->write_count;
+#endif
+	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0135",
+		    "fileops: write %s: %lu bytes", "%s %lu"),
+		    fhp->name, (u_long)len);
+
+#if defined(HAVE_FILESYSTEM_NOTZERO) && defined(DIAGNOSTIC)
+	if (__os_fs_notzero()) {
+		struct stat sb;
+		off_t cur_off;
+
+		DB_ASSERT(env, fstat(fhp->fd, &sb) != -1 &&
+		    (cur_off = lseek(fhp->fd, (off_t)0, SEEK_CUR)) != -1 &&
+		    cur_off <= sb.st_size);
+	}
+#endif
+	if (DB_GLOBAL(j_write) != NULL) {
+		*nwp = len;
+		LAST_PANIC_CHECK_BEFORE_IO(env);
+		if (DB_GLOBAL(j_write)(fhp->fd, addr, len) != (ssize_t)len) {
+			ret = __os_get_syserr();
+			__db_syserr(env, ret, DB_STR_A("0136",
+			    "write: %#lx, %lu", "%#lx %lu"),
+			    P_TO_ULONG(addr), (u_long)len);
+			ret = __os_posix_err(ret);
+
+			DB_EVENT(env, DB_EVENT_WRITE_FAILED, NULL);
+		}
+		return (ret);
+	}
+
+	for (taddr = addr, offset = 0;
+	    offset < len; taddr += nw, offset += (u_int32_t)nw) {
+		LAST_PANIC_CHECK_BEFORE_IO(env);
+		RETRY_CHK(((nw = write(fhp->fd,
+		    CHAR_STAR_CAST taddr, len - offset)) < 0 ? 1 : 0), ret);
+		if (ret != 0)
+			break;
+	}
+	*nwp = len;
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR_A("0137",
+		    "write: %#lx, %lu", "%#lx %lu"),
+		    P_TO_ULONG(taddr), (u_long)len - offset);
+		ret = __os_posix_err(ret);
+
+		DB_EVENT(env, DB_EVENT_WRITE_FAILED, NULL);
+	}
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_seek.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,88 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_seek --
+ *	Seek to a page/byte offset in the file.
+ *
+ * PUBLIC: int __os_seek __P((ENV *,
+ * PUBLIC:      DB_FH *, db_pgno_t, u_int32_t, off_t));
+ */
+int
+__os_seek(env, fhp, pgno, pgsize, relative)
+	ENV *env;
+	DB_FH *fhp;
+	db_pgno_t pgno;
+	u_int32_t pgsize;
+	off_t relative;
+{
+	DB_ENV *dbenv;
+	off_t offset;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
+
+#if defined(HAVE_STATISTICS)
+	++fhp->seek_count;
+#endif
+
+	offset = (off_t)pgsize * pgno + relative;
+
+	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0170",
+		    "fileops: seek %s to %lu", "%s %lu"),
+		    fhp->name, (u_long)offset);
+
+	if (DB_GLOBAL(j_seek) != NULL)
+		ret = DB_GLOBAL(j_seek)(fhp->fd, offset, SEEK_SET);
+	else
+		RETRY_CHK((lseek(
+		    fhp->fd, offset, SEEK_SET) == -1 ? 1 : 0), ret);
+
+	if (ret == 0) {
+		fhp->pgsize = pgsize;
+		fhp->pgno = pgno;
+		fhp->offset = relative;
+	} else {
+		__db_syserr(env, ret, DB_STR_A("0171",
+		    "seek: %lu: (%lu * %lu) + %lu", "%lu %lu %lu %lu"),
+		    (u_long)offset, (u_long)pgno, (u_long)pgsize,
+		    (u_long)relative);
+		ret = __os_posix_err(ret);
+	}
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_stack.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,67 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#if defined(HAVE_SYSTEM_INCLUDE_FILES) && defined(HAVE_BACKTRACE) && \
+    defined(HAVE_BACKTRACE_SYMBOLS) && defined(HAVE_EXECINFO_H)
+#include <execinfo.h>
+#endif
+
+/*
+ * __os_stack --
+ *	Output a stack trace to the message file handle.
+ *
+ * PUBLIC: void __os_stack __P((ENV *));
+ */
+void
+__os_stack(env)
+	ENV *env;
+{
+#if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS)
+	void *array[200];
+	size_t i, size;
+	char **strings;
+
+	/*
+	 * Solaris and the GNU C library support this interface.  Solaris
+	 * has additional interfaces (printstack and walkcontext), I don't
+	 * know if they offer any additional value or not.
+	 */
+	size = backtrace(array, sizeof(array) / sizeof(array[0]));
+	strings = backtrace_symbols(array, size);
+
+	for (i = 0; i < size; ++i)
+		__db_errx(env, "%s", strings[i]);
+	free(strings);
+#endif
+	COMPQUIET(env, NULL);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_stat.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,130 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_exists --
+ *	Return if the file exists.
+ *
+ * PUBLIC: int __os_exists __P((ENV *, const char *, int *));
+ */
+int
+__os_exists(env, path, isdirp)
+	ENV *env;
+	const char *path;
+	int *isdirp;
+{
+	DB_ENV *dbenv;
+	struct stat sb;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0165",
+		    "fileops: stat %s", "%s"), path);
+
+	if (DB_GLOBAL(j_exists) != NULL)
+		return (DB_GLOBAL(j_exists)(path, isdirp));
+
+	RETRY_CHK((stat(CHAR_STAR_CAST path, &sb)), ret);
+	if (ret != 0)
+		return (__os_posix_err(ret));
+
+#if !defined(S_ISDIR) || defined(STAT_MACROS_BROKEN)
+#undef	S_ISDIR
+#ifdef _S_IFDIR
+#define	S_ISDIR(m)	(_S_IFDIR & (m))
+#else
+#define	S_ISDIR(m)	(((m) & 0170000) == 0040000)
+#endif
+#endif
+	if (isdirp != NULL)
+		*isdirp = S_ISDIR(sb.st_mode);
+
+	return (0);
+}
+
+/*
+ * __os_ioinfo --
+ *	Return file size and I/O size; abstracted to make it easier
+ *	to replace.
+ *
+ * PUBLIC: int __os_ioinfo __P((ENV *, const char *,
+ * PUBLIC:    DB_FH *, u_int32_t *, u_int32_t *, u_int32_t *));
+ */
+int
+__os_ioinfo(env, path, fhp, mbytesp, bytesp, iosizep)
+	ENV *env;
+	const char *path;
+	DB_FH *fhp;
+	u_int32_t *mbytesp, *bytesp, *iosizep;
+{
+	struct stat sb;
+	int ret;
+
+	if (DB_GLOBAL(j_ioinfo) != NULL)
+		return (DB_GLOBAL(j_ioinfo)(path,
+		    fhp->fd, mbytesp, bytesp, iosizep));
+
+	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
+
+	RETRY_CHK((fstat(fhp->fd, &sb)), ret);
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR("0166", "fstat"));
+		return (__os_posix_err(ret));
+	}
+
+	/* Return the size of the file. */
+	if (mbytesp != NULL)
+		*mbytesp = (u_int32_t)(sb.st_size / MEGABYTE);
+	if (bytesp != NULL)
+		*bytesp = (u_int32_t)(sb.st_size % MEGABYTE);
+
+	/*
+	 * Return the underlying filesystem I/O size, if available.
+	 *
+	 * XXX
+	 * Check for a 0 size -- the HP MPE/iX architecture has st_blksize,
+	 * but it's always 0.
+	 */
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+	if (iosizep != NULL && (*iosizep = sb.st_blksize) == 0)
+		*iosizep = DB_DEF_IOSIZE;
+#else
+	if (iosizep != NULL)
+		*iosizep = DB_DEF_IOSIZE;
+#endif
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_tmpdir.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,163 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+#ifdef HAVE_SYSTEM_INCLUDE_FILES
+#ifdef macintosh
+#include <TFileSpec.h>
+#endif
+#endif
+
+/*
+ * __os_tmpdir --
+ *	Set the temporary directory path.
+ *
+ * The order of items in the list structure and the order of checks in
+ * the environment are documented.
+ *
+ * PUBLIC: int __os_tmpdir __P((ENV *, u_int32_t));
+ */
+int
+__os_tmpdir(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	DB_ENV *dbenv;
+	int isdir, ret;
+	char *tdir, tdir_buf[DB_MAXPATHLEN];
+
+	dbenv = env->dbenv;
+
+	/* Use the environment if it's permitted and initialized. */
+	if (LF_ISSET(DB_USE_ENVIRON) ||
+	    (LF_ISSET(DB_USE_ENVIRON_ROOT) && __os_isroot())) {
+		/* POSIX: TMPDIR */
+		tdir = tdir_buf;
+		if ((ret = __os_getenv(
+		    env, "TMPDIR", &tdir, sizeof(tdir_buf))) != 0)
+			return (ret);
+		if (tdir != NULL && tdir[0] != '\0')
+			goto found;
+
+		/*
+		 * Windows: TEMP, TMP
+		 */
+		tdir = tdir_buf;
+		if ((ret = __os_getenv(
+		    env, "TEMP", &tdir, sizeof(tdir_buf))) != 0)
+			return (ret);
+		if (tdir != NULL && tdir[0] != '\0')
+			goto found;
+
+		tdir = tdir_buf;
+		if ((ret = __os_getenv(
+		    env, "TMP", &tdir, sizeof(tdir_buf))) != 0)
+			return (ret);
+		if (tdir != NULL && tdir[0] != '\0')
+			goto found;
+
+		/* Macintosh */
+		tdir = tdir_buf;
+		if ((ret = __os_getenv(
+		    env, "TempFolder", &tdir, sizeof(tdir_buf))) != 0)
+			return (ret);
+
+		if (tdir != NULL && tdir[0] != '\0')
+found:			return (__os_strdup(env, tdir, &dbenv->db_tmp_dir));
+	}
+
+#ifdef macintosh
+	/* Get the path to the temporary folder. */
+	{FSSpec spec;
+
+		if (!Special2FSSpec(kTemporaryFolderType,
+		    kOnSystemDisk, 0, &spec))
+			return (__os_strdup(env,
+			    FSp2FullPath(&spec), &dbenv->db_tmp_dir));
+	}
+#endif
+#ifdef DB_WIN32
+	/* Get the path to the temporary directory. */
+	{
+		_TCHAR tpath[DB_MAXPATHLEN + 1];
+		char *path, *eos;
+
+		if (GetTempPath(DB_MAXPATHLEN, tpath) > 2) {
+			FROM_TSTRING(env, tpath, path, ret);
+			if (ret != 0)
+				return (ret);
+
+			eos = path + strlen(path) - 1;
+			if (*eos == '\\' || *eos == '/')
+				*eos = '\0';
+			if (__os_exists(env, path, &isdir) == 0 && isdir) {
+				ret = __os_strdup(env,
+				    path, &dbenv->db_tmp_dir);
+				FREE_STRING(env, path);
+				return (ret);
+			}
+			FREE_STRING(env, path);
+		}
+	}
+#endif
+
+	/*
+	 * Step through the static list looking for a possibility.
+	 *
+	 * We don't use the obvious data structure because some C compilers
+	 * (and I use the phrase loosely) don't like static data arrays.
+	 */
+#define	DB_TEMP_DIRECTORY(n) {						\
+	char *__p = n;							\
+	if (__os_exists(env, __p, &isdir) == 0 && isdir != 0)		\
+		return (__os_strdup(env, __p, &dbenv->db_tmp_dir));	\
+	}
+#ifdef DB_WIN32
+	DB_TEMP_DIRECTORY("/temp");
+	DB_TEMP_DIRECTORY("C:/temp");
+	DB_TEMP_DIRECTORY("C:/tmp");
+#else
+	DB_TEMP_DIRECTORY("/var/tmp");
+	DB_TEMP_DIRECTORY("/usr/tmp");
+	DB_TEMP_DIRECTORY("/tmp");
+#if defined(ANDROID) || defined(DB_ANDROID)
+	DB_TEMP_DIRECTORY("/cache");
+#endif
+#endif
+
+	/*
+	 * If we don't have any other place to store temporary files, store
+	 * them in the current directory.
+	 */
+	return (__os_strdup(env, "", &dbenv->db_tmp_dir));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_truncate.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,85 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2004, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_truncate --
+ *	Truncate the file.
+ *
+ * PUBLIC: int __os_truncate __P((ENV *, DB_FH *, db_pgno_t, u_int32_t));
+ */
+int
+__os_truncate(env, fhp, pgno, pgsize)
+	ENV *env;
+	DB_FH *fhp;
+	db_pgno_t pgno;
+	u_int32_t pgsize;
+{
+	DB_ENV *dbenv;
+	off_t offset;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	/*
+	 * Truncate a file so that "pgno" is discarded from the end of the
+	 * file.
+	 */
+	offset = (off_t)pgsize * pgno;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0141",
+		    "fileops: truncate %s to %lu", "%s %lu"),
+		    fhp->name, (u_long)offset);
+
+	LAST_PANIC_CHECK_BEFORE_IO(env);
+
+	if (DB_GLOBAL(j_ftruncate) != NULL)
+		ret = DB_GLOBAL(j_ftruncate)(fhp->fd, offset);
+	else {
+#ifdef HAVE_FTRUNCATE
+		RETRY_CHK((ftruncate(fhp->fd, offset)), ret);
+#else
+		ret = DB_OPNOTSUP;
+#endif
+	}
+
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR_A("0142",
+		    "ftruncate: %lu", "%lu"), (u_long)offset);
+		ret = __os_posix_err(ret);
+	}
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_uid.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,77 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_unique_id --
+ *	Return a unique 32-bit value.
+ *
+ * PUBLIC: void __os_unique_id __P((ENV *, u_int32_t *));
+ */
+void
+__os_unique_id(env, idp)
+	ENV *env;
+	u_int32_t *idp;
+{
+	DB_ENV *dbenv;
+	db_timespec v;
+	pid_t pid;
+	u_int32_t id;
+
+	*idp = 0;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	/*
+	 * Our randomized value is comprised of our process ID, the current
+	 * time of day and a stack address, all XOR'd together.
+	 */
+	__os_id(dbenv, &pid, NULL);
+	__os_gettime(env, &v, 1);
+
+	id = (u_int32_t)pid ^
+	    (u_int32_t)v.tv_sec ^ (u_int32_t)v.tv_nsec ^ P_TO_UINT32(&pid);
+
+	/*
+	 * We could try and find a reasonable random-number generator, but
+	 * that's not all that easy to do.  Seed and use srand()/rand(), if
+	 * we can find them.
+	 */
+	if (DB_GLOBAL(uid_init) == 0) {
+		DB_GLOBAL(uid_init) = 1;
+		srand((u_int)id);
+	}
+	id ^= (u_int)rand();
+
+	*idp = id;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_unlink.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,102 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_unlink --
+ *	Remove a file.
+ *
+ * PUBLIC: int __os_unlink __P((ENV *, const char *, int));
+ */
+int
+__os_unlink(env, path, overwrite_test)
+	ENV *env;
+	const char *path;
+	int overwrite_test;
+{
+	DB_ENV *dbenv;
+	int ret, t_ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0160", "fileops: unlink %s",
+		    "%s"), path);
+
+	/* Optionally overwrite the contents of the file to enhance security. */
+	if (dbenv != NULL && overwrite_test && F_ISSET(dbenv, DB_ENV_OVERWRITE))
+		(void)__db_file_multi_write(env, path);
+
+	LAST_PANIC_CHECK_BEFORE_IO(env);
+
+	if (DB_GLOBAL(j_unlink) != NULL)
+		ret = DB_GLOBAL(j_unlink)(path);
+	else {
+		RETRY_CHK((unlink(CHAR_STAR_CAST path)), ret);
+#ifdef HAVE_QNX
+		/*
+		 * The file may be a region file created by shm_open, not a
+		 * regular file.  Try and delete using unlink, and if that
+		 * fails for an unexpected reason, try a shared memory unlink.
+		 */
+		if (ret != 0 && __os_posix_err(ret) != ENOENT)
+			RETRY_CHK((shm_unlink(path)), ret);
+#endif
+	}
+
+	/*
+	 * !!!
+	 * The results of unlink are file system driver specific on VxWorks.
+	 * In the case of removing a file that did not exist, some, at least,
+	 * return an error, but with an errno of 0, not ENOENT.  We do not
+	 * have to test for that explicitly, the RETRY_CHK macro resets "ret"
+	 * to be the errno, and so we'll just slide right on through.
+	 *
+	 * XXX
+	 * We shouldn't be testing for an errno of ENOENT here, but ENOENT
+	 * signals that a file is missing, and we attempt to unlink things
+	 * (such as v. 2.x environment regions, in ENV->remove) that we
+	 * are expecting not to be there.  Reporting errors in these cases
+	 * is annoying.
+	 */
+	if (ret != 0) {
+		t_ret = __os_posix_err(ret);
+		if (t_ret != ENOENT)
+			__db_syserr(env, ret, DB_STR_A("0161",
+			    "unlink: %s", "%s"), path);
+		ret = t_ret;
+	}
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os/os_yield.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,117 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+#if defined(HAVE_SYSTEM_INCLUDE_FILES) && defined(HAVE_SCHED_YIELD)
+#include <sched.h>
+#endif
+
+static void __os_sleep __P((ENV *, u_long, u_long));
+
+/*
+ * __os_yield --
+ *	Yield the processor, optionally pausing until running again.
+ *
+ * PUBLIC: void __os_yield __P((ENV *, u_long, u_long));
+ */
+void
+__os_yield(env, secs, usecs)
+	ENV *env;
+	u_long secs, usecs;		/* Seconds and microseconds. */
+{
+	/*
+	 * Don't require the values be normalized (some operating systems
+	 * return an error if the usecs argument to select is too large).
+	 */
+	for (; usecs >= US_PER_SEC; usecs -= US_PER_SEC)
+		++secs;
+
+	if (DB_GLOBAL(j_yield) != NULL) {
+		(void)DB_GLOBAL(j_yield)(secs, usecs);
+		return;
+	}
+
+	/*
+	 * Yield the processor so other processes or threads can run.  Use
+	 * the local yield call if not pausing, otherwise call the select
+	 * function.
+	 */
+	if (secs != 0 || usecs != 0)
+		__os_sleep(env, secs, usecs);
+	else {
+#if defined(HAVE_MUTEX_UI_THREADS)
+		thr_yield();
+#elif defined(HAVE_PTHREAD_YIELD)
+		pthread_yield();
+#elif defined(HAVE_SCHED_YIELD)
+		(void)sched_yield();
+#elif defined(HAVE_YIELD)
+		yield();
+#else
+		__os_sleep(env, 0, 0);
+#endif
+	}
+}
+
+/*
+ * __os_sleep --
+ *	Pause the thread of control.
+ */
+static void
+__os_sleep(env, secs, usecs)
+	ENV *env;
+	u_long secs, usecs;		/* Seconds and microseconds. */
+{
+	struct timeval t;
+	int ret;
+
+	/*
+	 * Sheer raving paranoia -- don't select for 0 time, in case some
+	 * implementation doesn't yield the processor in that case.
+	 */
+	t.tv_sec = (long)secs;
+	t.tv_usec = (long)usecs + 1;
+
+	/*
+	 * We don't catch interrupts and restart the system call here, unlike
+	 * other Berkeley DB system calls.  This may be a user attempting to
+	 * interrupt a sleeping DB utility (for example, db_checkpoint), and
+	 * we want the utility to see the signal and quit.  This assumes it's
+	 * always OK for DB to sleep for less time than originally scheduled.
+	 */
+	if (select(0, NULL, NULL, NULL, &t) == -1) {
+		ret = __os_get_syserr();
+		if (__os_posix_err(ret) != EINTR)
+			__db_syserr(env, ret, DB_STR("0167", "select"));
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/ce_ctime.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,109 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+static void  __os_windows_ct_numb __P((char *, int));
+
+/*
+ * __os_ctime --
+ *	Format a time-stamp.
+ */
+char *
+__os_ctime(tod, time_buf)
+	const time_t *tod;
+	char *time_buf;
+{
+	char *ncp;
+	__int64 i64_tod;
+	struct _FILETIME file_tod, file_loc;
+	struct _SYSTEMTIME sys_loc;
+static const __int64 SECS_BETWEEN_EPOCHS = 11644473600;
+static const __int64 SECS_TO_100NS = 10000000; /* 10^7 */
+
+	strcpy(time_buf, "Thu Jan 01 00:00:00 1970");
+	time_buf[CTIME_BUFLEN - 1] = '\0';
+
+	/* Convert the tod to a SYSTEM_TIME struct */
+	i64_tod = *tod;
+	i64_tod = (i64_tod + SECS_BETWEEN_EPOCHS)*SECS_TO_100NS;
+	memcpy(&file_tod, &i64_tod, sizeof(file_tod));
+	FileTimeToLocalFileTime(&file_tod, &file_loc);
+	FileTimeToSystemTime(&file_loc, &sys_loc);
+
+	/*
+	 * Convert the _SYSTEMTIME to the correct format in time_buf.
+	 * Based closely on the os_brew/ctime.c implementation.
+	 *
+	 * wWeekDay : Day of the week 0-6 (0=Monday, 6=Sunday)
+	 */
+	ncp = &"MonTueWedThuFriSatSun"[sys_loc.wDayOfWeek*3];
+	time_buf[0] = *ncp++;
+	time_buf[1] = *ncp++;
+	time_buf[2] = *ncp;
+	ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(sys_loc.wMonth - 1) * 3];
+	time_buf[4] = *ncp++;
+	time_buf[5] = *ncp++;
+	time_buf[6] = *ncp;
+
+	__os_windows_ct_numb(time_buf + 8, sys_loc.wDay);
+					/* Add 100 to keep the leading zero. */
+	__os_windows_ct_numb(time_buf + 11, sys_loc.wHour + 100);
+	__os_windows_ct_numb(time_buf + 14, sys_loc.wMinute + 100);
+	__os_windows_ct_numb(time_buf + 17, sys_loc.wSecond + 100);
+
+	if (sys_loc.wYear < 100) {		/* 9 99 */
+		time_buf[20] = ' ';
+		time_buf[21] = ' ';
+		__os_windows_ct_numb(time_buf + 22, sys_loc.wYear);
+	} else {			/* 99 1999 */
+		__os_windows_ct_numb(time_buf + 20, sys_loc.wYear / 100);
+		__os_windows_ct_numb(time_buf + 22, sys_loc.wYear % 100 + 100);
+	}
+
+	return (time_buf);
+}
+
+/*
+ * __os_windows_ct_numb --
+ *	Append ASCII representations for two digits to a string.
+ */
+static void
+__os_windows_ct_numb(cp, n)
+	char *cp;
+	int n;
+{
+	cp[0] = ' ';
+	if (n >= 10)
+		cp[0] = (n / 10) % 10 + '0';
+	cp[1] = n % 10 + '0';
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_abs.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,55 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_abspath --
+ *	Return if a path is an absolute path.
+ */
+int
+__os_abspath(path)
+	const char *path;
+{
+	/*
+	 * !!!
+	 * Check for drive specifications, e.g., "C:".  In addition, the path
+	 * separator used by the win32 DB (PATH_SEPARATOR) is \; look for both
+	 * / and \ since these are user-input paths.
+	 */
+	if (strlen(path) == 0)
+		return (0);
+
+	if (strlen(path) >= 3 && isalpha(path[0]) && path[1] == ':')
+		path += 2;
+	return (path[0] == '/' || path[0] == '\\');
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_clock.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,101 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2001, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_gettime --
+ *	Return the current time-of-day clock in seconds and nanoseconds.
+ */
+void
+__os_gettime(env, tp, monotonic)
+	ENV *env;
+	db_timespec *tp;
+	int monotonic;
+{
+	if (monotonic) {
+		/*
+		 * The elapsed time is stored as a DWORD value, so time wraps
+		 * around to zero if the system runs for 49.7 days.  Initialize
+		 * a base value with 50 days worth of seconds, and add 50 more
+		 * days every time the counter wraps.  That ensures we always
+		 * move forward.
+		 *
+		 * It's possible this code could race, but the danger is we
+		 * would increment base_seconds more than once per wrap and
+		 * eventually overflow, which is a pretty remote possibility.
+		 */
+#define	TIMER_WRAP_SECONDS	(50 * 24 * 60 * 60)
+		static DWORD last_ticks;
+		static time_t base_seconds;
+		DWORD ticks;
+
+		ticks = GetTickCount();
+		if (ticks < last_ticks)
+			base_seconds += TIMER_WRAP_SECONDS;
+		last_ticks = ticks;
+		tp->tv_sec = base_seconds + (u_int32_t)(ticks / 1000);
+		tp->tv_nsec = (u_int32_t)((ticks % 1000) * NS_PER_MS);
+	} else {
+#ifdef DB_WINCE
+		FILETIME ft;
+		LARGE_INTEGER large_int;
+		LONGLONG ns_since_epoch, utc1970;
+		SYSTEMTIME st;
+
+		(void)GetSystemTime(&st);
+		(void)SystemTimeToFileTime(&st, &ft);
+
+		/*
+		 * A FILETIME expresses time as 100 nanosecond chunks from
+		 * Jan 1, 1601; convert to a timespec where the time is
+		 * is expressed in seconds and nanoseconds from Jan 1, 1970.
+		 *
+		 * UTC_1970 is the number of 100-nano-second chunks from
+		 * 1601 to 1970.
+		 */
+#define	NS100_PER_SEC	(NS_PER_SEC / 100)
+#define	UTC_1970	(((LONGLONG)27111902 << 32) + (LONGLONG)3577643008)
+		memcpy(&large_int, &ft, sizeof(large_int));
+		utc1970 = UTC_1970;
+		ns_since_epoch = (large_int.QuadPart - utc1970);
+		tp->tv_sec = (time_t)(ns_since_epoch / NS100_PER_SEC);
+		tp->tv_nsec = (long)(ns_since_epoch % NS100_PER_SEC);
+#else
+		struct _timeb now;
+
+		_ftime(&now);
+		tp->tv_sec = now.time;
+		tp->tv_nsec = now.millitm * NS_PER_MS;
+#endif
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_config.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,155 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_is_winnt --
+ *	Return 1 if Windows/NT, otherwise 0.
+ *
+ * PUBLIC: int __os_is_winnt __P((void));
+ */
+int
+__os_is_winnt()
+{
+#ifdef DB_WINCE
+	return (1);
+#else
+	static int __os_type = -1;
+
+	/*
+	 * The value of __os_type is computed only once, and cached to
+	 * avoid the overhead of repeated calls to GetVersion().
+	 */
+	if (__os_type == -1) {
+		if ((GetVersion() & 0x80000000) == 0)
+			__os_type = 1;
+		else
+			__os_type = 0;
+	}
+	return (__os_type);
+#endif
+}
+
+/*
+ * __os_fs_notzero --
+ *	Return 1 if allocated filesystem blocks are not zeroed.
+ */
+int
+__os_fs_notzero()
+{
+#ifdef DB_WINCE
+	return (1);
+#else
+	static int __os_notzero = -1;
+	OSVERSIONINFO osvi;
+
+	/*
+	 * Windows/NT zero-fills pages that were never explicitly written to
+	 * the file.  Note however that this is *NOT* documented.  In fact, the
+	 * Win32 documentation makes it clear that there are no guarantees that
+	 * uninitialized bytes will be zeroed:
+	 *
+	 *   If the file is extended, the contents of the file between the old
+	 *   EOF position and the new position are not defined.
+	 *
+	 * Experiments confirm that NT/2K/XP all zero fill for both NTFS and
+	 * FAT32.  Cygwin also relies on this behavior.  This is the relevant
+	 * comment from Cygwin:
+	 *
+	 *    Oops, this is the bug case - Win95 uses whatever is on the disk
+	 *    instead of some known (safe) value, so we must seek back and fill
+	 *    in the gap with zeros. - DJ
+	 *    Note: this bug doesn't happen on NT4, even though the
+	 *    documentation for WriteFile() says that it *may* happen on any OS.
+	 *
+	 * We're making a bet, here, but we made it a long time ago and haven't
+	 * yet seen any evidence that it was wrong.
+	 *
+	 * Windows 95/98 and On-Time give random garbage, and that breaks
+	 * Berkeley DB.
+	 *
+	 * The value of __os_notzero is computed only once, and cached to
+	 * avoid the overhead of repeated calls to GetVersion().
+	 */
+	if (__os_notzero == -1) {
+		if (__os_is_winnt()) {
+			osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+			GetVersionEx(&osvi);
+			if (_tcscmp(osvi.szCSDVersion, _T("RTTarget-32")) == 0)
+				__os_notzero = 1;	/* On-Time */
+			else
+				__os_notzero = 0;	/* Windows/NT */
+		} else
+			__os_notzero = 1;		/* Not Windows/NT */
+	}
+	return (__os_notzero);
+#endif
+}
+
+/*
+ * __os_support_direct_io --
+ *	Check to see if we support direct I/O.
+ */
+int
+__os_support_direct_io()
+{
+	return (1);
+}
+
+/*
+ * __os_support_db_register --
+ *	Return 1 if the system supports DB_REGISTER.
+ */
+int
+__os_support_db_register()
+{
+#ifdef DB_WINCE
+	return (0);
+#else
+	return (__os_is_winnt());
+#endif
+}
+
+/*
+ * __os_support_replication --
+ *	Return 1 if the system supports replication.
+ */
+int
+__os_support_replication()
+{
+#ifdef DB_WINCE
+	return (0);
+#else
+	return (__os_is_winnt());
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_cpu.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,49 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_cpu_count --
+ *	Return the number of CPUs.
+ *
+ * PUBLIC: u_int32_t __os_cpu_count __P((void));
+ */
+u_int32_t
+__os_cpu_count()
+{
+	SYSTEM_INFO SystemInfo;
+
+	GetSystemInfo(&SystemInfo);
+
+	return ((u_int32_t)SystemInfo.dwNumberOfProcessors);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_dir.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,144 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_dirlist --
+ *	Return a list of the files in a directory.
+ */
+int
+__os_dirlist(env, dir, returndir, namesp, cntp)
+	ENV *env;
+	const char *dir;
+	int returndir, *cntp;
+	char ***namesp;
+{
+	HANDLE dirhandle;
+	WIN32_FIND_DATA fdata;
+	int arraysz, cnt, ret;
+	char **names, *onename;
+	_TCHAR tfilespec[DB_MAXPATHLEN + 1];
+	_TCHAR *tdir;
+
+	*namesp = NULL;
+	*cntp = 0;
+
+	TO_TSTRING(env, dir, tdir, ret);
+	if (ret != 0)
+		return (ret);
+
+	(void)_sntprintf(tfilespec, DB_MAXPATHLEN,
+	    _T("%s%hc*"), tdir, PATH_SEPARATOR[0]);
+
+	/*
+	 * On WinCE, FindFirstFile will return INVALID_HANDLE_VALUE when
+	 * the searched directory is empty, and set last error to
+	 * ERROR_NO_MORE_FILES, on Windows it will return "." instead.
+	 */
+	if ((dirhandle =
+	    FindFirstFile(tfilespec, &fdata)) == INVALID_HANDLE_VALUE) {
+		if (GetLastError() == ERROR_NO_MORE_FILES)
+			return (0);
+		return (__os_posix_err(__os_get_syserr()));
+	}
+
+	names = NULL;
+	arraysz = cnt = ret = 0;
+	for (;;) {
+		if (returndir ||
+		    (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
+			if (fdata.cFileName[0] == _T('.') &&
+			    (fdata.cFileName[1] == _T('\0') ||
+			    (fdata.cFileName[1] == _T('.') &&
+			    fdata.cFileName[2] == _T('\0'))))
+				goto next;
+			if (cnt >= arraysz) {
+				arraysz += 100;
+				if ((ret = __os_realloc(env,
+				    arraysz * sizeof(names[0]), &names)) != 0)
+					goto err;
+			}
+			/*
+			 * FROM_TSTRING doesn't necessarily allocate new
+			 * memory, so we must do that explicitly.
+			 * Unfortunately, when compiled with UNICODE, we'll
+			 * copy twice.
+			 */
+			FROM_TSTRING(env, fdata.cFileName, onename, ret);
+			if (ret != 0)
+				goto err;
+			ret = __os_strdup(env, onename, &names[cnt]);
+			FREE_STRING(env, onename);
+			if (ret != 0)
+				goto err;
+			cnt++;
+		}
+next:
+		if (!FindNextFile(dirhandle, &fdata)) {
+			if (GetLastError() == ERROR_NO_MORE_FILES)
+				break;
+			else {
+				ret = __os_posix_err(__os_get_syserr());
+				goto err;
+			}
+		}
+	}
+
+err:	if (!FindClose(dirhandle) && ret == 0)
+		ret = __os_posix_err(__os_get_syserr());
+
+	if (ret == 0) {
+		*namesp = names;
+		*cntp = cnt;
+	} else if (names != NULL)
+		__os_dirfree(env, names, cnt);
+
+	FREE_STRING(env, tdir);
+
+	return (ret);
+}
+
+/*
+ * __os_dirfree --
+ *	Free the list of files.
+ */
+void
+__os_dirfree(env, names, cnt)
+	ENV *env;
+	char **names;
+	int cnt;
+{
+	while (cnt > 0)
+		__os_free(env, names[--cnt]);
+	__os_free(env, names);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_errno.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,450 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1999, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_get_errno_ret_zero --
+ *	Return the last system error, including an error of zero.
+ */
+int
+__os_get_errno_ret_zero()
+{
+	/* This routine must be able to return the same value repeatedly. */
+	return (errno);
+}
+
+/*
+ * We've seen cases where system calls failed but errno was never set.  For
+ * that reason, __os_get_errno() and __os_get_syserr set errno to EAGAIN if
+ * it's not already set, to work around the problem.  For obvious reasons,
+ * we can only call this function if we know an error has occurred, that
+ * is, we can't test the return for a non-zero value after the get call.
+ *
+ * __os_get_errno --
+ *	Return the last ANSI C "errno" value or EAGAIN if the last error
+ *	is zero.
+ */
+int
+__os_get_errno()
+{
+	/* This routine must be able to return the same value repeatedly. */
+	if (errno == 0)
+		__os_set_errno(EAGAIN);
+	return (errno);
+}
+
+#ifdef HAVE_REPLICATION_THREADS
+/*
+ * __os_get_neterr --
+ *	Return the last networking error or EAGAIN if the last error is zero.
+ *
+ * PUBLIC: #ifdef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __os_get_neterr __P((void));
+ * PUBLIC: #endif
+ */
+int
+__os_get_neterr()
+{
+	int err;
+
+	/* This routine must be able to return the same value repeatedly. */
+	err = WSAGetLastError();
+	if (err == 0)
+		WSASetLastError(err = ERROR_RETRY);
+	return (err);
+}
+#endif
+
+/*
+ * __os_get_syserr --
+ *	Return the last system error or EAGAIN if the last error is zero.
+ */
+int
+__os_get_syserr()
+{
+	int err;
+
+	/* This routine must be able to return the same value repeatedly. */
+	err = GetLastError();
+	if (err == 0)
+		SetLastError(err = ERROR_RETRY);
+	return (err);
+}
+
+/*
+ * __os_set_errno --
+ *	Set the value of errno.
+ */
+void
+__os_set_errno(evalue)
+	int evalue;
+{
+	/*
+	 * This routine is called by the compatibility interfaces (DB 1.85,
+	 * dbm and hsearch).  Force values > 0, that is, not one of DB 2.X
+	 * and later's public error returns.  If something bad has happened,
+	 * default to EFAULT -- a nasty return.  Otherwise, default to EINVAL.
+	 * As the compatibility APIs aren't included on Windows, the Windows
+	 * version of this routine doesn't need this behavior.
+	 */
+	errno =
+	    evalue >= 0 ? evalue : (evalue == DB_RUNRECOVERY ? EFAULT : EINVAL);
+}
+
+/*
+ * __os_strerror --
+ *	Return a string associated with the system error.
+ */
+char *
+__os_strerror(error, buf, len)
+	int error;
+	char *buf;
+	size_t len;
+{
+#ifdef DB_WINCE
+#define	MAX_TMPBUF_LEN 512
+	_TCHAR tbuf[MAX_TMPBUF_LEN];
+	size_t  maxlen;
+
+	DB_ASSERT(NULL, error != 0);
+
+	memset(tbuf, 0, sizeof(_TCHAR)*MAX_TMPBUF_LEN);
+	maxlen = (len > MAX_TMPBUF_LEN ? MAX_TMPBUF_LEN : len);
+	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, (DWORD)error,
+		0, tbuf, maxlen-1, NULL);
+
+	if (WideCharToMultiByte(CP_UTF8, 0, tbuf, -1,
+		buf, len, 0, NULL) == 0)
+		strncpy(buf, DB_STR("0035",
+		    "Error message translation failed."), len);
+#else
+	DB_ASSERT(NULL, error != 0);
+	/*
+	 * Explicitly call FormatMessageA, since we want to receive a char
+	 * string back, not a tchar string.
+	 */
+	FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
+	    0, (DWORD)error, 0, buf, (DWORD)(len - 1), NULL);
+	buf[len - 1] = '\0';
+#endif
+
+	return (buf);
+}
+
+/*
+ * __os_posix_err --
+ *	Convert a system error to a POSIX error.
+ */
+int
+__os_posix_err(error)
+	int error;
+{
+	/* Handle calls on successful returns. */
+	if (error == 0)
+		return (0);
+
+	/*
+	 * Translate the Windows error codes we care about.
+	 */
+	switch (error) {
+	case ERROR_INVALID_PARAMETER:
+		return (EINVAL);
+
+	case ERROR_FILE_NOT_FOUND:
+	case ERROR_INVALID_DRIVE:
+	case ERROR_PATH_NOT_FOUND:
+		return (ENOENT);
+
+	case ERROR_NO_MORE_FILES:
+	case ERROR_TOO_MANY_OPEN_FILES:
+		return (EMFILE);
+
+	case ERROR_ACCESS_DENIED:
+		return (EPERM);
+
+	case ERROR_INVALID_HANDLE:
+		return (EBADF);
+
+	case ERROR_NOT_ENOUGH_MEMORY:
+		return (ENOMEM);
+
+	case ERROR_DISK_FULL:
+		return (ENOSPC);
+
+	case ERROR_ARENA_TRASHED:
+	case ERROR_BAD_COMMAND:
+	case ERROR_BAD_ENVIRONMENT:
+	case ERROR_BAD_FORMAT:
+	case ERROR_GEN_FAILURE:
+	case ERROR_INVALID_ACCESS:
+	case ERROR_INVALID_BLOCK:
+	case ERROR_INVALID_DATA:
+	case ERROR_READ_FAULT:
+	case ERROR_WRITE_FAULT:
+		return (EFAULT);
+
+	case ERROR_ALREADY_EXISTS:
+	case ERROR_FILE_EXISTS:
+		return (EEXIST);
+
+	case ERROR_NOT_SAME_DEVICE:
+		return (EXDEV);
+
+	case ERROR_WRITE_PROTECT:
+		return (EACCES);
+
+	case ERROR_LOCK_FAILED:
+	case ERROR_LOCK_VIOLATION:
+	case ERROR_NOT_READY:
+	case ERROR_SHARING_VIOLATION:
+		return (EBUSY);
+
+	case ERROR_RETRY:
+		return (EINTR);
+	}
+
+	/*
+	 * Translate the Windows socket error codes.
+	 */
+	switch (error) {
+	case WSAEADDRINUSE:
+#ifdef EADDRINUSE
+		return (EADDRINUSE);
+#else
+		break;
+#endif
+	case WSAEADDRNOTAVAIL:
+#ifdef EADDRNOTAVAIL
+		return (EADDRNOTAVAIL);
+#else
+		break;
+#endif
+	case WSAEAFNOSUPPORT:
+#ifdef EAFNOSUPPORT
+		return (EAFNOSUPPORT);
+#else
+		break;
+#endif
+	case WSAEALREADY:
+#ifdef EALREADY
+		return (EALREADY);
+#else
+		break;
+#endif
+	case WSAEBADF:
+		return (EBADF);
+	case WSAECONNABORTED:
+#ifdef ECONNABORTED
+		return (ECONNABORTED);
+#else
+		break;
+#endif
+	case WSAECONNREFUSED:
+#ifdef ECONNREFUSED
+		return (ECONNREFUSED);
+#else
+		break;
+#endif
+	case WSAECONNRESET:
+#ifdef ECONNRESET
+		return (ECONNRESET);
+#else
+		break;
+#endif
+	case WSAEDESTADDRREQ:
+#ifdef EDESTADDRREQ
+		return (EDESTADDRREQ);
+#else
+		break;
+#endif
+	case WSAEFAULT:
+		return (EFAULT);
+	case WSAEHOSTDOWN:
+#ifdef EHOSTDOWN
+		return (EHOSTDOWN);
+#else
+		break;
+#endif
+	case WSAEHOSTUNREACH:
+#ifdef EHOSTUNREACH
+		return (EHOSTUNREACH);
+#else
+		break;
+#endif
+	case WSAEINPROGRESS:
+#ifdef EINPROGRESS
+		return (EINPROGRESS);
+#else
+		break;
+#endif
+	case WSAEINTR:
+		return (EINTR);
+	case WSAEINVAL:
+		return (EINVAL);
+	case WSAEISCONN:
+#ifdef EISCONN
+		return (EISCONN);
+#else
+		break;
+#endif
+	case WSAELOOP:
+#ifdef ELOOP
+		return (ELOOP);
+#else
+		break;
+#endif
+	case WSAEMFILE:
+		return (EMFILE);
+	case WSAEMSGSIZE:
+#ifdef EMSGSIZE
+		return (EMSGSIZE);
+#else
+		break;
+#endif
+	case WSAENAMETOOLONG:
+		return (ENAMETOOLONG);
+	case WSAENETDOWN:
+#ifdef ENETDOWN
+		return (ENETDOWN);
+#else
+		break;
+#endif
+	case WSAENETRESET:
+#ifdef ENETRESET
+		return (ENETRESET);
+#else
+		break;
+#endif
+	case WSAENETUNREACH:
+#ifdef ENETUNREACH
+		return (ENETUNREACH);
+#else
+		break;
+#endif
+	case WSAENOBUFS:
+#ifdef ENOBUFS
+		return (ENOBUFS);
+#else
+		break;
+#endif
+	case WSAENOPROTOOPT:
+#ifdef ENOPROTOOPT
+		return (ENOPROTOOPT);
+#else
+		break;
+#endif
+	case WSAENOTCONN:
+#ifdef ENOTCONN
+		return (ENOTCONN);
+#else
+		break;
+#endif
+	case WSANOTINITIALISED:
+		return (EAGAIN);
+	case WSAENOTSOCK:
+#ifdef ENOTSOCK
+		return (ENOTSOCK);
+#else
+		break;
+#endif
+	case WSAEOPNOTSUPP:
+		return (DB_OPNOTSUP);
+	case WSAEPFNOSUPPORT:
+#ifdef EPFNOSUPPORT
+		return (EPFNOSUPPORT);
+#else
+		break;
+#endif
+	case WSAEPROTONOSUPPORT:
+#ifdef EPROTONOSUPPORT
+		return (EPROTONOSUPPORT);
+#else
+		break;
+#endif
+	case WSAEPROTOTYPE:
+#ifdef EPROTOTYPE
+		return (EPROTOTYPE);
+#else
+		break;
+#endif
+	case WSAESHUTDOWN:
+#ifdef ESHUTDOWN
+		return (ESHUTDOWN);
+#else
+		break;
+#endif
+	case WSAESOCKTNOSUPPORT:
+#ifdef ESOCKTNOSUPPORT
+		return (ESOCKTNOSUPPORT);
+#else
+		break;
+#endif
+	case WSAETIMEDOUT:
+#ifdef ETIMEDOUT
+		return (ETIMEDOUT);
+#else
+		break;
+#endif
+	case WSAETOOMANYREFS:
+#ifdef ETOOMANYREFS
+		return (ETOOMANYREFS);
+#else
+		break;
+#endif
+	case WSAEWOULDBLOCK:
+#ifdef EWOULDBLOCK
+		return (EWOULDBLOCK);
+#else
+		return (EAGAIN);
+#endif
+	case WSAHOST_NOT_FOUND:
+#ifdef EHOSTUNREACH
+		return (EHOSTUNREACH);
+#else
+		break;
+#endif
+	case WSASYSNOTREADY:
+		return (EAGAIN);
+	case WSATRY_AGAIN:
+		return (EAGAIN);
+	case WSAVERNOTSUPPORTED:
+		return (DB_OPNOTSUP);
+	case WSAEACCES:
+		return (EACCES);
+	}
+
+	/*
+	 * EFAULT is the default if we don't have a translation.
+	 */
+	return (EFAULT);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_fid.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,151 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_fileid --
+ *	Return a unique identifier for a file.
+ */
+int
+__os_fileid(env, fname, unique_okay, fidp)
+	ENV *env;
+	const char *fname;
+	int unique_okay;
+	u_int8_t *fidp;
+{
+	pid_t pid;
+	size_t i;
+	u_int32_t tmp;
+	u_int8_t *p;
+	int ret;
+
+	/*
+	 * The documentation for GetFileInformationByHandle() states that the
+	 * inode-type numbers are not constant between processes.  Actually,
+	 * they are, they're the NTFS MFT indexes.  So, this works on NTFS,
+	 * but perhaps not on other platforms, and perhaps not over a network.
+	 * Can't think of a better solution right now.
+	 */
+	DB_FH *fhp;
+	BY_HANDLE_FILE_INFORMATION fi;
+	BOOL retval = FALSE;
+
+	DB_ASSERT(env, fname != NULL);
+
+	/* Clear the buffer. */
+	memset(fidp, 0, DB_FILE_ID_LEN);
+
+	/*
+	 * First we open the file, because we're not given a handle to it.
+	 * If we can't open it, we're in trouble.
+	 */
+	if ((ret = __os_open(env, fname, 0,
+	    DB_OSO_RDONLY, DB_MODE_400, &fhp)) != 0)
+		return (ret);
+
+	/* File open, get its info */
+	if ((retval = GetFileInformationByHandle(fhp->handle, &fi)) == FALSE)
+		ret = __os_get_syserr();
+	(void)__os_closehandle(env, fhp);
+
+	if (retval == FALSE)
+		return (__os_posix_err(ret));
+
+	/*
+	 * We want the three 32-bit words which tell us the volume ID and
+	 * the file ID.  We make a crude attempt to copy the bytes over to
+	 * the callers buffer.
+	 *
+	 * We don't worry about byte sexing or the actual variable sizes.
+	 *
+	 * When this routine is called from the DB access methods, it's only
+	 * called once -- whatever ID is generated when a database is created
+	 * is stored in the database file's metadata, and that is what is
+	 * saved in the mpool region's information to uniquely identify the
+	 * file.
+	 *
+	 * When called from the mpool layer this routine will be called each
+	 * time a new thread of control wants to share the file, which makes
+	 * things tougher.  As far as byte sexing goes, since the mpool region
+	 * lives on a single host, there's no issue of that -- the entire
+	 * region is byte sex dependent.  As far as variable sizes go, we make
+	 * the simplifying assumption that 32-bit and 64-bit processes will
+	 * get the same 32-bit values if we truncate any returned 64-bit value
+	 * to a 32-bit value.
+	 */
+	tmp = (u_int32_t)fi.nFileIndexLow;
+	for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
+		*fidp++ = *p++;
+	tmp = (u_int32_t)fi.nFileIndexHigh;
+	for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
+		*fidp++ = *p++;
+
+	if (unique_okay) {
+		/* Add in 32-bits of (hopefully) unique number. */
+		__os_unique_id(env, &tmp);
+		for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
+			*fidp++ = *p++;
+
+		/*
+		 * Initialize/increment the serial number we use to help
+		 * avoid fileid collisions.  Note we don't bother with
+		 * locking; it's unpleasant to do from down in here, and
+		 * if we race on this no real harm will be done, since the
+		 * finished fileid has so many other components.
+		 *
+		 * We use the bottom 32-bits of the process ID, hoping they
+		 * are more random than the top 32-bits (should we be on a
+		 * machine with 64-bit process IDs).
+		 *
+		 * We increment by 100000 on each call as a simple way of
+		 * randomizing; simply incrementing seems potentially less
+		 * useful if pids are also simply incremented, since this
+		 * is process-local and we may be one of a set of processes
+		 * starting up.  100000 pushes us out of pid space on most
+		 * 32-bit platforms, and has few interesting properties in
+		 * base 2.
+		 */
+		if (DB_GLOBAL(fid_serial) == 0) {
+			__os_id(env->dbenv, &pid, NULL);
+			DB_GLOBAL(fid_serial) = (u_int32_t)pid;
+		} else
+			DB_GLOBAL(fid_serial) += 100000;
+
+	} else {
+		tmp = (u_int32_t)fi.dwVolumeSerialNumber;
+		for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i)
+			*fidp++ = *p++;
+	}
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_flock.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,112 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_fdlock --
+ *	Acquire/release a lock on a byte in a file.
+ */
+int
+__os_fdlock(env, fhp, offset, acquire, nowait)
+	ENV *env;
+	DB_FH *fhp;
+	int acquire, nowait;
+	off_t offset;
+{
+#ifdef DB_WINCE
+	/*
+	 * This functionality is not supported by WinCE, so just fail.
+	 *
+	 * Should only happen if an app attempts to open an environment
+	 * with the DB_REGISTER flag.
+	 */
+	 __db_errx(env, DB_STR("0019",
+	    "fdlock API not implemented for WinCE, DB_REGISTER "
+	    "environment flag not supported."));
+	return (EFAULT);
+#else
+	DWORD low, high;
+	DB_ENV *dbenv;
+	OVERLAPPED over;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	DB_ASSERT(env,
+	    F_ISSET(fhp, DB_FH_OPENED) && fhp->handle != INVALID_HANDLE_VALUE);
+
+	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0020",
+		    "fileops: flock %s %s offset %lu", "%s %s %lu"), fhp->name,
+		    acquire ? DB_STR_P("acquire"): DB_STR_P("release"),
+		    (u_long)offset);
+
+	/*
+	 * Windows file locking interferes with read/write operations, so we
+	 * map the ranges to an area past the end of the file.
+	 */
+	DB_ASSERT(env, offset < (u_int64_t)INT64_MAX);
+	offset = UINT64_MAX - offset;
+	low = (DWORD)offset;
+	high = (DWORD)(offset >> 32);
+
+	if (acquire) {
+		if (nowait)
+			RETRY_CHK_EINTR_ONLY(
+			    !LockFile(fhp->handle, low, high, 1, 0), ret);
+		else if (__os_is_winnt()) {
+			memset(&over, 0, sizeof(over));
+			over.Offset = low;
+			over.OffsetHigh = high;
+			RETRY_CHK_EINTR_ONLY(
+			    !LockFileEx(fhp->handle, LOCKFILE_EXCLUSIVE_LOCK,
+			    0, 1, 0, &over),
+			    ret);
+		} else {
+			/* Windows 9x/ME doesn't support a blocking call. */
+			for (;;) {
+				RETRY_CHK_EINTR_ONLY(
+				    !LockFile(fhp->handle, low, high, 1, 0),
+				    ret);
+				if (__os_posix_err(ret) != EAGAIN)
+					break;
+				__os_yield(env, 1, 0);
+			}
+		}
+	} else
+		RETRY_CHK_EINTR_ONLY(
+		    !UnlockFile(fhp->handle, low, high, 1, 0), ret);
+
+	return (__os_posix_err(ret));
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_fsync.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,66 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_fsync --
+ *	Flush a file descriptor.
+ */
+int
+__os_fsync(env, fhp)
+	ENV *env;
+	DB_FH *fhp;
+{
+	DB_ENV *dbenv;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	/*
+	 * Do nothing if the file descriptor has been marked as not requiring
+	 * any sync to disk.
+	 */
+	if (F_ISSET(fhp, DB_FH_NOSYNC))
+		return (0);
+
+	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0023",
+		    "fileops: flush %s", "%s"), fhp->name);
+
+	RETRY_CHK((!FlushFileBuffers(fhp->handle)), ret);
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR("0024", "FlushFileBuffers"));
+		ret = __os_posix_err(ret);
+	}
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_getenv.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,125 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_getenv --
+ *	Retrieve an environment variable.
+ */
+int
+__os_getenv(env, name, bpp, buflen)
+	ENV *env;
+	const char *name;
+	char **bpp;
+	size_t buflen;
+{
+#ifdef DB_WINCE
+	COMPQUIET(name, NULL);
+	/* WinCE does not have a getenv implementation. */
+	return (0);
+#else
+	_TCHAR *tname, tbuf[1024];
+	int ret;
+	char *p;
+
+	/*
+	 * If there's a value and the buffer is large enough:
+	 *	copy value into the pointer, return 0
+	 * If there's a value and the buffer is too short:
+	 *	set pointer to NULL, return EINVAL
+	 * If there's no value:
+	 *	set pointer to NULL, return 0
+	 */
+	if ((p = getenv(name)) != NULL) {
+		if (strlen(p) < buflen) {
+			(void)strcpy(*bpp, p);
+			return (0);
+		}
+		goto small_buf;
+	}
+
+	TO_TSTRING(env, name, tname, ret);
+	if (ret != 0)
+		return (ret);
+	/*
+	 * The declared size of the tbuf buffer limits the maximum environment
+	 * variable size in Berkeley DB on Windows.  If that's too small, or if
+	 * we need to get rid of large allocations on the BDB stack, we should
+	 * malloc the tbuf memory.
+	 */
+	ret = GetEnvironmentVariable(tname, tbuf, sizeof(tbuf));
+	FREE_STRING(env, tname);
+
+	/*
+	 * If GetEnvironmentVariable succeeds, the return value is the number
+	 * of characters stored in the buffer pointed to by lpBuffer, not
+	 * including the terminating null character.  If the buffer is not
+	 * large enough to hold the data, the return value is the buffer size,
+	 * in characters, required to hold the string and its terminating null
+	 * character.  If GetEnvironmentVariable fails, the return value is
+	 * zero.  If the specified environment variable was not found in the
+	 * environment block, GetLastError returns ERROR_ENVVAR_NOT_FOUND.
+	 */
+	if (ret == 0) {
+		if ((ret = __os_get_syserr()) == ERROR_ENVVAR_NOT_FOUND) {
+			*bpp = NULL;
+			return (0);
+		}
+		__db_syserr(env, ret, DB_STR("0026",
+		    "GetEnvironmentVariable"));
+		return (__os_posix_err(ret));
+	}
+	if (ret > (int)sizeof(tbuf))
+		goto small_buf;
+
+	FROM_TSTRING(env, tbuf, p, ret);
+	if (ret != 0)
+		return (ret);
+	if (strlen(p) < buflen)
+		(void)strcpy(*bpp, p);
+	else
+		*bpp = NULL;
+	FREE_STRING(env, p);
+	if (*bpp == NULL)
+		goto small_buf;
+
+	return (0);
+
+small_buf:
+	*bpp = NULL;
+	__db_errx(env, DB_STR_A("0027",
+	    "%s: buffer too small to hold environment variable %s", "%s %s"),
+	    name, p);
+	return (EINVAL);
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_handle.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,189 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_openhandle --
+ *	Open a file, using POSIX 1003.1 open flags.
+ */
+int
+__os_openhandle(env, name, flags, mode, fhpp)
+	ENV *env;
+	const char *name;
+	int flags, mode;
+	DB_FH **fhpp;
+{
+#ifdef DB_WINCE
+	/*
+	 * __os_openhandle API is not implemented on WinCE.
+	 * It is not currently called from within the Berkeley DB library,
+	 * so don't log the failure via the __db_err mechanism.
+	 */
+	return (EFAULT);
+#else
+	DB_FH *fhp;
+	int ret, nrepeat, retries;
+
+	/*
+	 * Allocate the file handle and copy the file name.  We generally only
+	 * use the name for verbose or error messages, but on systems where we
+	 * can't unlink temporary files immediately, we use the name to unlink
+	 * the temporary file when the file handle is closed.
+	 *
+	 * Lock the ENV handle and insert the new file handle on the list.
+	 */
+	if ((ret = __os_calloc(env, 1, sizeof(DB_FH), &fhp)) != 0)
+		return (ret);
+	if ((ret = __os_strdup(env, name, &fhp->name)) != 0)
+		goto err;
+	if (env != NULL) {
+		MUTEX_LOCK(env, env->mtx_env);
+		TAILQ_INSERT_TAIL(&env->fdlist, fhp, q);
+		MUTEX_UNLOCK(env, env->mtx_env);
+		F_SET(fhp, DB_FH_ENVLINK);
+	}
+
+	retries = 0;
+	for (nrepeat = 1; nrepeat < 4; ++nrepeat) {
+		fhp->fd = _open(name, flags, mode);
+
+		if (fhp->fd != -1) {
+			ret = 0;
+			break;
+		}
+
+		switch (ret = __os_posix_err(__os_get_syserr())) {
+		case EMFILE:
+		case ENFILE:
+		case ENOSPC:
+			/*
+			 * If it's a "temporary" error, we retry up to 3 times,
+			 * waiting up to 12 seconds.  While it's not a problem
+			 * if we can't open a database, an inability to open a
+			 * log file is cause for serious dismay.
+			 */
+			__os_yield(env, nrepeat * 2, 0);
+			break;
+		case EAGAIN:
+		case EBUSY:
+		case EINTR:
+			/*
+			 * If an EAGAIN, EBUSY or EINTR, retry immediately for
+			 * DB_RETRY times.
+			 */
+			if (++retries < DB_RETRY)
+				--nrepeat;
+			break;
+		default:
+			/* Open is silent on error. */
+			goto err;
+		}
+	}
+
+	if (ret == 0) {
+		F_SET(fhp, DB_FH_OPENED);
+		*fhpp = fhp;
+		return (0);
+	}
+
+err:	(void)__os_closehandle(env, fhp);
+	return (ret);
+#endif
+}
+
+/*
+ * __os_closehandle --
+ *	Close a file.
+ */
+int
+__os_closehandle(env, fhp)
+	ENV *env;
+	DB_FH *fhp;
+{
+	DB_ENV *dbenv;
+	int ret, t_ret;
+
+	ret = 0;
+
+	if (env != NULL) {
+		dbenv = env->dbenv;
+		if (fhp->name != NULL && FLD_ISSET(
+		    dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+			__db_msg(env, DB_STR_A("0031",
+			    "fileops: %s: close", "%s"), fhp->name);
+
+		if (F_ISSET(fhp, DB_FH_ENVLINK)) {
+			/*
+			 * Lock the ENV handle and remove this file
+			 * handle from the list.
+			 */
+			MUTEX_LOCK(env, env->mtx_env);
+			TAILQ_REMOVE(&env->fdlist, fhp, q);
+			MUTEX_UNLOCK(env, env->mtx_env);
+		}
+	}
+
+	/* Discard any underlying system file reference. */
+	if (F_ISSET(fhp, DB_FH_OPENED)) {
+		if (fhp->handle != INVALID_HANDLE_VALUE)
+			RETRY_CHK((!CloseHandle(fhp->handle)), ret);
+		else
+#ifdef DB_WINCE
+			ret = EFAULT;
+#else
+			RETRY_CHK((_close(fhp->fd)), ret);
+#endif
+
+		if (fhp->trunc_handle != INVALID_HANDLE_VALUE) {
+			RETRY_CHK((!CloseHandle(fhp->trunc_handle)), t_ret);
+			if (t_ret != 0 && ret == 0)
+				ret = t_ret;
+		}
+
+		if (ret != 0) {
+			__db_syserr(env, ret, DB_STR("0032",
+			    "CloseHandle"));
+			ret = __os_posix_err(ret);
+		}
+	}
+
+	/* Unlink the file if we haven't already done so. */
+	if (F_ISSET(fhp, DB_FH_UNLINK))
+		(void)__os_unlink(env, fhp->name, 0);
+
+	if (fhp->name != NULL)
+		__os_free(env, fhp->name);
+	__os_free(env, fhp);
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_map.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,419 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+static int __os_map
+  __P((ENV *, char *, REGINFO *, DB_FH *, size_t, int, int, int, void **));
+static int __os_unique_name __P((_TCHAR *, HANDLE, _TCHAR *, size_t));
+
+/*
+ * __os_attach --
+ *	Create/join a shared memory region.
+ */
+int
+__os_attach(env, infop, rp)
+	ENV *env;
+	REGINFO *infop;
+	REGION *rp;
+{
+	int ret;
+	int is_sparse;
+#ifndef DB_WINCE
+	DWORD dw;
+#endif
+
+	infop->fhp = NULL;
+	/*
+	 * On Windows/9X, files that are opened by multiple processes do not
+	 * share data correctly.  For this reason, we require that DB_PRIVATE
+	 * be specified on that platform.
+	 */
+	if (!F_ISSET(env, ENV_PRIVATE) && __os_is_winnt() == 0) {
+		__db_err(env, EINVAL, DB_STR("0006",
+		    "Windows 9X systems must specify DB_PRIVATE"));
+		return (EINVAL);
+	}
+
+	/*
+	 * Try to open/create the file.  We DO NOT need to ensure that multiple
+	 * threads/processes attempting to simultaneously create the region are
+	 * properly ordered, our caller has already taken care of that.
+	 */
+	if ((ret = __os_open(env, infop->name, 0, DB_OSO_REGION |
+	    (F_ISSET(infop, REGION_CREATE_OK) ? DB_OSO_CREATE : 0),
+	    env->db_mode, &infop->fhp)) != 0) {
+		__db_err(env, ret, "%s", infop->name);
+		return (ret);
+	}
+
+	is_sparse = 0;
+#ifndef DB_WINCE
+	/*
+	 * Sparse file only works for NTFS filesystem. If we failed to set it,
+	 * just ignore the error and use the normal method.
+	 */
+	if (!F_ISSET(env, ENV_SYSTEM_MEM) && (DeviceIoControl(
+	    infop->fhp->handle, FSCTL_SET_SPARSE, NULL, 0, NULL, 0,
+	    &dw, NULL)))
+		is_sparse = 1;
+#endif
+
+	/*
+	 * Map the file in.  If we're creating an in-system-memory region,
+	 * specify a segment ID (which is never used again) so that the
+	 * calling code writes out the REGENV_REF structure to the primary
+	 * environment file.
+	 */
+	ret = __os_map(env, infop->name, infop, infop->fhp, rp->max,
+	   1, F_ISSET(env, ENV_SYSTEM_MEM), 0, &infop->addr);
+	if (ret == 0 && F_ISSET(env, ENV_SYSTEM_MEM))
+		rp->segid = 1;
+
+	if (ret != 0) {
+		(void)__os_closehandle(env, infop->fhp);
+		infop->fhp = NULL;
+		return (ret);
+	}
+
+	/*
+	 * If we are using sparse file, we don't need to keep the file handle
+	 * for writing or extending.
+	 */
+	if (is_sparse && infop->fhp != NULL) {
+		ret = __os_closehandle(env, infop->fhp);
+		infop->fhp = NULL;
+	}
+	return (ret);
+}
+
+/*
+ * __os_detach --
+ *	Detach from a shared memory region.
+ */
+int
+__os_detach(env, infop, destroy)
+	ENV *env;
+	REGINFO *infop;
+	int destroy;
+{
+	DB_ENV *dbenv;
+	int ret, t_ret;
+
+	dbenv = env->dbenv;
+
+	if (infop->wnt_handle != NULL) {
+		(void)CloseHandle(infop->wnt_handle);
+		infop->wnt_handle = NULL;
+	}
+	if (infop->fhp != NULL) {
+		ret = __os_closehandle(env, infop->fhp);
+		infop->fhp = NULL;
+		if (ret != 0)
+			return (ret);
+	}
+
+	ret = !UnmapViewOfFile(infop->addr) ? __os_get_syserr() : 0;
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR("0007", "UnmapViewOfFile"));
+		ret = __os_posix_err(ret);
+	}
+
+	if (!F_ISSET(env, ENV_SYSTEM_MEM) && destroy &&
+	    (t_ret = __os_unlink(env, infop->name, 1)) != 0 && ret == 0)
+		ret = t_ret;
+
+	return (ret);
+}
+
+/*
+ * __os_mapfile --
+ *	Map in a shared memory file.
+ */
+int
+__os_mapfile(env, path, fhp, len, is_rdonly, addr)
+	ENV *env;
+	char *path;
+	DB_FH *fhp;
+	int is_rdonly;
+	size_t len;
+	void **addr;
+{
+#ifdef DB_WINCE
+	/*
+	 * Windows CE has special requirements for file mapping to work.
+	 * * The input handle needs to be opened using CreateFileForMapping
+	 * * Concurrent access via a non mapped file is not supported.
+	 * So we disable support for memory mapping files on Windows CE. It is
+	 * currently only used as an optimization in mpool for small read only
+	 * databases.
+	 */
+	return (EFAULT);
+#else
+	DB_ENV *dbenv;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0008", "fileops: mmap %s", "%s"), path);
+	return (__os_map(env, path, NULL, fhp, len, 0, 0, is_rdonly, addr));
+#endif
+}
+
+/*
+ * __os_unmapfile --
+ *	Unmap the shared memory file.
+ */
+int
+__os_unmapfile(env, addr, len)
+	ENV *env;
+	void *addr;
+	size_t len;
+{
+	DB_ENV *dbenv;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR("0009", "fileops: munmap"));
+
+	return (!UnmapViewOfFile(addr) ? __os_posix_err(__os_get_syserr()) : 0);
+}
+
+/*
+ * __os_unique_name --
+ *	Create a unique identifying name from a pathname (may be absolute or
+ *	relative) and/or a file descriptor.
+ *
+ *	The name returned must be unique (different files map to different
+ *	names), and repeatable (same files, map to same names).  It's not
+ *	so easy to do by name.  Should handle not only:
+ *
+ *		foo.bar == ./foo.bar == c:/whatever_path/foo.bar
+ *
+ *	but also understand that:
+ *
+ *		foo.bar == Foo.Bar	(FAT file system)
+ *		foo.bar != Foo.Bar	(NTFS)
+ *
+ *	The best solution is to use the file index, found in the file
+ *	information structure (similar to UNIX inode #).
+ *
+ *	When a file is deleted, its file index may be reused,
+ *	but if the unique name has not gone from its namespace,
+ *	we may get a conflict.  So to ensure some tie in to the
+ *	original pathname, we also use the creation time and the
+ *	file basename.  This is not a perfect system, but it
+ *	should work for all but anamolous test cases.
+ *
+ */
+static int
+__os_unique_name(orig_path, hfile, result_path, result_path_len)
+	_TCHAR *orig_path, *result_path;
+	HANDLE hfile;
+	size_t result_path_len;
+{
+	BY_HANDLE_FILE_INFORMATION fileinfo;
+	_TCHAR *basename, *p;
+
+	/*
+	 * In Windows, pathname components are delimited by '/' or '\', and
+	 * if neither is present, we need to strip off leading drive letter
+	 * (e.g. c:foo.txt).
+	 */
+	basename = _tcsrchr(orig_path, '/');
+	p = _tcsrchr(orig_path, '\\');
+	if (basename == NULL || (p != NULL && p > basename))
+		basename = p;
+	if (basename == NULL)
+		basename = _tcsrchr(orig_path, ':');
+
+	if (basename == NULL)
+		basename = orig_path;
+	else
+		basename++;
+
+	if (!GetFileInformationByHandle(hfile, &fileinfo))
+		return (__os_posix_err(__os_get_syserr()));
+
+	(void)_sntprintf(result_path, result_path_len,
+	    _T("__db_shmem.%8.8lx.%8.8lx.%8.8lx.%8.8lx.%8.8lx.%s"),
+	    fileinfo.dwVolumeSerialNumber,
+	    fileinfo.nFileIndexHigh,
+	    fileinfo.nFileIndexLow,
+	    fileinfo.ftCreationTime.dwHighDateTime,
+	    fileinfo.ftCreationTime.dwHighDateTime,
+	    basename);
+
+	return (0);
+}
+
+/*
+ * __os_map --
+ *	The mmap(2) function for Windows.
+ */
+static int
+__os_map(env, path, infop, fhp, len, is_region, is_system, is_rdonly, addr)
+	ENV *env;
+	REGINFO *infop;
+	char *path;
+	DB_FH *fhp;
+	int is_region, is_system, is_rdonly;
+	size_t len;
+	void **addr;
+{
+	HANDLE hMemory;
+	int ret, use_pagefile;
+	_TCHAR *tpath, shmem_name[DB_MAXPATHLEN];
+	void *pMemory;
+	unsigned __int64 len64;
+
+	ret = 0;
+	if (infop != NULL)
+		infop->wnt_handle = NULL;
+
+	/*
+	 * On 64 bit systems, len is already a 64 bit value.
+	 * On 32 bit systems len is a 32 bit value.
+	 * Always convert to a 64 bit value, so that the high order
+	 * DWORD can be simply extracted on 64 bit platforms.
+	 */
+	len64 = len;
+
+	use_pagefile = is_region && is_system;
+
+	/*
+	 * If creating a region in system space, get a matching name in the
+	 * paging file namespace.
+	 */
+	if (use_pagefile) {
+#ifdef DB_WINCE
+		__db_errx(env, DB_STR("0010",
+		    "Unable to memory map regions using system "
+		    "memory on WinCE."));
+		return (EFAULT);
+#endif
+		TO_TSTRING(env, path, tpath, ret);
+		if (ret != 0)
+			return (ret);
+		ret = __os_unique_name(tpath, fhp->handle,
+		    shmem_name, sizeof(shmem_name));
+		FREE_STRING(env, tpath);
+		if (ret != 0)
+			return (ret);
+	}
+
+	/*
+	 * XXX
+	 * DB: We have not implemented copy-on-write here.
+	 *
+	 * If this is an region in system memory, we try to open it using the
+	 * OpenFileMapping() first, and only call CreateFileMapping() if we're
+	 * really creating the section.  There are two reasons:
+	 *
+	 * 1) We only create the mapping if we have newly created the region.
+	 *    This avoids a long-running problem caused by Windows reference
+	 *    counting, where regions that are closed by all processes are
+	 *    deleted.  It turns out that just checking for a zeroed region
+	 *    is not good enough. See [#4882] and [#7127] for the details.
+	 *
+	 * 2) CreateFileMapping seems to mess up making the commit charge to
+	 *    the process. It thinks, incorrectly, that when we want to join a
+	 *    previously existing section, that it should make a commit charge
+	 *    for the whole section.  In fact, there is no new committed memory
+	 *    whatever.  The call can fail if there is insufficient memory free
+	 *    to handle the erroneous commit charge.  So, we find that the
+	 *    bogus commit is not made if we call OpenFileMapping.
+	 */
+	hMemory = NULL;
+	if (use_pagefile) {
+#ifndef DB_WINCE
+		hMemory = OpenFileMapping(
+		    is_rdonly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS,
+		    0, shmem_name);
+
+		if (hMemory == NULL && F_ISSET(infop, REGION_CREATE_OK))
+			hMemory = CreateFileMapping((HANDLE)-1, 0,
+			    is_rdonly ? PAGE_READONLY : PAGE_READWRITE,
+			    (DWORD)(len64 >> 32), (DWORD)len64, shmem_name);
+#endif
+	} else {
+		hMemory = CreateFileMapping(fhp->handle, 0,
+		    is_rdonly ? PAGE_READONLY : PAGE_READWRITE,
+		    (DWORD)(len64 >> 32), (DWORD)len64, NULL);
+#ifdef DB_WINCE
+		/*
+		 * WinCE automatically closes the handle passed in.
+		 * Ensure DB does not attempt to close the handle again.
+		 */
+		fhp->handle = INVALID_HANDLE_VALUE;
+		F_CLR(fhp, DB_FH_OPENED);
+#endif
+	}
+
+	if (hMemory == NULL) {
+		ret = __os_get_syserr();
+		__db_syserr(env, ret, DB_STR("0011", "OpenFileMapping"));
+		return (__env_panic(env, __os_posix_err(ret)));
+	}
+
+	pMemory = MapViewOfFile(hMemory,
+	    (is_rdonly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS), 0, 0, len);
+	if (pMemory == NULL) {
+		ret = __os_get_syserr();
+		__db_syserr(env, ret, DB_STR("0012", "MapViewOfFile"));
+		return (__env_panic(env, __os_posix_err(ret)));
+	}
+
+	/*
+	 * XXX
+	 * It turns out that the kernel object underlying the named section
+	 * is reference counted, but that the call to MapViewOfFile() above
+	 * does NOT increment the reference count! So, if we close the handle
+	 * here, the kernel deletes the object from the kernel namespace.
+	 * When a second process comes along to join the region, the kernel
+	 * happily creates a new object with the same name, but completely
+	 * different identity. The two processes then have distinct isolated
+	 * mapped sections, not at all what was wanted. Not closing the handle
+	 * here fixes this problem.  We carry the handle around in the region
+	 * structure so we can close it when unmap is called.
+	 */
+	if (use_pagefile && infop != NULL)
+		infop->wnt_handle = hMemory;
+	else
+		CloseHandle(hMemory);
+
+	*addr = pMemory;
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_mkdir.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,66 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_mkdir --
+ *	Create a directory.
+ */
+int
+__os_mkdir(env, name, mode)
+	ENV *env;
+	const char *name;
+	int mode;
+{
+	DB_ENV *dbenv;
+	_TCHAR *tname;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0013", "fileops: mkdir %s",
+		    "%s"), name);
+
+	/* Make the directory, with paranoid permissions. */
+	TO_TSTRING(env, name, tname, ret);
+	if (ret != 0)
+		return (ret);
+	RETRY_CHK(!CreateDirectory(tname, NULL), ret);
+	FREE_STRING(env, tname);
+	if (ret != 0)
+		return (__os_posix_err(ret));
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_open.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,280 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_open --
+ *	Open a file descriptor (including page size and log size information).
+ */
+int
+__os_open(env, name, page_size, flags, mode, fhpp)
+	ENV *env;
+	const char *name;
+	u_int32_t page_size, flags;
+	int mode;
+	DB_FH **fhpp;
+{
+	DB_ENV *dbenv;
+	DB_FH *fhp;
+#ifndef DB_WINCE
+	DWORD cluster_size, sector_size, free_clusters, total_clusters;
+	_TCHAR *drive, dbuf[4]; /* <letter><colon><slash><nul> */
+
+#endif
+	int access, attr, createflag, nrepeat, ret, share;
+	_TCHAR *tname;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+	*fhpp = NULL;
+	tname = NULL;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0025", "fileops: open %s",
+		    "%s"), name);
+
+#undef	OKFLAGS
+#define	OKFLAGS								\
+	(DB_OSO_ABSMODE | DB_OSO_CREATE | DB_OSO_DIRECT | DB_OSO_DSYNC |\
+	DB_OSO_EXCL | DB_OSO_RDONLY | DB_OSO_REGION |	DB_OSO_SEQ |	\
+	DB_OSO_TEMP | DB_OSO_TRUNC)
+	if ((ret = __db_fchk(env, "__os_open", flags, OKFLAGS)) != 0)
+		return (ret);
+
+	TO_TSTRING(env, name, tname, ret);
+	if (ret != 0)
+		goto err;
+
+	/*
+	 * Allocate the file handle and copy the file name.  We generally only
+	 * use the name for verbose or error messages, but on systems where we
+	 * can't unlink temporary files immediately, we use the name to unlink
+	 * the temporary file when the file handle is closed.
+	 *
+	 * Lock the ENV handle and insert the new file handle on the list.
+	 */
+	if ((ret = __os_calloc(env, 1, sizeof(DB_FH), &fhp)) != 0)
+		return (ret);
+	if ((ret = __os_strdup(env, name, &fhp->name)) != 0)
+		goto err;
+	if (env != NULL) {
+		MUTEX_LOCK(env, env->mtx_env);
+		TAILQ_INSERT_TAIL(&env->fdlist, fhp, q);
+		MUTEX_UNLOCK(env, env->mtx_env);
+		F_SET(fhp, DB_FH_ENVLINK);
+	}
+
+	/*
+	 * Otherwise, use the Windows/32 CreateFile interface so that we can
+	 * play magic games with files to get data flush effects similar to
+	 * the POSIX O_DSYNC flag.
+	 *
+	 * !!!
+	 * We currently ignore the 'mode' argument.  It would be possible
+	 * to construct a set of security attributes that we could pass to
+	 * CreateFile that would accurately represents the mode.  In worst
+	 * case, this would require looking up user and all group names and
+	 * creating an entry for each.  Alternatively, we could call the
+	 * _chmod (partial emulation) function after file creation, although
+	 * this leaves us with an obvious race.  However, these efforts are
+	 * largely meaningless on FAT, the most common file system, which
+	 * only has a "readable" and "writable" flag, applying to all users.
+	 */
+	access = GENERIC_READ;
+	if (!LF_ISSET(DB_OSO_RDONLY))
+		access |= GENERIC_WRITE;
+
+#ifdef DB_WINCE
+	/*
+	 * WinCE translates these flags into share flags for
+	 * CreateFileForMapping.
+	 * Also WinCE does not support the FILE_SHARE_DELETE flag.
+	 */
+	if (LF_ISSET(DB_OSO_REGION))
+		share = GENERIC_READ | GENERIC_WRITE;
+	else
+		share = FILE_SHARE_READ | FILE_SHARE_WRITE;
+#else
+	share = FILE_SHARE_READ | FILE_SHARE_WRITE;
+	if (__os_is_winnt())
+		share |= FILE_SHARE_DELETE;
+#endif
+	attr = FILE_ATTRIBUTE_NORMAL;
+
+	/*
+	 * Reproduce POSIX 1003.1 semantics: if O_CREATE and O_EXCL are both
+	 * specified, fail, returning EEXIST, unless we create the file.
+	 */
+	if (LF_ISSET(DB_OSO_CREATE) && LF_ISSET(DB_OSO_EXCL))
+		createflag = CREATE_NEW;	/* create only if !exist*/
+	else if (!LF_ISSET(DB_OSO_CREATE) && LF_ISSET(DB_OSO_TRUNC))
+		createflag = TRUNCATE_EXISTING; /* truncate, fail if !exist */
+	else if (LF_ISSET(DB_OSO_TRUNC))
+		createflag = CREATE_ALWAYS;	/* create and truncate */
+	else if (LF_ISSET(DB_OSO_CREATE))
+		createflag = OPEN_ALWAYS;	/* open or create */
+	else
+		createflag = OPEN_EXISTING;	/* open only if existing */
+
+	if (LF_ISSET(DB_OSO_DSYNC)) {
+		F_SET(fhp, DB_FH_NOSYNC);
+		attr |= FILE_FLAG_WRITE_THROUGH;
+	}
+
+#ifndef DB_WINCE
+	if (LF_ISSET(DB_OSO_SEQ))
+		attr |= FILE_FLAG_SEQUENTIAL_SCAN;
+	else
+		attr |= FILE_FLAG_RANDOM_ACCESS;
+#endif
+
+	if (LF_ISSET(DB_OSO_TEMP))
+		attr |= FILE_FLAG_DELETE_ON_CLOSE;
+
+	/*
+	 * We can turn filesystem buffering off if the page size is a
+	 * multiple of the disk's sector size. To find the sector size,
+	 * we call GetDiskFreeSpace, which expects a drive name like "d:\\"
+	 * or NULL for the current disk (i.e., a relative path).
+	 *
+	 * WinCE only has GetDiskFreeSpaceEx which does not
+	 * return the sector size.
+	 */
+#ifndef DB_WINCE
+	if (LF_ISSET(DB_OSO_DIRECT) && page_size != 0 && name[0] != '\0') {
+		if (name[1] == ':') {
+			drive = dbuf;
+			_sntprintf(dbuf, sizeof(dbuf), _T("%c:\\"), tname[0]);
+		} else
+			drive = NULL;
+
+		/*
+		 * We ignore all results except sectorsize, but some versions
+		 * of Windows require that the parameters are non-NULL.
+		 */
+		if (GetDiskFreeSpace(drive, &cluster_size,
+		    &sector_size, &free_clusters, &total_clusters) &&
+		    page_size % sector_size == 0)
+			attr |= FILE_FLAG_NO_BUFFERING;
+	}
+#endif
+
+	fhp->handle = fhp->trunc_handle = INVALID_HANDLE_VALUE;
+	for (nrepeat = 1;; ++nrepeat) {
+		if (fhp->handle == INVALID_HANDLE_VALUE) {
+#ifdef DB_WINCE
+			if (LF_ISSET(DB_OSO_REGION))
+				fhp->handle = CreateFileForMapping(tname,
+				    access, share, NULL, createflag, attr, 0);
+			else
+#endif
+				fhp->handle = CreateFile(tname,
+				    access, share, NULL, createflag, attr, 0);
+		}
+
+#ifdef HAVE_FTRUNCATE
+		/*
+		 * Older versions of WinCE may not support truncate, if so, the
+		 * HAVE_FTRUNCATE macro should be #undef'ed, and we
+		 * don't need to open this second handle.
+		 *
+		 * WinCE dose not support opening a second handle on the same
+		 * file via CreateFileForMapping, but this dose not matter
+		 * since we are not truncating region files but database files.
+		 *
+		 * But some older versions of WinCE even
+		 * dose not allow a second handle opened via CreateFile. If
+		 * this is the case, users will need to #undef the
+		 * HAVE_FTRUNCATE macro in build_wince/db_config.h.
+		 */
+
+		/*
+		 * Windows does not provide truncate directly.  There is no
+		 * safe way to use a handle for truncate concurrently with
+		 * reads or writes.  To deal with this, we open a second handle
+		 * used just for truncating.
+		 */
+		if (fhp->handle != INVALID_HANDLE_VALUE &&
+		    !LF_ISSET(DB_OSO_RDONLY | DB_OSO_TEMP) &&
+		    fhp->trunc_handle == INVALID_HANDLE_VALUE
+#ifdef DB_WINCE
+		    /* Do not open trunc handle for region files. */
+		    && (!LF_ISSET(DB_OSO_REGION))
+#endif
+		    )
+			fhp->trunc_handle = CreateFile(
+			    tname, access, share, NULL, OPEN_EXISTING, attr, 0);
+#endif
+
+#ifndef HAVE_FTRUNCATE
+		if (fhp->handle == INVALID_HANDLE_VALUE)
+#else
+		if (fhp->handle == INVALID_HANDLE_VALUE ||
+		    (!LF_ISSET(DB_OSO_RDONLY | DB_OSO_TEMP) &&
+		    fhp->trunc_handle == INVALID_HANDLE_VALUE
+#ifdef DB_WINCE
+		    /* Do not open trunc handle for region files. */
+		    && (!LF_ISSET(DB_OSO_REGION))
+#endif
+		    ))
+#endif
+		{
+			/*
+			 * If it's a "temporary" error, we retry up to 3 times,
+			 * waiting up to 12 seconds.  While it's not a problem
+			 * if we can't open a database, an inability to open a
+			 * log file is cause for serious dismay.
+			 */
+			ret = __os_posix_err(__os_get_syserr());
+			if ((ret != ENFILE && ret != EMFILE && ret != ENOSPC) ||
+			    nrepeat > 3)
+				goto err;
+
+			__os_yield(env, nrepeat * 2, 0);
+		} else
+			break;
+	}
+
+	FREE_STRING(env, tname);
+
+	if (LF_ISSET(DB_OSO_REGION))
+		F_SET(fhp, DB_FH_REGION);
+	F_SET(fhp, DB_FH_OPENED);
+	*fhpp = fhp;
+	return (0);
+
+err:	FREE_STRING(env, tname);
+	if (fhp != NULL)
+		(void)__os_closehandle(env, fhp);
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_rename.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,104 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_rename --
+ *	Rename a file.
+ */
+int
+__os_rename(env, oldname, newname, silent)
+	ENV *env;
+	const char *oldname, *newname;
+	u_int32_t silent;
+{
+	DB_ENV *dbenv;
+	_TCHAR *toldname, *tnewname;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0036", "fileops: rename %s to %s",
+		    "%s %s"), oldname, newname);
+
+	TO_TSTRING(env, oldname, toldname, ret);
+	if (ret != 0)
+		return (ret);
+	TO_TSTRING(env, newname, tnewname, ret);
+	if (ret != 0) {
+		FREE_STRING(env, toldname);
+		return (ret);
+	}
+
+	LAST_PANIC_CHECK_BEFORE_IO(env);
+
+	if (!MoveFile(toldname, tnewname))
+		ret = __os_get_syserr();
+
+	if (__os_posix_err(ret) == EEXIST) {
+		ret = 0;
+#ifndef DB_WINCE
+		if (__os_is_winnt()) {
+			if (!MoveFileEx(
+			    toldname, tnewname, MOVEFILE_REPLACE_EXISTING))
+				ret = __os_get_syserr();
+		} else
+#endif
+		{
+			/*
+			 * There is no MoveFileEx for Win9x/Me/CE, so we have to
+			 * do the best we can.  Note that the MoveFile call
+			 * above would have succeeded if oldname and newname
+			 * refer to the same file, so we don't need to check
+			 * that here.
+			 */
+			(void)DeleteFile(tnewname);
+			if (!MoveFile(toldname, tnewname))
+				ret = __os_get_syserr();
+		}
+	}
+
+	FREE_STRING(env, tnewname);
+	FREE_STRING(env, toldname);
+
+	if (ret != 0) {
+		if (silent == 0)
+			__db_syserr(env, ret, DB_STR_A("0037",
+			    "MoveFileEx %s %s", "%s %s"), oldname, newname);
+		ret = __os_posix_err(ret);
+	}
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_rw.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,240 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_io --
+ *	Do an I/O.
+ */
+int
+__os_io(env, op, fhp, pgno, pgsize, relative, io_len, buf, niop)
+	ENV *env;
+	int op;
+	DB_FH *fhp;
+	db_pgno_t pgno;
+	u_int32_t pgsize, relative, io_len;
+	u_int8_t *buf;
+	size_t *niop;
+{
+	int ret;
+
+#ifndef DB_WINCE
+	if (__os_is_winnt()) {
+		DB_ENV *dbenv;
+		DWORD nbytes;
+		OVERLAPPED over;
+		ULONG64 off;
+		dbenv = env == NULL ? NULL : env->dbenv;
+		if ((off = relative) == 0)
+			off = (ULONG64)pgsize * pgno;
+		over.Offset = (DWORD)(off & 0xffffffff);
+		over.OffsetHigh = (DWORD)(off >> 32);
+		over.hEvent = 0; /* we don't want asynchronous notifications */
+
+		if (dbenv != NULL &&
+		    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+			__db_msg(env, DB_STR_A("0014",
+			    "fileops: %s %s: %lu bytes at offset %lu",
+			    "%s %s %lu %lu"), op == DB_IO_READ ?
+			    DB_STR_P("read") : DB_STR_P("write"),
+			    fhp->name, (u_long)io_len, (u_long)off);
+
+		LAST_PANIC_CHECK_BEFORE_IO(env);
+
+		switch (op) {
+		case DB_IO_READ:
+#if defined(HAVE_STATISTICS)
+			++fhp->read_count;
+#endif
+			if (!ReadFile(fhp->handle,
+			    buf, (DWORD)io_len, &nbytes, &over))
+				goto slow;
+			break;
+		case DB_IO_WRITE:
+#ifdef HAVE_FILESYSTEM_NOTZERO
+			if (__os_fs_notzero())
+				goto slow;
+#endif
+#if defined(HAVE_STATISTICS)
+			++fhp->write_count;
+#endif
+			if (!WriteFile(fhp->handle,
+			    buf, (DWORD)io_len, &nbytes, &over))
+				goto slow;
+			break;
+		}
+		if (nbytes == io_len) {
+			*niop = (size_t)nbytes;
+			return (0);
+		}
+	}
+
+slow:
+#endif
+	MUTEX_LOCK(env, fhp->mtx_fh);
+
+	if ((ret = __os_seek(env, fhp, pgno, pgsize, relative)) != 0)
+		goto err;
+
+	switch (op) {
+	case DB_IO_READ:
+		ret = __os_read(env, fhp, buf, io_len, niop);
+		break;
+	case DB_IO_WRITE:
+		ret = __os_write(env, fhp, buf, io_len, niop);
+		break;
+	}
+
+err:	MUTEX_UNLOCK(env, fhp->mtx_fh);
+
+	return (ret);
+}
+
+/*
+ * __os_read --
+ *	Read from a file handle.
+ */
+int
+__os_read(env, fhp, addr, len, nrp)
+	ENV *env;
+	DB_FH *fhp;
+	void *addr;
+	size_t len;
+	size_t *nrp;
+{
+	DB_ENV *dbenv;
+	DWORD count;
+	size_t offset, nr;
+	u_int8_t *taddr;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+	ret = 0;
+
+#if defined(HAVE_STATISTICS)
+	++fhp->read_count;
+#endif
+	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0015", "fileops: read %s: %lu bytes",
+		    "%s %lu"), fhp->name, (u_long)len);
+
+	for (taddr = addr,
+	    offset = 0; offset < len; taddr += nr, offset += nr) {
+		LAST_PANIC_CHECK_BEFORE_IO(env);
+		RETRY_CHK((!ReadFile(fhp->handle,
+		    taddr, (DWORD)(len - offset), &count, NULL)), ret);
+		if (count == 0 || ret != 0)
+			break;
+		nr = (size_t)count;
+	}
+	*nrp = taddr - (u_int8_t *)addr;
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR_A("0016",
+		    "read: 0x%lx, %lu", "%lx %lu"),
+		    P_TO_ULONG(taddr), (u_long)len - offset);
+		ret = __os_posix_err(ret);
+	}
+	return (ret);
+}
+
+/*
+ * __os_write --
+ *	Write to a file handle.
+ */
+int
+__os_write(env, fhp, addr, len, nwp)
+	ENV *env;
+	DB_FH *fhp;
+	void *addr;
+	size_t len;
+	size_t *nwp;
+{
+	int ret;
+
+#ifdef HAVE_FILESYSTEM_NOTZERO
+	/* Zero-fill as necessary. */
+	if (__os_fs_notzero() &&
+	    (ret = __db_zero_fill(env, fhp)) != 0)
+		return (ret);
+#endif
+	return (__os_physwrite(env, fhp, addr, len, nwp));
+}
+
+/*
+ * __os_physwrite --
+ *	Physical write to a file handle.
+ */
+int
+__os_physwrite(env, fhp, addr, len, nwp)
+	ENV *env;
+	DB_FH *fhp;
+	void *addr;
+	size_t len;
+	size_t *nwp;
+{
+	DB_ENV *dbenv;
+	DWORD count;
+	size_t offset, nw;
+	u_int8_t *taddr;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+	ret = 0;
+
+#if defined(HAVE_STATISTICS)
+	++fhp->write_count;
+#endif
+	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0017", "fileops: write %s: %lu bytes",
+		    "%s %lu"), fhp->name, (u_long)len);
+
+	for (taddr = addr,
+	    offset = 0; offset < len; taddr += nw, offset += nw) {
+		LAST_PANIC_CHECK_BEFORE_IO(env);
+		RETRY_CHK((!WriteFile(fhp->handle,
+		    taddr, (DWORD)(len - offset), &count, NULL)), ret);
+		if (ret != 0)
+			break;
+		nw = (size_t)count;
+	}
+	*nwp = len;
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR_A("0018",
+		    "write: %#lx, %lu", "%#lx %lu"),
+		    P_TO_ULONG(taddr), (u_long)len - offset);
+		ret = __os_posix_err(ret);
+
+		DB_EVENT(env, DB_EVENT_WRITE_FAILED, NULL);
+	}
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_seek.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,89 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_seek --
+ *	Seek to a page/byte offset in the file.
+ */
+int
+__os_seek(env, fhp, pgno, pgsize, relative)
+	ENV *env;
+	DB_FH *fhp;
+	db_pgno_t pgno;
+	u_int32_t pgsize;
+	off_t relative;
+{
+	/* Yes, this really is how Microsoft designed their API. */
+	union {
+		__int64 bigint;
+		struct {
+			unsigned long low;
+			long high;
+		};
+	} offbytes;
+	DB_ENV *dbenv;
+	off_t offset;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+#if defined(HAVE_STATISTICS)
+	++fhp->seek_count;
+#endif
+
+	offset = (off_t)pgsize * pgno + relative;
+
+	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0038",
+		    "fileops: seek %s to %lu", "%s %lu"),
+		    fhp->name, (u_long)offset);
+
+	offbytes.bigint = offset;
+	ret = (SetFilePointer(fhp->handle, offbytes.low,
+	    &offbytes.high, FILE_BEGIN) == (DWORD)-1) ? __os_get_syserr() : 0;
+
+	if (ret == 0) {
+		fhp->pgsize = pgsize;
+		fhp->pgno = pgno;
+		fhp->offset = relative;
+	} else {
+		__db_syserr(env, ret, DB_STR_A("0039",
+		    "seek: %lu: (%lu * %lu) + %lu", "%lu %lu %lu %lu"),
+		    (u_long)offset, (u_long)pgno,
+		    (u_long)pgsize, (u_long)relative);
+		ret = __os_posix_err(ret);
+	}
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_stat.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,253 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * Raw data reads must be done in multiples of the disk sector size. Currently
+ * the sector size is either 512 bytes or 4096 bytes. So we set the
+ * MAX_SECTOR_SIZE to 4096.
+ */
+#define	MAX_SECTOR_SIZE 4096
+
+/*
+ * Find the cluster size of the file system that would contain the given path.
+ * If the value can't be determined, an error is returned.
+ */
+int
+__os_get_cluster_size(path, psize)
+	const char *path;
+	u_int32_t *psize;
+{
+
+#if (WINVER < 0x500) || defined(DB_WINCE)
+	/*
+	 * WinCE and versions of Windows earlier than Windows NT don't have
+	 * the APIs required to retrieve the cluster size.
+	 */
+	*psize = DB_DEF_IOSIZE;
+	return (0);
+#else
+	BYTE clustershift, sectorshift, *pcluster;
+	char buffer[MAX_SECTOR_SIZE];
+	DWORD flags, infolen, length, mcl, name_size;
+	HANDLE vhandle;
+	int ret;
+	NTFS_VOLUME_DATA_BUFFER ntfsinfo;
+	size_t name_len;
+	TCHAR *env_path, name_buffer[MAX_PATH + 1], root_path[MAX_PATH + 1];
+	WORD *psector;
+
+	if (path == NULL || psize == NULL) {
+		return (EINVAL);
+	}
+
+	name_size = MAX_PATH + 1;
+	*psize = 0;
+
+	TO_TSTRING(NULL, path, env_path, ret);
+	if (ret != 0)
+		return (ret);
+	/* Retrieve the volume root path where the input path resides. */
+	if (!GetVolumePathName(env_path, root_path, name_size)) {
+		FREE_STRING(NULL, env_path);
+		return (__os_posix_err(__os_get_syserr()));
+	}
+	FREE_STRING(NULL, env_path);
+
+	/* Get the volume GUID name from the root path. */
+	if (!GetVolumeNameForVolumeMountPoint(
+	    root_path, name_buffer, name_size))
+		return (__os_posix_err(__os_get_syserr()));
+
+	/* Delete the last trail "\" in the GUID name. */
+	name_len = _tcsclen(name_buffer);
+	if (name_len > 0)
+		name_buffer[name_len - 1] = _T('\0');
+
+	/* Create a handle to the volume. */
+	vhandle = CreateFile(name_buffer, FILE_READ_ATTRIBUTES | FILE_READ_DATA,
+	    FILE_SHARE_READ | FILE_SHARE_WRITE,	NULL, OPEN_EXISTING,
+	    FILE_ATTRIBUTE_NORMAL, NULL);
+
+	/* If open failed, return error */
+	if (vhandle == INVALID_HANDLE_VALUE)
+		return (__os_posix_err(__os_get_syserr()));
+
+	/* Get the volume information through the root path. */
+	if (!GetVolumeInformation(root_path, NULL, name_size, NULL, &mcl,
+	    &flags, name_buffer, name_size)) {
+		ret = __os_posix_err(__os_get_syserr());
+		CloseHandle(vhandle);
+		return (ret);
+	}
+
+	ret = 0;
+	if (_tcscmp(name_buffer, _T("NTFS")) == 0) {
+		/*
+		 * If this is NTFS file system, use FSCTL_GET_NTFS_VOLUME_DATA
+		 * to get the cluster size.
+		 */
+		if (DeviceIoControl(
+		    vhandle,			/* volume handle */
+		    FSCTL_GET_NTFS_VOLUME_DATA,	/* Control Code */
+		    NULL,			/* not use */
+		    0,				/* not use */
+		    &ntfsinfo,			/* output buffer */
+		    sizeof(NTFS_VOLUME_DATA_BUFFER),/* output buffer length */
+		    &infolen,			/* number of returned bytes */
+		    NULL))			/* ignore here */
+			*psize = ntfsinfo.BytesPerCluster;
+		else
+			ret = __os_posix_err(__os_get_syserr());
+	} else if (_tcscmp(name_buffer, _T("exFAT")) == 0) {
+		/*
+		 * If this is exFAT file system, read the information of sector
+		 * and cluster from the BPB on sector 0
+		 * +6C H: BYTE SectorSizeShift
+		 * +6D H: BYTE ClusterShift
+		 */
+		if (ReadFile(vhandle, buffer, MAX_SECTOR_SIZE, &length, NULL)) {
+			sectorshift = *(BYTE *)(&buffer[0x6C]);
+			clustershift = *(BYTE *)(&buffer[0x6D]);
+			*psize = 1 << sectorshift;
+			*psize = (*psize) << clustershift;
+		}
+		else
+			ret = __os_posix_err(__os_get_syserr());
+	} else if (_tcscmp(name_buffer, _T("FAT")) == 0 ||
+	    _tcscmp(name_buffer, _T("FAT32")) == 0) {
+		/*
+		 * If this is FAT or FAT32 file system, read the information of
+		 * sector and cluster from the BPB on sector 0.
+		 * +0B H: WORD Bytes per Sector.
+		 * +0D H: BYTE Sectors Per Cluster.
+		 */
+		if (ReadFile(vhandle, buffer, MAX_SECTOR_SIZE, &length, NULL)) {
+			psector = (WORD *)(&buffer[0x0B]);
+			pcluster = (BYTE *)(&buffer[0x0D]);
+			*psize = (*psector) * (*pcluster);
+		}
+		else
+			ret = __os_posix_err(__os_get_syserr());
+	}
+
+	CloseHandle(vhandle);
+	return (ret);
+#endif
+}
+
+/*
+ * __os_exists --
+ *	Return if the file exists.
+ */
+int
+__os_exists(env, path, isdirp)
+	ENV *env;
+	const char *path;
+	int *isdirp;
+{
+	DB_ENV *dbenv;
+	DWORD attrs;
+	_TCHAR *tpath;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	TO_TSTRING(env, path, tpath, ret);
+	if (ret != 0)
+		return (ret);
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0033", "fileops: stat %s",
+		    "%s"), path);
+
+	RETRY_CHK(
+	    ((attrs = GetFileAttributes(tpath)) == (DWORD)-1 ? 1 : 0), ret);
+	if (ret == 0) {
+		if (isdirp != NULL)
+			*isdirp = (attrs & FILE_ATTRIBUTE_DIRECTORY);
+	} else
+		ret = __os_posix_err(ret);
+
+	FREE_STRING(env, tpath);
+	return (ret);
+}
+
+/*
+ * __os_ioinfo --
+ *	Return file size and I/O size; abstracted to make it easier
+ *	to replace.
+ */
+int
+__os_ioinfo(env, path, fhp, mbytesp, bytesp, iosizep)
+	ENV *env;
+	const char *path;
+	DB_FH *fhp;
+	u_int32_t *mbytesp, *bytesp, *iosizep;
+{
+	int ret;
+	BY_HANDLE_FILE_INFORMATION bhfi;
+	unsigned __int64 filesize;
+	u_int32_t io_sz;
+
+	RETRY_CHK((!GetFileInformationByHandle(fhp->handle, &bhfi)), ret);
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR("0034",
+		    "GetFileInformationByHandle"));
+		return (__os_posix_err(ret));
+	}
+
+	filesize = ((unsigned __int64)bhfi.nFileSizeHigh << 32) +
+	    bhfi.nFileSizeLow;
+
+	/* Return the size of the file. */
+	if (mbytesp != NULL)
+		*mbytesp = (u_int32_t)(filesize / MEGABYTE);
+	if (bytesp != NULL)
+		*bytesp = (u_int32_t)(filesize % MEGABYTE);
+
+	if (iosizep != NULL) {
+		/*
+		 * Attempt to retrieve a file system cluster size, if the
+		 * call succeeds, and the value returned is reasonable,
+		 * use it as the default page size. Otherwise use a
+		 * reasonable default value.
+		 */
+		if (__os_get_cluster_size(path, &io_sz) != 0 || io_sz < 1025)
+			*iosizep = DB_DEF_IOSIZE;
+		else
+			*iosizep = io_sz;
+	}
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_truncate.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,121 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 2004, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_truncate --
+ *	Truncate the file.
+ */
+int
+__os_truncate(env, fhp, pgno, pgsize)
+	ENV *env;
+	DB_FH *fhp;
+	db_pgno_t pgno;
+	u_int32_t pgsize;
+{
+	/* Yes, this really is how Microsoft have designed their API */
+	union {
+		__int64 bigint;
+		struct {
+			unsigned long low;
+			long high;
+		};
+	} off;
+	DB_ENV *dbenv;
+	off_t offset;
+	int ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+	offset = (off_t)pgsize * pgno;
+	ret = 0;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0021", "fileops: truncate %s to %lu",
+		    "%s %lu"), fhp->name, (u_long)offset);
+
+#ifdef HAVE_FILESYSTEM_NOTZERO
+	/*
+	 * If the filesystem doesn't zero fill, it isn't safe to extend the
+	 * file, or we end up with junk blocks.  Just return in that case.
+	 */
+	if (__os_fs_notzero()) {
+		off_t stat_offset;
+		u_int32_t mbytes, bytes;
+
+		/* Stat the file. */
+		if ((ret =
+		    __os_ioinfo(env, NULL, fhp, &mbytes, &bytes, NULL)) != 0)
+			return (ret);
+		stat_offset = (off_t)mbytes * MEGABYTE + bytes;
+
+		if (offset > stat_offset)
+			return (0);
+	}
+#endif
+
+	LAST_PANIC_CHECK_BEFORE_IO(env);
+
+	/*
+	 * Windows doesn't provide truncate directly.  Instead, it has
+	 * SetEndOfFile, which truncates to the current position.  To
+	 * deal with that, we open a duplicate file handle for truncating.
+	 *
+	 * We want to retry the truncate call, which involves a SetFilePointer
+	 * and a SetEndOfFile, but there are several complications:
+	 *
+	 * 1) since the Windows API deals in 32-bit values, it's possible that
+	 *    the return from SetFilePointer (the low 32-bits) is
+	 *    INVALID_SET_FILE_POINTER even when the call has succeeded.  So we
+	 *    have to also check whether GetLastError() returns NO_ERROR.
+	 *
+	 * 2) when it returns, SetFilePointer overwrites the high bits of the
+	 *    offset, so if we need to retry, we have to reset the offset each
+	 *    time.
+	 *
+	 * We can't switch to SetFilePointerEx, which knows about 64-bit
+	 * offsets, because it isn't supported on Win9x/ME.
+	 */
+	RETRY_CHK((off.bigint = (__int64)pgsize * pgno,
+	    (SetFilePointer(fhp->trunc_handle, off.low, &off.high, FILE_BEGIN)
+	    == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) ||
+	    !SetEndOfFile(fhp->trunc_handle)), ret);
+
+	if (ret != 0) {
+		__db_syserr(env, ret, DB_STR_A("0022", "SetFilePointer: %lu",
+		    "%lu"), pgno * pgsize);
+		ret = __os_posix_err(ret);
+	}
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_unlink.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,145 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_unlink --
+ *	Remove a file.
+ */
+int
+__os_unlink(env, path, overwrite_test)
+	ENV *env;
+	const char *path;
+	int overwrite_test;
+{
+	DB_ENV *dbenv;
+	HANDLE h;
+	_TCHAR *tpath, *orig_tpath, buf[DB_MAXPATHLEN];
+	u_int32_t id;
+	int ret, t_ret;
+
+	dbenv = env == NULL ? NULL : env->dbenv;
+
+	if (dbenv != NULL &&
+	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+		__db_msg(env, DB_STR_A("0028", "fileops: unlink %s",
+		    "%s"), path);
+
+	/* Optionally overwrite the contents of the file to enhance security. */
+	if (dbenv != NULL && overwrite_test && F_ISSET(dbenv, DB_ENV_OVERWRITE))
+		(void)__db_file_multi_write(env, path);
+
+	TO_TSTRING(env, path, tpath, ret);
+	if (ret != 0)
+		return (ret);
+	orig_tpath = tpath;
+
+	LAST_PANIC_CHECK_BEFORE_IO(env);
+
+	/*
+	 * Windows NT and its descendants allow removal of open files, but the
+	 * DeleteFile Win32 system call isn't equivalent to a POSIX unlink.
+	 * Firstly, it only succeeds if FILE_SHARE_DELETE is set when the file
+	 * is opened.  Secondly, it leaves the file in a "zombie" state, where
+	 * it can't be opened again, but a new file with the same name can't be
+	 * created either.
+	 *
+	 * Since we depend on being able to recreate files (during recovery,
+	 * say), we have to first rename the file, and then delete it.  It
+	 * still hangs around, but with a name we don't care about.  The rename
+	 * will fail if the file doesn't exist, which isn't a problem, but if
+	 * it fails for some other reason, we need to know about it or a
+	 * subsequent open may fail for no apparent reason.
+	 */
+	if (__os_is_winnt()) {
+		__os_unique_id(env, &id);
+		_sntprintf(buf, DB_MAXPATHLEN, _T("%s.del.%010u"), tpath, id);
+		if (MoveFile(tpath, buf))
+			tpath = buf;
+		else {
+			ret = __os_get_syserr();
+			if (__os_posix_err(ret) != ENOENT)
+				/*
+				 * System doesn't always return ENOENT when
+				 * file is missing. So we need a double check
+				 * here. Set the return value to ENOENT when
+				 * file doesn't exist.
+				 */
+				if (__os_exists(env, path, NULL) == 0)
+					__db_err(env, ret, DB_STR_A("0029",
+					    "MoveFile: "
+					    "rename %s to temporary file",
+					    "%s"), path);
+				else
+					ret = ENOENT;
+		}
+
+		/*
+		 * Try removing the file using the delete-on-close flag.  This
+		 * plays nicer with files that are still open than DeleteFile.
+		 */
+		h = CreateFile(tpath, 0,
+		    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+		    NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
+		if (h != INVALID_HANDLE_VALUE) {
+			(void)CloseHandle (h);
+			if (GetFileAttributes(tpath) == INVALID_FILE_ATTRIBUTES)
+				goto skipdel;
+		}
+	}
+
+	RETRY_CHK((!DeleteFile(tpath)), ret);
+
+skipdel:
+	FREE_STRING(env, orig_tpath);
+
+	/*
+	 * XXX
+	 * We shouldn't be testing for an errno of ENOENT here, but ENOENT
+	 * signals that a file is missing, and we attempt to unlink things
+	 * (such as v. 2.x environment regions, in ENV->remove) that we
+	 * are expecting not to be there.  Reporting errors in these cases
+	 * is annoying.
+	 */
+	if ((ret != 0) && (t_ret = __os_posix_err(ret)) != ENOENT) {
+		/* Double check if the file exists. */
+		if (__os_exists(env, path, NULL) == 0) {
+			__db_syserr(env, ret, DB_STR_A("0030",
+			    "DeleteFile: %s", "%s"), path);
+			ret = t_ret;
+		} else
+			ret = ENOENT;
+	}
+
+	return (ret);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/os_windows/os_yield.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,57 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_yield --
+ *	Yield the processor, optionally pausing until running again.
+ */
+void
+__os_yield(env, secs, usecs)
+	ENV *env;
+	u_long secs, usecs;		/* Seconds and microseconds. */
+{
+	COMPQUIET(env, NULL);
+
+	/* Don't require the values be normalized. */
+	for (; usecs >= US_PER_SEC; usecs -= US_PER_SEC)
+		++secs;
+
+	/*
+	 * Yield the processor so other processes or threads can run.
+	 *
+	 * Sheer raving paranoia -- don't sleep for 0 time, in case some
+	 * implementation doesn't yield the processor in that case.
+	 */
+	Sleep(secs * MS_PER_SEC + (usecs / US_PER_MS) + 1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/qam/qam_stub.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,361 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef	HAVE_QUEUE
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/qam.h"
+
+/*
+ * If the library wasn't compiled with the Queue access method, various
+ * routines aren't available.  Stub them here, returning an appropriate
+ * error.
+ */
+
+/*
+ * __db_no_queue_am --
+ *	Error when a Berkeley DB build doesn't include the access method.
+ *
+ * PUBLIC: int __db_no_queue_am __P((ENV *));
+ */
+int
+__db_no_queue_am(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("1145",
+    "library build did not include support for the Queue access method"));
+	return (DB_OPNOTSUP);
+}
+
+int
+__db_prqueue(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_31_qammeta(dbp, real_name, buf)
+	DB *dbp;
+	char *real_name;
+	u_int8_t *buf;
+{
+	COMPQUIET(real_name, NULL);
+	COMPQUIET(buf, NULL);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_32_qammeta(dbp, real_name, buf)
+	DB *dbp;
+	char *real_name;
+	u_int8_t *buf;
+{
+	COMPQUIET(real_name, NULL);
+	COMPQUIET(buf, NULL);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_append(dbc, key, data)
+	DBC *dbc;
+	DBT *key, *data;
+{
+	COMPQUIET(key, NULL);
+	COMPQUIET(data, NULL);
+	return (__db_no_queue_am(dbc->env));
+}
+
+int
+__qamc_dup(orig_dbc, new_dbc)
+	DBC *orig_dbc, *new_dbc;
+{
+	COMPQUIET(new_dbc, NULL);
+	return (__db_no_queue_am(orig_dbc->env));
+}
+
+int
+__qamc_init(dbc)
+	DBC *dbc;
+{
+	return (__db_no_queue_am(dbc->env));
+}
+
+int
+__qam_db_close(dbp, flags)
+	DB *dbp;
+	u_int32_t flags;
+{
+	COMPQUIET(dbp, NULL);
+	COMPQUIET(flags, 0);
+	return (0);
+}
+
+int
+__qam_db_create(dbp)
+	DB *dbp;
+{
+	COMPQUIET(dbp, NULL);
+	return (0);
+}
+
+int
+__qam_extent_names(env, name, namelistp)
+	ENV *env;
+	char *name;
+	char ***namelistp;
+{
+	COMPQUIET(name, NULL);
+	COMPQUIET(namelistp, NULL);
+	return (__db_no_queue_am(env));
+}
+
+int
+__qam_gen_filelist(dbp, ip, filelistp)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	QUEUE_FILELIST **filelistp;
+{
+	COMPQUIET(ip, NULL);
+	COMPQUIET(filelistp, NULL);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_init_print(env, dtabp)
+	ENV *env;
+	DB_DISTAB *dtabp;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(dtabp, NULL);
+	return (0);
+}
+
+int
+__qam_init_recover(env, dtabp)
+	ENV *env;
+	DB_DISTAB *dtabp;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(dtabp, NULL);
+	return (0);
+}
+
+int
+__qam_metachk(dbp, name, qmeta)
+	DB *dbp;
+	const char *name;
+	QMETA *qmeta;
+{
+	COMPQUIET(name, NULL);
+	COMPQUIET(qmeta, NULL);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_mswap(env, pg)
+	ENV *env;
+	PAGE *pg;
+{
+	COMPQUIET(pg, NULL);
+	return (__db_no_queue_am(env));
+}
+
+int
+__qam_new_file(dbp, ip, txn, fhp, name)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	DB_FH *fhp;
+	const char *name;
+{
+	COMPQUIET(ip, NULL);
+	COMPQUIET(txn, NULL);
+	COMPQUIET(fhp, NULL);
+	COMPQUIET(name, NULL);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_open(dbp, ip, txn, name, base_pgno, mode, flags)
+	DB *dbp;
+	DB_THREAD_INFO *ip;
+	DB_TXN *txn;
+	const char *name;
+	db_pgno_t base_pgno;
+	int mode;
+	u_int32_t flags;
+{
+	COMPQUIET(ip, NULL);
+	COMPQUIET(txn, NULL);
+	COMPQUIET(name, NULL);
+	COMPQUIET(base_pgno, 0);
+	COMPQUIET(mode, 0);
+	COMPQUIET(flags, 0);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_pgin_out(env, pg, pp, cookie)
+	ENV *env;
+	db_pgno_t pg;
+	void *pp;
+	DBT *cookie;
+{
+	COMPQUIET(pg, 0);
+	COMPQUIET(pp, NULL);
+	COMPQUIET(cookie, NULL);
+	return (__db_no_queue_am(env));
+}
+
+int
+__qam_salvage(dbp, vdp, pgno, h, handle, callback, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	db_pgno_t pgno;
+	PAGE *h;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(h, NULL);
+	COMPQUIET(handle, NULL);
+	COMPQUIET(callback, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_set_ext_data(dbp, name)
+	DB *dbp;
+	const char *name;
+{
+	COMPQUIET(name, NULL);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_stat(dbc, spp, flags)
+	DBC *dbc;
+	void *spp;
+	u_int32_t flags;
+{
+	COMPQUIET(spp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_no_queue_am(dbc->env));
+}
+
+int
+__qam_stat_print(dbc, flags)
+	DBC *dbc;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_no_queue_am(dbc->env));
+}
+
+int
+__qam_sync(dbp)
+	DB *dbp;
+{
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_truncate(dbc, countp)
+	DBC *dbc;
+	u_int32_t *countp;
+{
+	COMPQUIET(countp, NULL);
+	return (__db_no_queue_am(dbc->env));
+}
+
+int
+__qam_vrfy_data(dbp, vdp, h, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	QPAGE *h;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(h, NULL);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(flags, 0);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_vrfy_meta(dbp, vdp, meta, pgno, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	QMETA *meta;
+	db_pgno_t pgno;
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(meta, NULL);
+	COMPQUIET(pgno, 0);
+	COMPQUIET(flags, 0);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_vrfy_structure(dbp, vdp, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_no_queue_am(dbp->env));
+}
+
+int
+__qam_vrfy_walkqueue(dbp, vdp, handle, callback, flags)
+	DB *dbp;
+	VRFY_DBINFO *vdp;
+	void *handle;
+	int (*callback) __P((void *, const void *));
+	u_int32_t flags;
+{
+	COMPQUIET(vdp, NULL);
+	COMPQUIET(handle, NULL);
+	COMPQUIET(callback, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_no_queue_am(dbp->env));
+}
+#endif	/* !HAVE_QUEUE */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/rep/rep_stub.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,447 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef HAVE_REPLICATION
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+
+/*
+ * If the library wasn't compiled with replication support, various routines
+ * aren't available.  Stub them here, returning an appropriate error.
+ */
+static int __db_norep __P((ENV *));
+
+/*
+ * __db_norep --
+ *	Error when a Berkeley DB build doesn't include replication support.
+ */
+static int
+__db_norep(env)
+	ENV *env;
+{
+	__db_errx(env, DB_STR("3581",
+	    "library build did not include support for replication"));
+	return (DB_OPNOTSUP);
+}
+
+int
+__db_rep_enter(dbp, checkgen, checklock, return_now)
+	DB *dbp;
+	int checkgen, checklock, return_now;
+{
+	COMPQUIET(checkgen, 0);
+	COMPQUIET(checklock, 0);
+	COMPQUIET(return_now, 0);
+	return (__db_norep(dbp->env));
+}
+
+int
+__env_rep_enter(env, checklock)
+	ENV *env;
+	int checklock;
+{
+	COMPQUIET(checklock, 0);
+	return (__db_norep(env));
+}
+
+int
+__env_db_rep_exit(env)
+	ENV *env;
+{
+	return (__db_norep(env));
+}
+
+int
+__op_rep_enter(env, local_nowait, obey_user)
+	ENV *env;
+	int local_nowait, obey_user;
+{
+	COMPQUIET(local_nowait, 0);
+	COMPQUIET(obey_user, 0);
+	return (__db_norep(env));
+}
+
+int
+__op_rep_exit(env)
+	ENV *env;
+{
+	return (__db_norep(env));
+}
+
+int
+__archive_rep_enter(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+int
+__archive_rep_exit(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+int
+__rep_bulk_message(env, bulkp, repth, lsnp, dbt, flags)
+	ENV *env;
+	REP_BULK *bulkp;
+	REP_THROTTLE *repth;
+	DB_LSN *lsnp;
+	const DBT *dbt;
+	u_int32_t flags;
+{
+	COMPQUIET(bulkp, NULL);
+	COMPQUIET(repth, NULL);
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(dbt, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_norep(env));
+}
+
+int
+__rep_env_refresh(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+int
+__rep_elect_pp(dbenv, nsites, nvotes, flags)
+	DB_ENV *dbenv;
+	u_int32_t nsites, nvotes;
+	u_int32_t flags;
+{
+	COMPQUIET(nsites, 0);
+	COMPQUIET(nvotes, 0);
+	COMPQUIET(flags, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_flush(dbenv)
+	DB_ENV *dbenv;
+{
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_lease_check(env, refresh)
+	ENV *env;
+	int refresh;
+{
+	COMPQUIET(refresh, 0);
+	return (__db_norep(env));
+}
+
+int
+__rep_lease_expire(env)
+	ENV *env;
+{
+	return (__db_norep(env));
+}
+
+void
+__rep_msg(env, msg)
+	const ENV *env;
+	const char *msg;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(msg, NULL);
+	return;
+}
+
+int
+__rep_get_clockskew(dbenv, fast_clockp, slow_clockp)
+	DB_ENV *dbenv;
+	u_int32_t *fast_clockp, *slow_clockp;
+{
+	COMPQUIET(fast_clockp, NULL);
+	COMPQUIET(slow_clockp, NULL);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_set_clockskew(dbenv, fast_clock, slow_clock)
+	DB_ENV *dbenv;
+	u_int32_t fast_clock, slow_clock;
+{
+	COMPQUIET(fast_clock, 0);
+	COMPQUIET(slow_clock, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_set_nsites_pp(dbenv, n)
+	DB_ENV *dbenv;
+	u_int32_t n;
+{
+	COMPQUIET(n, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_get_nsites(dbenv, n)
+	DB_ENV *dbenv;
+	u_int32_t *n;
+{
+	COMPQUIET(n, NULL);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_set_priority(dbenv, priority)
+	DB_ENV *dbenv;
+	u_int32_t priority;
+{
+	COMPQUIET(priority, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_get_priority(dbenv, priority)
+	DB_ENV *dbenv;
+	u_int32_t *priority;
+{
+	COMPQUIET(priority, NULL);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_set_timeout(dbenv, which, timeout)
+	DB_ENV *dbenv;
+	int which;
+	db_timeout_t timeout;
+{
+	COMPQUIET(which, 0);
+	COMPQUIET(timeout, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_get_timeout(dbenv, which, timeout)
+	DB_ENV *dbenv;
+	int which;
+	db_timeout_t *timeout;
+{
+	COMPQUIET(which, 0);
+	COMPQUIET(timeout, NULL);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_get_config(dbenv, which, onp)
+	DB_ENV *dbenv;
+	u_int32_t which;
+	int *onp;
+{
+	COMPQUIET(which, 0);
+	COMPQUIET(onp, NULL);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_set_config(dbenv, which, on)
+	DB_ENV *dbenv;
+	u_int32_t which;
+	int on;
+{
+	COMPQUIET(which, 0);
+	COMPQUIET(on, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_get_limit(dbenv, gbytesp, bytesp)
+	DB_ENV *dbenv;
+	u_int32_t *gbytesp, *bytesp;
+{
+	COMPQUIET(gbytesp, NULL);
+	COMPQUIET(bytesp, NULL);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_open(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+int
+__rep_preclose(env)
+	ENV *env;
+{
+	return (__db_norep(env));
+}
+
+int
+__rep_process_message_pp(dbenv, control, rec, eid, ret_lsnp)
+	DB_ENV *dbenv;
+	DBT *control, *rec;
+	int eid;
+	DB_LSN *ret_lsnp;
+{
+	COMPQUIET(control, NULL);
+	COMPQUIET(rec, NULL);
+	COMPQUIET(eid, 0);
+	COMPQUIET(ret_lsnp, NULL);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_send_message(env, eid, rtype, lsnp, dbtp, logflags, repflags)
+	ENV *env;
+	int eid;
+	u_int32_t rtype;
+	DB_LSN *lsnp;
+	const DBT *dbtp;
+	u_int32_t logflags, repflags;
+{
+	COMPQUIET(eid, 0);
+	COMPQUIET(rtype, 0);
+	COMPQUIET(lsnp, NULL);
+	COMPQUIET(dbtp, NULL);
+	COMPQUIET(logflags, 0);
+	COMPQUIET(repflags, 0);
+	return (__db_norep(env));
+}
+
+int
+__rep_set_limit(dbenv, gbytes, bytes)
+	DB_ENV *dbenv;
+	u_int32_t gbytes, bytes;
+{
+	COMPQUIET(gbytes, 0);
+	COMPQUIET(bytes, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_set_transport_pp(dbenv, eid, f_send)
+	DB_ENV *dbenv;
+	int eid;
+	int (*f_send) __P((DB_ENV *, const DBT *, const DBT *, const DB_LSN *,
+	    int, u_int32_t));
+{
+	COMPQUIET(eid, 0);
+	COMPQUIET(f_send, NULL);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_set_request(dbenv, min, max)
+	DB_ENV *dbenv;
+	u_int32_t min, max;
+{
+	COMPQUIET(min, 0);
+	COMPQUIET(max, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_get_request(dbenv, minp, maxp)
+	DB_ENV *dbenv;
+	u_int32_t *minp, *maxp;
+{
+	COMPQUIET(minp, NULL);
+	COMPQUIET(maxp, NULL);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_start_pp(dbenv, dbt, flags)
+	DB_ENV *dbenv;
+	DBT *dbt;
+	u_int32_t flags;
+{
+	COMPQUIET(dbt, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_stat_pp(dbenv, statp, flags)
+	DB_ENV *dbenv;
+	DB_REP_STAT **statp;
+	u_int32_t flags;
+{
+	COMPQUIET(statp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_stat_print_pp(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_stat_print(env, flags)
+	ENV *env;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_norep(env));
+}
+
+int
+__rep_sync(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_norep(dbenv->env));
+}
+
+int
+__rep_txn_applied(env, ip, commit_info, timeout)
+	ENV *env;
+	DB_THREAD_INFO *ip;
+	DB_COMMIT_INFO *commit_info;
+	db_timeout_t timeout;
+{
+	COMPQUIET(ip, 0);
+	COMPQUIET(commit_info, NULL);
+	COMPQUIET(timeout, 0);
+	return (__db_norep(env));
+}
+#endif /* !HAVE_REPLICATION */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/repmgr/repmgr_stub.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,284 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef HAVE_REPLICATION_THREADS
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * If the library wasn't compiled with replication support, various routines
+ * aren't available.  Stub them here, returning an appropriate error.
+ */
+static int __db_norepmgr __P((DB_ENV *));
+
+/*
+ * __db_norepmgr --
+ *	Error when a Berkeley DB build doesn't include replication mgr support.
+ */
+static int
+__db_norepmgr(dbenv)
+	DB_ENV *dbenv;
+{
+	__db_errx(dbenv->env, DB_STR("3628",
+    "library build did not include support for the Replication Manager"));
+	return (DB_OPNOTSUP);
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_close __P((ENV *));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_close(env)
+	ENV *env;
+{
+	COMPQUIET(env, NULL);
+	return (0);
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_get_ack_policy __P((DB_ENV *, int *));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_get_ack_policy(dbenv, policy)
+	DB_ENV *dbenv;
+	int *policy;
+{
+	COMPQUIET(policy, NULL);
+	return (__db_norepmgr(dbenv));
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_set_ack_policy __P((DB_ENV *, int));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_set_ack_policy(dbenv, policy)
+	DB_ENV *dbenv;
+	int policy;
+{
+	COMPQUIET(policy, 0);
+	return (__db_norepmgr(dbenv));
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_site
+ * PUBLIC:     __P((DB_ENV *, const char *, u_int, DB_SITE **, u_int32_t));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_site(dbenv, host, port, dbsitep, flags)
+	DB_ENV *dbenv;
+	const char *host;
+	u_int port;
+	DB_SITE **dbsitep;
+	u_int32_t flags;
+{
+	COMPQUIET(host, NULL);
+	COMPQUIET(port, 0);
+	COMPQUIET(dbsitep, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_norepmgr(dbenv));
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_site_by_eid __P((DB_ENV *, int, DB_SITE **));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_site_by_eid(dbenv, eid, dbsitep)
+	DB_ENV *dbenv;
+	int eid;
+	DB_SITE **dbsitep;
+{
+	COMPQUIET(eid, 0);
+	COMPQUIET(dbsitep, NULL);
+	return (__db_norepmgr(dbenv));
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_local_site
+ * PUBLIC:     __P((DB_ENV *, DB_SITE **));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_local_site(dbenv, dbsitep)
+	DB_ENV *dbenv;
+	DB_SITE **dbsitep;
+{
+	COMPQUIET(dbsitep, NULL);
+	return (__db_norepmgr(dbenv));
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_site_list __P((DB_ENV *, u_int *, DB_REPMGR_SITE **));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_site_list(dbenv, countp, listp)
+	DB_ENV *dbenv;
+	u_int *countp;
+	DB_REPMGR_SITE **listp;
+{
+	COMPQUIET(countp, NULL);
+	COMPQUIET(listp, NULL);
+	return (__db_norepmgr(dbenv));
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_start __P((DB_ENV *, int, u_int32_t));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_start(dbenv, nthreads, flags)
+	DB_ENV *dbenv;
+	int nthreads;
+	u_int32_t flags;
+{
+	COMPQUIET(nthreads, 0);
+	COMPQUIET(flags, 0);
+	return (__db_norepmgr(dbenv));
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_stat_pp __P((DB_ENV *, DB_REPMGR_STAT **, u_int32_t));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_stat_pp(dbenv, statp, flags)
+	DB_ENV *dbenv;
+	DB_REPMGR_STAT **statp;
+	u_int32_t flags;
+{
+	COMPQUIET(statp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_norepmgr(dbenv));
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_stat_print_pp __P((DB_ENV *, u_int32_t));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_stat_print_pp(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	COMPQUIET(flags, 0);
+	return (__db_norepmgr(dbenv));
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_handle_event __P((ENV *, u_int32_t, void *));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_handle_event(env, event, info)
+	ENV *env;
+	u_int32_t event;
+	void *info;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(event, 0);
+	COMPQUIET(info, NULL);
+
+	/*
+	 * It's not an error for this function to be called.  Replication calls
+	 * this to let repmgr handle events.  If repmgr isn't part of the build,
+	 * all replication events should be forwarded to the application.
+	 */
+	return (DB_EVENT_NOT_HANDLED);
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_channel __P((DB_ENV *, int, DB_CHANNEL **, u_int32_t));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_channel(dbenv, eid, dbchannelp, flags)
+	DB_ENV *dbenv;
+	int eid;
+	DB_CHANNEL **dbchannelp;
+	u_int32_t flags;
+{
+	COMPQUIET(eid, 0);
+	COMPQUIET(dbchannelp, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_norepmgr(dbenv));
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_set_msg_dispatch __P((DB_ENV *,
+ * PUBLIC:     void (*)(DB_ENV *, DB_CHANNEL *, DBT *, u_int32_t, u_int32_t),
+ * PUBLIC:     u_int32_t));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_set_msg_dispatch(dbenv, dispatch, flags)
+	DB_ENV *dbenv;
+	void (*dispatch) __P((DB_ENV *,
+		DB_CHANNEL *, DBT *, u_int32_t, u_int32_t));
+	u_int32_t flags;
+{
+	COMPQUIET(dispatch, NULL);
+	COMPQUIET(flags, 0);
+	return (__db_norepmgr(dbenv));
+}
+
+/*
+ * PUBLIC: #ifndef HAVE_REPLICATION_THREADS
+ * PUBLIC: int __repmgr_init_recover __P((ENV *, DB_DISTAB *));
+ * PUBLIC: #endif
+ */
+int
+__repmgr_init_recover(env, dtabp)
+	ENV *env;
+	DB_DISTAB *dtabp;
+{
+	COMPQUIET(env, NULL);
+	COMPQUIET(dtabp, NULL);
+	return (0);
+}
+#endif /* !HAVE_REPLICATION_THREADS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/windows_incl/clib_port.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,304 @@
+/* DO NOT EDIT: automatically built from dist/clib_port.in.
+ *
+ * Copyright (c) 2006, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * Minimum/maximum values for various types.
+ */
+#ifndef	UINT16_MAX			/* Maximum 16-bit unsigned. */
+#define	UINT16_MAX	65535
+#endif
+#ifndef	UINT32_MAX			/* Maximum 32-bit unsigned. */
+#define	UINT32_MAX	4294967295U
+#endif
+
+#ifndef	INT_MAX
+#if SIZEOF_INT == 4
+#define	INT_MAX		2147483647
+#endif
+#if SIZEOF_INT == 8
+#define	INT_MAX		9223372036854775807
+#endif
+#endif
+
+#ifndef	INT_MIN				/* minimum (signed) int value */
+#define	INT_MIN		(-INT_MAX-1)
+#endif
+
+#ifndef	UINT_MAX			/* maximum (signed) int value */
+#if SIZEOF_INT == 4
+#define	UINT_MAX	4294967295U
+#endif
+#if SIZEOF_INT == 8
+#define	UINT_MAX	18446744073709551615U
+#endif
+#endif
+
+#ifndef	LONG_MAX			/* maximum (signed) long value */
+#if SIZEOF_LONG == 4
+#define	LONG_MAX	2147483647
+#endif
+#if SIZEOF_LONG == 8
+#define	LONG_MAX	9223372036854775807L
+#endif
+#endif
+
+#ifndef	LONG_MIN			/* minimum (signed) long value */
+#define	LONG_MIN	(-LONG_MAX-1)
+#endif
+
+#ifndef	ULONG_MAX			/* maximum (unsigned) long value */
+#if SIZEOF_LONG == 4
+#define	ULONG_MAX	4294967295U
+#endif
+#if SIZEOF_LONG == 8
+#define	ULONG_MAX	18446744073709551615UL
+#endif
+#endif
+
+#if defined(HAVE_64BIT_TYPES)
+/*
+ * Override the system's 64-bit min/max constants.  AIX's 32-bit compiler can
+ * handle 64-bit values, but the system's constants don't include the LL/ULL
+ * suffix, and so can't be compiled using the 32-bit compiler.
+ */
+#undef	INT64_MAX
+#undef	INT64_MIN
+#undef	UINT64_MAX
+
+#ifdef	DB_WIN32
+#define	INT64_MAX	_I64_MAX
+#define	INT64_MIN	_I64_MIN
+#define	UINT64_MAX	_UI64_MAX
+#else
+#define	INT64_MAX	9223372036854775807LL
+#define	INT64_MIN	(-INT64_MAX-1)
+#define	UINT64_MAX	18446744073709551615ULL
+#endif	/* DB_WIN32 */
+
+#define	INT64_FMT	"%I64d"
+#define	UINT64_FMT	"%I64u"
+#endif	/* HAVE_64BIT_TYPES */
+
+/*
+ * Exit success/failure macros.
+ */
+#ifndef	HAVE_EXIT_SUCCESS
+#define	EXIT_FAILURE	1
+#define	EXIT_SUCCESS	0
+#endif
+
+/*
+ * File modes.
+ */
+#ifdef DB_WIN32
+#ifndef S_IREAD				/* WinCE doesn't have S_IREAD. */
+#define	S_IREAD		0
+#endif
+#ifndef S_IWRITE			/* WinCE doesn't have S_IWRITE. */
+#define	S_IWRITE	0
+#endif
+#ifndef	S_IRUSR
+#define	S_IRUSR		S_IREAD		/* R for owner */
+#endif
+#ifndef	S_IWUSR
+#define	S_IWUSR		S_IWRITE	/* W for owner */
+#endif
+#ifndef	S_IXUSR
+#define	S_IXUSR		0		/* X for owner */
+#endif
+#ifndef	S_IRGRP
+#define	S_IRGRP		0		/* R for group */
+#endif
+#ifndef	S_IWGRP
+#define	S_IWGRP		0		/* W for group */
+#endif
+#ifndef	S_IXGRP
+#define	S_IXGRP		0		/* X for group */
+#endif
+#ifndef	S_IROTH
+#define	S_IROTH		0		/* R for other */
+#endif
+#ifndef	S_IWOTH
+#define	S_IWOTH		0		/* W for other */
+#endif
+#ifndef	S_IXOTH
+#define	S_IXOTH		0		/* X for other */
+#endif
+#else /* !DB_WIN32 */
+#ifndef	S_IRUSR
+#define	S_IRUSR		0000400		/* R for owner */
+#endif
+#ifndef	S_IWUSR
+#define	S_IWUSR		0000200		/* W for owner */
+#endif
+#ifndef	S_IXUSR
+#define	S_IXUSR		0000100		/* X for owner */
+#endif
+#ifndef	S_IRGRP
+#define	S_IRGRP		0000040		/* R for group */
+#endif
+#ifndef	S_IWGRP
+#define	S_IWGRP		0000020		/* W for group */
+#endif
+#ifndef	S_IXGRP
+#define	S_IXGRP		0000010		/* X for group */
+#endif
+#ifndef	S_IROTH
+#define	S_IROTH		0000004		/* R for other */
+#endif
+#ifndef	S_IWOTH
+#define	S_IWOTH		0000002		/* W for other */
+#endif
+#ifndef	S_IXOTH
+#define	S_IXOTH		0000001		/* X for other */
+#endif
+#endif /* !DB_WIN32 */
+
+/*
+ * Don't step on the namespace.  Other libraries may have their own
+ * implementations of these functions, we don't want to use their
+ * implementations or force them to use ours based on the load order.
+ */
+#ifndef	HAVE_ATOI
+#define	atoi		__db_Catoi
+#endif
+#ifndef	HAVE_ATOL
+#define	atol		__db_Catol
+#endif
+#ifndef	HAVE_BSEARCH
+#define	bsearch		__db_Cbsearch
+#endif
+#ifndef	HAVE_FCLOSE
+#define	fclose		__db_Cfclose
+#endif
+#ifndef	HAVE_FGETC
+#define	fgetc		__db_Cfgetc
+#endif
+#ifndef	HAVE_FGETS
+#define	fgets		__db_Cfgets
+#endif
+#ifndef	HAVE_FOPEN
+#define	fopen		__db_Cfopen
+#endif
+#ifndef	HAVE_FWRITE
+#define	fwrite		__db_Cfwrite
+#endif
+#ifndef	HAVE_GETADDRINFO
+#define	freeaddrinfo(a)		__db_Cfreeaddrinfo(a)
+#define	getaddrinfo(a, b, c, d)	__db_Cgetaddrinfo(a, b, c, d)
+#endif
+#ifndef	HAVE_GETCWD
+#define	getcwd		__db_Cgetcwd
+#endif
+#ifndef	HAVE_GETOPT
+#define	getopt		__db_Cgetopt
+#define	optarg		__db_Coptarg
+#define	opterr		__db_Copterr
+#define	optind		__db_Coptind
+#define	optopt		__db_Coptopt
+#define	optreset	__db_Coptreset
+#endif
+#ifndef	HAVE_ISALPHA
+#define	isalpha		__db_Cisalpha
+#endif
+#ifndef	HAVE_ISDIGIT
+#define	isdigit		__db_Cisdigit
+#endif
+#ifndef	HAVE_ISPRINT
+#define	isprint		__db_Cisprint
+#endif
+#ifndef	HAVE_ISSPACE
+#define	isspace		__db_Cisspace
+#endif
+#ifndef	HAVE_LOCALTIME
+#define	localtime	__db_Clocaltime
+#endif
+#ifndef	HAVE_MEMCMP
+#define	memcmp		__db_Cmemcmp
+#endif
+#ifndef	HAVE_MEMCPY
+#define	memcpy		__db_Cmemcpy
+#endif
+#ifndef	HAVE_MEMMOVE
+#define	memmove		__db_Cmemmove
+#endif
+#ifndef	HAVE_PRINTF
+#define	printf		__db_Cprintf
+#define	fprintf		__db_Cfprintf
+#endif
+#ifndef	HAVE_QSORT
+#define	qsort		__db_Cqsort
+#endif
+#ifndef	HAVE_RAISE
+#define	raise		__db_Craise
+#endif
+#ifndef	HAVE_RAND
+#define	rand		__db_Crand
+#define	srand		__db_Csrand
+#endif
+#ifndef	HAVE_SNPRINTF
+#define	snprintf	__db_Csnprintf
+#endif
+#ifndef	HAVE_STRCASECMP
+#define	strcasecmp	__db_Cstrcasecmp
+#define	strncasecmp	__db_Cstrncasecmp
+#endif
+#ifndef	HAVE_STRCAT
+#define	strcat		__db_Cstrcat
+#endif
+#ifndef	HAVE_STRCHR
+#define	strchr		__db_Cstrchr
+#endif
+#ifndef	HAVE_STRDUP
+#define	strdup		__db_Cstrdup
+#endif
+#ifndef	HAVE_STRERROR
+#define	strerror	__db_Cstrerror
+#endif
+#ifndef	HAVE_STRNCAT
+#define	strncat		__db_Cstrncat
+#endif
+#ifndef	HAVE_STRNCMP
+#define	strncmp		__db_Cstrncmp
+#endif
+#ifndef	HAVE_STRRCHR
+#define	strrchr		__db_Cstrrchr
+#endif
+#ifndef	HAVE_STRSEP
+#define	strsep		__db_Cstrsep
+#endif
+#ifndef	HAVE_STRTOL
+#define	strtol		__db_Cstrtol
+#endif
+#ifndef	HAVE_STRTOUL
+#define	strtoul		__db_Cstrtoul
+#endif
+#ifndef	HAVE_TIME
+#define	time		__db_Ctime
+#endif
+#ifndef	HAVE_VSNPRINTF
+#define	vsnprintf	__db_Cvsnprintf
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/windows_incl/db.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,3221 @@
+/* DO NOT EDIT: automatically built by dist/s_windows. */
+/*
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ *
+ * db.h include file layout:
+ *	General.
+ *	Database Environment.
+ *	Locking subsystem.
+ *	Logging subsystem.
+ *	Shared buffer cache (mpool) subsystem.
+ *	Transaction subsystem.
+ *	Access methods.
+ *	Access method cursors.
+ *	Dbm/Ndbm, Hsearch historic interfaces.
+ */
+
+#ifndef _DB_H_
+#define	_DB_H_
+
+#ifndef	__NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+#include <stddef.h>
+#include <stdio.h>
+#endif
+
+/*
+ * Turn off inappropriate compiler warnings
+ */
+#ifdef _MSC_VER
+/*
+ * This warning is explicitly disabled in Visual C++ by default.
+ * It is necessary to explicitly enable the /Wall flag to generate this
+ * warning.
+ * Since this is a shared include file it should compile without warnings
+ * at the highest warning level, so third party applications can use
+ * higher warning levels cleanly.
+ *
+ * 4820: 'bytes' bytes padding added after member 'member'
+ *       The type and order of elements caused the compiler to
+ *       add padding to the end of a struct.
+ */
+#pragma warning(push)
+#pragma warning(disable: 4820)
+#endif /* _MSC_VER */
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+#undef __P
+#define	__P(protos)	protos
+
+/*
+ * Berkeley DB version information.
+ */
+#define	DB_VERSION_FAMILY	11
+#define	DB_VERSION_RELEASE	2
+#define	DB_VERSION_MAJOR	5
+#define	DB_VERSION_MINOR	4
+#define	DB_VERSION_PATCH	0
+#define	DB_VERSION_STRING	"Berkeley DB 5.4.0: (May  7, 2012)"
+#define	DB_VERSION_FULL_STRING	"Berkeley DB 11g Release 2, library version 11.2.5.4.0: (May  7, 2012)"
+
+/*
+ * !!!
+ * Berkeley DB uses specifically sized types.  If they're not provided by
+ * the system, typedef them here.
+ *
+ * We protect them against multiple inclusion using __BIT_TYPES_DEFINED__,
+ * as does BIND and Kerberos, since we don't know for sure what #include
+ * files the user is using.
+ *
+ * !!!
+ * We also provide the standard u_int, u_long etc., if they're not provided
+ * by the system.
+ */
+#ifndef	__BIT_TYPES_DEFINED__
+#define	__BIT_TYPES_DEFINED__
+typedef unsigned char u_int8_t;
+typedef short int16_t;
+typedef unsigned short u_int16_t;
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 u_int64_t;
+#endif
+
+#ifndef _WINSOCKAPI_
+typedef unsigned char u_char;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+#endif
+typedef unsigned short u_short;
+
+/*
+ * Missing ANSI types.
+ *
+ * uintmax_t --
+ * Largest unsigned type, used to align structures in memory.  We don't store
+ * floating point types in structures, so integral types should be sufficient
+ * (and we don't have to worry about systems that store floats in other than
+ * power-of-2 numbers of bytes).  Additionally this fixes compilers that rewrite
+ * structure assignments and ANSI C memcpy calls to be in-line instructions
+ * that happen to require alignment.
+ *
+ * uintptr_t --
+ * Unsigned type that's the same size as a pointer.  There are places where
+ * DB modifies pointers by discarding the bottom bits to guarantee alignment.
+ * We can't use uintmax_t, it may be larger than the pointer, and compilers
+ * get upset about that.  So far we haven't run on any machine where there's
+ * no unsigned type the same size as a pointer -- here's hoping.
+ */
+#if defined(_MSC_VER) && _MSC_VER < 1300
+typedef u_int32_t uintmax_t;
+#else
+typedef u_int64_t uintmax_t;
+#endif
+#ifdef _WIN64
+typedef u_int64_t uintptr_t;
+#else
+typedef u_int32_t uintptr_t;
+#endif
+
+/*
+ * Windows defines off_t to long (i.e., 32 bits).  We need to pass 64-bit
+ * file offsets, so we declare our own.
+ */
+#define	off_t	__db_off_t
+typedef int64_t off_t;
+typedef int32_t pid_t;
+#ifdef HAVE_MIXED_SIZE_ADDRESSING
+typedef u_int32_t db_size_t;
+#else
+typedef size_t db_size_t;
+#endif
+#ifdef _WIN64
+typedef int64_t ssize_t;
+#else
+typedef int32_t ssize_t;
+#endif
+#ifdef HAVE_MIXED_SIZE_ADDRESSING
+typedef int32_t db_ssize_t;
+#else
+typedef ssize_t db_ssize_t;
+#endif
+
+/*
+ * Sequences are only available on machines with 64-bit integral types.
+ */
+typedef int64_t db_seq_t;
+
+/* Thread and process identification. */
+typedef u_int32_t db_threadid_t;
+
+/* Basic types that are exported or quasi-exported. */
+typedef	u_int32_t	db_pgno_t;	/* Page number type. */
+typedef	u_int16_t	db_indx_t;	/* Page offset type. */
+#define	DB_MAX_PAGES	0xffffffff	/* >= # of pages in a file */
+
+typedef	u_int32_t	db_recno_t;	/* Record number type. */
+#define	DB_MAX_RECORDS	0xffffffff	/* >= # of records in a tree */
+
+typedef u_int32_t	db_timeout_t;	/* Type of a timeout. */
+
+/*
+ * Region offsets are the difference between a pointer in a region and the
+ * region's base address.  With private environments, both addresses are the
+ * result of calling malloc, and we can't assume anything about what malloc
+ * will return, so region offsets have to be able to hold differences between
+ * arbitrary pointers.
+ */
+typedef	db_size_t	roff_t;
+
+/*
+ * Forward structure declarations, so we can declare pointers and
+ * applications can get type checking.
+ */
+struct __channel;	typedef struct __channel CHANNEL;
+struct __db;		typedef struct __db DB;
+struct __db_bt_stat;	typedef struct __db_bt_stat DB_BTREE_STAT;
+struct __db_channel;	typedef struct __db_channel DB_CHANNEL;
+struct __db_cipher;	typedef struct __db_cipher DB_CIPHER;
+struct __db_compact;	typedef struct __db_compact DB_COMPACT;
+struct __db_dbt;	typedef struct __db_dbt DBT;
+struct __db_distab;	typedef struct __db_distab DB_DISTAB;
+struct __db_env;	typedef struct __db_env DB_ENV;
+struct __db_h_stat;	typedef struct __db_h_stat DB_HASH_STAT;
+struct __db_heap_rid;	typedef struct __db_heap_rid DB_HEAP_RID;
+struct __db_heap_stat;	typedef struct __db_heap_stat DB_HEAP_STAT;
+struct __db_ilock;	typedef struct __db_ilock DB_LOCK_ILOCK;
+struct __db_lock_hstat;	typedef struct __db_lock_hstat DB_LOCK_HSTAT;
+struct __db_lock_pstat;	typedef struct __db_lock_pstat DB_LOCK_PSTAT;
+struct __db_lock_stat;	typedef struct __db_lock_stat DB_LOCK_STAT;
+struct __db_lock_u;	typedef struct __db_lock_u DB_LOCK;
+struct __db_locker;	typedef struct __db_locker DB_LOCKER;
+struct __db_lockreq;	typedef struct __db_lockreq DB_LOCKREQ;
+struct __db_locktab;	typedef struct __db_locktab DB_LOCKTAB;
+struct __db_log;	typedef struct __db_log DB_LOG;
+struct __db_log_cursor;	typedef struct __db_log_cursor DB_LOGC;
+struct __db_log_stat;	typedef struct __db_log_stat DB_LOG_STAT;
+struct __db_lsn;	typedef struct __db_lsn DB_LSN;
+struct __db_mpool;	typedef struct __db_mpool DB_MPOOL;
+struct __db_mpool_fstat;typedef struct __db_mpool_fstat DB_MPOOL_FSTAT;
+struct __db_mpool_stat;	typedef struct __db_mpool_stat DB_MPOOL_STAT;
+struct __db_mpoolfile;	typedef struct __db_mpoolfile DB_MPOOLFILE;
+struct __db_mutex_stat;	typedef struct __db_mutex_stat DB_MUTEX_STAT;
+struct __db_mutex_t;	typedef struct __db_mutex_t DB_MUTEX;
+struct __db_mutexmgr;	typedef struct __db_mutexmgr DB_MUTEXMGR;
+struct __db_preplist;	typedef struct __db_preplist DB_PREPLIST;
+struct __db_qam_stat;	typedef struct __db_qam_stat DB_QUEUE_STAT;
+struct __db_rep;	typedef struct __db_rep DB_REP;
+struct __db_rep_stat;	typedef struct __db_rep_stat DB_REP_STAT;
+struct __db_repmgr_conn_err;
+	typedef struct __db_repmgr_conn_err DB_REPMGR_CONN_ERR;
+struct __db_repmgr_site;typedef struct __db_repmgr_site DB_REPMGR_SITE;
+struct __db_repmgr_stat;typedef struct __db_repmgr_stat DB_REPMGR_STAT;
+struct __db_seq_record; typedef struct __db_seq_record DB_SEQ_RECORD;
+struct __db_seq_stat;	typedef struct __db_seq_stat DB_SEQUENCE_STAT;
+struct __db_site;	typedef struct __db_site DB_SITE;
+struct __db_sequence;	typedef struct __db_sequence DB_SEQUENCE;
+struct __db_thread_info;typedef struct __db_thread_info DB_THREAD_INFO;
+struct __db_txn;	typedef struct __db_txn DB_TXN;
+struct __db_txn_active;	typedef struct __db_txn_active DB_TXN_ACTIVE;
+struct __db_txn_stat;	typedef struct __db_txn_stat DB_TXN_STAT;
+struct __db_txn_token;	typedef struct __db_txn_token DB_TXN_TOKEN;
+struct __db_txnmgr;	typedef struct __db_txnmgr DB_TXNMGR;
+struct __dbc;		typedef struct __dbc DBC;
+struct __dbc_internal;	typedef struct __dbc_internal DBC_INTERNAL;
+struct __env;		typedef struct __env ENV;
+struct __fh_t;		typedef struct __fh_t DB_FH;
+struct __fname;		typedef struct __fname FNAME;
+struct __key_range;	typedef struct __key_range DB_KEY_RANGE;
+struct __mpoolfile;	typedef struct __mpoolfile MPOOLFILE;
+struct __db_logvrfy_config;
+typedef struct __db_logvrfy_config DB_LOG_VERIFY_CONFIG;
+
+/*
+ * The Berkeley DB API flags are automatically-generated -- the following flag
+ * names are no longer used, but remain for compatibility reasons.
+ */
+#define	DB_DEGREE_2	      DB_READ_COMMITTED
+#define	DB_DIRTY_READ	      DB_READ_UNCOMMITTED
+#define	DB_JOINENV	      0x0
+
+/* Key/data structure -- a Data-Base Thang. */
+struct __db_dbt {
+	void	 *data;			/* Key/data */
+	u_int32_t size;			/* key/data length */
+
+	u_int32_t ulen;			/* RO: length of user buffer. */
+	u_int32_t dlen;			/* RO: get/put record length. */
+	u_int32_t doff;			/* RO: get/put record offset. */
+
+	void *app_data;
+
+#define	DB_DBT_APPMALLOC	0x001	/* Callback allocated memory. */
+#define	DB_DBT_BULK		0x002	/* Internal: Insert if duplicate. */
+#define	DB_DBT_DUPOK		0x004	/* Internal: Insert if duplicate. */
+#define	DB_DBT_ISSET		0x008	/* Lower level calls set value. */
+#define	DB_DBT_MALLOC		0x010	/* Return in malloc'd memory. */
+#define	DB_DBT_MULTIPLE		0x020	/* References multiple records. */
+#define	DB_DBT_PARTIAL		0x040	/* Partial put/get. */
+#define	DB_DBT_REALLOC		0x080	/* Return in realloc'd memory. */
+#define	DB_DBT_READONLY		0x100	/* Readonly, don't update. */
+#define	DB_DBT_STREAMING	0x200	/* Internal: DBT is being streamed. */
+#define	DB_DBT_USERCOPY		0x400	/* Use the user-supplied callback. */
+#define	DB_DBT_USERMEM		0x800	/* Return in user's memory. */
+	u_int32_t flags;
+};
+
+/*******************************************************
+ * Mutexes.
+ *******************************************************/
+/* 
+ * When mixed size addressing is supported mutexes need to be the same size
+ * independent of the process address size is.
+ */
+#ifdef HAVE_MIXED_SIZE_ADDRESSING
+typedef db_size_t	db_mutex_t;
+#else
+typedef uintptr_t	db_mutex_t;
+#endif
+
+struct __db_mutex_stat { /* SHARED */
+	/* The following fields are maintained in the region's copy. */
+	u_int32_t st_mutex_align;	/* Mutex alignment */
+	u_int32_t st_mutex_tas_spins;	/* Mutex test-and-set spins */
+	u_int32_t st_mutex_init;	/* Initial mutex count */
+	u_int32_t st_mutex_cnt;		/* Mutex count */
+	u_int32_t st_mutex_max;		/* Mutex max */
+	u_int32_t st_mutex_free;	/* Available mutexes */
+	u_int32_t st_mutex_inuse;	/* Mutexes in use */
+	u_int32_t st_mutex_inuse_max;	/* Maximum mutexes ever in use */
+
+	/* The following fields are filled-in from other places. */
+#ifndef __TEST_DB_NO_STATISTICS
+	uintmax_t st_region_wait;	/* Region lock granted after wait. */
+	uintmax_t st_region_nowait;	/* Region lock granted without wait. */
+	roff_t	  st_regsize;		/* Region size. */
+	roff_t	  st_regmax;		/* Region max. */
+#endif
+};
+
+/* This is the length of the buffer passed to DB_ENV->thread_id_string() */
+#define	DB_THREADID_STRLEN	128
+
+/*******************************************************
+ * Locking.
+ *******************************************************/
+#define	DB_LOCKVERSION	1
+
+#define	DB_FILE_ID_LEN		20	/* Unique file ID length. */
+
+/*
+ * Deadlock detector modes; used in the DB_ENV structure to configure the
+ * locking subsystem.
+ */
+#define	DB_LOCK_NORUN		0
+#define	DB_LOCK_DEFAULT		1	/* Default policy. */
+#define	DB_LOCK_EXPIRE		2	/* Only expire locks, no detection. */
+#define	DB_LOCK_MAXLOCKS	3	/* Select locker with max locks. */
+#define	DB_LOCK_MAXWRITE	4	/* Select locker with max writelocks. */
+#define	DB_LOCK_MINLOCKS	5	/* Select locker with min locks. */
+#define	DB_LOCK_MINWRITE	6	/* Select locker with min writelocks. */
+#define	DB_LOCK_OLDEST		7	/* Select oldest locker. */
+#define	DB_LOCK_RANDOM		8	/* Select random locker. */
+#define	DB_LOCK_YOUNGEST	9	/* Select youngest locker. */
+
+/*
+ * Simple R/W lock modes and for multi-granularity intention locking.
+ *
+ * !!!
+ * These values are NOT random, as they are used as an index into the lock
+ * conflicts arrays, i.e., DB_LOCK_IWRITE must be == 3, and DB_LOCK_IREAD
+ * must be == 4.
+ */
+typedef enum {
+	DB_LOCK_NG=0,			/* Not granted. */
+	DB_LOCK_READ=1,			/* Shared/read. */
+	DB_LOCK_WRITE=2,		/* Exclusive/write. */
+	DB_LOCK_WAIT=3,			/* Wait for event */
+	DB_LOCK_IWRITE=4,		/* Intent exclusive/write. */
+	DB_LOCK_IREAD=5,		/* Intent to share/read. */
+	DB_LOCK_IWR=6,			/* Intent to read and write. */
+	DB_LOCK_READ_UNCOMMITTED=7,	/* Degree 1 isolation. */
+	DB_LOCK_WWRITE=8		/* Was Written. */
+} db_lockmode_t;
+
+/*
+ * Request types.
+ */
+typedef enum {
+	DB_LOCK_DUMP=0,			/* Display held locks. */
+	DB_LOCK_GET=1,			/* Get the lock. */
+	DB_LOCK_GET_TIMEOUT=2,		/* Get lock with a timeout. */
+	DB_LOCK_INHERIT=3,		/* Pass locks to parent. */
+	DB_LOCK_PUT=4,			/* Release the lock. */
+	DB_LOCK_PUT_ALL=5,		/* Release locker's locks. */
+	DB_LOCK_PUT_OBJ=6,		/* Release locker's locks on obj. */
+	DB_LOCK_PUT_READ=7,		/* Release locker's read locks. */
+	DB_LOCK_TIMEOUT=8,		/* Force a txn to timeout. */
+	DB_LOCK_TRADE=9,		/* Trade locker ids on a lock. */
+	DB_LOCK_UPGRADE_WRITE=10	/* Upgrade writes for dirty reads. */
+} db_lockop_t;
+
+/*
+ * Status of a lock.
+ */
+typedef enum  {
+	DB_LSTAT_ABORTED=1,		/* Lock belongs to an aborted txn. */
+	DB_LSTAT_EXPIRED=2,		/* Lock has expired. */
+	DB_LSTAT_FREE=3,		/* Lock is unallocated. */
+	DB_LSTAT_HELD=4,		/* Lock is currently held. */
+	DB_LSTAT_PENDING=5,		/* Lock was waiting and has been
+					 * promoted; waiting for the owner
+					 * to run and upgrade it to held. */
+	DB_LSTAT_WAITING=6		/* Lock is on the wait queue. */
+}db_status_t;
+
+/* Lock statistics structure. */
+struct __db_lock_stat { /* SHARED */
+	u_int32_t st_id;		/* Last allocated locker ID. */
+	u_int32_t st_cur_maxid;		/* Current maximum unused ID. */
+	u_int32_t st_initlocks;		/* Initial number of locks in table. */
+	u_int32_t st_initlockers;	/* Initial num of lockers in table. */
+	u_int32_t st_initobjects;	/* Initial num of objects in table. */
+	u_int32_t st_locks;		/* Current number of locks in table. */
+	u_int32_t st_lockers;		/* Current num of lockers in table. */
+	u_int32_t st_objects;		/* Current num of objects in table. */
+	u_int32_t st_maxlocks;		/* Maximum number of locks in table. */
+	u_int32_t st_maxlockers;	/* Maximum num of lockers in table. */
+	u_int32_t st_maxobjects;	/* Maximum num of objects in table. */
+	u_int32_t st_partitions;	/* number of partitions. */
+	u_int32_t st_tablesize;		/* Size of object hash table. */
+	int32_t   st_nmodes;		/* Number of lock modes. */
+	u_int32_t st_nlockers;		/* Current number of lockers. */
+#ifndef __TEST_DB_NO_STATISTICS
+	u_int32_t st_nlocks;		/* Current number of locks. */
+	u_int32_t st_maxnlocks;		/* Maximum number of locks so far. */
+	u_int32_t st_maxhlocks;		/* Maximum number of locks in any bucket. */
+	uintmax_t st_locksteals;	/* Number of lock steals so far. */
+	uintmax_t st_maxlsteals;	/* Maximum number steals in any partition. */
+	u_int32_t st_maxnlockers;	/* Maximum number of lockers so far. */
+	u_int32_t st_nobjects;		/* Current number of objects. */
+	u_int32_t st_maxnobjects;	/* Maximum number of objects so far. */
+	u_int32_t st_maxhobjects;	/* Maximum number of objectsin any bucket. */
+	uintmax_t st_objectsteals;	/* Number of objects steals so far. */
+	uintmax_t st_maxosteals;	/* Maximum number of steals in any partition. */
+	uintmax_t st_nrequests;		/* Number of lock gets. */
+	uintmax_t st_nreleases;		/* Number of lock puts. */
+	uintmax_t st_nupgrade;		/* Number of lock upgrades. */
+	uintmax_t st_ndowngrade;	/* Number of lock downgrades. */
+	uintmax_t st_lock_wait;		/* Lock conflicts w/ subsequent wait */
+	uintmax_t st_lock_nowait;	/* Lock conflicts w/o subsequent wait */
+	uintmax_t st_ndeadlocks;	/* Number of lock deadlocks. */
+	db_timeout_t st_locktimeout;	/* Lock timeout. */
+	uintmax_t st_nlocktimeouts;	/* Number of lock timeouts. */
+	db_timeout_t st_txntimeout;	/* Transaction timeout. */
+	uintmax_t st_ntxntimeouts;	/* Number of transaction timeouts. */
+	uintmax_t st_part_wait;		/* Partition lock granted after wait. */
+	uintmax_t st_part_nowait;	/* Partition lock granted without wait. */
+	uintmax_t st_part_max_wait;	/* Max partition lock granted after wait. */
+	uintmax_t st_part_max_nowait;	/* Max partition lock granted without wait. */
+	uintmax_t st_objs_wait;	/* 	Object lock granted after wait. */
+	uintmax_t st_objs_nowait;	/* Object lock granted without wait. */
+	uintmax_t st_lockers_wait;	/* Locker lock granted after wait. */
+	uintmax_t st_lockers_nowait;	/* Locker lock granted without wait. */
+	uintmax_t st_region_wait;	/* Region lock granted after wait. */
+	uintmax_t st_region_nowait;	/* Region lock granted without wait. */
+	u_int32_t st_hash_len;		/* Max length of bucket. */
+	roff_t	  st_regsize;		/* Region size. */
+#endif
+};
+
+struct __db_lock_hstat { /* SHARED */
+	uintmax_t st_nrequests;		/* Number of lock gets. */
+	uintmax_t st_nreleases;		/* Number of lock puts. */
+	uintmax_t st_nupgrade;		/* Number of lock upgrades. */
+	uintmax_t st_ndowngrade;	/* Number of lock downgrades. */
+	u_int32_t st_nlocks;		/* Current number of locks. */
+	u_int32_t st_maxnlocks;		/* Maximum number of locks so far. */
+	u_int32_t st_nobjects;		/* Current number of objects. */
+	u_int32_t st_maxnobjects;	/* Maximum number of objects so far. */
+	uintmax_t st_lock_wait;		/* Lock conflicts w/ subsequent wait */
+	uintmax_t st_lock_nowait;	/* Lock conflicts w/o subsequent wait */
+	uintmax_t st_nlocktimeouts;	/* Number of lock timeouts. */
+	uintmax_t st_ntxntimeouts;	/* Number of transaction timeouts. */
+	u_int32_t st_hash_len;		/* Max length of bucket. */
+};
+
+struct __db_lock_pstat { /* SHARED */
+	u_int32_t st_nlocks;		/* Current number of locks. */
+	u_int32_t st_maxnlocks;		/* Maximum number of locks so far. */
+	u_int32_t st_nobjects;		/* Current number of objects. */
+	u_int32_t st_maxnobjects;	/* Maximum number of objects so far. */
+	uintmax_t st_locksteals;	/* Number of lock steals so far. */
+	uintmax_t st_objectsteals;	/* Number of objects steals so far. */
+};
+
+/*
+ * DB_LOCK_ILOCK --
+ *	Internal DB access method lock.
+ */
+struct __db_ilock { /* SHARED */
+	db_pgno_t pgno;			/* Page being locked. */
+	u_int8_t fileid[DB_FILE_ID_LEN];/* File id. */
+#define	DB_HANDLE_LOCK		1
+#define	DB_RECORD_LOCK		2
+#define	DB_PAGE_LOCK		3
+#define	DB_DATABASE_LOCK	4
+	u_int32_t type;			/* Type of lock. */
+};
+
+/*
+ * DB_LOCK --
+ *	The structure is allocated by the caller and filled in during a
+ *	lock_get request (or a lock_vec/DB_LOCK_GET).
+ */
+struct __db_lock_u { /* SHARED */
+	roff_t		off;		/* Offset of the lock in the region */
+	u_int32_t	ndx;		/* Index of the object referenced by
+					 * this lock; used for locking. */
+	u_int32_t	gen;		/* Generation number of this lock. */
+	db_lockmode_t	mode;		/* mode of this lock. */
+};
+
+/* Lock request structure. */
+struct __db_lockreq {
+	db_lockop_t	 op;		/* Operation. */
+	db_lockmode_t	 mode;		/* Requested mode. */
+	db_timeout_t	 timeout;	/* Time to expire lock. */
+	DBT		*obj;		/* Object being locked. */
+	DB_LOCK		 lock;		/* Lock returned. */
+};
+
+/*******************************************************
+ * Logging.
+ *******************************************************/
+#define	DB_LOGVERSION	20		/* Current log version. */
+#define	DB_LOGVERSION_LATCHING 15	/* Log version using latching: db-4.8 */
+#define	DB_LOGCHKSUM	12		/* Check sum headers: db-4.5 */
+#define	DB_LOGOLDVER	8		/* Oldest version supported: db-4.2 */
+#define	DB_LOGMAGIC	0x040988
+
+/*
+ * A DB_LSN has two parts, a fileid which identifies a specific file, and an
+ * offset within that file.  The fileid is an unsigned 4-byte quantity that
+ * uniquely identifies a file within the log directory -- currently a simple
+ * counter inside the log.  The offset is also an unsigned 4-byte value.  The
+ * log manager guarantees the offset is never more than 4 bytes by switching
+ * to a new log file before the maximum length imposed by an unsigned 4-byte
+ * offset is reached.
+ */
+struct __db_lsn { /* SHARED */
+	u_int32_t	file;		/* File ID. */
+	u_int32_t	offset;		/* File offset. */
+};
+
+/*
+ * Application-specified log record types start at DB_user_BEGIN, and must not
+ * equal or exceed DB_debug_FLAG.
+ *
+ * DB_debug_FLAG is the high-bit of the u_int32_t that specifies a log record
+ * type.  If the flag is set, it's a log record that was logged for debugging
+ * purposes only, even if it reflects a database change -- the change was part
+ * of a non-durable transaction.
+ */
+#define	DB_user_BEGIN		10000
+#define	DB_debug_FLAG		0x80000000
+
+/*
+ * DB_LOGC --
+ *	Log cursor.
+ */
+struct __db_log_cursor {
+	ENV	 *env;			/* Environment */
+
+	DB_FH	 *fhp;			/* File handle. */
+	DB_LSN	  lsn;			/* Cursor: LSN */
+	u_int32_t len;			/* Cursor: record length */
+	u_int32_t prev;			/* Cursor: previous record's offset */
+
+	DBT	  dbt;			/* Return DBT. */
+	DB_LSN    p_lsn;		/* Persist LSN. */
+	u_int32_t p_version;		/* Persist version. */
+
+	u_int8_t *bp;			/* Allocated read buffer. */
+	u_int32_t bp_size;		/* Read buffer length in bytes. */
+	u_int32_t bp_rlen;		/* Read buffer valid data length. */
+	DB_LSN	  bp_lsn;		/* Read buffer first byte LSN. */
+
+	u_int32_t bp_maxrec;		/* Max record length in the log file. */
+
+	/* DB_LOGC PUBLIC HANDLE LIST BEGIN */
+	int (*close) __P((DB_LOGC *, u_int32_t));
+	int (*get) __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t));
+	int (*version) __P((DB_LOGC *, u_int32_t *, u_int32_t));
+	/* DB_LOGC PUBLIC HANDLE LIST END */
+
+#define	DB_LOG_DISK		0x01	/* Log record came from disk. */
+#define	DB_LOG_LOCKED		0x02	/* Log region already locked */
+#define	DB_LOG_SILENT_ERR	0x04	/* Turn-off error messages. */
+	u_int32_t flags;
+};
+
+/* Log statistics structure. */
+struct __db_log_stat { /* SHARED */
+	u_int32_t st_magic;		/* Log file magic number. */
+	u_int32_t st_version;		/* Log file version number. */
+	int32_t   st_mode;		/* Log file permissions mode. */
+	u_int32_t st_lg_bsize;		/* Log buffer size. */
+	u_int32_t st_lg_size;		/* Log file size. */
+	u_int32_t st_wc_bytes;		/* Bytes to log since checkpoint. */
+	u_int32_t st_wc_mbytes;		/* Megabytes to log since checkpoint. */
+	u_int32_t st_fileid_init;	/* Initial allocation for fileids. */
+#ifndef __TEST_DB_NO_STATISTICS
+	u_int32_t st_nfileid;		/* Current number of fileids. */
+	u_int32_t st_maxnfileid;	/* Maximum number of fileids used. */
+	uintmax_t st_record;		/* Records entered into the log. */
+	u_int32_t st_w_bytes;		/* Bytes to log. */
+	u_int32_t st_w_mbytes;		/* Megabytes to log. */
+	uintmax_t st_wcount;		/* Total I/O writes to the log. */
+	uintmax_t st_wcount_fill;	/* Overflow writes to the log. */
+	uintmax_t st_rcount;		/* Total I/O reads from the log. */
+	uintmax_t st_scount;		/* Total syncs to the log. */
+	uintmax_t st_region_wait;	/* Region lock granted after wait. */
+	uintmax_t st_region_nowait;	/* Region lock granted without wait. */
+	u_int32_t st_cur_file;		/* Current log file number. */
+	u_int32_t st_cur_offset;	/* Current log file offset. */
+	u_int32_t st_disk_file;		/* Known on disk log file number. */
+	u_int32_t st_disk_offset;	/* Known on disk log file offset. */
+	u_int32_t st_maxcommitperflush;	/* Max number of commits in a flush. */
+	u_int32_t st_mincommitperflush;	/* Min number of commits in a flush. */
+	roff_t	  st_regsize;		/* Region size. */
+#endif
+};
+
+/*
+ * We need to record the first log record of a transaction.  For user
+ * defined logging this macro returns the place to put that information,
+ * if it is need in rlsnp, otherwise it leaves it unchanged.  We also
+ * need to track the last record of the transaction, this returns the
+ * place to put that info.
+ */
+#define	DB_SET_TXN_LSNP(txn, blsnp, llsnp)		\
+	((txn)->set_txn_lsnp(txn, blsnp, llsnp))
+
+/*
+ * Definition of the structure which specifies marshalling of log records.
+ */
+typedef enum {
+	LOGREC_Done,
+	LOGREC_ARG,
+	LOGREC_HDR,
+	LOGREC_DATA,
+	LOGREC_DB,
+	LOGREC_DBOP,
+	LOGREC_DBT,
+	LOGREC_LOCKS,
+	LOGREC_OP,
+	LOGREC_PGDBT,
+	LOGREC_PGDDBT,
+	LOGREC_PGLIST,
+	LOGREC_POINTER,
+	LOGREC_TIME
+} log_rec_type_t;
+
+typedef const struct __log_rec_spec {
+	log_rec_type_t	type;
+	u_int32_t	offset;
+	const char 	*name;
+	const char	fmt[4];
+} DB_LOG_RECSPEC;
+
+/*
+ * Size of a DBT in a log record.
+ */
+#define	LOG_DBT_SIZE(dbt)						\
+    (sizeof(u_int32_t) + ((dbt) == NULL ? 0 : (dbt)->size))
+
+/*******************************************************
+ * Shared buffer cache (mpool).
+ *******************************************************/
+/* Priority values for DB_MPOOLFILE->{put,set_priority}. */
+typedef enum {
+	DB_PRIORITY_UNCHANGED=0,
+	DB_PRIORITY_VERY_LOW=1,
+	DB_PRIORITY_LOW=2,
+	DB_PRIORITY_DEFAULT=3,
+	DB_PRIORITY_HIGH=4,
+	DB_PRIORITY_VERY_HIGH=5
+} DB_CACHE_PRIORITY;
+
+/* Per-process DB_MPOOLFILE information. */
+struct __db_mpoolfile {
+	DB_FH	  *fhp;			/* Underlying file handle. */
+
+	/*
+	 * !!!
+	 * The ref, pinref and q fields are protected by the region lock.
+	 */
+	u_int32_t  ref;			/* Reference count. */
+
+	u_int32_t pinref;		/* Pinned block reference count. */
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__db_mpoolfile) q;
+	 */
+	struct {
+		struct __db_mpoolfile *tqe_next;
+		struct __db_mpoolfile **tqe_prev;
+	} q;				/* Linked list of DB_MPOOLFILE's. */
+
+	/*
+	 * !!!
+	 * The rest of the fields (with the exception of the MP_FLUSH flag)
+	 * are not thread-protected, even when they may be modified at any
+	 * time by the application.  The reason is the DB_MPOOLFILE handle
+	 * is single-threaded from the viewpoint of the application, and so
+	 * the only fields needing to be thread-protected are those accessed
+	 * by checkpoint or sync threads when using DB_MPOOLFILE structures
+	 * to flush buffers from the cache.
+	 */
+	ENV	       *env;		/* Environment */
+	MPOOLFILE      *mfp;		/* Underlying MPOOLFILE. */
+
+	u_int32_t	clear_len;	/* Cleared length on created pages. */
+	u_int8_t			/* Unique file ID. */
+			fileid[DB_FILE_ID_LEN];
+	int		ftype;		/* File type. */
+	int32_t		lsn_offset;	/* LSN offset in page. */
+	u_int32_t	gbytes, bytes;	/* Maximum file size. */
+	DBT	       *pgcookie;	/* Byte-string passed to pgin/pgout. */
+	int32_t		priority;	/* Cache priority. */
+
+	void	       *addr;		/* Address of mmap'd region. */
+	size_t		len;		/* Length of mmap'd region. */
+
+	u_int32_t	config_flags;	/* Flags to DB_MPOOLFILE->set_flags. */
+
+	/* DB_MPOOLFILE PUBLIC HANDLE LIST BEGIN */
+	int (*close) __P((DB_MPOOLFILE *, u_int32_t));
+	int (*get)
+	    __P((DB_MPOOLFILE *, db_pgno_t *, DB_TXN *, u_int32_t, void *));
+	int (*get_clear_len) __P((DB_MPOOLFILE *, u_int32_t *));
+	int (*get_fileid) __P((DB_MPOOLFILE *, u_int8_t *));
+	int (*get_flags) __P((DB_MPOOLFILE *, u_int32_t *));
+	int (*get_ftype) __P((DB_MPOOLFILE *, int *));
+	int (*get_last_pgno) __P((DB_MPOOLFILE *, db_pgno_t *));
+	int (*get_lsn_offset) __P((DB_MPOOLFILE *, int32_t *));
+	int (*get_maxsize) __P((DB_MPOOLFILE *, u_int32_t *, u_int32_t *));
+	int (*get_pgcookie) __P((DB_MPOOLFILE *, DBT *));
+	int (*get_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY *));
+	int (*open) __P((DB_MPOOLFILE *, const char *, u_int32_t, int, size_t));
+	int (*put) __P((DB_MPOOLFILE *, void *, DB_CACHE_PRIORITY, u_int32_t));
+	int (*set_clear_len) __P((DB_MPOOLFILE *, u_int32_t));
+	int (*set_fileid) __P((DB_MPOOLFILE *, u_int8_t *));
+	int (*set_flags) __P((DB_MPOOLFILE *, u_int32_t, int));
+	int (*set_ftype) __P((DB_MPOOLFILE *, int));
+	int (*set_lsn_offset) __P((DB_MPOOLFILE *, int32_t));
+	int (*set_maxsize) __P((DB_MPOOLFILE *, u_int32_t, u_int32_t));
+	int (*set_pgcookie) __P((DB_MPOOLFILE *, DBT *));
+	int (*set_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY));
+	int (*sync) __P((DB_MPOOLFILE *));
+	/* DB_MPOOLFILE PUBLIC HANDLE LIST END */
+
+	/*
+	 * MP_FILEID_SET, MP_OPEN_CALLED and MP_READONLY do not need to be
+	 * thread protected because they are initialized before the file is
+	 * linked onto the per-process lists, and never modified.
+	 *
+	 * MP_FLUSH is thread protected because it is potentially read/set by
+	 * multiple threads of control.
+	 */
+#define	MP_FILEID_SET	0x001		/* Application supplied a file ID. */
+#define	MP_FLUSH	0x002		/* Was used to flush a buffer. */
+#define	MP_FOR_FLUSH	0x004		/* Was opened to flush a buffer. */
+#define	MP_MULTIVERSION	0x008		/* Opened for multiversion access. */
+#define	MP_OPEN_CALLED	0x010		/* File opened. */
+#define	MP_READONLY	0x020		/* File is readonly. */
+#define	MP_DUMMY	0x040		/* File is dummy for __memp_fput. */
+	u_int32_t  flags;
+};
+
+/* Mpool statistics structure. */
+struct __db_mpool_stat { /* SHARED */
+	u_int32_t st_gbytes;		/* Total cache size: GB. */
+	u_int32_t st_bytes;		/* Total cache size: B. */
+	u_int32_t st_ncache;		/* Number of cache regions. */
+	u_int32_t st_max_ncache;	/* Maximum number of regions. */
+	db_size_t st_mmapsize;		/* Maximum file size for mmap. */
+	int32_t st_maxopenfd;		/* Maximum number of open fd's. */
+	int32_t st_maxwrite;		/* Maximum buffers to write. */
+	db_timeout_t st_maxwrite_sleep;	/* Sleep after writing max buffers. */
+	u_int32_t st_pages;		/* Total number of pages. */
+#ifndef __TEST_DB_NO_STATISTICS
+	u_int32_t st_map;		/* Pages from mapped files. */
+	uintmax_t st_cache_hit;	/* Pages found in the cache. */
+	uintmax_t st_cache_miss;	/* Pages not found in the cache. */
+	uintmax_t st_page_create;	/* Pages created in the cache. */
+	uintmax_t st_page_in;		/* Pages read in. */
+	uintmax_t st_page_out;		/* Pages written out. */
+	uintmax_t st_ro_evict;		/* Clean pages forced from the cache. */
+	uintmax_t st_rw_evict;		/* Dirty pages forced from the cache. */
+	uintmax_t st_page_trickle;	/* Pages written by memp_trickle. */
+	u_int32_t st_page_clean;	/* Clean pages. */
+	u_int32_t st_page_dirty;	/* Dirty pages. */
+	u_int32_t st_hash_buckets;	/* Number of hash buckets. */
+	u_int32_t st_hash_mutexes;	/* Number of hash bucket mutexes. */
+	u_int32_t st_pagesize;		/* Assumed page size. */
+	u_int32_t st_hash_searches;	/* Total hash chain searches. */
+	u_int32_t st_hash_longest;	/* Longest hash chain searched. */
+	uintmax_t st_hash_examined;	/* Total hash entries searched. */
+	uintmax_t st_hash_nowait;	/* Hash lock granted with nowait. */
+	uintmax_t st_hash_wait;		/* Hash lock granted after wait. */
+	uintmax_t st_hash_max_nowait;	/* Max hash lock granted with nowait. */
+	uintmax_t st_hash_max_wait;	/* Max hash lock granted after wait. */
+	uintmax_t st_region_nowait;	/* Region lock granted with nowait. */
+	uintmax_t st_region_wait;	/* Region lock granted after wait. */
+	uintmax_t st_mvcc_frozen;	/* Buffers frozen. */
+	uintmax_t st_mvcc_thawed;	/* Buffers thawed. */
+	uintmax_t st_mvcc_freed;	/* Frozen buffers freed. */
+	uintmax_t st_alloc;		/* Number of page allocations. */
+	uintmax_t st_alloc_buckets;	/* Buckets checked during allocation. */
+	uintmax_t st_alloc_max_buckets;/* Max checked during allocation. */
+	uintmax_t st_alloc_pages;	/* Pages checked during allocation. */
+	uintmax_t st_alloc_max_pages;	/* Max checked during allocation. */
+	uintmax_t st_io_wait;		/* Thread waited on buffer I/O. */
+	uintmax_t st_sync_interrupted;	/* Number of times sync interrupted. */
+	uintmax_t st_oddfsize_detect;	/* Odd file size detected. */
+	uintmax_t st_oddfsize_resolve;	/* Odd file size resolved. */
+	roff_t	  st_regsize;		/* Region size. */
+	roff_t	  st_regmax;		/* Region max. */
+#endif
+};
+
+/*
+ * Mpool file statistics structure.
+ * The first fields in this structure must mirror the __db_mpool_fstat_int
+ * structure, since content is mem copied between the two.
+ */
+struct __db_mpool_fstat {
+	u_int32_t st_pagesize;		/* Page size. */
+#ifndef __TEST_DB_NO_STATISTICS
+	u_int32_t st_map;		/* Pages from mapped files. */
+	uintmax_t st_cache_hit;	/* Pages found in the cache. */
+	uintmax_t st_cache_miss;	/* Pages not found in the cache. */
+	uintmax_t st_page_create;	/* Pages created in the cache. */
+	uintmax_t st_page_in;		/* Pages read in. */
+	uintmax_t st_page_out;		/* Pages written out. */
+	uintmax_t st_backup_spins;	/* Number of spins during a copy. */
+#endif
+	char *file_name;	/* File name. */
+};
+
+/*******************************************************
+ * Transactions and recovery.
+ *******************************************************/
+#define	DB_TXNVERSION	1
+
+typedef enum {
+	DB_TXN_ABORT=0,			/* Public. */
+	DB_TXN_APPLY=1,			/* Public. */
+	DB_TXN_BACKWARD_ROLL=3,		/* Public. */
+	DB_TXN_FORWARD_ROLL=4,		/* Public. */
+	DB_TXN_OPENFILES=5,		/* Internal. */
+	DB_TXN_POPENFILES=6,		/* Internal. */
+	DB_TXN_PRINT=7,			/* Public. */
+	DB_TXN_LOG_VERIFY=8		/* Internal. */
+} db_recops;
+
+/*
+ * BACKWARD_ALLOC is used during the forward pass to pick up any aborted
+ * allocations for files that were created during the forward pass.
+ * The main difference between _ALLOC and _ROLL is that the entry for
+ * the file not exist during the rollforward pass.
+ */
+#define	DB_UNDO(op)	((op) == DB_TXN_ABORT || (op) == DB_TXN_BACKWARD_ROLL)
+#define	DB_REDO(op)	((op) == DB_TXN_FORWARD_ROLL || (op) == DB_TXN_APPLY)
+
+struct __db_txn {
+	DB_TXNMGR	*mgrp;		/* Pointer to transaction manager. */
+	DB_TXN		*parent;	/* Pointer to transaction's parent. */
+	DB_LOCKER	*locker;	/* Locker for this txn. */
+	DB_THREAD_INFO	*thread_info;	/* Pointer to thread information. */
+
+	char		*name;		/* Transaction name. */
+
+	void		*td;		/* Detail structure within region. */
+	db_timeout_t	lock_timeout;	/* Timeout for locks for this txn. */
+	void		*txn_list;	/* Undo information for parent. */
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__db_txn) links;
+	 */
+	struct {
+		struct __db_txn *tqe_next;
+		struct __db_txn **tqe_prev;
+	} links;			/* Links transactions off manager. */
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from shqueue.h.
+	 * SH_TAILQ_ENTRY xa_links;
+	 * These links link together transactions that are active in
+	 * the same thread of control.
+	 */
+	struct {
+		db_ssize_t stqe_next;
+		db_ssize_t stqe_prev;
+	} xa_links;			/* Links XA transactions. */
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_HEAD(__events, __txn_event) events;
+	 */
+	struct {
+		struct __txn_event *tqh_first;
+		struct __txn_event **tqh_last;
+	} events;			/* Links deferred events. */
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * STAILQ_HEAD(__logrec, __txn_logrec) logs;
+	 */
+	struct {
+		struct __txn_logrec *stqh_first;
+		struct __txn_logrec **stqh_last;
+	} logs;				/* Links in memory log records. */
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__db_txn) klinks;
+	 */
+	struct {
+		struct __db_txn *tqe_next;
+		struct __db_txn **tqe_prev;
+	} klinks;			/* Links of children in parent. */
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_HEAD(__kids, __db_txn) kids;
+	 */
+	struct __kids {
+		struct __db_txn *tqh_first;
+		struct __db_txn **tqh_last;
+	} kids;
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_HEAD(__my_cursors, __dbc) my_cursors;
+	 */
+	struct __my_cursors {
+		struct __dbc *tqh_first;
+		struct __dbc **tqh_last;
+	} my_cursors;
+	u_int32_t	cursors;	/* Number of cursors open for txn */
+	u_int32_t	txnid;		/* Unique transaction id. */
+
+	void	*api_internal;		/* C++ API private. */
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_HEAD(__femfs, MPOOLFILE) femfs;
+	 *
+	 * These are DBs involved in file extension in this transaction.
+	 */
+	struct __femfs {
+		DB *tqh_first;
+		DB **tqh_last;
+	} femfs;
+
+	DB_TXN_TOKEN	*token_buffer;	/* User's commit token buffer. */
+	void	*xml_internal;		/* XML API private. */
+
+	/* DB_TXN PUBLIC HANDLE LIST BEGIN */
+	int	  (*abort) __P((DB_TXN *));
+	int	  (*commit) __P((DB_TXN *, u_int32_t));
+	int	  (*discard) __P((DB_TXN *, u_int32_t));
+	int	  (*get_name) __P((DB_TXN *, const char **));
+	int	  (*get_priority) __P((DB_TXN *, u_int32_t *));
+	u_int32_t (*id) __P((DB_TXN *));
+	int	  (*prepare) __P((DB_TXN *, u_int8_t *));
+	int	  (*set_commit_token) __P((DB_TXN *, DB_TXN_TOKEN *));
+	int	  (*set_name) __P((DB_TXN *, const char *));
+	int	  (*set_priority) __P((DB_TXN *, u_int32_t));
+	int	  (*set_timeout) __P((DB_TXN *, db_timeout_t, u_int32_t));
+	/* DB_TXN PUBLIC HANDLE LIST END */
+
+	/* DB_TXN PRIVATE HANDLE LIST BEGIN */
+	void	  (*set_txn_lsnp) __P((DB_TXN *txn, DB_LSN **, DB_LSN **));
+	/* DB_TXN PRIVATE HANDLE LIST END */
+
+#define	TXN_XA_THREAD_NOTA		0
+#define	TXN_XA_THREAD_ASSOCIATED	1
+#define	TXN_XA_THREAD_SUSPENDED		2
+#define	TXN_XA_THREAD_UNASSOCIATED 	3
+	u_int32_t	xa_thr_status;
+
+#define	TXN_CHILDCOMMIT		0x00001	/* Txn has committed. */
+#define	TXN_COMPENSATE		0x00002	/* Compensating transaction. */
+#define	TXN_DEADLOCK		0x00004	/* Txn has deadlocked. */
+#define	TXN_FAMILY		0x00008	/* Cursors/children are independent. */
+#define	TXN_IGNORE_LEASE	0x00010	/* Skip lease check at commit time. */
+#define	TXN_INFAMILY		0x00020	/* Part of a transaction family. */
+#define	TXN_LOCKTIMEOUT		0x00040	/* Txn has a lock timeout. */
+#define	TXN_MALLOC		0x00080	/* Structure allocated by TXN system. */
+#define	TXN_NOSYNC		0x00100	/* Do not sync on prepare and commit. */
+#define	TXN_NOWAIT		0x00200	/* Do not wait on locks. */
+#define	TXN_PRIVATE		0x00400	/* Txn owned by cursor. */
+#define	TXN_READONLY		0x00800	/* CDS group handle. */
+#define	TXN_READ_COMMITTED	0x01000	/* Txn has degree 2 isolation. */
+#define	TXN_READ_UNCOMMITTED	0x02000	/* Txn has degree 1 isolation. */
+#define	TXN_RESTORED		0x04000	/* Txn has been restored. */
+#define	TXN_SNAPSHOT		0x08000	/* Snapshot Isolation. */
+#define	TXN_SYNC		0x10000	/* Write and sync on prepare/commit. */
+#define	TXN_WRITE_NOSYNC	0x20000	/* Write only on prepare/commit. */
+#define TXN_BULK		0x40000 /* Enable bulk loading optimization. */
+	u_int32_t	flags;
+};
+
+#define	TXN_SYNC_FLAGS (TXN_SYNC | TXN_NOSYNC | TXN_WRITE_NOSYNC)
+
+/*
+ * Structure used for two phase commit interface.
+ * We set the size of our global transaction id (gid) to be 128 in order
+ * to match that defined by the XA X/Open standard.
+ */
+#define	DB_GID_SIZE	128
+struct __db_preplist {
+	DB_TXN	*txn;
+	u_int8_t gid[DB_GID_SIZE];
+};
+
+/* Transaction statistics structure. */
+struct __db_txn_active {
+	u_int32_t txnid;		/* Transaction ID */
+	u_int32_t parentid;		/* Transaction ID of parent */
+	pid_t     pid;			/* Process owning txn ID */
+	db_threadid_t tid;		/* Thread owning txn ID */
+
+	DB_LSN	  lsn;			/* LSN when transaction began */
+
+	DB_LSN	  read_lsn;		/* Read LSN for MVCC */
+	u_int32_t mvcc_ref;		/* MVCC reference count */
+
+	u_int32_t priority;		/* Deadlock resolution priority */
+
+#define	TXN_ABORTED		1
+#define	TXN_COMMITTED		2
+#define	TXN_NEED_ABORT		3
+#define	TXN_PREPARED		4
+#define	TXN_RUNNING		5
+	u_int32_t status;		/* Status of the transaction */
+
+#define	TXN_XA_ACTIVE		1
+#define	TXN_XA_DEADLOCKED	2
+#define	TXN_XA_IDLE		3
+#define	TXN_XA_PREPARED		4
+#define	TXN_XA_ROLLEDBACK	5
+	u_int32_t xa_status;		/* XA status */
+
+	u_int8_t  gid[DB_GID_SIZE];	/* Global transaction ID */
+	char	  name[51];		/* 50 bytes of name, nul termination */
+};
+
+struct __db_txn_stat {
+	u_int32_t st_nrestores;		/* number of restored transactions
+					   after recovery. */
+#ifndef __TEST_DB_NO_STATISTICS
+	DB_LSN	  st_last_ckp;		/* lsn of the last checkpoint */
+	time_t	  st_time_ckp;		/* time of last checkpoint */
+	u_int32_t st_last_txnid;	/* last transaction id given out */
+	u_int32_t st_inittxns;		/* inital txns allocated */
+	u_int32_t st_maxtxns;		/* maximum txns possible */
+	uintmax_t st_naborts;		/* number of aborted transactions */
+	uintmax_t st_nbegins;		/* number of begun transactions */
+	uintmax_t st_ncommits;		/* number of committed transactions */
+	u_int32_t st_nactive;		/* number of active transactions */
+	u_int32_t st_nsnapshot;		/* number of snapshot transactions */
+	u_int32_t st_maxnactive;	/* maximum active transactions */
+	u_int32_t st_maxnsnapshot;	/* maximum snapshot transactions */
+	uintmax_t st_region_wait;	/* Region lock granted after wait. */
+	uintmax_t st_region_nowait;	/* Region lock granted without wait. */
+	roff_t	  st_regsize;		/* Region size. */
+	DB_TXN_ACTIVE *st_txnarray;	/* array of active transactions */
+#endif
+};
+
+#define	DB_TXN_TOKEN_SIZE		20
+struct __db_txn_token {
+	u_int8_t buf[DB_TXN_TOKEN_SIZE];
+};
+
+/*******************************************************
+ * Replication.
+ *******************************************************/
+/* Special, out-of-band environment IDs. */
+#define	DB_EID_BROADCAST	-1
+#define	DB_EID_INVALID		-2
+#define	DB_EID_MASTER		-3
+
+#define	DB_REP_DEFAULT_PRIORITY		100
+
+/* Acknowledgement policies; 0 reserved as OOB. */
+#define	DB_REPMGR_ACKS_ALL		1
+#define	DB_REPMGR_ACKS_ALL_AVAILABLE	2
+#define	DB_REPMGR_ACKS_ALL_PEERS	3
+#define	DB_REPMGR_ACKS_NONE		4
+#define	DB_REPMGR_ACKS_ONE		5
+#define	DB_REPMGR_ACKS_ONE_PEER		6
+#define	DB_REPMGR_ACKS_QUORUM		7
+
+/* Replication timeout configuration values. */
+#define	DB_REP_ACK_TIMEOUT		1	/* RepMgr acknowledgements. */
+#define	DB_REP_CHECKPOINT_DELAY		2	/* Master checkpoint delay. */
+#define	DB_REP_CONNECTION_RETRY		3	/* RepMgr connections. */
+#define	DB_REP_ELECTION_RETRY		4	/* RepMgr elect retries. */
+#define	DB_REP_ELECTION_TIMEOUT		5	/* Rep normal elections. */
+#define	DB_REP_FULL_ELECTION_TIMEOUT	6	/* Rep full elections. */
+#define	DB_REP_HEARTBEAT_MONITOR	7	/* RepMgr client HB monitor. */
+#define	DB_REP_HEARTBEAT_SEND		8	/* RepMgr master send freq. */
+#define	DB_REP_LEASE_TIMEOUT		9	/* Master leases. */
+
+/*
+ * Event notification types.  (Tcl testing interface currently assumes there are
+ * no more than 32 of these.)
+ */
+#define	DB_EVENT_PANIC			 0
+#define	DB_EVENT_REG_ALIVE		 1
+#define	DB_EVENT_REG_PANIC		 2
+#define	DB_EVENT_REP_CLIENT		 3
+#define	DB_EVENT_REP_CONNECT_BROKEN	 4
+#define	DB_EVENT_REP_CONNECT_ESTD	 5
+#define	DB_EVENT_REP_CONNECT_TRY_FAILED	 6
+#define	DB_EVENT_REP_DUPMASTER		 7
+#define	DB_EVENT_REP_ELECTED		 8
+#define	DB_EVENT_REP_ELECTION_FAILED	 9
+#define	DB_EVENT_REP_INIT_DONE		10
+#define	DB_EVENT_REP_JOIN_FAILURE	11
+#define	DB_EVENT_REP_LOCAL_SITE_REMOVED	12
+#define	DB_EVENT_REP_MASTER		13
+#define	DB_EVENT_REP_MASTER_FAILURE	14
+#define	DB_EVENT_REP_NEWMASTER		15
+#define	DB_EVENT_REP_PERM_FAILED	16
+#define	DB_EVENT_REP_SITE_ADDED		17
+#define	DB_EVENT_REP_SITE_REMOVED	18
+#define	DB_EVENT_REP_STARTUPDONE	19
+#define	DB_EVENT_REP_WOULD_ROLLBACK	20	/* Undocumented; C API only. */
+#define	DB_EVENT_WRITE_FAILED		21
+#define	DB_EVENT_NO_SUCH_EVENT		 0xffffffff /* OOB sentinel value */
+
+/* Replication Manager site status. */
+struct __db_repmgr_site {
+	int eid;
+	char *host;
+	u_int port;
+
+#define	DB_REPMGR_CONNECTED	1
+#define	DB_REPMGR_DISCONNECTED	2
+	u_int32_t status;
+
+#define	DB_REPMGR_ISPEER	0x01
+	u_int32_t flags;
+};
+
+/* Replication statistics. */
+struct __db_rep_stat { /* SHARED */
+	/* !!!
+	 * Many replication statistics fields cannot be protected by a mutex
+	 * without an unacceptable performance penalty, since most message
+	 * processing is done without the need to hold a region-wide lock.
+	 * Fields whose comments end with a '+' may be updated without holding
+	 * the replication or log mutexes (as appropriate), and thus may be
+	 * off somewhat (or, on unreasonable architectures under unlucky
+	 * circumstances, garbaged).
+	 */
+	u_int32_t st_startup_complete;	/* Site completed client sync-up. */
+#ifndef __TEST_DB_NO_STATISTICS
+	uintmax_t st_log_queued;	/* Log records currently queued.+ */
+	u_int32_t st_status;		/* Current replication status. */
+	DB_LSN st_next_lsn;		/* Next LSN to use or expect. */
+	DB_LSN st_waiting_lsn;		/* LSN we're awaiting, if any. */
+	DB_LSN st_max_perm_lsn;		/* Maximum permanent LSN. */
+	db_pgno_t st_next_pg;		/* Next pg we expect. */
+	db_pgno_t st_waiting_pg;	/* pg we're awaiting, if any. */
+
+	u_int32_t st_dupmasters;	/* # of times a duplicate master
+					   condition was detected.+ */
+	db_ssize_t st_env_id;		/* Current environment ID. */
+	u_int32_t st_env_priority;	/* Current environment priority. */
+	uintmax_t st_bulk_fills;	/* Bulk buffer fills. */
+	uintmax_t st_bulk_overflows;	/* Bulk buffer overflows. */
+	uintmax_t st_bulk_records;	/* Bulk records stored. */
+	uintmax_t st_bulk_transfers;	/* Transfers of bulk buffers. */
+	uintmax_t st_client_rerequests;/* Number of forced rerequests. */
+	uintmax_t st_client_svc_req;	/* Number of client service requests
+					   received by this client. */
+	uintmax_t st_client_svc_miss;	/* Number of client service requests
+					   missing on this client. */
+	u_int32_t st_gen;		/* Current generation number. */
+	u_int32_t st_egen;		/* Current election gen number. */
+	uintmax_t st_lease_chk;		/* Lease validity checks. */
+	uintmax_t st_lease_chk_misses;	/* Lease checks invalid. */
+	uintmax_t st_lease_chk_refresh;	/* Lease refresh attempts. */
+	uintmax_t st_lease_sends;	/* Lease messages sent live. */
+
+	uintmax_t st_log_duplicated;	/* Log records received multiply.+ */
+	uintmax_t st_log_queued_max;	/* Max. log records queued at once.+ */
+	uintmax_t st_log_queued_total;	/* Total # of log recs. ever queued.+ */
+	uintmax_t st_log_records;	/* Log records received and put.+ */
+	uintmax_t st_log_requested;	/* Log recs. missed and requested.+ */
+	db_ssize_t st_master;		/* Env. ID of the current master. */
+	uintmax_t st_master_changes;	/* # of times we've switched masters. */
+	uintmax_t st_msgs_badgen;	/* Messages with a bad generation #.+ */
+	uintmax_t st_msgs_processed;	/* Messages received and processed.+ */
+	uintmax_t st_msgs_recover;	/* Messages ignored because this site
+					   was a client in recovery.+ */
+	uintmax_t st_msgs_send_failures;/* # of failed message sends.+ */
+	uintmax_t st_msgs_sent;	/* # of successful message sends.+ */
+	uintmax_t st_newsites;		/* # of NEWSITE msgs. received.+ */
+	u_int32_t st_nsites;		/* Current number of sites we will
+					   assume during elections. */
+	uintmax_t st_nthrottles;	/* # of times we were throttled. */
+	uintmax_t st_outdated;		/* # of times we detected and returned
+					   an OUTDATED condition.+ */
+	uintmax_t st_pg_duplicated;	/* Pages received multiply.+ */
+	uintmax_t st_pg_records;	/* Pages received and stored.+ */
+	uintmax_t st_pg_requested;	/* Pages missed and requested.+ */
+	uintmax_t st_txns_applied;	/* # of transactions applied.+ */
+	uintmax_t st_startsync_delayed;/* # of STARTSYNC msgs delayed.+ */
+
+	/* Elections generally. */
+	uintmax_t st_elections;	/* # of elections held.+ */
+	uintmax_t st_elections_won;	/* # of elections won by this site.+ */
+
+	/* Statistics about an in-progress election. */
+	db_ssize_t st_election_cur_winner;	/* Current front-runner. */
+	u_int32_t st_election_gen;	/* Election generation number. */
+	u_int32_t st_election_datagen;	/* Election data generation number. */
+	DB_LSN st_election_lsn;		/* Max. LSN of current winner. */
+	u_int32_t st_election_nsites;	/* # of "registered voters". */
+	u_int32_t st_election_nvotes;	/* # of "registered voters" needed. */
+	u_int32_t st_election_priority;	/* Current election priority. */
+	int32_t   st_election_status;	/* Current election status. */
+	u_int32_t st_election_tiebreaker;/* Election tiebreaker value. */
+	u_int32_t st_election_votes;	/* Votes received in this round. */
+	u_int32_t st_election_sec;	/* Last election time seconds. */
+	u_int32_t st_election_usec;	/* Last election time useconds. */
+	u_int32_t st_max_lease_sec;	/* Maximum lease timestamp seconds. */
+	u_int32_t st_max_lease_usec;	/* Maximum lease timestamp useconds. */
+
+	/* Undocumented statistics only used by the test system. */
+#ifdef	CONFIG_TEST
+	u_int32_t st_filefail_cleanups;	/* # of FILE_FAIL cleanups done. */
+#endif
+#endif
+};
+
+/* Replication Manager statistics. */
+struct __db_repmgr_stat { /* SHARED */
+	uintmax_t st_perm_failed;	/* # of insufficiently ack'ed msgs. */
+	uintmax_t st_msgs_queued;	/* # msgs queued for network delay. */
+	uintmax_t st_msgs_dropped;	/* # msgs discarded due to excessive
+					   queue length. */
+	uintmax_t st_connection_drop;	/* Existing connections dropped. */
+	uintmax_t st_connect_fail;	/* Failed new connection attempts. */
+	uintmax_t st_elect_threads;	/* # of active election threads. */
+	uintmax_t st_max_elect_threads;	/* Max concurrent e-threads ever. */
+};
+
+/* Replication Manager connection error. */
+struct __db_repmgr_conn_err {
+	int		eid;		/* Replication Environment ID. */
+	int		error;		/* System networking error code. */
+};
+
+/*******************************************************
+ * Sequences.
+ *******************************************************/
+/*
+ * The storage record for a sequence.
+ */
+struct __db_seq_record {
+	u_int32_t	seq_version;	/* Version size/number. */
+	u_int32_t	flags;		/* DB_SEQ_XXX Flags. */
+	db_seq_t	seq_value;	/* Current value. */
+	db_seq_t	seq_max;	/* Max permitted. */
+	db_seq_t	seq_min;	/* Min permitted. */
+};
+
+/*
+ * Handle for a sequence object.
+ */
+struct __db_sequence {
+	DB		*seq_dbp;	/* DB handle for this sequence. */
+	db_mutex_t	mtx_seq;	/* Mutex if sequence is threaded. */
+	DB_SEQ_RECORD	*seq_rp;	/* Pointer to current data. */
+	DB_SEQ_RECORD	seq_record;	/* Data from DB_SEQUENCE. */
+	int32_t		seq_cache_size; /* Number of values cached. */
+	db_seq_t	seq_last_value;	/* Last value cached. */
+	db_seq_t	seq_prev_value;	/* Last value returned. */
+	DBT		seq_key;	/* DBT pointing to sequence key. */
+	DBT		seq_data;	/* DBT pointing to seq_record. */
+
+	/* API-private structure: used by C++ and Java. */
+	void		*api_internal;
+
+	/* DB_SEQUENCE PUBLIC HANDLE LIST BEGIN */
+	int		(*close) __P((DB_SEQUENCE *, u_int32_t));
+	int		(*get) __P((DB_SEQUENCE *,
+			      DB_TXN *, int32_t, db_seq_t *, u_int32_t));
+	int		(*get_cachesize) __P((DB_SEQUENCE *, int32_t *));
+	int		(*get_db) __P((DB_SEQUENCE *, DB **));
+	int		(*get_flags) __P((DB_SEQUENCE *, u_int32_t *));
+	int		(*get_key) __P((DB_SEQUENCE *, DBT *));
+	int		(*get_range) __P((DB_SEQUENCE *,
+			     db_seq_t *, db_seq_t *));
+	int		(*initial_value) __P((DB_SEQUENCE *, db_seq_t));
+	int		(*open) __P((DB_SEQUENCE *,
+			    DB_TXN *, DBT *, u_int32_t));
+	int		(*remove) __P((DB_SEQUENCE *, DB_TXN *, u_int32_t));
+	int		(*set_cachesize) __P((DB_SEQUENCE *, int32_t));
+	int		(*set_flags) __P((DB_SEQUENCE *, u_int32_t));
+	int		(*set_range) __P((DB_SEQUENCE *, db_seq_t, db_seq_t));
+	int		(*stat) __P((DB_SEQUENCE *,
+			    DB_SEQUENCE_STAT **, u_int32_t));
+	int		(*stat_print) __P((DB_SEQUENCE *, u_int32_t));
+	/* DB_SEQUENCE PUBLIC HANDLE LIST END */
+};
+
+struct __db_seq_stat { /* SHARED */
+	uintmax_t st_wait;		/* Sequence lock granted w/o wait. */
+	uintmax_t st_nowait;		/* Sequence lock granted after wait. */
+	db_seq_t  st_current;		/* Current value in db. */
+	db_seq_t  st_value;		/* Current cached value. */
+	db_seq_t  st_last_value;	/* Last cached value. */
+	db_seq_t  st_min;		/* Minimum value. */
+	db_seq_t  st_max;		/* Maximum value. */
+	int32_t   st_cache_size;	/* Cache size. */
+	u_int32_t st_flags;		/* Flag value. */
+};
+
+/*******************************************************
+ * Access methods.
+ *******************************************************/
+/*
+ * Any new methods need to retain the original numbering.  The type
+ * is written in a log record so must be maintained.
+ */
+typedef enum {
+	DB_BTREE=1,
+	DB_HASH=2,
+	DB_HEAP=6,
+	DB_RECNO=3,
+	DB_QUEUE=4,
+	DB_UNKNOWN=5			/* Figure it out on open. */
+} DBTYPE;
+
+#define	DB_RENAMEMAGIC	0x030800	/* File has been renamed. */
+
+#define	DB_BTREEVERSION	9		/* Current btree version. */
+#define	DB_BTREEOLDVER	8		/* Oldest btree version supported. */
+#define	DB_BTREEMAGIC	0x053162
+
+#define	DB_HASHVERSION	9		/* Current hash version. */
+#define	DB_HASHOLDVER	7		/* Oldest hash version supported. */
+#define	DB_HASHMAGIC	0x061561
+
+#define	DB_HEAPVERSION	1		/* Current heap version. */
+#define	DB_HEAPOLDVER	1		/* Oldest heap version supported. */
+#define	DB_HEAPMAGIC	0x074582
+
+#define	DB_QAMVERSION	4		/* Current queue version. */
+#define	DB_QAMOLDVER	3		/* Oldest queue version supported. */
+#define	DB_QAMMAGIC	0x042253
+
+#define	DB_SEQUENCE_VERSION 2		/* Current sequence version. */
+#define	DB_SEQUENCE_OLDVER  1		/* Oldest sequence version supported. */
+
+/*
+ * DB access method and cursor operation values.  Each value is an operation
+ * code to which additional bit flags are added.
+ */
+#define	DB_AFTER		 1	/* Dbc.put */
+#define	DB_APPEND		 2	/* Db.put */
+#define	DB_BEFORE		 3	/* Dbc.put */
+#define	DB_CONSUME		 4	/* Db.get */
+#define	DB_CONSUME_WAIT		 5	/* Db.get */
+#define	DB_CURRENT		 6	/* Dbc.get, Dbc.put, DbLogc.get */
+#define	DB_FIRST		 7	/* Dbc.get, DbLogc->get */
+#define	DB_GET_BOTH		 8	/* Db.get, Dbc.get */
+#define	DB_GET_BOTHC		 9	/* Dbc.get (internal) */
+#define	DB_GET_BOTH_RANGE	10	/* Db.get, Dbc.get */
+#define	DB_GET_RECNO		11	/* Dbc.get */
+#define	DB_JOIN_ITEM		12	/* Dbc.get; don't do primary lookup */
+#define	DB_KEYFIRST		13	/* Dbc.put */
+#define	DB_KEYLAST		14	/* Dbc.put */
+#define	DB_LAST			15	/* Dbc.get, DbLogc->get */
+#define	DB_NEXT			16	/* Dbc.get, DbLogc->get */
+#define	DB_NEXT_DUP		17	/* Dbc.get */
+#define	DB_NEXT_NODUP		18	/* Dbc.get */
+#define	DB_NODUPDATA		19	/* Db.put, Dbc.put */
+#define	DB_NOOVERWRITE		20	/* Db.put */
+#define	DB_OVERWRITE_DUP	21	/* Dbc.put, Db.put; no DB_KEYEXIST */
+#define	DB_POSITION		22	/* Dbc.dup */
+#define	DB_PREV			23	/* Dbc.get, DbLogc->get */
+#define	DB_PREV_DUP		24	/* Dbc.get */
+#define	DB_PREV_NODUP		25	/* Dbc.get */
+#define	DB_SET			26	/* Dbc.get, DbLogc->get */
+#define	DB_SET_RANGE		27	/* Dbc.get */
+#define	DB_SET_RECNO		28	/* Db.get, Dbc.get */
+#define	DB_UPDATE_SECONDARY	29	/* Dbc.get, Dbc.del (internal) */
+#define	DB_SET_LTE		30	/* Dbc.get (internal) */
+#define	DB_GET_BOTH_LTE		31	/* Dbc.get (internal) */
+
+/* This has to change when the max opcode hits 255. */
+#define	DB_OPFLAGS_MASK	0x000000ff	/* Mask for operations flags. */
+
+/*
+ * DB (user visible) error return codes.
+ *
+ * !!!
+ * We don't want our error returns to conflict with other packages where
+ * possible, so pick a base error value that's hopefully not common.  We
+ * document that we own the error name space from -30,800 to -30,999.
+ */
+/* DB (public) error return codes. */
+#define	DB_BUFFER_SMALL		(-30999)/* User memory too small for return. */
+#define	DB_DONOTINDEX		(-30998)/* "Null" return from 2ndary callbk. */
+#define	DB_FOREIGN_CONFLICT	(-30997)/* A foreign db constraint triggered. */
+#define	DB_HEAP_FULL		(-30996)/* No free space in a heap file. */
+#define	DB_KEYEMPTY		(-30995)/* Key/data deleted or never created. */
+#define	DB_KEYEXIST		(-30994)/* The key/data pair already exists. */
+#define	DB_LOCK_DEADLOCK	(-30993)/* Deadlock. */
+#define	DB_LOCK_NOTGRANTED	(-30992)/* Lock unavailable. */
+#define	DB_LOG_BUFFER_FULL	(-30991)/* In-memory log buffer full. */
+#define	DB_LOG_VERIFY_BAD	(-30990)/* Log verification failed. */
+#define	DB_NOSERVER		(-30989)/* Server panic return. */
+#define	DB_NOTFOUND		(-30988)/* Key/data pair not found (EOF). */
+#define	DB_OLD_VERSION		(-30987)/* Out-of-date version. */
+#define	DB_PAGE_NOTFOUND	(-30986)/* Requested page not found. */
+#define	DB_REP_DUPMASTER	(-30985)/* There are two masters. */
+#define	DB_REP_HANDLE_DEAD	(-30984)/* Rolled back a commit. */
+#define	DB_REP_HOLDELECTION	(-30983)/* Time to hold an election. */
+#define	DB_REP_IGNORE		(-30982)/* This msg should be ignored.*/
+#define	DB_REP_ISPERM		(-30981)/* Cached not written perm written.*/
+#define	DB_REP_JOIN_FAILURE	(-30980)/* Unable to join replication group. */
+#define	DB_REP_LEASE_EXPIRED	(-30979)/* Master lease has expired. */
+#define	DB_REP_LOCKOUT		(-30978)/* API/Replication lockout now. */
+#define	DB_REP_NEWSITE		(-30977)/* New site entered system. */
+#define	DB_REP_NOTPERM		(-30976)/* Permanent log record not written. */
+#define	DB_REP_UNAVAIL		(-30975)/* Site cannot currently be reached. */
+#define	DB_REP_WOULDROLLBACK	(-30974)/* UNDOC: rollback inhibited by app. */
+#define	DB_RUNRECOVERY		(-30973)/* Panic return. */
+#define	DB_SECONDARY_BAD	(-30972)/* Secondary index corrupt. */
+#define	DB_TIMEOUT		(-30971)/* Timed out on read consistency. */
+#define	DB_VERIFY_BAD		(-30970)/* Verify failed; bad format. */
+#define	DB_VERSION_MISMATCH	(-30969)/* Environment version mismatch. */
+
+/* DB (private) error return codes. */
+#define	DB_ALREADY_ABORTED	(-30899)
+#define	DB_CHKSUM_FAIL		(-30898)/* Checksum failed. */
+#define	DB_DELETED		(-30897)/* Recovery file marked deleted. */
+#define	DB_EVENT_NOT_HANDLED	(-30896)/* Forward event to application. */
+#define	DB_NEEDSPLIT		(-30895)/* Page needs to be split. */
+#define	DB_REP_BULKOVF		(-30894)/* Rep bulk buffer overflow. */
+#define	DB_REP_LOGREADY		(-30893)/* Rep log ready for recovery. */
+#define	DB_REP_NEWMASTER	(-30892)/* We have learned of a new master. */
+#define	DB_REP_PAGEDONE		(-30891)/* This page was already done. */
+#define	DB_SURPRISE_KID		(-30890)/* Child commit where parent
+					   didn't know it was a parent. */
+#define	DB_SWAPBYTES		(-30889)/* Database needs byte swapping. */
+#define	DB_TXN_CKP		(-30888)/* Encountered ckp record in log. */
+#define	DB_VERIFY_FATAL		(-30887)/* DB->verify cannot proceed. */
+
+/* Database handle. */
+struct __db {
+	/*******************************************************
+	 * Public: owned by the application.
+	 *******************************************************/
+	u_int32_t pgsize;		/* Database logical page size. */
+	DB_CACHE_PRIORITY priority;	/* Database priority in cache. */
+
+					/* Callbacks. */
+	int (*db_append_recno) __P((DB *, DBT *, db_recno_t));
+	void (*db_feedback) __P((DB *, int, int));
+	int (*dup_compare) __P((DB *, const DBT *, const DBT *));
+
+	void	*app_private;		/* Application-private handle. */
+
+	/*******************************************************
+	 * Private: owned by DB.
+	 *******************************************************/
+	DB_ENV	*dbenv;			/* Backing public environment. */
+	ENV	*env;			/* Backing private environment. */
+
+	DBTYPE	 type;			/* DB access method type. */
+
+	DB_MPOOLFILE *mpf;		/* Backing buffer pool. */
+
+	db_mutex_t mutex;		/* Synchronization for free threading */
+
+	char *fname, *dname;		/* File/database passed to DB->open. */
+	const char *dirname;		/* Directory of DB file. */
+	u_int32_t open_flags;		/* Flags passed to DB->open. */
+
+	u_int8_t fileid[DB_FILE_ID_LEN];/* File's unique ID for locking. */
+
+	u_int32_t adj_fileid;		/* File's unique ID for curs. adj. */
+
+#define	DB_LOGFILEID_INVALID	-1
+	FNAME *log_filename;		/* File's naming info for logging. */
+
+	db_pgno_t meta_pgno;		/* Meta page number */
+	DB_LOCKER *locker;		/* Locker for handle locking. */
+	DB_LOCKER *cur_locker;		/* Current handle lock holder. */
+	DB_TXN *cur_txn;		/* Opening transaction. */
+	DB_LOCKER *associate_locker;	/* Locker for DB->associate call. */
+	DB_LOCK	 handle_lock;		/* Lock held on this handle. */
+
+	time_t	 timestamp;		/* Handle timestamp for replication. */
+	u_int32_t fid_gen;		/* Rep generation number for fids. */
+
+	/*
+	 * Returned data memory for DB->get() and friends.
+	 */
+	DBT	 my_rskey;		/* Secondary key. */
+	DBT	 my_rkey;		/* [Primary] key. */
+	DBT	 my_rdata;		/* Data. */
+
+	/*
+	 * !!!
+	 * Some applications use DB but implement their own locking outside of
+	 * DB.  If they're using fcntl(2) locking on the underlying database
+	 * file, and we open and close a file descriptor for that file, we will
+	 * discard their locks.  The DB_FCNTL_LOCKING flag to DB->open is an
+	 * undocumented interface to support this usage which leaves any file
+	 * descriptors we open until DB->close.  This will only work with the
+	 * DB->open interface and simple caches, e.g., creating a transaction
+	 * thread may open/close file descriptors this flag doesn't protect.
+	 * Locking with fcntl(2) on a file that you don't own is a very, very
+	 * unsafe thing to do.  'Nuff said.
+	 */
+	DB_FH	*saved_open_fhp;	/* Saved file handle. */
+
+	/*
+	 * Linked list of DBP's, linked from the ENV, used to keep track
+	 * of all open db handles for cursor adjustment.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__db) dblistlinks;
+	 */
+	struct {
+		struct __db *tqe_next;
+		struct __db **tqe_prev;
+	} dblistlinks;
+
+	/*
+	 * Cursor queues.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_HEAD(__cq_fq, __dbc) free_queue;
+	 * TAILQ_HEAD(__cq_aq, __dbc) active_queue;
+	 * TAILQ_HEAD(__cq_jq, __dbc) join_queue;
+	 */
+	struct __cq_fq {
+		struct __dbc *tqh_first;
+		struct __dbc **tqh_last;
+	} free_queue;
+	struct __cq_aq {
+		struct __dbc *tqh_first;
+		struct __dbc **tqh_last;
+	} active_queue;
+	struct __cq_jq {
+		struct __dbc *tqh_first;
+		struct __dbc **tqh_last;
+	} join_queue;
+
+	/*
+	 * Secondary index support.
+	 *
+	 * Linked list of secondary indices -- set in the primary.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * LIST_HEAD(s_secondaries, __db);
+	 */
+	struct {
+		struct __db *lh_first;
+	} s_secondaries;
+
+	/*
+	 * List entries for secondaries, and reference count of how many
+	 * threads are updating this secondary (see Dbc.put).
+	 *
+	 * !!!
+	 * Note that these are synchronized by the primary's mutex, but
+	 * filled in in the secondaries.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * LIST_ENTRY(__db) s_links;
+	 */
+	struct {
+		struct __db *le_next;
+		struct __db **le_prev;
+	} s_links;
+	u_int32_t s_refcnt;
+
+	/* Secondary callback and free functions -- set in the secondary. */
+	int	(*s_callback) __P((DB *, const DBT *, const DBT *, DBT *));
+
+	/* Reference to primary -- set in the secondary. */
+	DB	*s_primary;
+
+#define	DB_ASSOC_IMMUTABLE_KEY    0x00000001 /* Secondary key is immutable. */
+#define	DB_ASSOC_CREATE    0x00000002 /* Secondary db populated on open. */
+
+	/* Flags passed to associate -- set in the secondary. */
+	u_int32_t s_assoc_flags;
+
+	/*
+	 * Foreign key support.
+	 *
+	 * Linked list of primary dbs -- set in the foreign db
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * LIST_HEAD(f_primaries, __db);
+	 */
+	struct {
+		struct __db_foreign_info *lh_first;
+	} f_primaries;
+
+	/*
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__db) felink;
+	 *
+	 * Links in a list of DBs involved in file extension
+	 * during a transaction.  These are to be used only while the
+	 * metadata is locked.
+	 */
+	struct {
+		struct __db *tqe_next;
+		struct __db **tqe_prev;
+	} felink;
+
+	/* Reference to foreign -- set in the secondary. */
+	DB      *s_foreign;
+
+	/* API-private structure: used by DB 1.85, C++, Java, Perl and Tcl */
+	void	*api_internal;
+
+	/* Subsystem-private structure. */
+	void	*bt_internal;		/* Btree/Recno access method. */
+	void	*h_internal;		/* Hash access method. */
+	void	*heap_internal;		/* Heap access method. */
+	void	*p_internal;		/* Partition informaiton. */
+	void	*q_internal;		/* Queue access method. */
+
+	/* DB PUBLIC HANDLE LIST BEGIN */
+	int  (*associate) __P((DB *, DB_TXN *, DB *,
+		int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t));
+	int  (*associate_foreign) __P((DB *, DB *,
+		int (*)(DB *, const DBT *, DBT *, const DBT *, int *),
+		u_int32_t));
+	int  (*close) __P((DB *, u_int32_t));
+	int  (*compact) __P((DB *,
+		DB_TXN *, DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *));
+	int  (*cursor) __P((DB *, DB_TXN *, DBC **, u_int32_t));
+	int  (*del) __P((DB *, DB_TXN *, DBT *, u_int32_t));
+	void (*err) __P((DB *, int, const char *, ...));
+	void (*errx) __P((DB *, const char *, ...));
+	int  (*exists) __P((DB *, DB_TXN *, DBT *, u_int32_t));
+	int  (*fd) __P((DB *, int *));
+	int  (*get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
+	int  (*get_alloc) __P((DB *, void *(**)(size_t),
+		void *(**)(void *, size_t), void (**)(void *)));
+	int  (*get_append_recno) __P((DB *, int (**)(DB *, DBT *, db_recno_t)));
+	int  (*get_assoc_flags) __P((DB *, u_int32_t *));
+	int  (*get_bt_compare)
+		__P((DB *, int (**)(DB *, const DBT *, const DBT *)));
+	int  (*get_bt_compress) __P((DB *,
+		int (**)(DB *,
+		const DBT *, const DBT *, const DBT *, const DBT *, DBT *),
+		int (**)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *)));
+	int  (*get_bt_minkey) __P((DB *, u_int32_t *));
+	int  (*get_bt_prefix)
+		__P((DB *, size_t (**)(DB *, const DBT *, const DBT *)));
+	int  (*get_byteswapped) __P((DB *, int *));
+	int  (*get_cachesize) __P((DB *, u_int32_t *, u_int32_t *, int *));
+	int  (*get_create_dir) __P((DB *, const char **));
+	int  (*get_dbname) __P((DB *, const char **, const char **));
+	int  (*get_dup_compare)
+		__P((DB *, int (**)(DB *, const DBT *, const DBT *)));
+	int  (*get_encrypt_flags) __P((DB *, u_int32_t *));
+	DB_ENV *(*get_env) __P((DB *));
+	void (*get_errcall) __P((DB *,
+		void (**)(const DB_ENV *, const char *, const char *)));
+	void (*get_errfile) __P((DB *, FILE **));
+	void (*get_errpfx) __P((DB *, const char **));
+	int  (*get_feedback) __P((DB *, void (**)(DB *, int, int)));
+	int  (*get_flags) __P((DB *, u_int32_t *));
+	int  (*get_h_compare)
+		__P((DB *, int (**)(DB *, const DBT *, const DBT *)));
+	int  (*get_h_ffactor) __P((DB *, u_int32_t *));
+	int  (*get_h_hash)
+		__P((DB *, u_int32_t (**)(DB *, const void *, u_int32_t)));
+	int  (*get_h_nelem) __P((DB *, u_int32_t *));
+	int  (*get_heapsize) __P((DB *, u_int32_t *, u_int32_t *));
+	int  (*get_heap_regionsize) __P((DB *, u_int32_t *));
+	int  (*get_lk_exclusive) __P((DB *, int *, int *));
+	int  (*get_lorder) __P((DB *, int *));
+	DB_MPOOLFILE *(*get_mpf) __P((DB *));
+	void (*get_msgcall) __P((DB *,
+	    void (**)(const DB_ENV *, const char *)));
+	void (*get_msgfile) __P((DB *, FILE **));
+	int  (*get_multiple) __P((DB *));
+	int  (*get_open_flags) __P((DB *, u_int32_t *));
+	int  (*get_pagesize) __P((DB *, u_int32_t *));
+	int  (*get_partition_callback) __P((DB *,
+		u_int32_t *, u_int32_t (**)(DB *, DBT *key)));
+	int  (*get_partition_dirs) __P((DB *, const char ***));
+	int  (*get_partition_keys) __P((DB *, u_int32_t *, DBT **));
+	int  (*get_priority) __P((DB *, DB_CACHE_PRIORITY *));
+	int  (*get_q_extentsize) __P((DB *, u_int32_t *));
+	int  (*get_re_delim) __P((DB *, int *));
+	int  (*get_re_len) __P((DB *, u_int32_t *));
+	int  (*get_re_pad) __P((DB *, int *));
+	int  (*get_re_source) __P((DB *, const char **));
+	int  (*get_transactional) __P((DB *));
+	int  (*get_type) __P((DB *, DBTYPE *));
+	int  (*join) __P((DB *, DBC **, DBC **, u_int32_t));
+	int  (*key_range)
+		__P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t));
+	int  (*open) __P((DB *,
+		DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int));
+	int  (*pget) __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t));
+	int  (*put) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
+	int  (*remove) __P((DB *, const char *, const char *, u_int32_t));
+	int  (*rename) __P((DB *,
+		const char *, const char *, const char *, u_int32_t));
+	int  (*set_alloc) __P((DB *, void *(*)(size_t),
+		void *(*)(void *, size_t), void (*)(void *)));
+	int  (*set_append_recno) __P((DB *, int (*)(DB *, DBT *, db_recno_t)));
+	int  (*set_bt_compare)
+		__P((DB *, int (*)(DB *, const DBT *, const DBT *)));
+	int  (*set_bt_compress) __P((DB *,
+		int (*)(DB *, const DBT *, const DBT *, const DBT *, const DBT *, DBT *),
+		int (*)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *)));
+	int  (*set_bt_minkey) __P((DB *, u_int32_t));
+	int  (*set_bt_prefix)
+		__P((DB *, size_t (*)(DB *, const DBT *, const DBT *)));
+	int  (*set_cachesize) __P((DB *, u_int32_t, u_int32_t, int));
+	int  (*set_create_dir) __P((DB *, const char *));
+	int  (*set_dup_compare)
+		__P((DB *, int (*)(DB *, const DBT *, const DBT *)));
+	int  (*set_encrypt) __P((DB *, const char *, u_int32_t));
+	void (*set_errcall) __P((DB *,
+		void (*)(const DB_ENV *, const char *, const char *)));
+	void (*set_errfile) __P((DB *, FILE *));
+	void (*set_errpfx) __P((DB *, const char *));
+	int  (*set_feedback) __P((DB *, void (*)(DB *, int, int)));
+	int  (*set_flags) __P((DB *, u_int32_t));
+	int  (*set_h_compare)
+		__P((DB *, int (*)(DB *, const DBT *, const DBT *)));
+	int  (*set_h_ffactor) __P((DB *, u_int32_t));
+	int  (*set_h_hash)
+		__P((DB *, u_int32_t (*)(DB *, const void *, u_int32_t)));
+	int  (*set_h_nelem) __P((DB *, u_int32_t));
+	int  (*set_heapsize) __P((DB *, u_int32_t, u_int32_t, u_int32_t));
+	int  (*set_heap_regionsize) __P((DB *, u_int32_t));
+	int  (*set_lk_exclusive) __P((DB *, int));
+	int  (*set_lorder) __P((DB *, int));
+	void (*set_msgcall) __P((DB *, void (*)(const DB_ENV *, const char *)));
+	void (*set_msgfile) __P((DB *, FILE *));
+	int  (*set_pagesize) __P((DB *, u_int32_t));
+	int  (*set_paniccall) __P((DB *, void (*)(DB_ENV *, int)));
+	int  (*set_partition) __P((DB *,
+		u_int32_t, DBT *, u_int32_t (*)(DB *, DBT *key)));
+	int  (*set_partition_dirs) __P((DB *, const char **));
+	int  (*set_priority) __P((DB *, DB_CACHE_PRIORITY));
+	int  (*set_q_extentsize) __P((DB *, u_int32_t));
+	int  (*set_re_delim) __P((DB *, int));
+	int  (*set_re_len) __P((DB *, u_int32_t));
+	int  (*set_re_pad) __P((DB *, int));
+	int  (*set_re_source) __P((DB *, const char *));
+	int  (*sort_multiple) __P((DB *, DBT *, DBT *, u_int32_t));
+	int  (*stat) __P((DB *, DB_TXN *, void *, u_int32_t));
+	int  (*stat_print) __P((DB *, u_int32_t));
+	int  (*sync) __P((DB *, u_int32_t));
+	int  (*truncate) __P((DB *, DB_TXN *, u_int32_t *, u_int32_t));
+	int  (*upgrade) __P((DB *, const char *, u_int32_t));
+	int  (*verify)
+		__P((DB *, const char *, const char *, FILE *, u_int32_t));
+	/* DB PUBLIC HANDLE LIST END */
+
+	/* DB PRIVATE HANDLE LIST BEGIN */
+	int  (*dump) __P((DB *, const char *,
+		int (*)(void *, const void *), void *, int, int));
+	int  (*db_am_remove) __P((DB *, DB_THREAD_INFO *,
+		DB_TXN *, const char *, const char *, u_int32_t));
+	int  (*db_am_rename) __P((DB *, DB_THREAD_INFO *,
+		DB_TXN *, const char *, const char *, const char *));
+	/* DB PRIVATE HANDLE LIST END */
+
+	/*
+	 * Never called; these are a place to save function pointers
+	 * so that we can undo an associate.
+	 */
+	int  (*stored_get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
+	int  (*stored_close) __P((DB *, u_int32_t));
+
+	/* Alternative handle close function, used by C++ API. */
+	int  (*alt_close) __P((DB *, u_int32_t));
+
+#define	DB_OK_BTREE	0x01
+#define	DB_OK_HASH	0x02
+#define	DB_OK_HEAP	0x04
+#define	DB_OK_QUEUE	0x08
+#define	DB_OK_RECNO	0x10
+	u_int32_t	am_ok;		/* Legal AM choices. */
+
+	/*
+	 * This field really ought to be an AM_FLAG, but we have
+	 * have run out of bits.  If/when we decide to split up
+	 * the flags, we can incorporate it.
+	 */
+	int	 preserve_fid;		/* Do not free fileid on close. */
+
+#define	DB_AM_CHKSUM		0x00000001 /* Checksumming */
+#define	DB_AM_COMPENSATE	0x00000002 /* Created by compensating txn */
+#define	DB_AM_COMPRESS		0x00000004 /* Compressed BTree */
+#define	DB_AM_CREATED		0x00000008 /* Database was created upon open */
+#define	DB_AM_CREATED_MSTR	0x00000010 /* Encompassing file was created */
+#define	DB_AM_DBM_ERROR		0x00000020 /* Error in DBM/NDBM database */
+#define	DB_AM_DELIMITER		0x00000040 /* Variable length delimiter set */
+#define	DB_AM_DISCARD		0x00000080 /* Discard any cached pages */
+#define	DB_AM_DUP		0x00000100 /* DB_DUP */
+#define	DB_AM_DUPSORT		0x00000200 /* DB_DUPSORT */
+#define	DB_AM_ENCRYPT		0x00000400 /* Encryption */
+#define	DB_AM_FIXEDLEN		0x00000800 /* Fixed-length records */
+#define	DB_AM_INMEM		0x00001000 /* In-memory; no sync on close */
+#define	DB_AM_INORDER		0x00002000 /* DB_INORDER */
+#define	DB_AM_IN_RENAME		0x00004000 /* File is being renamed */
+#define	DB_AM_NOT_DURABLE	0x00008000 /* Do not log changes */
+#define	DB_AM_OPEN_CALLED	0x00010000 /* DB->open called */
+#define	DB_AM_PAD		0x00020000 /* Fixed-length record pad */
+#define	DB_AM_PARTDB		0x00040000 /* Handle for a database partition */
+#define	DB_AM_PGDEF		0x00080000 /* Page size was defaulted */
+#define	DB_AM_RDONLY		0x00100000 /* Database is readonly */
+#define	DB_AM_READ_UNCOMMITTED	0x00200000 /* Support degree 1 isolation */
+#define	DB_AM_RECNUM		0x00400000 /* DB_RECNUM */
+#define	DB_AM_RECOVER		0x00800000 /* DB opened by recovery routine */
+#define	DB_AM_RENUMBER		0x01000000 /* DB_RENUMBER */
+#define	DB_AM_REVSPLITOFF	0x02000000 /* DB_REVSPLITOFF */
+#define	DB_AM_SECONDARY		0x04000000 /* Database is a secondary index */
+#define	DB_AM_SNAPSHOT		0x08000000 /* DB_SNAPSHOT */
+#define	DB_AM_SUBDB		0x10000000 /* Subdatabases supported */
+#define	DB_AM_SWAP		0x20000000 /* Pages need to be byte-swapped */
+#define	DB_AM_TXN		0x40000000 /* Opened in a transaction */
+#define	DB_AM_VERIFYING		0x80000000 /* DB handle is in the verifier */
+	u_int32_t orig_flags;		   /* Flags at  open, for refresh */
+	u_int32_t flags;
+
+#define DB2_AM_EXCL		0x00000001 /* Exclusively lock the handle */ 
+#define DB2_AM_INTEXCL		0x00000002 /* Internal exclusive lock. */
+#define DB2_AM_NOWAIT		0x00000004 /* Do not wait for handle lock */ 
+	u_int32_t orig_flags2;		   /* Second flags word; for refresh */ 
+	u_int32_t flags2;		   /* Second flags word */
+};
+
+/*
+ * Macros for bulk operations.  These are only intended for the C API.
+ * For C++, use DbMultiple*Iterator or DbMultiple*Builder.
+ *
+ * Bulk operations store multiple entries into a single DBT structure. The
+ * following macros assist with creating and reading these Multiple DBTs.
+ *
+ * The basic layout for single data items is:
+ *
+ * -------------------------------------------------------------------------
+ * | data1 | ... | dataN | ..... |-1 | dNLen | dNOff | ... | d1Len | d1Off |
+ * -------------------------------------------------------------------------
+ *
+ * For the DB_MULTIPLE_KEY* macros, the items are in key/data pairs, so data1
+ * would be a key, and data2 its corresponding value (N is always even).
+ *
+ * For the DB_MULTIPLE_RECNO* macros, the record number is stored along with
+ * the len/off pair in the "header" section, and the list is zero terminated
+ * (since -1 is a valid record number):
+ *
+ * --------------------------------------------------------------------------
+ * | d1 |..| dN |..| 0 | dNLen | dNOff | recnoN |..| d1Len | d1Off | recno1 |
+ * --------------------------------------------------------------------------
+ */
+#define	DB_MULTIPLE_INIT(pointer, dbt)					\
+	(pointer = (u_int8_t *)(dbt)->data +				\
+	    (dbt)->ulen - sizeof(u_int32_t))
+
+#define	DB_MULTIPLE_NEXT(pointer, dbt, retdata, retdlen)		\
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		if (*__p == (u_int32_t)-1) {				\
+			retdata = NULL;					\
+			pointer = NULL;					\
+			break;						\
+		}							\
+		retdata = (u_int8_t *)(dbt)->data + *__p--;		\
+		retdlen = *__p--;					\
+		pointer = __p;						\
+		if (retdlen == 0 && retdata == (u_int8_t *)(dbt)->data)	\
+			retdata = NULL;					\
+	} while (0)
+
+#define	DB_MULTIPLE_KEY_NEXT(pointer, dbt, retkey, retklen, retdata, retdlen) \
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		if (*__p == (u_int32_t)-1) {				\
+			retdata = NULL;					\
+			retkey = NULL;					\
+			pointer = NULL;					\
+			break;						\
+		}							\
+		retkey = (u_int8_t *)(dbt)->data + *__p--;		\
+		retklen = *__p--;					\
+		retdata = (u_int8_t *)(dbt)->data + *__p--;		\
+		retdlen = *__p--;					\
+		pointer = __p;						\
+	} while (0)
+
+#define	DB_MULTIPLE_RECNO_NEXT(pointer, dbt, recno, retdata, retdlen)   \
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		if (*__p == (u_int32_t)0) {				\
+			recno = 0;					\
+			retdata = NULL;					\
+			pointer = NULL;					\
+			break;						\
+		}							\
+		recno = *__p--;						\
+		retdata = (u_int8_t *)(dbt)->data + *__p--;		\
+		retdlen = *__p--;					\
+		pointer = __p;						\
+	} while (0)
+
+#define DB_MULTIPLE_WRITE_INIT(pointer, dbt)				\
+	do {								\
+		(dbt)->flags |= DB_DBT_BULK;				\
+		pointer = (u_int8_t *)(dbt)->data +			\
+		    (dbt)->ulen - sizeof(u_int32_t);			\
+		*(u_int32_t *)(pointer) = (u_int32_t)-1;		\
+	} while (0)
+
+#define DB_MULTIPLE_RESERVE_NEXT(pointer, dbt, writedata, writedlen)	\
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		u_int32_t __off = ((pointer) ==	(u_int8_t *)(dbt)->data +\
+		    (dbt)->ulen - sizeof(u_int32_t)) ?  0 : __p[1] + __p[2];\
+		if ((u_int8_t *)(dbt)->data + __off + (writedlen) >	\
+		    (u_int8_t *)(__p - 2))				\
+			writedata = NULL;				\
+		else {							\
+			writedata = (u_int8_t *)(dbt)->data + __off;	\
+			__p[0] = __off;					\
+			__p[-1] = (u_int32_t)(writedlen);		\
+			__p[-2] = (u_int32_t)-1;			\
+			pointer = __p - 2;				\
+		}							\
+	} while (0)
+
+#define DB_MULTIPLE_WRITE_NEXT(pointer, dbt, writedata, writedlen)	\
+	do {								\
+		void *__destd;						\
+		DB_MULTIPLE_RESERVE_NEXT((pointer), (dbt),		\
+		    __destd, (writedlen));				\
+		if (__destd == NULL)					\
+			pointer = NULL;					\
+		else							\
+			memcpy(__destd, (writedata), (writedlen));	\
+	} while (0)
+
+#define DB_MULTIPLE_KEY_RESERVE_NEXT(pointer, dbt, writekey, writeklen, writedata, writedlen) \
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		u_int32_t __off = ((pointer) == (u_int8_t *)(dbt)->data +\
+		    (dbt)->ulen - sizeof(u_int32_t)) ?  0 : __p[1] + __p[2];\
+		if ((u_int8_t *)(dbt)->data + __off + (writeklen) +	\
+		    (writedlen) > (u_int8_t *)(__p - 4)) {		\
+			writekey = NULL;				\
+			writedata = NULL;				\
+		} else {						\
+			writekey = (u_int8_t *)(dbt)->data + __off;	\
+			__p[0] = __off;					\
+			__p[-1] = (u_int32_t)(writeklen);		\
+			__p -= 2;					\
+			__off += (u_int32_t)(writeklen);		\
+			writedata = (u_int8_t *)(dbt)->data + __off;	\
+			__p[0] = __off;					\
+			__p[-1] = (u_int32_t)(writedlen);		\
+			__p[-2] = (u_int32_t)-1;			\
+			pointer = __p - 2;				\
+		}							\
+	} while (0)
+
+#define DB_MULTIPLE_KEY_WRITE_NEXT(pointer, dbt, writekey, writeklen, writedata, writedlen) \
+	do {								\
+		void *__destk, *__destd;				\
+		DB_MULTIPLE_KEY_RESERVE_NEXT((pointer), (dbt),		\
+		    __destk, (writeklen), __destd, (writedlen));	\
+		if (__destk == NULL)					\
+			pointer = NULL;					\
+		else {							\
+			memcpy(__destk, (writekey), (writeklen));	\
+			if (__destd != NULL)				\
+				memcpy(__destd, (writedata), (writedlen));\
+		}							\
+	} while (0)
+
+#define DB_MULTIPLE_RECNO_WRITE_INIT(pointer, dbt)			\
+	do {								\
+		(dbt)->flags |= DB_DBT_BULK;				\
+		pointer = (u_int8_t *)(dbt)->data +			\
+		    (dbt)->ulen - sizeof(u_int32_t);			\
+		*(u_int32_t *)(pointer) = 0;				\
+	} while (0)
+
+#define DB_MULTIPLE_RECNO_RESERVE_NEXT(pointer, dbt, recno, writedata, writedlen) \
+	do {								\
+		u_int32_t *__p = (u_int32_t *)(pointer);		\
+		u_int32_t __off = ((pointer) == (u_int8_t *)(dbt)->data +\
+		    (dbt)->ulen - sizeof(u_int32_t)) ? 0 : __p[1] + __p[2]; \
+		if (((u_int8_t *)(dbt)->data + __off) + (writedlen) >	\
+		    (u_int8_t *)(__p - 3))				\
+			writedata = NULL;				\
+		else {							\
+			writedata = (u_int8_t *)(dbt)->data + __off;	\
+			__p[0] = (u_int32_t)(recno);			\
+			__p[-1] = __off;				\
+			__p[-2] = (u_int32_t)(writedlen);		\
+			__p[-3] = 0;					\
+			pointer = __p - 3;				\
+		}							\
+	} while (0)
+
+#define DB_MULTIPLE_RECNO_WRITE_NEXT(pointer, dbt, recno, writedata, writedlen)\
+	do {								\
+		void *__destd;						\
+		DB_MULTIPLE_RECNO_RESERVE_NEXT((pointer), (dbt),	\
+		    (recno), __destd, (writedlen));			\
+		if (__destd == NULL)					\
+			pointer = NULL;					\
+		else if ((writedlen) != 0)				\
+			memcpy(__destd, (writedata), (writedlen));	\
+	} while (0)
+
+struct __db_heap_rid {
+	db_pgno_t pgno;			/* Page number. */
+	db_indx_t indx;			/* Index in the offset table. */
+};
+#define DB_HEAP_RID_SZ	(sizeof(db_pgno_t) + sizeof(db_indx_t))
+
+/*******************************************************
+ * Access method cursors.
+ *******************************************************/
+struct __dbc {
+	DB *dbp;			/* Backing database */
+	DB_ENV *dbenv;			/* Backing environment */
+	ENV *env;			/* Backing environment */
+
+	DB_THREAD_INFO *thread_info;	/* Thread that owns this cursor. */
+	DB_TXN	 *txn;			/* Associated transaction. */
+	DB_CACHE_PRIORITY priority;	/* Priority in cache. */
+
+	/*
+	 * Active/free cursor queues.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__dbc) links;
+	 */
+	struct {
+		DBC *tqe_next;
+		DBC **tqe_prev;
+	} links;
+
+	/*
+	 * Cursor queue of the owning transaction.
+	 *
+	 * !!!
+	 * Explicit representations of structures from queue.h.
+	 * TAILQ_ENTRY(__dbc) txn_cursors;
+	 */
+	struct {
+		DBC *tqe_next;	/* next element */
+		DBC **tqe_prev;	/* address of previous next element */
+	} txn_cursors;
+
+	/*
+	 * The DBT *'s below are used by the cursor routines to return
+	 * data to the user when DBT flags indicate that DB should manage
+	 * the returned memory.  They point at a DBT containing the buffer
+	 * and length that will be used, and "belonging" to the handle that
+	 * should "own" this memory.  This may be a "my_*" field of this
+	 * cursor--the default--or it may be the corresponding field of
+	 * another cursor, a DB handle, a join cursor, etc.  In general, it
+	 * will be whatever handle the user originally used for the current
+	 * DB interface call.
+	 */
+	DBT	 *rskey;		/* Returned secondary key. */
+	DBT	 *rkey;			/* Returned [primary] key. */
+	DBT	 *rdata;		/* Returned data. */
+
+	DBT	  my_rskey;		/* Space for returned secondary key. */
+	DBT	  my_rkey;		/* Space for returned [primary] key. */
+	DBT	  my_rdata;		/* Space for returned data. */
+
+	DB_LOCKER *lref;		/* Reference to default locker. */
+	DB_LOCKER *locker;		/* Locker for this operation. */
+	DBT	  lock_dbt;		/* DBT referencing lock. */
+	DB_LOCK_ILOCK lock;		/* Object to be locked. */
+	DB_LOCK	  mylock;		/* CDB lock held on this cursor. */
+
+	DBTYPE	  dbtype;		/* Cursor type. */
+
+	DBC_INTERNAL *internal;		/* Access method private. */
+
+	/* DBC PUBLIC HANDLE LIST BEGIN */
+	int (*close) __P((DBC *));
+	int (*cmp) __P((DBC *, DBC *, int *, u_int32_t));
+	int (*count) __P((DBC *, db_recno_t *, u_int32_t));
+	int (*del) __P((DBC *, u_int32_t));
+	int (*dup) __P((DBC *, DBC **, u_int32_t));
+	int (*get) __P((DBC *, DBT *, DBT *, u_int32_t));
+	int (*get_priority) __P((DBC *, DB_CACHE_PRIORITY *));
+	int (*pget) __P((DBC *, DBT *, DBT *, DBT *, u_int32_t));
+	int (*put) __P((DBC *, DBT *, DBT *, u_int32_t));
+	int (*set_priority) __P((DBC *, DB_CACHE_PRIORITY));
+	/* DBC PUBLIC HANDLE LIST END */
+
+	/* The following are the method names deprecated in the 4.6 release. */
+	int (*c_close) __P((DBC *));
+	int (*c_count) __P((DBC *, db_recno_t *, u_int32_t));
+	int (*c_del) __P((DBC *, u_int32_t));
+	int (*c_dup) __P((DBC *, DBC **, u_int32_t));
+	int (*c_get) __P((DBC *, DBT *, DBT *, u_int32_t));
+	int (*c_pget) __P((DBC *, DBT *, DBT *, DBT *, u_int32_t));
+	int (*c_put) __P((DBC *, DBT *, DBT *, u_int32_t));
+
+	/* DBC PRIVATE HANDLE LIST BEGIN */
+	int (*am_bulk) __P((DBC *, DBT *, u_int32_t));
+	int (*am_close) __P((DBC *, db_pgno_t, int *));
+	int (*am_del) __P((DBC *, u_int32_t));
+	int (*am_destroy) __P((DBC *));
+	int (*am_get) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
+	int (*am_put) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
+	int (*am_writelock) __P((DBC *));
+	/* DBC PRIVATE HANDLE LIST END */
+
+/*
+ * DBC_DONTLOCK and DBC_RECOVER are used during recovery and transaction
+ * abort.  If a transaction is being aborted or recovered then DBC_RECOVER
+ * will be set and locking and logging will be disabled on this cursor.  If
+ * we are performing a compensating transaction (e.g. free page processing)
+ * then DB_DONTLOCK will be set to inhibit locking, but logging will still
+ * be required. DB_DONTLOCK is also used if the whole database is locked.
+ */
+#define	DBC_ACTIVE		0x00001	/* Cursor in use. */
+#define	DBC_BULK		0x00002	/* Bulk update cursor. */
+#define	DBC_DONTLOCK		0x00004	/* Don't lock on this cursor. */
+#define	DBC_DOWNREV		0x00008	/* Down rev replication master. */
+#define	DBC_DUPLICATE		0x00010	/* Create a duplicate cursor. */
+#define	DBC_ERROR		0x00020	/* Error in this request. */
+#define	DBC_FAMILY		0x00040 /* Part of a locker family. */
+#define	DBC_FROM_DB_GET		0x00080 /* Called from the DB->get() method. */
+#define	DBC_MULTIPLE		0x00100	/* Return Multiple data. */
+#define	DBC_MULTIPLE_KEY	0x00200	/* Return Multiple keys and data. */
+#define	DBC_OPD			0x00400	/* Cursor references off-page dups. */
+#define	DBC_OWN_LID		0x00800	/* Free lock id on destroy. */
+#define	DBC_PARTITIONED		0x01000	/* Cursor for a partitioned db. */
+#define	DBC_READ_COMMITTED	0x02000	/* Cursor has degree 2 isolation. */
+#define	DBC_READ_UNCOMMITTED	0x04000	/* Cursor has degree 1 isolation. */
+#define	DBC_RECOVER		0x08000	/* Recovery cursor; don't log/lock. */
+#define	DBC_RMW			0x10000	/* Acquire write flag in read op. */
+#define	DBC_TRANSIENT		0x20000	/* Cursor is transient. */
+#define	DBC_WAS_READ_COMMITTED	0x40000	/* Cursor holds a read commited lock. */
+#define	DBC_WRITECURSOR		0x80000	/* Cursor may be used to write (CDB). */
+#define	DBC_WRITER	       0x100000	/* Cursor immediately writing (CDB). */
+	u_int32_t flags;
+};
+
+/* Key range statistics structure */
+struct __key_range {
+	double less;
+	double equal;
+	double greater;
+};
+
+/* Btree/Recno statistics structure. */
+struct __db_bt_stat { /* SHARED */
+	u_int32_t bt_magic;		/* Magic number. */
+	u_int32_t bt_version;		/* Version number. */
+	u_int32_t bt_metaflags;		/* Metadata flags. */
+	u_int32_t bt_nkeys;		/* Number of unique keys. */
+	u_int32_t bt_ndata;		/* Number of data items. */
+	u_int32_t bt_pagecnt;		/* Page count. */
+	u_int32_t bt_pagesize;		/* Page size. */
+	u_int32_t bt_minkey;		/* Minkey value. */
+	u_int32_t bt_re_len;		/* Fixed-length record length. */
+	u_int32_t bt_re_pad;		/* Fixed-length record pad. */
+	u_int32_t bt_levels;		/* Tree levels. */
+	u_int32_t bt_int_pg;		/* Internal pages. */
+	u_int32_t bt_leaf_pg;		/* Leaf pages. */
+	u_int32_t bt_dup_pg;		/* Duplicate pages. */
+	u_int32_t bt_over_pg;		/* Overflow pages. */
+	u_int32_t bt_empty_pg;		/* Empty pages. */
+	u_int32_t bt_free;		/* Pages on the free list. */
+	uintmax_t bt_int_pgfree;	/* Bytes free in internal pages. */
+	uintmax_t bt_leaf_pgfree;	/* Bytes free in leaf pages. */
+	uintmax_t bt_dup_pgfree;	/* Bytes free in duplicate pages. */
+	uintmax_t bt_over_pgfree;	/* Bytes free in overflow pages. */
+};
+
+struct __db_compact {
+	/* Input Parameters. */
+	u_int32_t	compact_fillpercent;	/* Desired fillfactor: 1-100 */
+	db_timeout_t	compact_timeout;	/* Lock timeout. */
+	u_int32_t	compact_pages;		/* Max pages to process. */
+	/* Output Stats. */
+	u_int32_t	compact_empty_buckets;	/* Empty hash buckets found. */
+	u_int32_t	compact_pages_free;	/* Number of pages freed. */
+	u_int32_t	compact_pages_examine;	/* Number of pages examine. */
+	u_int32_t	compact_levels;		/* Number of levels removed. */
+	u_int32_t	compact_deadlock;	/* Number of deadlocks. */
+	db_pgno_t	compact_pages_truncated; /* Pages truncated to OS. */
+	/* Internal. */
+	db_pgno_t	compact_truncate;	/* Page number for truncation */
+};
+
+/* Hash statistics structure. */
+struct __db_h_stat { /* SHARED */
+	u_int32_t hash_magic;		/* Magic number. */
+	u_int32_t hash_version;		/* Version number. */
+	u_int32_t hash_metaflags;	/* Metadata flags. */
+	u_int32_t hash_nkeys;		/* Number of unique keys. */
+	u_int32_t hash_ndata;		/* Number of data items. */
+	u_int32_t hash_pagecnt;		/* Page count. */
+	u_int32_t hash_pagesize;	/* Page size. */
+	u_int32_t hash_ffactor;		/* Fill factor specified at create. */
+	u_int32_t hash_buckets;		/* Number of hash buckets. */
+	u_int32_t hash_free;		/* Pages on the free list. */
+	uintmax_t hash_bfree;		/* Bytes free on bucket pages. */
+	u_int32_t hash_bigpages;	/* Number of big key/data pages. */
+	uintmax_t hash_big_bfree;	/* Bytes free on big item pages. */
+	u_int32_t hash_overflows;	/* Number of overflow pages. */
+	uintmax_t hash_ovfl_free;	/* Bytes free on ovfl pages. */
+	u_int32_t hash_dup;		/* Number of dup pages. */
+	uintmax_t hash_dup_free;	/* Bytes free on duplicate pages. */
+};
+
+/* Heap statistics structure. */
+struct __db_heap_stat { /* SHARED */
+	u_int32_t heap_magic;		/* Magic number. */
+	u_int32_t heap_version;		/* Version number. */
+	u_int32_t heap_metaflags;	/* Metadata flags. */
+	u_int32_t heap_nrecs;		/* Number of records. */
+	u_int32_t heap_pagecnt;		/* Page count. */
+	u_int32_t heap_pagesize;	/* Page size. */
+	u_int32_t heap_nregions;	/* Number of regions. */
+	u_int32_t heap_regionsize;	/* Number of pages in a region. */
+};
+
+/* Queue statistics structure. */
+struct __db_qam_stat { /* SHARED */
+	u_int32_t qs_magic;		/* Magic number. */
+	u_int32_t qs_version;		/* Version number. */
+	u_int32_t qs_metaflags;		/* Metadata flags. */
+	u_int32_t qs_nkeys;		/* Number of unique keys. */
+	u_int32_t qs_ndata;		/* Number of data items. */
+	u_int32_t qs_pagesize;		/* Page size. */
+	u_int32_t qs_extentsize;	/* Pages per extent. */
+	u_int32_t qs_pages;		/* Data pages. */
+	u_int32_t qs_re_len;		/* Fixed-length record length. */
+	u_int32_t qs_re_pad;		/* Fixed-length record pad. */
+	u_int32_t qs_pgfree;		/* Bytes free in data pages. */
+	u_int32_t qs_first_recno;	/* First not deleted record. */
+	u_int32_t qs_cur_recno;		/* Next available record number. */
+};
+
+/*******************************************************
+ * Environment.
+ *******************************************************/
+#define	DB_REGION_MAGIC	0x120897	/* Environment magic number. */
+
+/*
+ * Database environment structure.
+ *
+ * This is the public database environment handle.  The private environment
+ * handle is the ENV structure.   The user owns this structure, the library
+ * owns the ENV structure.  The reason there are two structures is because
+ * the user's configuration outlives any particular DB_ENV->open call, and
+ * separate structures allows us to easily discard internal information without
+ * discarding the user's configuration.
+ *
+ * Fields in the DB_ENV structure should normally be set only by application
+ * DB_ENV handle methods.
+ */
+
+/*
+ * Memory configuration types.
+ */
+typedef enum {
+	DB_MEM_LOCK=1,
+	DB_MEM_LOCKOBJECT=2,
+	DB_MEM_LOCKER=3,
+	DB_MEM_LOGID=4,
+	DB_MEM_TRANSACTION=5,
+	DB_MEM_THREAD=6
+} DB_MEM_CONFIG;
+
+/*
+ * Backup configuration types.
+ */
+typedef enum {
+	DB_BACKUP_READ_COUNT = 1,
+	DB_BACKUP_READ_SLEEP = 2,
+	DB_BACKUP_SIZE = 3,
+	DB_BACKUP_WRITE_DIRECT = 4
+} DB_BACKUP_CONFIG;
+
+struct __db_env {
+	ENV *env;			/* Linked ENV structure */
+
+	/*
+	 * The DB_ENV structure can be used concurrently, so field access is
+	 * protected.
+	 */
+	db_mutex_t mtx_db_env;		/* DB_ENV structure mutex */
+
+					/* Error message callback */
+	void (*db_errcall) __P((const DB_ENV *, const char *, const char *));
+	FILE		*db_errfile;	/* Error message file stream */
+	const char	*db_errpfx;	/* Error message prefix */
+
+					/* Other message callback */
+	void (*db_msgcall) __P((const DB_ENV *, const char *));
+	FILE		*db_msgfile;	/* Other message file stream */
+
+	/* Other application callback functions */
+	int   (*app_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops));
+	void  (*db_event_func) __P((DB_ENV *, u_int32_t, void *));
+	void  (*db_feedback) __P((DB_ENV *, int, int));
+	void  (*db_free) __P((void *));
+	void  (*db_paniccall) __P((DB_ENV *, int));
+	void *(*db_malloc) __P((size_t));
+	void *(*db_realloc) __P((void *, size_t));
+	int   (*is_alive) __P((DB_ENV *, pid_t, db_threadid_t, u_int32_t));
+	void  (*thread_id) __P((DB_ENV *, pid_t *, db_threadid_t *));
+	char *(*thread_id_string) __P((DB_ENV *, pid_t, db_threadid_t, char *));
+
+	/* Application specified paths */
+	char	*db_log_dir;		/* Database log file directory */
+	char	*db_md_dir;		/* Persistent metadata directory */
+	char	*db_tmp_dir;		/* Database tmp file directory */
+
+	char    *db_create_dir;		/* Create directory for data files */
+	char   **db_data_dir;		/* Database data file directories */
+	int	 data_cnt;		/* Database data file slots */
+	int	 data_next;		/* Next database data file slot */
+
+	char	*intermediate_dir_mode;	/* Intermediate directory perms */
+
+	long	 shm_key;		/* shmget key */
+
+	char	*passwd;		/* Cryptography support */
+	size_t	 passwd_len;
+
+	/* Private handle references */
+	void	*app_private;		/* Application-private handle */
+	void	*api1_internal;		/* C++, Perl API private */
+	void	*api2_internal;		/* Java API private */
+
+	u_int32_t	verbose;	/* DB_VERB_XXX flags */
+
+	/* Mutex configuration */
+	u_int32_t	mutex_align;	/* Mutex alignment */
+	u_int32_t	mutex_cnt;	/* Number of mutexes to configure */
+	u_int32_t	mutex_inc;	/* Number of mutexes to add */
+	u_int32_t	mutex_max;	/* Max number of mutexes */
+	u_int32_t	mutex_tas_spins;/* Test-and-set spin count */
+
+	/* Locking configuration */
+	u_int8_t       *lk_conflicts;	/* Two dimensional conflict matrix */
+	int		lk_modes;	/* Number of lock modes in table */
+	u_int32_t	lk_detect;	/* Deadlock detect on all conflicts */
+	u_int32_t	lk_max;	/* Maximum number of locks */
+	u_int32_t	lk_max_lockers;/* Maximum number of lockers */
+	u_int32_t	lk_max_objects;/* Maximum number of locked objects */
+	u_int32_t	lk_init;	/* Initial number of locks */
+	u_int32_t	lk_init_lockers;/* Initial number of lockers */
+	u_int32_t	lk_init_objects;/* Initial number of locked objects */
+	u_int32_t	lk_partitions ;/* Number of object partitions */
+	db_timeout_t	lk_timeout;	/* Lock timeout period */
+	/* Used during initialization */
+	u_int32_t	locker_t_size;	/* Locker hash table size. */
+	u_int32_t	object_t_size;	/* Object hash table size. */
+
+	/* Logging configuration */
+	u_int32_t	lg_bsize;	/* Buffer size */
+	u_int32_t	lg_fileid_init;	/* Initial allocation for fname structs */
+	int		lg_filemode;	/* Log file permission mode */
+	u_int32_t	lg_regionmax;	/* Region size */
+	u_int32_t	lg_size;	/* Log file size */
+	u_int32_t	lg_flags;	/* Log configuration */
+
+	/* Memory pool configuration */
+	u_int32_t	mp_gbytes;	/* Cache size: GB */
+	u_int32_t	mp_bytes;	/* Cache size: bytes */
+	u_int32_t	mp_max_gbytes;	/* Maximum cache size: GB */
+	u_int32_t	mp_max_bytes;	/* Maximum cache size: bytes */
+	size_t		mp_mmapsize;	/* Maximum file size for mmap */
+	int		mp_maxopenfd;	/* Maximum open file descriptors */
+	int		mp_maxwrite;	/* Maximum buffers to write */
+	u_int		mp_ncache;	/* Initial number of cache regions */
+	u_int32_t	mp_pagesize;	/* Average page size */
+	u_int32_t	mp_tablesize;	/* Approximate hash table size */
+	u_int32_t	mp_mtxcount;	/* Number of mutexs */
+					/* Sleep after writing max buffers */
+	db_timeout_t	mp_maxwrite_sleep;
+
+	/* Transaction configuration */
+	u_int32_t	tx_init;	/* Initial number of transactions */
+	u_int32_t	tx_max;		/* Maximum number of transactions */
+	time_t		tx_timestamp;	/* Recover to specific timestamp */
+	db_timeout_t	tx_timeout;	/* Timeout for transactions */
+
+	/* Thread tracking configuration */
+	u_int32_t	thr_init;	/* Thread count */
+	u_int32_t	thr_max;	/* Thread max */
+	roff_t		memory_max;	/* Maximum region memory */
+
+	/*
+	 * The following fields are not strictly user-owned, but they outlive
+	 * the ENV structure, and so are stored here.
+	 */
+	DB_FH		*registry;	/* DB_REGISTER file handle */
+	u_int32_t	registry_off;	/*
+					 * Offset of our slot.  We can't use
+					 * off_t because its size depends on
+					 * build settings.
+					 */
+        db_timeout_t	envreg_timeout; /* DB_REGISTER wait timeout */
+
+#define	DB_ENV_AUTO_COMMIT	0x00000001 /* DB_AUTO_COMMIT */
+#define	DB_ENV_CDB_ALLDB	0x00000002 /* CDB environment wide locking */
+#define	DB_ENV_FAILCHK		0x00000004 /* Failchk is running */
+#define	DB_ENV_DIRECT_DB	0x00000008 /* DB_DIRECT_DB set */
+#define	DB_ENV_DSYNC_DB		0x00000010 /* DB_DSYNC_DB set */
+#define	DB_ENV_DATABASE_LOCKING	0x00000020 /* Try database-level locking */
+#define	DB_ENV_MULTIVERSION	0x00000040 /* DB_MULTIVERSION set */
+#define	DB_ENV_NOLOCKING	0x00000080 /* DB_NOLOCKING set */
+#define	DB_ENV_NOMMAP		0x00000100 /* DB_NOMMAP set */
+#define	DB_ENV_NOPANIC		0x00000200 /* Okay if panic set */
+#define	DB_ENV_OVERWRITE	0x00000400 /* DB_OVERWRITE set */
+#define	DB_ENV_REGION_INIT	0x00000800 /* DB_REGION_INIT set */
+#define	DB_ENV_TIME_NOTGRANTED	0x00001000 /* DB_TIME_NOTGRANTED set */
+#define	DB_ENV_TXN_NOSYNC	0x00002000 /* DB_TXN_NOSYNC set */
+#define	DB_ENV_TXN_NOWAIT	0x00004000 /* DB_TXN_NOWAIT set */
+#define	DB_ENV_TXN_SNAPSHOT	0x00008000 /* DB_TXN_SNAPSHOT set */
+#define	DB_ENV_TXN_WRITE_NOSYNC	0x00010000 /* DB_TXN_WRITE_NOSYNC set */
+#define	DB_ENV_YIELDCPU		0x00020000 /* DB_YIELDCPU set */
+#define DB_ENV_HOTBACKUP	0x00040000 /* DB_HOTBACKUP_IN_PROGRESS set */
+#define DB_ENV_NOFLUSH		0x00080000 /* DB_NOFLUSH set */
+	u_int32_t flags;
+
+	/* DB_ENV PUBLIC HANDLE LIST BEGIN */
+	int  (*add_data_dir) __P((DB_ENV *, const char *));
+	int  (*backup)	__P((DB_ENV *, const char *, u_int32_t));
+	int  (*cdsgroup_begin) __P((DB_ENV *, DB_TXN **));
+	int  (*close) __P((DB_ENV *, u_int32_t));
+	int  (*dbbackup) __P((DB_ENV *, const char *, const char *, u_int32_t));
+	int  (*dbremove) __P((DB_ENV *,
+		DB_TXN *, const char *, const char *, u_int32_t));
+	int  (*dbrename) __P((DB_ENV *,
+		DB_TXN *, const char *, const char *, const char *, u_int32_t));
+	void (*err) __P((const DB_ENV *, int, const char *, ...));
+	void (*errx) __P((const DB_ENV *, const char *, ...));
+	int  (*failchk) __P((DB_ENV *, u_int32_t));
+	int  (*fileid_reset) __P((DB_ENV *, const char *, u_int32_t));
+	int  (*get_alloc) __P((DB_ENV *, void *(**)(size_t),
+		void *(**)(void *, size_t), void (**)(void *)));
+	int  (*get_app_dispatch)
+		__P((DB_ENV *, int (**)(DB_ENV *, DBT *, DB_LSN *, db_recops)));
+	int  (*get_cache_max) __P((DB_ENV *, u_int32_t *, u_int32_t *));
+	int  (*get_cachesize) __P((DB_ENV *, u_int32_t *, u_int32_t *, int *));
+	int  (*get_create_dir) __P((DB_ENV *, const char **));
+	int  (*get_data_dirs) __P((DB_ENV *, const char ***));
+	int  (*get_data_len) __P((DB_ENV *, u_int32_t *));
+	int  (*get_backup_callbacks) __P((DB_ENV *,
+		int (**)(DB_ENV *, const char *, const char *, void **),
+		int (**)(DB_ENV *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *),
+		int (**)(DB_ENV *, const char *, void *)));
+	int  (*get_backup_config) __P((DB_ENV *, DB_BACKUP_CONFIG, u_int32_t *));
+	int  (*get_encrypt_flags) __P((DB_ENV *, u_int32_t *));
+	void (*get_errcall) __P((DB_ENV *,
+		void (**)(const DB_ENV *, const char *, const char *)));
+	void (*get_errfile) __P((DB_ENV *, FILE **));
+	void (*get_errpfx) __P((DB_ENV *, const char **));
+	int  (*get_flags) __P((DB_ENV *, u_int32_t *));
+	int  (*get_feedback) __P((DB_ENV *, void (**)(DB_ENV *, int, int)));
+	int  (*get_home) __P((DB_ENV *, const char **));
+	int  (*get_intermediate_dir_mode) __P((DB_ENV *, const char **));
+	int  (*get_isalive) __P((DB_ENV *,
+		int (**)(DB_ENV *, pid_t, db_threadid_t, u_int32_t)));
+	int  (*get_lg_bsize) __P((DB_ENV *, u_int32_t *));
+	int  (*get_lg_dir) __P((DB_ENV *, const char **));
+	int  (*get_lg_filemode) __P((DB_ENV *, int *));
+	int  (*get_lg_max) __P((DB_ENV *, u_int32_t *));
+	int  (*get_lg_regionmax) __P((DB_ENV *, u_int32_t *));
+	int  (*get_lk_conflicts) __P((DB_ENV *, const u_int8_t **, int *));
+	int  (*get_lk_detect) __P((DB_ENV *, u_int32_t *));
+	int  (*get_lk_max_lockers) __P((DB_ENV *, u_int32_t *));
+	int  (*get_lk_max_locks) __P((DB_ENV *, u_int32_t *));
+	int  (*get_lk_max_objects) __P((DB_ENV *, u_int32_t *));
+	int  (*get_lk_partitions) __P((DB_ENV *, u_int32_t *));
+	int  (*get_lk_priority) __P((DB_ENV *, u_int32_t, u_int32_t *));
+	int  (*get_lk_tablesize) __P((DB_ENV *, u_int32_t *));
+	int  (*get_memory_init) __P((DB_ENV *, DB_MEM_CONFIG, u_int32_t *));
+	int  (*get_memory_max) __P((DB_ENV *, u_int32_t *, u_int32_t *));
+	int  (*get_metadata_dir) __P((DB_ENV *, const char **));
+	int  (*get_mp_max_openfd) __P((DB_ENV *, int *));
+	int  (*get_mp_max_write) __P((DB_ENV *, int *, db_timeout_t *));
+	int  (*get_mp_mmapsize) __P((DB_ENV *, size_t *));
+	int  (*get_mp_mtxcount) __P((DB_ENV *, u_int32_t *));
+	int  (*get_mp_pagesize) __P((DB_ENV *, u_int32_t *));
+	int  (*get_mp_tablesize) __P((DB_ENV *, u_int32_t *));
+	void (*get_msgcall)
+		__P((DB_ENV *, void (**)(const DB_ENV *, const char *)));
+	void (*get_msgfile) __P((DB_ENV *, FILE **));
+	int  (*get_open_flags) __P((DB_ENV *, u_int32_t *));
+	int  (*get_shm_key) __P((DB_ENV *, long *));
+	int  (*get_thread_count) __P((DB_ENV *, u_int32_t *));
+	int  (*get_thread_id_fn)
+		__P((DB_ENV *, void (**)(DB_ENV *, pid_t *, db_threadid_t *)));
+	int  (*get_thread_id_string_fn) __P((DB_ENV *,
+		char *(**)(DB_ENV *, pid_t, db_threadid_t, char *)));
+	int  (*get_timeout) __P((DB_ENV *, db_timeout_t *, u_int32_t));
+	int  (*get_tmp_dir) __P((DB_ENV *, const char **));
+	int  (*get_tx_max) __P((DB_ENV *, u_int32_t *));
+	int  (*get_tx_timestamp) __P((DB_ENV *, time_t *));
+	int  (*get_verbose) __P((DB_ENV *, u_int32_t, int *));
+	int  (*is_bigendian) __P((void));
+	int  (*lock_detect) __P((DB_ENV *, u_int32_t, u_int32_t, int *));
+	int  (*lock_get) __P((DB_ENV *,
+		u_int32_t, u_int32_t, DBT *, db_lockmode_t, DB_LOCK *));
+	int  (*lock_id) __P((DB_ENV *, u_int32_t *));
+	int  (*lock_id_free) __P((DB_ENV *, u_int32_t));
+	int  (*lock_put) __P((DB_ENV *, DB_LOCK *));
+	int  (*lock_stat) __P((DB_ENV *, DB_LOCK_STAT **, u_int32_t));
+	int  (*lock_stat_print) __P((DB_ENV *, u_int32_t));
+	int  (*lock_vec) __P((DB_ENV *,
+		u_int32_t, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **));
+	int  (*log_archive) __P((DB_ENV *, char **[], u_int32_t));
+	int  (*log_cursor) __P((DB_ENV *, DB_LOGC **, u_int32_t));
+	int  (*log_file) __P((DB_ENV *, const DB_LSN *, char *, size_t));
+	int  (*log_flush) __P((DB_ENV *, const DB_LSN *));
+	int  (*log_get_config) __P((DB_ENV *, u_int32_t, int *));
+	int  (*log_printf) __P((DB_ENV *, DB_TXN *, const char *, ...));
+	int  (*log_put) __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t));
+	int  (*log_put_record) __P((DB_ENV *, DB *, DB_TXN *, DB_LSN *,
+		u_int32_t, u_int32_t, u_int32_t, u_int32_t,
+		DB_LOG_RECSPEC *, ...));
+	int  (*log_read_record) __P((DB_ENV *, DB **,
+		void *, void *, DB_LOG_RECSPEC *, u_int32_t, void **));
+	int  (*log_set_config) __P((DB_ENV *, u_int32_t, int));
+	int  (*log_stat) __P((DB_ENV *, DB_LOG_STAT **, u_int32_t));
+	int  (*log_stat_print) __P((DB_ENV *, u_int32_t));
+	int  (*log_verify) __P((DB_ENV *, const DB_LOG_VERIFY_CONFIG *));
+	int  (*lsn_reset) __P((DB_ENV *, const char *, u_int32_t));
+	int  (*memp_fcreate) __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t));
+	int  (*memp_register) __P((DB_ENV *, int, int (*)(DB_ENV *, db_pgno_t,
+		void *, DBT *), int (*)(DB_ENV *, db_pgno_t, void *, DBT *)));
+	int  (*memp_stat) __P((DB_ENV *,
+		DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t));
+	int  (*memp_stat_print) __P((DB_ENV *, u_int32_t));
+	int  (*memp_sync) __P((DB_ENV *, DB_LSN *));
+	int  (*memp_trickle) __P((DB_ENV *, int, int *));
+	int  (*mutex_alloc) __P((DB_ENV *, u_int32_t, db_mutex_t *));
+	int  (*mutex_free) __P((DB_ENV *, db_mutex_t));
+	int  (*mutex_get_align) __P((DB_ENV *, u_int32_t *));
+	int  (*mutex_get_increment) __P((DB_ENV *, u_int32_t *));
+	int  (*mutex_get_init) __P((DB_ENV *, u_int32_t *));
+	int  (*mutex_get_max) __P((DB_ENV *, u_int32_t *));
+	int  (*mutex_get_tas_spins) __P((DB_ENV *, u_int32_t *));
+	int  (*mutex_lock) __P((DB_ENV *, db_mutex_t));
+	int  (*mutex_set_align) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_set_increment) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_set_init) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_set_max) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_set_tas_spins) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_stat) __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t));
+	int  (*mutex_stat_print) __P((DB_ENV *, u_int32_t));
+	int  (*mutex_unlock) __P((DB_ENV *, db_mutex_t));
+	int  (*open) __P((DB_ENV *, const char *, u_int32_t, int));
+	int  (*remove) __P((DB_ENV *, const char *, u_int32_t));
+	int  (*rep_elect) __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t));
+	int  (*rep_flush) __P((DB_ENV *));
+	int  (*rep_get_clockskew) __P((DB_ENV *, u_int32_t *, u_int32_t *));
+	int  (*rep_get_config) __P((DB_ENV *, u_int32_t, int *));
+	int  (*rep_get_limit) __P((DB_ENV *, u_int32_t *, u_int32_t *));
+	int  (*rep_get_nsites) __P((DB_ENV *, u_int32_t *));
+	int  (*rep_get_priority) __P((DB_ENV *, u_int32_t *));
+	int  (*rep_get_request) __P((DB_ENV *, u_int32_t *, u_int32_t *));
+	int  (*rep_get_timeout) __P((DB_ENV *, int, u_int32_t *));
+	int  (*rep_process_message)
+		__P((DB_ENV *, DBT *, DBT *, int, DB_LSN *));
+	int  (*rep_set_clockskew) __P((DB_ENV *, u_int32_t, u_int32_t));
+	int  (*rep_set_config) __P((DB_ENV *, u_int32_t, int));
+	int  (*rep_set_limit) __P((DB_ENV *, u_int32_t, u_int32_t));
+	int  (*rep_set_nsites) __P((DB_ENV *, u_int32_t));
+	int  (*rep_set_priority) __P((DB_ENV *, u_int32_t));
+	int  (*rep_set_request) __P((DB_ENV *, u_int32_t, u_int32_t));
+	int  (*rep_set_timeout) __P((DB_ENV *, int, db_timeout_t));
+	int  (*rep_set_transport) __P((DB_ENV *, int, int (*)(DB_ENV *,
+		const DBT *, const DBT *, const DB_LSN *, int, u_int32_t)));
+	int  (*rep_start) __P((DB_ENV *, DBT *, u_int32_t));
+	int  (*rep_stat) __P((DB_ENV *, DB_REP_STAT **, u_int32_t));
+	int  (*rep_stat_print) __P((DB_ENV *, u_int32_t));
+	int  (*rep_sync) __P((DB_ENV *, u_int32_t));
+	int  (*repmgr_channel) __P((DB_ENV *, int, DB_CHANNEL **, u_int32_t));
+	int  (*repmgr_get_ack_policy) __P((DB_ENV *, int *));
+	int  (*repmgr_local_site) __P((DB_ENV *, DB_SITE **));
+	int  (*repmgr_msg_dispatch) __P((DB_ENV *,
+		void (*)(DB_ENV *, DB_CHANNEL *, DBT *, u_int32_t, u_int32_t),
+		u_int32_t));
+	int  (*repmgr_set_ack_policy) __P((DB_ENV *, int));
+	int  (*repmgr_site)
+		__P((DB_ENV *, const char *, u_int, DB_SITE**, u_int32_t));
+	int  (*repmgr_site_by_eid) __P((DB_ENV *, int, DB_SITE**));
+	int  (*repmgr_site_list) __P((DB_ENV *, u_int *, DB_REPMGR_SITE **));
+	int  (*repmgr_start) __P((DB_ENV *, int, u_int32_t));
+	int  (*repmgr_stat) __P((DB_ENV *, DB_REPMGR_STAT **, u_int32_t));
+	int  (*repmgr_stat_print) __P((DB_ENV *, u_int32_t));
+	int  (*set_alloc) __P((DB_ENV *, void *(*)(size_t),
+		void *(*)(void *, size_t), void (*)(void *)));
+	int  (*set_app_dispatch)
+		__P((DB_ENV *, int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops)));
+	int  (*set_cache_max) __P((DB_ENV *, u_int32_t, u_int32_t));
+	int  (*set_cachesize) __P((DB_ENV *, u_int32_t, u_int32_t, int));
+	int  (*set_create_dir) __P((DB_ENV *, const char *));
+	int  (*set_data_dir) __P((DB_ENV *, const char *));
+	int  (*set_data_len) __P((DB_ENV *, u_int32_t));
+	int  (*set_backup_callbacks) __P((DB_ENV *,
+		int (*)(DB_ENV *, const char *, const char *, void **),
+		int (*)(DB_ENV *, u_int32_t,
+		    u_int32_t, u_int32_t, u_int8_t *, void *),
+		int (*)(DB_ENV *, const char *, void *)));
+	int  (*set_backup_config) __P((DB_ENV *, DB_BACKUP_CONFIG, u_int32_t));
+	int  (*set_encrypt) __P((DB_ENV *, const char *, u_int32_t));
+	void (*set_errcall) __P((DB_ENV *,
+		void (*)(const DB_ENV *, const char *, const char *)));
+	void (*set_errfile) __P((DB_ENV *, FILE *));
+	void (*set_errpfx) __P((DB_ENV *, const char *));
+	int  (*set_event_notify)
+		__P((DB_ENV *, void (*)(DB_ENV *, u_int32_t, void *)));
+	int  (*set_feedback) __P((DB_ENV *, void (*)(DB_ENV *, int, int)));
+	int  (*set_flags) __P((DB_ENV *, u_int32_t, int));
+	int  (*set_intermediate_dir_mode) __P((DB_ENV *, const char *));
+	int  (*set_isalive) __P((DB_ENV *,
+		int (*)(DB_ENV *, pid_t, db_threadid_t, u_int32_t)));
+	int  (*set_lg_bsize) __P((DB_ENV *, u_int32_t));
+	int  (*set_lg_dir) __P((DB_ENV *, const char *));
+	int  (*set_lg_filemode) __P((DB_ENV *, int));
+	int  (*set_lg_max) __P((DB_ENV *, u_int32_t));
+	int  (*set_lg_regionmax) __P((DB_ENV *, u_int32_t));
+	int  (*set_lk_conflicts) __P((DB_ENV *, u_int8_t *, int));
+	int  (*set_lk_detect) __P((DB_ENV *, u_int32_t));
+	int  (*set_lk_max_lockers) __P((DB_ENV *, u_int32_t));
+	int  (*set_lk_max_locks) __P((DB_ENV *, u_int32_t));
+	int  (*set_lk_max_objects) __P((DB_ENV *, u_int32_t));
+	int  (*set_lk_partitions) __P((DB_ENV *, u_int32_t));
+	int  (*set_lk_priority) __P((DB_ENV *, u_int32_t, u_int32_t));
+	int  (*set_lk_tablesize) __P((DB_ENV *, u_int32_t));
+	int  (*set_memory_init) __P((DB_ENV *, DB_MEM_CONFIG, u_int32_t));
+	int  (*set_memory_max) __P((DB_ENV *, u_int32_t, u_int32_t));
+	int  (*set_metadata_dir) __P((DB_ENV *, const char *));
+	int  (*set_mp_max_openfd) __P((DB_ENV *, int));
+	int  (*set_mp_max_write) __P((DB_ENV *, int, db_timeout_t));
+	int  (*set_mp_mmapsize) __P((DB_ENV *, size_t));
+	int  (*set_mp_mtxcount) __P((DB_ENV *, u_int32_t));
+	int  (*set_mp_pagesize) __P((DB_ENV *, u_int32_t));
+	int  (*set_mp_tablesize) __P((DB_ENV *, u_int32_t));
+	void (*set_msgcall)
+		__P((DB_ENV *, void (*)(const DB_ENV *, const char *)));
+	void (*set_msgfile) __P((DB_ENV *, FILE *));
+	int  (*set_paniccall) __P((DB_ENV *, void (*)(DB_ENV *, int)));
+	int  (*set_shm_key) __P((DB_ENV *, long));
+	int  (*set_thread_count) __P((DB_ENV *, u_int32_t));
+	int  (*set_thread_id)
+		__P((DB_ENV *, void (*)(DB_ENV *, pid_t *, db_threadid_t *)));
+	int  (*set_thread_id_string) __P((DB_ENV *,
+		char *(*)(DB_ENV *, pid_t, db_threadid_t, char *)));
+	int  (*set_timeout) __P((DB_ENV *, db_timeout_t, u_int32_t));
+	int  (*set_tmp_dir) __P((DB_ENV *, const char *));
+	int  (*set_tx_max) __P((DB_ENV *, u_int32_t));
+	int  (*set_tx_timestamp) __P((DB_ENV *, time_t *));
+	int  (*set_verbose) __P((DB_ENV *, u_int32_t, int));
+	int  (*txn_applied) __P((DB_ENV *,
+		DB_TXN_TOKEN *, db_timeout_t, u_int32_t));
+	int  (*stat_print) __P((DB_ENV *, u_int32_t));
+	int  (*txn_begin) __P((DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t));
+	int  (*txn_checkpoint) __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t));
+	int  (*txn_recover) __P((DB_ENV *,
+		DB_PREPLIST *, long, long *, u_int32_t));
+	int  (*txn_stat) __P((DB_ENV *, DB_TXN_STAT **, u_int32_t));
+	int  (*txn_stat_print) __P((DB_ENV *, u_int32_t));
+	/* DB_ENV PUBLIC HANDLE LIST END */
+
+	/* DB_ENV PRIVATE HANDLE LIST BEGIN */
+	int  (*prdbt) __P((DBT *, int,
+		const char *, void *, int (*)(void *, const void *), int, int));
+	/* DB_ENV PRIVATE HANDLE LIST END */
+};
+
+/*
+ * Dispatch structure for recovery, log verification and print routines. Since
+ * internal and external routines take different arguments (ENV versus DB_ENV),
+ * we need something more elaborate than a single pointer and size.
+ */
+struct __db_distab {
+	int   (**int_dispatch) __P((ENV *, DBT *, DB_LSN *, db_recops, void *));
+	size_t	int_size;
+	int   (**ext_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops));
+	size_t	ext_size;
+};
+
+/*
+ * Log verification configuration structure.
+ */
+struct __db_logvrfy_config {
+	int continue_after_fail, verbose;
+	u_int32_t cachesize;
+	const char *temp_envhome;
+	const char *dbfile, *dbname;
+	DB_LSN start_lsn, end_lsn;
+	time_t start_time, end_time;
+};
+
+struct __db_channel {
+	CHANNEL *channel;	/* Pointer to internal state details. */
+	int eid;		/* Env. ID passed in constructor. */
+	db_timeout_t timeout;
+
+	/* DB_CHANNEL PUBLIC HANDLE LIST BEGIN */
+	int (*close) __P((DB_CHANNEL *, u_int32_t));
+	int (*send_msg) __P((DB_CHANNEL *, DBT *, u_int32_t, u_int32_t));
+	int (*send_request) __P((DB_CHANNEL *,
+		DBT *, u_int32_t, DBT *, db_timeout_t, u_int32_t));
+	int  (*set_timeout) __P((DB_CHANNEL *, db_timeout_t));
+	/* DB_CHANNEL PUBLIC HANDLE LIST END */
+};
+
+struct __db_site {
+	ENV *env;
+	int eid;
+	const char *host;
+	u_int port;
+	u_int32_t flags;
+
+	/* DB_SITE PUBLIC HANDLE LIST BEGIN */
+	int (*get_address) __P((DB_SITE *, const char **, u_int *));
+	int (*get_config) __P((DB_SITE *, u_int32_t, u_int32_t *));
+	int (*get_eid) __P((DB_SITE *, int *));
+	int (*set_config) __P((DB_SITE *, u_int32_t, u_int32_t));
+	int (*remove) __P((DB_SITE *));
+	int (*close) __P((DB_SITE *));
+	/* DB_SITE PUBLIC HANDLE LIST END */
+};
+
+#if DB_DBM_HSEARCH != 0
+/*******************************************************
+ * Dbm/Ndbm historic interfaces.
+ *******************************************************/
+typedef struct __db DBM;
+
+#define	DBM_INSERT	0		/* Flags to dbm_store(). */
+#define	DBM_REPLACE	1
+
+/*
+ * The DB support for ndbm(3) always appends this suffix to the
+ * file name to avoid overwriting the user's original database.
+ */
+#define	DBM_SUFFIX	".db"
+
+#if defined(_XPG4_2)
+typedef struct {
+	char *dptr;
+	size_t dsize;
+} datum;
+#else
+typedef struct {
+	char *dptr;
+	int dsize;
+} datum;
+#endif
+
+/*
+ * Translate NDBM calls into DB calls so that DB doesn't step on the
+ * application's name space.
+ */
+#define	dbm_clearerr(a)		__db_ndbm_clearerr(a)
+#define	dbm_close(a)		__db_ndbm_close(a)
+#define	dbm_delete(a, b)	__db_ndbm_delete(a, b)
+#define	dbm_dirfno(a)		__db_ndbm_dirfno(a)
+#define	dbm_error(a)		__db_ndbm_error(a)
+#define	dbm_fetch(a, b)		__db_ndbm_fetch(a, b)
+#define	dbm_firstkey(a)		__db_ndbm_firstkey(a)
+#define	dbm_nextkey(a)		__db_ndbm_nextkey(a)
+#define	dbm_open(a, b, c)	__db_ndbm_open(a, b, c)
+#define	dbm_pagfno(a)		__db_ndbm_pagfno(a)
+#define	dbm_rdonly(a)		__db_ndbm_rdonly(a)
+#define	dbm_store(a, b, c, d) \
+	__db_ndbm_store(a, b, c, d)
+
+/*
+ * Translate DBM calls into DB calls so that DB doesn't step on the
+ * application's name space.
+ *
+ * The global variables dbrdonly, dirf and pagf were not retained when 4BSD
+ * replaced the dbm interface with ndbm, and are not supported here.
+ */
+#define	dbminit(a)	__db_dbm_init(a)
+#define	dbmclose	__db_dbm_close
+#if !defined(__cplusplus)
+#define	delete(a)	__db_dbm_delete(a)
+#endif
+#define	fetch(a)	__db_dbm_fetch(a)
+#define	firstkey	__db_dbm_firstkey
+#define	nextkey(a)	__db_dbm_nextkey(a)
+#define	store(a, b)	__db_dbm_store(a, b)
+
+/*******************************************************
+ * Hsearch historic interface.
+ *******************************************************/
+typedef enum {
+	FIND, ENTER
+} ACTION;
+
+typedef struct entry {
+	char *key;
+	char *data;
+} ENTRY;
+
+#define	hcreate(a)	__db_hcreate(a)
+#define	hdestroy	__db_hdestroy
+#define	hsearch(a, b)	__db_hsearch(a, b)
+
+#endif /* DB_DBM_HSEARCH */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/* Restore default compiler warnings */
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+#endif /* !_DB_H_ */
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#define	DB_AGGRESSIVE				0x00000001
+#define	DB_ARCH_ABS				0x00000001
+#define	DB_ARCH_DATA				0x00000002
+#define	DB_ARCH_LOG				0x00000004
+#define	DB_ARCH_REMOVE				0x00000008
+#define	DB_AUTO_COMMIT				0x00000100
+#define	DB_BACKUP_CLEAN				0x00000002
+#define	DB_BACKUP_FILES				0x00000008
+#define	DB_BACKUP_NO_LOGS			0x00000010
+#define	DB_BACKUP_SINGLE_DIR			0x00000020
+#define	DB_BACKUP_UPDATE			0x00000040
+#define	DB_BOOTSTRAP_HELPER			0x00000001
+#define	DB_CDB_ALLDB				0x00000040
+#define	DB_CHKSUM				0x00000008
+#define	DB_CKP_INTERNAL				0x00000002
+#define	DB_CREATE				0x00000001
+#define	DB_CURSOR_BULK				0x00000001
+#define	DB_CURSOR_TRANSIENT			0x00000008
+#define	DB_CXX_NO_EXCEPTIONS			0x00000002
+#define	DB_DATABASE_LOCKING			0x00000080
+#define	DB_DIRECT				0x00000020
+#define	DB_DIRECT_DB				0x00000200
+#define	DB_DSYNC_DB				0x00000400
+#define	DB_DUP					0x00000010
+#define	DB_DUPSORT				0x00000002
+#define	DB_DURABLE_UNKNOWN			0x00000040
+#define	DB_ENCRYPT				0x00000001
+#define	DB_ENCRYPT_AES				0x00000001
+#define	DB_EXCL					0x00000004
+#define	DB_EXTENT				0x00000100
+#define	DB_FAILCHK				0x00000010
+#define	DB_FAILCHK_ISALIVE			0x00000040
+#define	DB_FAST_STAT				0x00000001
+#define	DB_FCNTL_LOCKING			0x00000800
+#define	DB_FLUSH				0x00000002
+#define	DB_FORCE				0x00000001
+#define	DB_FORCESYNC				0x00000001
+#define	DB_FOREIGN_ABORT			0x00000001
+#define	DB_FOREIGN_CASCADE			0x00000002
+#define	DB_FOREIGN_NULLIFY			0x00000004
+#define	DB_FREELIST_ONLY			0x00000001
+#define	DB_FREE_SPACE				0x00000002
+#define	DB_GROUP_CREATOR			0x00000002
+#define	DB_HOTBACKUP_IN_PROGRESS		0x00000800
+#define	DB_IGNORE_LEASE				0x00001000
+#define	DB_IMMUTABLE_KEY			0x00000002
+#define	DB_INIT_CDB				0x00000080
+#define	DB_INIT_LOCK				0x00000100
+#define	DB_INIT_LOG				0x00000200
+#define	DB_INIT_MPOOL				0x00000400
+#define	DB_INIT_MUTEX				0x00000800
+#define	DB_INIT_REP				0x00001000
+#define	DB_INIT_TXN				0x00002000
+#define	DB_INORDER				0x00000020
+#define	DB_INTERNAL_PERSISTENT_DB		0x00001000
+#define	DB_INTERNAL_TEMPORARY_DB		0x00002000
+#define	DB_JOIN_NOSORT				0x00000001
+#define	DB_LEGACY				0x00000004
+#define	DB_LOCAL_SITE				0x00000008
+#define	DB_LOCKDOWN				0x00004000
+#define	DB_LOCK_CHECK				0x00000001
+#define	DB_LOCK_IGNORE_REC			0x00000002
+#define	DB_LOCK_NOWAIT				0x00000004
+#define	DB_LOCK_RECORD				0x00000008
+#define	DB_LOCK_SET_TIMEOUT			0x00000010
+#define	DB_LOCK_SWITCH				0x00000020
+#define	DB_LOCK_UPGRADE				0x00000040
+#define	DB_LOG_AUTO_REMOVE			0x00000001
+#define	DB_LOG_CHKPNT				0x00000001
+#define	DB_LOG_COMMIT				0x00000004
+#define	DB_LOG_DIRECT				0x00000002
+#define	DB_LOG_DSYNC				0x00000004
+#define	DB_LOG_IN_MEMORY			0x00000008
+#define	DB_LOG_NOCOPY				0x00000008
+#define	DB_LOG_NOT_DURABLE			0x00000010
+#define	DB_LOG_NO_DATA				0x00000002
+#define	DB_LOG_VERIFY_CAF			0x00000001
+#define	DB_LOG_VERIFY_DBFILE			0x00000002
+#define	DB_LOG_VERIFY_ERR			0x00000004
+#define	DB_LOG_VERIFY_FORWARD			0x00000008
+#define	DB_LOG_VERIFY_INTERR			0x00000010
+#define	DB_LOG_VERIFY_PARTIAL			0x00000020
+#define	DB_LOG_VERIFY_VERBOSE			0x00000040
+#define	DB_LOG_VERIFY_WARNING			0x00000080
+#define	DB_LOG_WRNOSYNC				0x00000020
+#define	DB_LOG_ZERO				0x00000010
+#define	DB_MPOOL_CREATE				0x00000001
+#define	DB_MPOOL_DIRTY				0x00000002
+#define	DB_MPOOL_DISCARD			0x00000001
+#define	DB_MPOOL_EDIT				0x00000004
+#define	DB_MPOOL_FREE				0x00000008
+#define	DB_MPOOL_LAST				0x00000010
+#define	DB_MPOOL_NEW				0x00000020
+#define	DB_MPOOL_NOFILE				0x00000001
+#define	DB_MPOOL_NOLOCK				0x00000004
+#define	DB_MPOOL_TRY				0x00000040
+#define	DB_MPOOL_UNLINK				0x00000002
+#define	DB_MULTIPLE				0x00000800
+#define	DB_MULTIPLE_KEY				0x00004000
+#define	DB_MULTIVERSION				0x00000008
+#define	DB_MUTEX_ALLOCATED			0x00000001
+#define	DB_MUTEX_LOCKED				0x00000002
+#define	DB_MUTEX_LOGICAL_LOCK			0x00000004
+#define	DB_MUTEX_PROCESS_ONLY			0x00000008
+#define	DB_MUTEX_SELF_BLOCK			0x00000010
+#define	DB_MUTEX_SHARED				0x00000020
+#define	DB_NOERROR				0x00004000
+#define	DB_NOFLUSH				0x00001000
+#define	DB_NOLOCKING				0x00002000
+#define	DB_NOMMAP				0x00000010
+#define	DB_NOORDERCHK				0x00000002
+#define	DB_NOPANIC				0x00004000
+#define	DB_NOSYNC				0x00000001
+#define	DB_NO_AUTO_COMMIT			0x00008000
+#define	DB_NO_CHECKPOINT			0x00008000
+#define	DB_ODDFILESIZE				0x00000080
+#define	DB_ORDERCHKONLY				0x00000004
+#define	DB_OVERWRITE				0x00008000
+#define	DB_PANIC_ENVIRONMENT			0x00010000
+#define	DB_PRINTABLE				0x00000008
+#define	DB_PRIVATE				0x00010000
+#define	DB_PR_PAGE				0x00000010
+#define	DB_PR_RECOVERYTEST			0x00000020
+#define	DB_RDONLY				0x00000400
+#define	DB_RDWRMASTER				0x00010000
+#define	DB_READ_COMMITTED			0x00000400
+#define	DB_READ_UNCOMMITTED			0x00000200
+#define	DB_RECNUM				0x00000040
+#define	DB_RECOVER				0x00000002
+#define	DB_RECOVER_FATAL			0x00020000
+#define	DB_REGION_INIT				0x00020000
+#define	DB_REGISTER				0x00040000
+#define	DB_RENUMBER				0x00000080
+#define	DB_REPMGR_CONF_2SITE_STRICT		0x00000001
+#define	DB_REPMGR_CONF_ELECTIONS		0x00000002
+#define	DB_REPMGR_NEED_RESPONSE			0x00000001
+#define	DB_REPMGR_PEER				0x00000010
+#define	DB_REP_ANYWHERE				0x00000001
+#define	DB_REP_CLIENT				0x00000001
+#define	DB_REP_CONF_AUTOINIT			0x00000004
+#define	DB_REP_CONF_AUTOROLLBACK		0x00000008
+#define	DB_REP_CONF_BULK			0x00000010
+#define	DB_REP_CONF_DELAYCLIENT			0x00000020
+#define	DB_REP_CONF_INMEM			0x00000040
+#define	DB_REP_CONF_LEASE			0x00000080
+#define	DB_REP_CONF_NOWAIT			0x00000100
+#define	DB_REP_ELECTION				0x00000004
+#define	DB_REP_MASTER				0x00000002
+#define	DB_REP_NOBUFFER				0x00000002
+#define	DB_REP_PERMANENT			0x00000004
+#define	DB_REP_REREQUEST			0x00000008
+#define	DB_REVSPLITOFF				0x00000100
+#define	DB_RMW					0x00002000
+#define	DB_SALVAGE				0x00000040
+#define	DB_SA_SKIPFIRSTKEY			0x00000080
+#define	DB_SA_UNKNOWNKEY			0x00000100
+#define	DB_SEQ_DEC				0x00000001
+#define	DB_SEQ_INC				0x00000002
+#define	DB_SEQ_RANGE_SET			0x00000004
+#define	DB_SEQ_WRAP				0x00000008
+#define	DB_SEQ_WRAPPED				0x00000010
+#define	DB_SET_LOCK_TIMEOUT			0x00000001
+#define	DB_SET_REG_TIMEOUT			0x00000004
+#define	DB_SET_TXN_NOW				0x00000008
+#define	DB_SET_TXN_TIMEOUT			0x00000002
+#define	DB_SHALLOW_DUP				0x00000100
+#define	DB_SNAPSHOT				0x00000200
+#define	DB_STAT_ALL				0x00000004
+#define	DB_STAT_ALLOC				0x00000008
+#define	DB_STAT_CLEAR				0x00000001
+#define	DB_STAT_LOCK_CONF			0x00000010
+#define	DB_STAT_LOCK_LOCKERS			0x00000020
+#define	DB_STAT_LOCK_OBJECTS			0x00000040
+#define	DB_STAT_LOCK_PARAMS			0x00000080
+#define	DB_STAT_MEMP_HASH			0x00000010
+#define	DB_STAT_MEMP_NOERROR			0x00000020
+#define	DB_STAT_SUBSYSTEM			0x00000002
+#define	DB_STAT_SUMMARY				0x00000010
+#define	DB_ST_DUPOK				0x00000200
+#define	DB_ST_DUPSET				0x00000400
+#define	DB_ST_DUPSORT				0x00000800
+#define	DB_ST_IS_RECNO				0x00001000
+#define	DB_ST_OVFL_LEAF				0x00002000
+#define	DB_ST_RECNUM				0x00004000
+#define	DB_ST_RELEN				0x00008000
+#define	DB_ST_TOPLEVEL				0x00010000
+#define	DB_SYSTEM_MEM				0x00080000
+#define	DB_THREAD				0x00000020
+#define	DB_TIME_NOTGRANTED			0x00040000
+#define	DB_TRUNCATE				0x00020000
+#define	DB_TXN_BULK				0x00000010
+#define	DB_TXN_FAMILY				0x00000040
+#define	DB_TXN_NOSYNC				0x00000001
+#define	DB_TXN_NOT_DURABLE			0x00000004
+#define	DB_TXN_NOWAIT				0x00000002
+#define	DB_TXN_SNAPSHOT				0x00000004
+#define	DB_TXN_SYNC				0x00000008
+#define	DB_TXN_WAIT				0x00000080
+#define	DB_TXN_WRITE_NOSYNC			0x00000020
+#define	DB_UNREF				0x00020000
+#define	DB_UPGRADE				0x00000001
+#define	DB_USE_ENVIRON				0x00000004
+#define	DB_USE_ENVIRON_ROOT			0x00000008
+#define	DB_VERB_BACKUP				0x00000001
+#define	DB_VERB_DEADLOCK			0x00000002
+#define	DB_VERB_FILEOPS				0x00000004
+#define	DB_VERB_FILEOPS_ALL			0x00000008
+#define	DB_VERB_RECOVERY			0x00000010
+#define	DB_VERB_REGISTER			0x00000020
+#define	DB_VERB_REPLICATION			0x00000040
+#define	DB_VERB_REPMGR_CONNFAIL			0x00000080
+#define	DB_VERB_REPMGR_MISC			0x00000100
+#define	DB_VERB_REP_ELECT			0x00000200
+#define	DB_VERB_REP_LEASE			0x00000400
+#define	DB_VERB_REP_MISC			0x00000800
+#define	DB_VERB_REP_MSGS			0x00001000
+#define	DB_VERB_REP_SYNC			0x00002000
+#define	DB_VERB_REP_SYSTEM			0x00004000
+#define	DB_VERB_REP_TEST			0x00008000
+#define	DB_VERB_WAITSFOR			0x00010000
+#define	DB_VERIFY				0x00000002
+#define	DB_VERIFY_PARTITION			0x00040000
+#define	DB_WRITECURSOR				0x00000010
+#define	DB_WRITELOCK				0x00000020
+#define	DB_WRITEOPEN				0x00040000
+#define	DB_XA_CREATE				0x00000001
+#define	DB_YIELDCPU				0x00080000
+
+/* DO NOT EDIT: automatically built by dist/s_include.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef	_DB_EXT_PROT_IN_
+#define	_DB_EXT_PROT_IN_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int db_copy __P((DB_ENV *, const char *, const char *, const char *));
+int db_create __P((DB **, DB_ENV *, u_int32_t));
+char *db_strerror __P((int));
+int db_env_set_func_assert __P((void (*)(const char *, const char *, int)));
+int db_env_set_func_close __P((int (*)(int)));
+int db_env_set_func_dirfree __P((void (*)(char **, int)));
+int db_env_set_func_dirlist __P((int (*)(const char *, char ***, int *)));
+int db_env_set_func_exists __P((int (*)(const char *, int *)));
+int db_env_set_func_free __P((void (*)(void *)));
+int db_env_set_func_fsync __P((int (*)(int)));
+int db_env_set_func_ftruncate __P((int (*)(int, off_t)));
+int db_env_set_func_ioinfo __P((int (*)(const char *, int, u_int32_t *, u_int32_t *, u_int32_t *)));
+int db_env_set_func_malloc __P((void *(*)(size_t)));
+int db_env_set_func_file_map __P((int (*)(DB_ENV *, char *, size_t, int, void **), int (*)(DB_ENV *, void *)));
+int db_env_set_func_region_map __P((int (*)(DB_ENV *, char *, size_t, int *, void **), int (*)(DB_ENV *, void *)));
+int db_env_set_func_pread __P((ssize_t (*)(int, void *, size_t, off_t)));
+int db_env_set_func_pwrite __P((ssize_t (*)(int, const void *, size_t, off_t)));
+int db_env_set_func_open __P((int (*)(const char *, int, ...)));
+int db_env_set_func_read __P((ssize_t (*)(int, void *, size_t)));
+int db_env_set_func_realloc __P((void *(*)(void *, size_t)));
+int db_env_set_func_rename __P((int (*)(const char *, const char *)));
+int db_env_set_func_seek __P((int (*)(int, off_t, int)));
+int db_env_set_func_unlink __P((int (*)(const char *)));
+int db_env_set_func_write __P((ssize_t (*)(int, const void *, size_t)));
+int db_env_set_func_yield __P((int (*)(u_long, u_long)));
+int db_env_create __P((DB_ENV **, u_int32_t));
+char *db_version __P((int *, int *, int *));
+char *db_full_version __P((int *, int *, int *, int *, int *));
+int log_compare __P((const DB_LSN *, const DB_LSN *));
+#if defined(DB_WIN32) && !defined(DB_WINCE)
+int db_env_set_win_security __P((SECURITY_ATTRIBUTES *sa));
+#endif
+int db_sequence_create __P((DB_SEQUENCE **, DB *, u_int32_t));
+#if DB_DBM_HSEARCH != 0
+int	 __db_ndbm_clearerr __P((DBM *));
+void	 __db_ndbm_close __P((DBM *));
+int	 __db_ndbm_delete __P((DBM *, datum));
+int	 __db_ndbm_dirfno __P((DBM *));
+int	 __db_ndbm_error __P((DBM *));
+datum __db_ndbm_fetch __P((DBM *, datum));
+datum __db_ndbm_firstkey __P((DBM *));
+datum __db_ndbm_nextkey __P((DBM *));
+DBM	*__db_ndbm_open __P((const char *, int, int));
+int	 __db_ndbm_pagfno __P((DBM *));
+int	 __db_ndbm_rdonly __P((DBM *));
+int	 __db_ndbm_store __P((DBM *, datum, datum, int));
+int	 __db_dbm_close __P((void));
+int	 __db_dbm_delete __P((datum));
+datum __db_dbm_fetch __P((datum));
+datum __db_dbm_firstkey __P((void));
+int	 __db_dbm_init __P((char *));
+datum __db_dbm_nextkey __P((datum));
+int	 __db_dbm_store __P((datum, datum));
+#endif
+#if DB_DBM_HSEARCH != 0
+int __db_hcreate __P((size_t));
+ENTRY *__db_hsearch __P((ENTRY, ACTION));
+void __db_hdestroy __P((void));
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !_DB_EXT_PROT_IN_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/windows_incl/db_config.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,706 @@
+/* DO NOT EDIT: automatically built by dist/s_windows. */
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+/* Define to 1 if you want to build a version for running the test suite. */
+/* #undef CONFIG_TEST */
+
+/* Defined to a size to limit the stack size of Berkeley DB threads. */
+/* #undef DB_STACKSIZE */
+
+/* We use DB_WIN32 much as one would use _WIN32 -- to specify that we're using
+   an operating system environment that supports Win32 calls and semantics. We
+   don't use _WIN32 because Cygwin/GCC also defines _WIN32, even though
+   Cygwin/GCC closely emulates the Unix environment. */
+#define DB_WIN32 1
+
+/* Define to 1 if you want a debugging version. */
+#if defined(_DEBUG)
+#if !defined(DEBUG)
+#define DEBUG 1
+#endif
+#endif
+
+/* Define to 1 if you want a version that logs read operations. */
+/* #undef DEBUG_ROP */
+
+/* Define to 1 if you want a version that logs write operations. */
+/* #undef DEBUG_WOP */
+
+/* Define to 1 if you want a version with run-time diagnostic checking. */
+/* #undef DIAGNOSTIC */
+
+/* Define to 1 if building only the most basic features. */
+#define HAVE_RDS_BUILD 1
+
+/* Define to 1 if 64-bit types are available. */
+#define HAVE_64BIT_TYPES 1
+
+/* Define to 1 if you have the `abort' function. */
+#define HAVE_ABORT 1
+
+/* Define to 1 if you have the `atoi' function. */
+#define HAVE_ATOI 1
+
+/* Define to 1 if you have the `atol' function. */
+#define HAVE_ATOL 1
+
+/* Define to 1 if platform reads and writes files atomically. */
+/* #undef HAVE_ATOMICFILEREAD */
+
+/* Define to 1 to use Solaris library routes for atomic operations. */
+/* #undef HAVE_ATOMIC_SOLARIS */
+
+/* Define to 1 to use native atomic operations. */
+#define HAVE_ATOMIC_SUPPORT 1
+
+/* Define to 1 to use GCC and x86 or x86_64 assemlby language atomic
+   operations. */
+/* #undef HAVE_ATOMIC_X86_GCC_ASSEMBLY */
+
+/* Define to 1 if you have the `backtrace' function. */
+/* Define to 1 if you have the `backtrace' function. */
+/* #undef HAVE_BACKTRACE */
+
+/* Define to 1 if you have the `backtrace_symbols' function. */
+/* #undef HAVE_BACKTRACE_SYMBOLS */
+
+/* Define to 1 if you have the `bsearch' function. */
+#define HAVE_BSEARCH 1
+
+/* Define to 1 if you have the `clock_gettime' function. */
+/* #undef HAVE_CLOCK_GETTIME */
+
+/* Define to 1 if clock_gettime supports CLOCK_MONOTONIC. */
+/* #undef HAVE_CLOCK_MONOTONIC */
+
+/* Define to 1 if building compression support. */
+#if !defined(HAVE_SMALLBUILD) && !defined(HAVE_RDS_BUILD)
+#define HAVE_COMPRESSION 1
+#endif
+
+/* Define to 1 if Berkeley DB release includes strong cryptography. */
+#if !defined(HAVE_SMALLBUILD) && !defined(HAVE_RDS_BUILD)
+#define HAVE_CRYPTO 1
+#endif
+
+/* Define to 1 if using Intel IPP for cryptography. */
+/* #undef HAVE_CRYPTO_IPP */
+
+/* Define to 1 if you have the `ctime_r' function. */
+/* #undef HAVE_CTIME_R  */
+
+/* Define to 1 if ctime_r takes a buffer length as a third argument. */
+/* #undef HAVE_CTIME_R_3ARG */
+
+/* Define to 1 if building the DBM API. */
+#define HAVE_DBM 1
+
+/* Define to 1 if you have the `directio' function. */
+/* #undef HAVE_DIRECTIO */
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+/* #undef HAVE_DIRENT_H */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+/* #undef HAVE_DLFCN_H */
+
+/* Define to 1 to use dtrace for performance event tracing. */
+/* #undef HAVE_DTRACE */
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+/* #undef HAVE_EXECINFO_H */
+
+/* Define to 1 if you have EXIT_SUCCESS/EXIT_FAILURE #defines. */
+#define HAVE_EXIT_SUCCESS 1
+
+/* Define to 1 if you have the `fchmod' function. */
+/* #undef HAVE_FCHMOD */
+
+/* Define to 1 if you have the `fclose' function. */
+#define HAVE_FCLOSE 1
+
+/* Define to 1 if you have the `fcntl' function. */
+/* #undef HAVE_FCNTL */
+
+/* Define to 1 if fcntl/F_SETFD denies child access to file descriptors. */
+/* #undef HAVE_FCNTL_F_SETFD */
+
+/* Define to 1 if you have the `fdatasync' function. */
+/* #undef HAVE_FDATASYNC */
+
+/* Define to 1 if you have the `fgetc' function. */
+#define HAVE_FGETC 1
+
+/* Define to 1 if you have the `fgets' function. */
+#define HAVE_FGETS 1
+
+/* Define to 1 if allocated filesystem blocks are not zeroed. */
+#define HAVE_FILESYSTEM_NOTZERO 1
+
+/* Define to 1 if you have the `fopen' function. */
+#define HAVE_FOPEN 1
+
+/* Define to 1 if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define to 1 if you have the `fwrite' function. */
+#define HAVE_FWRITE 1
+
+/* Define to 1 if you have the `getaddrinfo' function. */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if you have the `getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define to 1 if you have the `getenv' function. */
+#define HAVE_GETENV 1
+
+/* Define to 1 if you have the `getgid' function. */
+/* #undef HAVE_GETGID */
+
+/* Define to 1 if you have the `getopt' function. */
+/*
+ * Windows does not have the getopt function, but as Berkeley DB example
+ * programs require getopt, we handle it outside of this configuration.
+ */
+#define	HAVE_GETOPT 1
+
+/* Define to 1 if getopt supports the optreset variable. */
+#define HAVE_GETOPT_OPTRESET 1
+
+/* Define to 1 if you have the `getrusage' function. */
+/* #undef HAVE_GETRUSAGE */
+
+/* Define to 1 if you have the `gettimeofday' function. */
+/* #undef HAVE_GETTIMEOFDAY */
+
+/* Define to 1 if you have the `getuid' function. */
+/* #undef HAVE_GETUID */
+
+/* Define to 1 if building Hash access method. */
+#if !defined(HAVE_SMALLBUILD) && !defined(HAVE_RDS_BUILD)
+#define HAVE_HASH 1
+#endif
+
+/* Define to 1 if building Heap access method. */
+#if !defined(HAVE_SMALLBUILD) && !defined(HAVE_RDS_BUILD)
+#define HAVE_HEAP 1
+#endif
+
+/* Define to 1 if you have the `hstrerror' function. */
+/* #undef HAVE_HSTRERROR */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+/* #undef HAVE_INTTYPES_H */
+
+/* Define to 1 if you have the `isalpha' function. */
+/* #undef HAVE_ISALPHA */
+
+/* Define to 1 if you have the `isdigit' function. */
+#define HAVE_ISDIGIT 1
+
+/* Define to 1 if you have the `isprint' function. */
+#define HAVE_ISPRINT 1
+
+/* Define to 1 if you have localization function to support globalization. */
+/* #undef HAVE_LOCALIZATION */
+
+/* Define to 1 if you have the `localtime' function. */
+#define HAVE_LOCALTIME 1
+
+/* Define to 1 to enable log checksums. */
+/* #undef HAVE_LOG_CHECKSUM */
+
+/* Define to 1 if you have the `isspace' function. */
+#define HAVE_ISSPACE 1
+
+/* Define to 1 if you have the `memcmp' function. */
+#define HAVE_MEMCMP 1
+
+/* Define to 1 if you have the `memcpy' function. */
+#define HAVE_MEMCPY 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mlock' function. */
+/* #undef HAVE_MLOCK */
+
+/* Define to 1 if you have the `mmap' function. */
+/* #undef HAVE_MMAP */
+
+/* Define to 1 where mmap() incrementally extends the accessible mapping as
+   the underlying file grows. */
+/* #undef HAVE_MMAP_EXTEND */
+
+/* Define to 1 if you have the `mprotect' function. */
+/* #undef HAVE_MPROTECT */
+
+/* Define to 1 if you have the `munlock' function. */
+/* #undef HAVE_MUNLOCK */
+
+/* Define to 1 if you have the `munmap' function. */
+/* #undef HAVE_MUNMAP */
+
+/* Define to 1 to use the GCC compiler and 68K assembly language mutexes. */
+/* #undef HAVE_MUTEX_68K_GCC_ASSEMBLY */
+
+/* Define to 1 to use the AIX _check_lock mutexes. */
+/* #undef HAVE_MUTEX_AIX_CHECK_LOCK */
+
+/* Define to 1 to use the GCC compiler and Alpha assembly language mutexes. */
+/* #undef HAVE_MUTEX_ALPHA_GCC_ASSEMBLY */
+
+/* Define to 1 to use the GCC compiler and ARM assembly language mutexes. */
+/* #undef HAVE_MUTEX_ARM_GCC_ASSEMBLY */
+
+/* Define to 1 to use the Apple/Darwin _spin_lock_try mutexes. */
+/* #undef HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY */
+
+/* Define to 1 to use the UNIX fcntl system call mutexes. */
+/* #undef HAVE_MUTEX_FCNTL */
+
+/* Define to 1 to use the GCC compiler and PaRisc assembly language mutexes.
+   */
+/* #undef HAVE_MUTEX_HPPA_GCC_ASSEMBLY */
+
+/* Define to 1 to use the msem_XXX mutexes on HP-UX. */
+/* #undef HAVE_MUTEX_HPPA_MSEM_INIT */
+
+/* Define to 1 to use test-and-set mutexes with blocking mutexes. */
+/* #undef HAVE_MUTEX_HYBRID */
+
+/* Define to 1 to use the GCC compiler and IA64 assembly language mutexes. */
+/* #undef HAVE_MUTEX_IA64_GCC_ASSEMBLY */
+
+/* Define to 1 to use the GCC compiler and MIPS assembly language mutexes. */
+/* #undef HAVE_MUTEX_MIPS_GCC_ASSEMBLY */
+
+/* Define to 1 to use the msem_XXX mutexes on systems other than HP-UX. */
+/* #undef HAVE_MUTEX_MSEM_INIT */
+
+/* Define to 1 to use the GCC compiler and PowerPC assembly language mutexes.
+   */
+/* #undef HAVE_MUTEX_PPC_GCC_ASSEMBLY */
+
+/* Define to 1 to use POSIX 1003.1 pthread_XXX mutexes. */
+/* #undef HAVE_MUTEX_PTHREADS */
+
+/* Define to 1 to use Reliant UNIX initspin mutexes. */
+/* #undef HAVE_MUTEX_RELIANTUNIX_INITSPIN */
+
+/* Define to 1 to use the IBM C compiler and S/390 assembly language mutexes.
+   */
+/* #undef HAVE_MUTEX_S390_CC_ASSEMBLY */
+
+/* Define to 1 to use the GCC compiler and S/390 assembly language mutexes. */
+/* #undef HAVE_MUTEX_S390_GCC_ASSEMBLY */
+
+/* Define to 1 to use the SCO compiler and x86 assembly language mutexes. */
+/* #undef HAVE_MUTEX_SCO_X86_CC_ASSEMBLY */
+
+/* Define to 1 to use the obsolete POSIX 1003.1 sema_XXX mutexes. */
+/* #undef HAVE_MUTEX_SEMA_INIT */
+
+/* Define to 1 to use the SGI XXX_lock mutexes. */
+/* #undef HAVE_MUTEX_SGI_INIT_LOCK */
+
+/* Define to 1 to use the Solaris _lock_XXX mutexes. */
+/* #undef HAVE_MUTEX_SOLARIS_LOCK_TRY */
+
+/* Define to 1 to use the Solaris lwp threads mutexes. */
+/* #undef HAVE_MUTEX_SOLARIS_LWP */
+
+/* Define to 1 to use the GCC compiler and Sparc assembly language mutexes. */
+/* #undef HAVE_MUTEX_SPARC_GCC_ASSEMBLY */
+
+/* Define to 1 if the Berkeley DB library should support mutexes. */
+#define HAVE_MUTEX_SUPPORT 1
+
+/* Define to 1 if mutexes hold system resources. */
+/* #undef HAVE_MUTEX_SYSTEM_RESOURCES */
+
+/* Define to 1 to configure mutexes intra-process only. */
+/* #undef HAVE_MUTEX_THREAD_ONLY */
+
+/* Define to 1 to use the CC compiler and Tru64 assembly language mutexes. */
+/* #undef HAVE_MUTEX_TRU64_CC_ASSEMBLY */
+
+/* Define to 1 to use the UNIX International mutexes. */
+/* #undef HAVE_MUTEX_UI_THREADS */
+
+/* Define to 1 to use the UTS compiler and assembly language mutexes. */
+/* #undef HAVE_MUTEX_UTS_CC_ASSEMBLY */
+
+/* Define to 1 to use VMS mutexes. */
+/* #undef HAVE_MUTEX_VMS */
+
+/* Define to 1 to use VxWorks mutexes. */
+/* #undef HAVE_MUTEX_VXWORKS */
+
+/* Define to 1 to use the MSVC compiler and Windows mutexes. */
+#define HAVE_MUTEX_WIN32 1
+
+/* Define to 1 to use the GCC compiler and Windows mutexes. */
+/* #undef HAVE_MUTEX_WIN32_GCC */
+
+/* Define to 1 to use the GCC compiler and 64-bit x86 assembly language
+   mutexes. */
+/* #undef HAVE_MUTEX_X86_64_GCC_ASSEMBLY */
+
+/* Define to 1 to use the GCC compiler and 32-bit x86 assembly language
+   mutexes. */
+/* #undef HAVE_MUTEX_X86_GCC_ASSEMBLY */
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+/* #undef HAVE_NDIR_H */
+
+/* Define to 1 if you have the O_DIRECT flag. */
+/* #undef HAVE_O_DIRECT */
+
+/* Define to 1 if building partitioned database support. */
+#if !defined(HAVE_SMALLBUILD) && !defined(HAVE_RDS_BUILD)
+#define HAVE_PARTITION 1
+#endif
+
+/* Define to 1 to enable some kind of performance event monitoring. */
+/* #undef HAVE_PERFMON */
+
+/* Define to 1 to enable performance event monitoring of *_stat() statistics.
+   */
+/* #undef HAVE_PERFMON_STATISTICS */
+
+/* Define to 1 if you have the `pread' function. */
+/* #undef HAVE_PREAD */
+
+/* Define to 1 if you have the `printf' function. */
+#define HAVE_PRINTF 1
+
+/* Define to 1 if you have the `pstat_getdynamic' function. */
+/* #undef HAVE_PSTAT_GETDYNAMIC */
+
+/* Define to 1 if it is OK to initialize an already initialized
+   pthread_cond_t. */
+/* #undef HAVE_PTHREAD_COND_REINIT_OKAY */
+
+/* Define to 1 if it is OK to initialize an already initialized
+   pthread_rwlock_t. */
+/* #undef HAVE_PTHREAD_RWLOCK_REINIT_OKAY */
+
+/* Define to 1 if you have the `pthread_self' function. */
+/* #undef HAVE_PTHREAD_SELF */
+
+/* Define to 1 if you have the `pthread_yield' function. */
+/* #undef HAVE_PTHREAD_YIELD */
+
+/* Define to 1 if you have the `pwrite' function. */
+/* #undef HAVE_PWRITE */
+
+/* Define to 1 if building on QNX. */
+/* #undef HAVE_QNX */
+
+/* Define to 1 if you have the `qsort' function. */
+#define HAVE_QSORT 1
+
+/* Define to 1 if building Queue access method. */
+#if !defined(HAVE_SMALLBUILD) && !defined(HAVE_RDS_BUILD)
+#define HAVE_QUEUE 1
+#endif
+
+/* Define to 1 if you have the `raise' function. */
+#define HAVE_RAISE 1
+
+/* Define to 1 if you have the `rand' function. */
+#define HAVE_RAND 1
+
+/* Define to 1 if you have the `random' function. */
+/* #undef HAVE_RANDOM */
+
+/* Define to 1 if building replication support. */
+#if !defined(HAVE_SMALLBUILD) && !defined(HAVE_RDS_BUILD)
+#define HAVE_REPLICATION 1
+#endif
+
+/* Define to 1 if building the Berkeley DB replication framework. */
+#if !defined(HAVE_SMALLBUILD) && !defined(HAVE_RDS_BUILD)
+#define HAVE_REPLICATION_THREADS 1
+#endif
+
+/* Define to 1 if you have the `sched_yield' function. */
+/* #undef HAVE_SCHED_YIELD */
+
+/* Define to 1 if you have the `select' function. */
+/* #undef HAVE_SELECT */
+
+/* Define to 1 if you have the `setgid' function. */
+/* #undef HAVE_SETGID */
+
+/* Define to 1 if you have the `setuid' function. */
+#define HAVE_SETUID 1
+
+/* Define to 1 to configure Berkeley DB to use shared, read/write latches. */
+#define HAVE_SHARED_LATCHES 1
+
+/* Define to 1 if shmctl/SHM_LOCK locks down shared memory segments. */
+/* #undef HAVE_SHMCTL_SHM_LOCK */
+
+/* Define to 1 if you have the `shmget' function. */
+/* #undef HAVE_SHMGET */
+
+/* Define to 1 if you have the `sigaction' function. */
+/* #undef HAVE_SIGACTION */
+
+/* Define to 1 if thread identifier type db_threadid_t is integral. */
+#define HAVE_SIMPLE_THREAD_TYPE 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the `stat' function. */
+#define HAVE_STAT 1
+
+/* Define to 1 if building statistics support. */
+#define HAVE_STATISTICS 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+/* #undef HAVE_STDINT_H */
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strcat' function. */
+#define HAVE_STRCAT 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the `strftime' function. */
+#define HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if building without output message content. */
+#ifdef HAVE_SMALLBUILD
+#define HAVE_STRIPPED_MESSAGES 1
+#endif
+
+/* Define to 1 if you have the `strncat' function. */
+#define HAVE_STRNCAT 1
+
+/* Define to 1 if you have the `strncmp' function. */
+#define HAVE_STRNCMP 1
+
+/* Define to 1 if you have the `strrchr' function. */
+#define HAVE_STRRCHR 1
+
+/* Define to 1 if you have the `strsep' function. */
+/* #undef HAVE_STRSEP */
+
+/* Define to 1 if you have the `strtol' function. */
+#define HAVE_STRTOL 1
+
+/* Define to 1 if you have the `strtoul' function. */
+#define HAVE_STRTOUL 1
+
+/* Define to 1 if `st_blksize' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_BLKSIZE */
+
+/* Define to 1 if you have the `sysconf' function. */
+/* #undef HAVE_SYSCONF */
+
+/* Define to 1 if port includes files in the Berkeley DB source code. */
+/* #undef HAVE_SYSTEM_INCLUDE_FILES */
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define to 1 if you have the <sys/sdt.h> header file. */
+/* #undef HAVE_SYS_SDT_H */
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+/* #undef HAVE_SYS_SELECT_H */
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+/* #undef HAVE_SYS_SOCKET_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+/* #undef HAVE_SYS_TIME_H */
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the `time' function. */
+#define HAVE_TIME 1
+
+/* Define to 1 if building in transaction support. */
+/* #undef HAVE_TRANSACTIONS */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+/* #undef HAVE_UNISTD_H */
+
+/* Define to 1 if unlink of file with open file descriptors will fail. */
+/* #undef HAVE_UNLINK_WITH_OPEN_FAILURE */
+
+/* Define to 1 if port includes historic database upgrade support. */
+#define HAVE_UPGRADE_SUPPORT 1
+
+/* Define to 1 if building access method verification support. */
+#if !defined(HAVE_SMALLBUILD) && !defined(HAVE_RDS_BUILD)
+#define HAVE_VERIFY 1
+#endif
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define to 1 if building VxWorks. */
+/* #undef HAVE_VXWORKS */
+
+/* Define to 1 if you have the `yield' function. */
+/* #undef HAVE_YIELD */
+
+/* Define to 1 if you have the `_fstati64' function. */
+#define HAVE__FSTATI64 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries. */
+/* #undef LT_OBJDIR */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "Oracle Technology Network Berkeley DB forum"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "Berkeley DB"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "Berkeley DB 5.4.0"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "db-5.4.0"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "http://www.oracle.com/technology/software/products/berkeley-db/index.html"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "5.4.0"
+
+/* The size of a `char', as computed by sizeof. */
+/* #undef SIZEOF_CHAR */
+
+/* The size of a `char *', as computed by sizeof. */
+#if defined(_WIN64)
+#define SIZEOF_CHAR_P 8
+#else
+#define SIZEOF_CHAR_P 4
+#endif
+
+/* The size of a `int', as computed by sizeof. */
+/* #undef SIZEOF_INT */
+
+/* The size of a `long', as computed by sizeof. */
+/* #undef SIZEOF_LONG */
+
+/* The size of a `long long', as computed by sizeof. */
+/* #undef SIZEOF_LONG_LONG */
+
+/* The size of a `short', as computed by sizeof. */
+/* #undef SIZEOF_SHORT */
+
+/* The size of a `size_t', as computed by sizeof. */
+/* #undef SIZEOF_SIZE_T */
+
+/* The size of a `unsigned char', as computed by sizeof. */
+/* #undef SIZEOF_UNSIGNED_CHAR */
+
+/* The size of a `unsigned int', as computed by sizeof. */
+/* #undef SIZEOF_UNSIGNED_INT */
+
+/* The size of a `unsigned long', as computed by sizeof. */
+/* #undef SIZEOF_UNSIGNED_LONG */
+
+/* The size of a `unsigned long long', as computed by sizeof. */
+/* #undef SIZEOF_UNSIGNED_LONG_LONG */
+
+/* The size of a `unsigned short', as computed by sizeof. */
+/* #undef SIZEOF_UNSIGNED_SHORT */
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+/* #undef TIME_WITH_SYS_TIME */
+
+/* Define to 1 to mask harmless uninitialized memory read/writes. */
+/* #undef UMRW */
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#define inline __inline
+#endif
+
+/* type to use in place of socklen_t if not defined */
+/* #undef socklen_t */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/windows_incl/db_int.h	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1185 @@
+/* DO NOT EDIT: automatically built by dist/s_windows. */
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#ifndef _DB_INT_H_
+#define	_DB_INT_H_
+
+/*******************************************************
+ * Berkeley DB ANSI/POSIX include files.
+ *******************************************************/
+#ifdef HAVE_SYSTEM_INCLUDE_FILES
+#include <sys/types.h>
+#ifdef DIAG_MVCC
+#include <sys/mman.h>
+#endif
+#include <sys/stat.h>
+
+#if defined(HAVE_REPLICATION_THREADS)
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_VXWORKS
+#include <selectLib.h>
+#endif
+#endif
+
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+
+#ifdef HAVE_VXWORKS
+#include <net/uio.h>
+#else
+#include <sys/uio.h>
+#endif
+
+#if defined(HAVE_REPLICATION_THREADS)
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#endif
+
+#if defined(STDC_HEADERS) || defined(__cplusplus)
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#endif /* !HAVE_SYSTEM_INCLUDE_FILES */
+
+#ifdef DB_WIN32
+#include "dbinc/win_db.h"
+#endif
+
+#ifdef HAVE_DBM
+#undef	DB_DBM_HSEARCH
+#define	DB_DBM_HSEARCH 1
+#endif
+
+#include "db.h"
+#include "clib_port.h"
+
+#include "dbinc/queue.h"
+#include "dbinc/shqueue.h"
+#include "dbinc/perfmon.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * The Windows compiler needs to be told about structures that are available
+ * outside a dll.
+ */
+#if defined(DB_WIN32) && defined(_MSC_VER) && \
+    !defined(DB_CREATE_DLL) && !defined(_LIB)
+#define	__DB_IMPORT __declspec(dllimport)
+#else
+#define	__DB_IMPORT
+#endif
+
+/*******************************************************
+ * Forward structure declarations.
+ *******************************************************/
+struct __db_commit_info; typedef struct __db_commit_info DB_COMMIT_INFO;
+struct __db_reginfo_t;	typedef struct __db_reginfo_t REGINFO;
+struct __db_txnhead;	typedef struct __db_txnhead DB_TXNHEAD;
+struct __db_txnlist;	typedef struct __db_txnlist DB_TXNLIST;
+struct __vrfy_childinfo;typedef struct __vrfy_childinfo VRFY_CHILDINFO;
+struct __vrfy_dbinfo;   typedef struct __vrfy_dbinfo VRFY_DBINFO;
+struct __vrfy_pageinfo; typedef struct __vrfy_pageinfo VRFY_PAGEINFO;
+
+struct __db_log_verify_info;
+struct __txn_verify_info;
+struct __lv_filereg_info;
+struct __lv_ckp_info;
+struct __lv_timestamp_info;
+typedef struct __db_log_verify_info DB_LOG_VRFY_INFO;
+typedef struct __txn_verify_info VRFY_TXN_INFO;
+typedef struct __lv_filereg_info VRFY_FILEREG_INFO;
+typedef struct __lv_filelife VRFY_FILELIFE;
+typedef struct __lv_ckp_info VRFY_CKP_INFO;
+typedef struct __lv_timestamp_info VRFY_TIMESTAMP_INFO;
+
+/*
+ * TXNINFO_HANDLER --
+ *	Callback function pointer type for __iterate_txninfo.
+ */
+typedef int (*TXNINFO_HANDLER) __P((DB_LOG_VRFY_INFO *, VRFY_TXN_INFO *, void *));
+
+typedef SH_TAILQ_HEAD(__hash_head) DB_HASHTAB;
+
+/*******************************************************
+ * General purpose constants and macros.
+ *******************************************************/
+#undef	FALSE
+#define	FALSE		0
+#undef	TRUE
+#define	TRUE		(!FALSE)
+
+#define	MEGABYTE	1048576
+#define	GIGABYTE	1073741824
+
+#define	NS_PER_MS	1000000		/* Nanoseconds in a millisecond */
+#define	NS_PER_US	1000		/* Nanoseconds in a microsecond */
+#define	NS_PER_SEC	1000000000	/* Nanoseconds in a second */
+#define	US_PER_MS	1000		/* Microseconds in a millisecond */
+#define	US_PER_SEC	1000000		/* Microseconds in a second */
+#define	MS_PER_SEC	1000		/* Milliseconds in a second */
+
+#define	RECNO_OOB	0		/* Illegal record number. */
+
+/*
+ * Define a macro which has no runtime effect, yet avoids triggering empty
+ * statement compiler warnings. Use it as the text of conditionally-null macros.
+ */
+#define	NOP_STATEMENT	do { } while (0)
+
+/* Test for a power-of-two (tests true for zero, which doesn't matter here). */
+#define	POWER_OF_TWO(x)	(((x) & ((x) - 1)) == 0)
+
+/* Test for valid page sizes. */
+#define	DB_MIN_PGSIZE	0x000200	/* Minimum page size (512). */
+#define	DB_MAX_PGSIZE	0x010000	/* Maximum page size (65536). */
+#define	IS_VALID_PAGESIZE(x)						\
+	(POWER_OF_TWO(x) && (x) >= DB_MIN_PGSIZE && ((x) <= DB_MAX_PGSIZE))
+
+/* Minimum number of pages cached, by default. */
+#define	DB_MINPAGECACHE	16
+
+/*
+ * If we are unable to determine the underlying filesystem block size, use
+ * 8K on the grounds that most OS's use less than 8K for a VM page size.
+ */
+#define	DB_DEF_IOSIZE	(8 * 1024)
+
+/* Align an integer to a specific boundary. */
+#undef	DB_ALIGN
+#define	DB_ALIGN(v, bound)						\
+	(((v) + (bound) - 1) & ~(((uintmax_t)(bound)) - 1))
+
+/* Increment a pointer to a specific boundary. */
+#undef	ALIGNP_INC
+#define	ALIGNP_INC(p, bound)						\
+	(void *)(((uintptr_t)(p) + (bound) - 1) & ~(((uintptr_t)(bound)) - 1))
+
+/*
+ * DB_ALIGN8 adjusts structure alignments to make sure shared structures have
+ * fixed size and filed offset on both 32bit and 64bit platforms when
+ * HAVE_MIXED_SIZE_ADDRESSING is defined.
+ */
+#ifdef HAVE_MIXED_SIZE_ADDRESSING
+#define DB_ALIGN8 __declspec(align(8))
+#else
+#define DB_ALIGN8
+#endif
+
+/*
+ * Berkeley DB uses the va_copy macro from C99, not all compilers include
+ * it, so add a dumb implementation compatible with pre C99 implementations.
+ */
+#ifndef	va_copy
+#define	va_copy(d, s)	((d) = (s))
+#endif
+
+/*
+ * Print an address as a u_long (a u_long is the largest type we can print
+ * portably).  Most 64-bit systems have made longs 64-bits, so this should
+ * work.
+ */
+#define	P_TO_ULONG(p)	((u_long)(uintptr_t)(p))
+
+/*
+ * Convert a pointer to an integral value.
+ *
+ * The (u_int16_t)(uintptr_t) cast avoids warnings: the (uintptr_t) cast
+ * converts the value to an integral type, and the (u_int16_t) cast converts
+ * it to a small integral type so we don't get complaints when we assign the
+ * final result to an integral type smaller than uintptr_t.
+ */
+#define	P_TO_UINT32(p)	((u_int32_t)(uintptr_t)(p))
+#define	P_TO_UINT16(p)	((u_int16_t)(uintptr_t)(p))
+#define	P_TO_ROFF(p)	((roff_t)(uintptr_t)(p))
+
+/* The converse of P_TO_ROFF() above. */
+#define	ROFF_TO_P(roff)	((void *)(uintptr_t)(roff))
+
+/*
+ * There are several on-page structures that are declared to have a number of
+ * fields followed by a variable length array of items.  The structure size
+ * without including the variable length array or the address of the first of
+ * those elements can be found using SSZ.
+ *
+ * This macro can also be used to find the offset of a structure element in a
+ * structure.  This is used in various places to copy structure elements from
+ * unaligned memory references, e.g., pointers into a packed page.
+ *
+ * There are two versions because compilers object if you take the address of
+ * an array.
+ */
+#undef	SSZ
+#define	SSZ(name, field)  P_TO_UINT16(&(((name *)0)->field))
+
+#undef	SSZA
+#define	SSZA(name, field) P_TO_UINT16(&(((name *)0)->field[0]))
+
+/* Structure used to print flag values. */
+typedef struct __fn {
+	u_int32_t mask;			/* Flag value. */
+	const char *name;		/* Flag name. */
+} FN;
+
+/* Set, clear and test flags. */
+#define	FLD_CLR(fld, f)		(fld) &= ~(f)
+#define	FLD_ISSET(fld, f)	((fld) & (f))
+#define	FLD_SET(fld, f)		(fld) |= (f)
+#define	F_CLR(p, f)		(p)->flags &= ~(f)
+#define	F_ISSET(p, f)		((p)->flags & (f))
+#define	F_SET(p, f)		(p)->flags |= (f)
+#define	F2_CLR(p, f)		((p)->flags2 &= ~(f))
+#define	F2_ISSET(p, f)		((p)->flags2 & (f))
+#define	F2_SET(p, f)		((p)->flags2 |= (f))
+#define	LF_CLR(f)		((flags) &= ~(f))
+#define	LF_ISSET(f)		((flags) & (f))
+#define	LF_SET(f)		((flags) |= (f))
+
+/*
+ * Calculate a percentage.  The values can overflow 32-bit integer arithmetic
+ * so we use floating point.
+ *
+ * When calculating a bytes-vs-page size percentage, we're getting the inverse
+ * of the percentage in all cases, that is, we want 100 minus the percentage we
+ * calculate.
+ */
+#define	DB_PCT(v, total)						\
+	((int)((total) == 0 ? 0 : ((double)(v) * 100) / (total)))
+#define	DB_PCT_PG(v, total, pgsize)					\
+	((int)((total) == 0 ? 0 :					\
+	    100 - ((double)(v) * 100) / (((double)total) * (pgsize))))
+
+/*
+ * Statistics update shared memory and so are expensive -- don't update the
+ * values unless we're going to display the results.
+ * When performance monitoring is enabled, the changed value can be published
+ * (via DTrace or SystemTap) along with another associated value or two.
+ */
+#undef	STAT
+#ifdef	HAVE_STATISTICS
+#define	STAT(x)	x
+#define	STAT_ADJUST(env, cat, subcat, val, amount, id)			\
+	do {								\
+		(val) += (amount);					\
+		STAT_PERFMON2((env), cat, subcat, (val), (id));		\
+	} while (0)
+#define	STAT_ADJUST_VERB(env, cat, subcat, val, amount, id1, id2)	\
+	do {								\
+		(val) += (amount);					\
+		STAT_PERFMON3((env), cat, subcat, (val), (id1), (id2));	\
+	} while (0)
+#define	STAT_INC(env, cat, subcat, val, id) 				\
+	STAT_ADJUST(env, cat, subcat, (val), 1, (id))
+#define	STAT_INC_VERB(env, cat, subcat, val, id1, id2) 			\
+	STAT_ADJUST_VERB((env), cat, subcat, (val), 1, (id1), (id2))
+/*
+ * STAT_DEC() subtracts one rather than adding (-1) with STAT_ADJUST(); the
+ * latter might generate a compilation warning for an unsigned value.
+ */
+#define	STAT_DEC(env, cat, subcat, val, id) 				\
+	do {								\
+		(val)--;						\
+		STAT_PERFMON2((env), cat, subcat, (val), (id));		\
+	} while (0)
+/* N.B.: Add a verbose version of STAT_DEC() when needed. */
+
+#define	STAT_SET(env, cat, subcat, val, newval, id) 			\
+	do {								\
+		(val) = (newval);					\
+		STAT_PERFMON2((env), cat, subcat, (val), (id));		\
+	} while (0)
+#define	STAT_SET_VERB(env, cat, subcat, val, newval, id1, id2) 		\
+	do {								\
+		(val) = (newval);					\
+		STAT_PERFMON3((env), cat, subcat, (val), (id1), (id2));	\
+	} while (0)
+#else
+#define	STAT(x)							NOP_STATEMENT
+#define	STAT_ADJUST(env, cat, subcat, val, amt, id)		NOP_STATEMENT
+#define	STAT_ADJUST_VERB(env, cat, subcat, val, amt, id1, id2)	NOP_STATEMENT
+#define	STAT_INC(env, cat, subcat, val, id)			NOP_STATEMENT
+#define	STAT_INC_VERB(env, cat, subcat, val, id1, id2)		NOP_STATEMENT
+#define	STAT_DEC(env, cat, subcat, val, id)			NOP_STATEMENT
+#define	STAT_SET(env, cat, subcat, val, newval, id)		NOP_STATEMENT
+#define	STAT_SET_VERB(env, cat, subcat, val, newval, id1, id2)	NOP_STATEMENT
+#endif
+
+#if defined HAVE_SIMPLE_THREAD_TYPE
+#define DB_THREADID_INIT(t)	COMPQUIET((t), 0)
+#else
+#define DB_THREADID_INIT(t)	memset(&(t), 0, sizeof(t))
+#endif
+
+/*
+ * These macros are used when an error condition is first noticed. They allow
+ * one to be notified (via e.g. DTrace, SystemTap, ...) when an error occurs
+ * deep inside DB, rather than when it is returned back through the API.
+ *
+ * The second actual argument to these is the second part of the error or
+ * warning event name. They work when 'errcode' is a symbolic name e.g.
+ * EINVAL or DB_LOCK_DEALOCK, not a variable.  Noticing system call failures
+ * would be handled by tracing on syscall exit; when e.g., it returns < 0.
+ */
+#define	ERR_ORIGIN(env, errcode)        				\
+	(PERFMON0(env, error, errcode), errcode)
+
+#define	ERR_ORIGIN_MSG(env, errcode, msg)				\
+	(PERFMON1(env, error, errcode, msg), errcode)
+
+#define	WARNING_ORIGIN(env, errcode)					\
+	(PERFMON0(env, warning, errcode), errcode)
+
+/*
+ * Structure used for callback message aggregation.
+ *
+ * Display values in XXX_stat_print calls.
+ */
+typedef struct __db_msgbuf {
+	char *buf;			/* Heap allocated buffer. */
+	char *cur;			/* Current end of message. */
+	size_t len;			/* Allocated length of buffer. */
+} DB_MSGBUF;
+#define	DB_MSGBUF_INIT(a) do {						\
+	(a)->buf = (a)->cur = NULL;					\
+	(a)->len = 0;							\
+} while (0)
+#define	DB_MSGBUF_FLUSH(env, a) do {					\
+	if ((a)->buf != NULL) {						\
+		if ((a)->cur != (a)->buf)				\
+			__db_msg(env, "%s", (a)->buf);			\
+		__os_free(env, (a)->buf);				\
+		DB_MSGBUF_INIT(a);					\
+	}								\
+} while (0)
+#define	DB_MSGBUF_REP_FLUSH(env, a, diag_msg, regular_msg) do {		\
+	if ((a)->buf != NULL) {						\
+		if ((a)->cur != (a)->buf && diag_msg)			\
+			__db_repmsg(env, "%s", (a)->buf);		\
+		if (regular_msg)					\
+			DB_MSGBUF_FLUSH(env, a);			\
+		else {							\
+			__os_free(env, (a)->buf);			\
+			DB_MSGBUF_INIT(a);				\
+		}							\
+	}								\
+} while (0)
+#define	STAT_FMT(msg, fmt, type, v) do {				\
+	DB_MSGBUF __mb;							\
+	DB_MSGBUF_INIT(&__mb);						\
+	__db_msgadd(env, &__mb, fmt, (type)(v));			\
+	__db_msgadd(env, &__mb, "\t%s", msg);				\
+	DB_MSGBUF_FLUSH(env, &__mb);					\
+} while (0)
+#define	STAT_HEX(msg, v)						\
+	__db_msg(env, "%#lx\t%s", (u_long)(v), msg)
+#define	STAT_ISSET(msg, p)						\
+	__db_msg(env, "%sSet\t%s", (p) == NULL ? "!" : " ", msg)
+#define	STAT_LONG(msg, v)						\
+	__db_msg(env, "%ld\t%s", (long)(v), msg)
+#define	STAT_LSN(msg, lsnp)						\
+	__db_msg(env, "%lu/%lu\t%s",					\
+	    (u_long)(lsnp)->file, (u_long)(lsnp)->offset, msg)
+#define	STAT_POINTER(msg, v)						\
+	__db_msg(env, "%#lx\t%s", P_TO_ULONG(v), msg)
+#define	STAT_STRING(msg, p) do {					\
+	const char *__p = p;	/* p may be a function call. */		\
+	__db_msg(env, "%s\t%s", __p == NULL ? "!Set" : __p, msg);	\
+} while (0)
+#define	STAT_ULONG(msg, v)						\
+	__db_msg(env, "%lu\t%s", (u_long)(v), msg)
+
+/*
+ * The following macros are used to control how error and message strings are
+ * output by Berkeley DB. There are essentially three different controls
+ * available:
+ *  - Default behavior is to output error strings with its unique identifier.
+ *  - If HAVE_STRIPPED_MESSAGES is enabled, a unique identifier along with any
+ *    parameters to the error string will be output.
+ *  - If HAVE_LOCALIZATION is defined, and the '_()' macro is implemented, a
+ *    gettext or ICU style translation will be done.
+ *
+ * Each new string that will be output should be wrapped in a DB_STR* macro.
+ * There are three versions of this macro for different scenarions:
+ *  - DB_STR for strings that need an identifier, and don't have any argument.
+ *  - DB_STR_A for strings that need an identifier, and have argument(s).
+ *  - DB_STR_P for strings that don't need an identifier, and don't have
+ *    arguments.
+ *
+ * Error message IDs are automatically assigned by dist/s_message_id script.
+ */
+#ifdef HAVE_LOCALIZATION
+#define _(msg)	msg	/* Replace with localization function. */
+#else
+#define _(msg)	msg
+#endif
+
+#ifdef HAVE_STRIPPED_MESSAGES
+#define DB_STR_C(msg, fmt)	fmt
+#else
+#define DB_STR_C(msg, fmt)	_(msg)
+#endif
+
+#define DB_MSGID(id)		"BDB" id
+
+#define DB_STR(id, msg)		DB_MSGID(id) " " DB_STR_C(msg, "")
+
+#define DB_STR_A(id, msg, fmt)	DB_MSGID(id) " " DB_STR_C(msg, fmt)
+
+#define DB_STR_P(msg)		_(msg)
+
+/*
+ * There are quite a few places in Berkeley DB where we want to initialize
+ * a DBT from a string or other random pointer type, using a length typed
+ * to size_t in most cases.  This macro avoids a lot of casting.  The macro
+ * comes in two flavors because we often want to clear the DBT first.
+ */
+#define	DB_SET_DBT(dbt, d, s)  do {					\
+	(dbt).data = (void *)(d);					\
+	(dbt).size = (u_int32_t)(s);					\
+} while (0)
+#define	DB_INIT_DBT(dbt, d, s)  do {					\
+	memset(&(dbt), 0, sizeof(dbt));					\
+	DB_SET_DBT(dbt, d, s);						\
+} while (0)
+
+/*******************************************************
+ * API return values
+ *******************************************************/
+/*
+ * Return values that are OK for each different call.  Most calls have a
+ * standard 'return of 0 is only OK value', but some, like db->get have
+ * DB_NOTFOUND as a return value, but it really isn't an error.
+ */
+#define	DB_RETOK_STD(ret)	((ret) == 0)
+#define	DB_RETOK_DBCDEL(ret)	((ret) == 0 || (ret) == DB_KEYEMPTY || \
+				    (ret) == DB_NOTFOUND)
+#define	DB_RETOK_DBCGET(ret)	((ret) == 0 || (ret) == DB_KEYEMPTY || \
+				    (ret) == DB_NOTFOUND)
+#define	DB_RETOK_DBCPUT(ret)	((ret) == 0 || (ret) == DB_KEYEXIST || \
+				    (ret) == DB_NOTFOUND)
+#define	DB_RETOK_DBDEL(ret)	DB_RETOK_DBCDEL(ret)
+#define	DB_RETOK_DBGET(ret)	DB_RETOK_DBCGET(ret)
+#define	DB_RETOK_DBPUT(ret)	((ret) == 0 || (ret) == DB_KEYEXIST)
+#define	DB_RETOK_EXISTS(ret)	DB_RETOK_DBCGET(ret)
+#define	DB_RETOK_LGGET(ret)	((ret) == 0 || (ret) == DB_NOTFOUND)
+#define	DB_RETOK_MPGET(ret)	((ret) == 0 || (ret) == DB_PAGE_NOTFOUND)
+#define	DB_RETOK_REPPMSG(ret)	((ret) == 0 || \
+				    (ret) == DB_REP_IGNORE || \
+				    (ret) == DB_REP_ISPERM || \
+				    (ret) == DB_REP_NEWMASTER || \
+				    (ret) == DB_REP_NEWSITE || \
+				    (ret) == DB_REP_NOTPERM || \
+				    (ret) == DB_REP_WOULDROLLBACK)
+#define	DB_RETOK_REPMGR_LOCALSITE(ret)	((ret) == 0 || (ret) == DB_NOTFOUND)
+#define	DB_RETOK_REPMGR_START(ret) ((ret) == 0 || (ret) == DB_REP_IGNORE)
+#define	DB_RETOK_TXNAPPLIED(ret) ((ret) == 0 || \
+				    (ret) == DB_NOTFOUND ||		\
+				    (ret) == DB_TIMEOUT ||		\
+				    (ret) == DB_KEYEMPTY)
+
+/* Find a reasonable operation-not-supported error. */
+#ifdef	EOPNOTSUPP
+#define	DB_OPNOTSUP	EOPNOTSUPP
+#else
+#ifdef	ENOTSUP
+#define	DB_OPNOTSUP	ENOTSUP
+#else
+#define	DB_OPNOTSUP	EINVAL
+#endif
+#endif
+
+/*******************************************************
+ * Files.
+ *******************************************************/
+/*
+ * We use 1024 as the maximum path length.  It's too hard to figure out what
+ * the real path length is, as it was traditionally stored in <sys/param.h>,
+ * and that file isn't always available.
+ */
+#define	DB_MAXPATHLEN	1024
+
+#define	PATH_DOT	"."	/* Current working directory. */
+				/* Path separator character(s). */
+#define	PATH_SEPARATOR	"\\/:"
+
+/*******************************************************
+ * Environment.
+ *******************************************************/
+/* Type passed to __db_appname(). */
+typedef enum {
+	DB_APP_NONE=0,			/* No type (region). */
+	DB_APP_DATA,			/* Data file. */
+	DB_APP_LOG,			/* Log file. */
+	DB_APP_META,			/* Persistent metadata file. */
+	DB_APP_RECOVER,			/* We are in recovery. */
+	DB_APP_TMP			/* Temporary file. */
+} APPNAME;
+
+/*
+ * A set of macros to check if various functionality has been configured.
+ *
+ * ALIVE_ON	The is_alive function is configured.
+ * CDB_LOCKING	CDB product locking.
+ * CRYPTO_ON	Security has been configured.
+ * LOCKING_ON	Locking has been configured.
+ * LOGGING_ON	Logging has been configured.
+ * MUTEX_ON	Mutexes have been configured.
+ * MPOOL_ON	Memory pool has been configured.
+ * REP_ON	Replication has been configured.
+ * TXN_ON	Transactions have been configured.
+ *
+ * REP_ON is more complex than most: if the BDB library was compiled without
+ * replication support, ENV->rep_handle will be NULL; if the BDB library has
+ * replication support, but it was not configured, the region reference will
+ * be NULL.
+ */
+#define	ALIVE_ON(env)		((env)->dbenv->is_alive != NULL)
+#define	CDB_LOCKING(env)	F_ISSET(env, ENV_CDB)
+#define	CRYPTO_ON(env)		((env)->crypto_handle != NULL)
+#define	LOCKING_ON(env)		((env)->lk_handle != NULL)
+#define	LOGGING_ON(env)		((env)->lg_handle != NULL)
+#define	MPOOL_ON(env)		((env)->mp_handle != NULL)
+#define	MUTEX_ON(env)		((env)->mutex_handle != NULL)
+#define	REP_ON(env)							\
+	((env)->rep_handle != NULL && (env)->rep_handle->region != NULL)
+#define	TXN_ON(env)		((env)->tx_handle != NULL)
+
+/*
+ * STD_LOCKING	Standard locking, that is, locking was configured and CDB
+ *		was not.  We do not do locking in off-page duplicate trees,
+ *		so we check for that in the cursor first.
+ */
+#define	STD_LOCKING(dbc)						\
+	(!F_ISSET(dbc, DBC_OPD) &&					\
+	    !CDB_LOCKING((dbc)->env) && LOCKING_ON((dbc)->env))
+
+/*
+ * IS_RECOVERING: The system is running recovery.
+ */
+#define	IS_RECOVERING(env)						\
+	(LOGGING_ON(env) && F_ISSET((env)->lg_handle, DBLOG_RECOVER))
+
+/* Initialization methods are often illegal before/after open is called. */
+#define	ENV_ILLEGAL_AFTER_OPEN(env, name)				\
+	if (F_ISSET((env), ENV_OPEN_CALLED))				\
+		return (__db_mi_open(env, name, 1));
+#define	ENV_ILLEGAL_BEFORE_OPEN(env, name)				\
+	if (!F_ISSET((env), ENV_OPEN_CALLED))				\
+		return (__db_mi_open(env, name, 0));
+
+/* We're not actually user hostile, honest. */
+#define	ENV_REQUIRES_CONFIG(env, handle, i, flags)			\
+	if (handle == NULL)						\
+		return (__env_not_config(env, i, flags));
+#define	ENV_REQUIRES_CONFIG_XX(env, handle, i, flags)			\
+	if ((env)->handle->region == NULL)				\
+		return (__env_not_config(env, i, flags));
+#define	ENV_NOT_CONFIGURED(env, handle, i, flags)			\
+	if (F_ISSET((env), ENV_OPEN_CALLED))				\
+		ENV_REQUIRES_CONFIG(env, handle, i, flags)
+
+#define	ENV_ENTER_RET(env, ip, ret) do {				\
+	ret = 0;							\
+	PANIC_CHECK_RET(env, ret);					\
+ 	if (ret == 0) {							\
+		if ((env)->thr_hashtab == NULL)				\
+			ip = NULL;					\
+		else 							\
+			ret = __env_set_state(env, &(ip), THREAD_ACTIVE);\
+	}								\
+} while (0)
+
+#define	ENV_ENTER(env, ip) do {						\
+	int __ret;							\
+	ip = NULL;							\
+	ENV_ENTER_RET(env, ip, __ret);					\
+	if (__ret != 0)							\
+		return (__ret);						\
+} while (0)
+
+#define	FAILCHK_THREAD(env, ip) do {					\
+	if ((ip) != NULL)						\
+		(ip)->dbth_state = THREAD_FAILCHK;			\
+} while (0)
+
+#define	ENV_GET_THREAD_INFO(env, ip) ENV_ENTER(env, ip)
+
+#ifdef DIAGNOSTIC
+#define	ENV_LEAVE(env, ip) do {						\
+	if ((ip) != NULL) {						\
+		DB_ASSERT(env, ((ip)->dbth_state == THREAD_ACTIVE  ||	\
+		    (ip)->dbth_state == THREAD_FAILCHK));		\
+		(ip)->dbth_state = THREAD_OUT;				\
+	}								\
+} while (0)
+#else
+#define	ENV_LEAVE(env, ip) do {						\
+	if ((ip) != NULL)						\
+		(ip)->dbth_state = THREAD_OUT;				\
+} while (0)
+#endif
+#ifdef DIAGNOSTIC
+#define	CHECK_THREAD(env) do {						\
+	if ((env)->thr_hashtab != NULL)					\
+		(void)__env_set_state(env, NULL, THREAD_VERIFY);	\
+} while (0)
+#ifdef HAVE_STATISTICS
+#define	CHECK_MTX_THREAD(env, mtx) do {					\
+	if (mtx->alloc_id != MTX_MUTEX_REGION &&			\
+	    mtx->alloc_id != MTX_ENV_REGION &&				\
+	    mtx->alloc_id != MTX_APPLICATION)				\
+		CHECK_THREAD(env);					\
+} while (0)
+#else
+#define	CHECK_MTX_THREAD(env, mtx)	NOP_STATEMENT
+#endif
+#else
+#define	CHECK_THREAD(env)		NOP_STATEMENT
+#define	CHECK_MTX_THREAD(env, mtx)	NOP_STATEMENT
+#endif
+
+typedef enum {
+	THREAD_SLOT_NOT_IN_USE=0,
+	THREAD_OUT,
+	THREAD_ACTIVE,
+	THREAD_BLOCKED,
+	THREAD_BLOCKED_DEAD,
+	THREAD_FAILCHK,
+	THREAD_VERIFY
+} DB_THREAD_STATE;
+
+typedef struct __pin_list {
+	roff_t b_ref;		/* offset to buffer. */
+	int region;		/* region containing buffer. */
+} PIN_LIST;
+#define	PINMAX 4
+
+struct __db_thread_info { /* SHARED */
+	pid_t		dbth_pid;
+	db_threadid_t	dbth_tid;
+	DB_THREAD_STATE	dbth_state;
+	SH_TAILQ_ENTRY	dbth_links;
+	/*
+	 * The next field contains the (process local) reference to the XA
+	 * transaction currently associated with this thread of control.
+	 */
+	SH_TAILQ_HEAD(__dbth_xatxn) dbth_xatxn;
+	u_int32_t	dbth_xa_status;
+	/*
+	 * The following fields track which buffers this thread of
+	 * control has pinned in the mpool buffer cache.
+	 */
+	u_int16_t	dbth_pincount;	/* Number of pins for this thread. */
+	u_int16_t	dbth_pinmax;	/* Number of slots allocated. */
+	roff_t		dbth_pinlist;	/* List of pins. */
+	PIN_LIST	dbth_pinarray[PINMAX];	/* Initial array of slots. */
+#ifdef DIAGNOSTIC
+	roff_t		dbth_locker;	/* Current locker for this thread. */
+	u_int32_t	dbth_check_off;	/* Count of number of LOCK_OFF calls. */
+#endif
+};
+#ifdef DIAGNOSTIC
+#define LOCK_CHECK_OFF(ip) if ((ip) != NULL)				\
+	(ip)->dbth_check_off++
+
+#define LOCK_CHECK_ON(ip) if ((ip) != NULL)				\
+	(ip)->dbth_check_off--
+
+#define LOCK_CHECK(dbc, pgno, mode, type)				\
+	DB_ASSERT((dbc)->dbp->env, (dbc)->locker == NULL ||		\
+	     __db_haslock((dbc)->dbp->env,				\
+	    (dbc)->locker, (dbc)->dbp->mpf, pgno, mode, type) == 0)
+#else
+#define LOCK_CHECK_OFF(ip)	NOP_STATEMENT
+#define LOCK_CHECK_ON(ip)	NOP_STATEMENT
+#define LOCK_CHECK(dbc, pgno, mode)	NOP_STATEMENT
+#endif
+
+typedef struct __env_thread_info {
+	u_int32_t	thr_count;
+	u_int32_t	thr_init;
+	u_int32_t	thr_max;
+	u_int32_t	thr_nbucket;
+	roff_t		thr_hashoff;
+} THREAD_INFO;
+
+#define	DB_EVENT(env, e, einfo) do {					\
+	DB_ENV *__dbenv = (env)->dbenv;					\
+	if (__dbenv->db_event_func != NULL)				\
+		__dbenv->db_event_func(__dbenv, e, einfo);		\
+} while (0)
+
+typedef struct __flag_map {
+	u_int32_t inflag, outflag;
+} FLAG_MAP;
+
+typedef struct __db_backup_handle {
+	int	(*open) __P((DB_ENV *, const char *, const char *, void **));
+	int	(*write) __P((DB_ENV *,
+		    u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *));
+	int	(*close) __P((DB_ENV *, const char *, void *));
+	u_int32_t	size;
+	u_int32_t	read_count;
+	u_int32_t	read_sleep;
+#define	BACKUP_WRITE_DIRECT	0x0001
+	int	flags;
+} DB_BACKUP;
+
+/*
+ * Internal database environment structure.
+ *
+ * This is the private database environment handle.  The public environment
+ * handle is the DB_ENV structure.   The library owns this structure, the user
+ * owns the DB_ENV structure.  The reason there are two structures is because
+ * the user's configuration outlives any particular DB_ENV->open call, and
+ * separate structures allows us to easily discard internal information without
+ * discarding the user's configuration.
+ */
+struct __env {
+	DB_ENV *dbenv;			/* Linked DB_ENV structure */
+
+	/*
+	 * The ENV structure can be used concurrently, so field access is
+	 * protected.
+	 */
+	db_mutex_t mtx_env;		/* ENV structure mutex */
+
+	/*
+	 * Some fields are included in the ENV structure rather than in the
+	 * DB_ENV structure because they are only set as arguments to the
+	 * DB_ENV->open method.  In other words, because of the historic API,
+	 * not for any rational reason.
+	 *
+	 * Arguments to DB_ENV->open.
+	 */
+	char	 *db_home;		/* Database home */
+	u_int32_t open_flags;		/* Flags */
+	int	  db_mode;		/* Default open permissions */
+
+	pid_t	pid_cache;		/* Cached process ID */
+
+	DB_FH	*lockfhp;		/* fcntl(2) locking file handle */
+
+	DB_LOCKER *env_lref;		/* Locker in non-threaded handles */
+
+	DB_DISTAB   recover_dtab;	/* Dispatch table for recover funcs */
+
+	int dir_mode;			/* Intermediate directory perms. */
+
+#define ENV_DEF_DATA_LEN		100
+	u_int32_t data_len;		/* Data length in __db_prbytes. */
+
+	/* Thread tracking */
+	u_int32_t	 thr_nbucket;	/* Number of hash buckets */
+	DB_HASHTAB	*thr_hashtab;	/* Hash table of DB_THREAD_INFO */
+
+	/*
+	 * List of open DB handles for this ENV, used for cursor
+	 * adjustment.  Must be protected for multi-threaded support.
+	 */
+	db_mutex_t mtx_dblist;
+	int	   db_ref;		/* DB handle reference count */
+	TAILQ_HEAD(__dblist, __db) dblist;
+
+	/*
+	 * List of open file handles for this ENV.  Must be protected
+	 * for multi-threaded support.
+	 */
+	TAILQ_HEAD(__fdlist, __fh_t) fdlist;
+
+	db_mutex_t	 mtx_mt;	/* Mersenne Twister mutex */
+	int		 mti;		/* Mersenne Twister index */
+	u_long		*mt;		/* Mersenne Twister state vector */
+
+	DB_CIPHER	*crypto_handle;	/* Crypto handle */
+	DB_LOCKTAB	*lk_handle;	/* Lock handle */
+	DB_LOG		*lg_handle;	/* Log handle */
+	DB_MPOOL	*mp_handle;	/* Mpool handle */
+	DB_MUTEXMGR	*mutex_handle;	/* Mutex handle */
+	DB_REP		*rep_handle;	/* Replication handle */
+	DB_TXNMGR	*tx_handle;	/* Txn handle */
+
+	DB_BACKUP	*backup_handle;	/* database copy configuration. */
+
+	/*
+	 * XA support.
+	 */
+	int		 xa_rmid;	/* XA Resource Manager ID */
+	int		 xa_ref;	/* XA Reference count */
+	TAILQ_ENTRY(__env) links;	/* XA environments */
+
+	/* Application callback to copy data to/from a custom data source */
+#define	DB_USERCOPY_GETDATA	0x0001
+#define	DB_USERCOPY_SETDATA	0x0002
+	int (*dbt_usercopy)
+	    __P((DBT *, u_int32_t, void *, u_int32_t, u_int32_t));
+
+	int (*log_verify_wrap) __P((ENV *, const char *, u_int32_t,
+	    const char *, const char *, time_t, time_t, u_int32_t,  u_int32_t,
+	    u_int32_t, u_int32_t, int, int));
+
+	REGINFO	*reginfo;		/* REGINFO structure reference */
+
+#define	DB_TEST_ELECTINIT	 1	/* after __rep_elect_init */
+#define	DB_TEST_ELECTVOTE1	 2	/* after sending VOTE1 */
+#define	DB_TEST_NO_PAGES	 3	/* before sending PAGE */
+#define	DB_TEST_POSTDESTROY	 4	/* after destroy op */
+#define	DB_TEST_POSTLOG		 5	/* after logging all pages */
+#define	DB_TEST_POSTLOGMETA	 6	/* after logging meta in btree */
+#define	DB_TEST_POSTOPEN	 7	/* after __os_open */
+#define	DB_TEST_POSTSYNC	 8	/* after syncing the log */
+#define	DB_TEST_PREDESTROY	 9	/* before destroy op */
+#define	DB_TEST_PREOPEN		 10	/* before __os_open */
+#define	DB_TEST_REPMGR_PERM	 11	/* repmgr perm/archiving tests */
+#define	DB_TEST_SUBDB_LOCKS	 12	/* subdb locking tests */
+	int	test_abort;		/* Abort value for testing */
+	int	test_check;		/* Checkpoint value for testing */
+	int	test_copy;		/* Copy value for testing */
+
+#define	ENV_CDB			0x00000001 /* DB_INIT_CDB */
+#define	ENV_DBLOCAL		0x00000002 /* Environment for a private DB */
+#define	ENV_LITTLEENDIAN	0x00000004 /* Little endian system. */
+#define	ENV_LOCKDOWN		0x00000008 /* DB_LOCKDOWN set */
+#define	ENV_NO_OUTPUT_SET	0x00000010 /* No output channel set */
+#define	ENV_OPEN_CALLED		0x00000020 /* DB_ENV->open called */
+#define	ENV_PRIVATE		0x00000040 /* DB_PRIVATE set */
+#define	ENV_RECOVER_FATAL	0x00000080 /* Doing fatal recovery in env */
+#define	ENV_REF_COUNTED		0x00000100 /* Region references this handle */
+#define	ENV_SYSTEM_MEM		0x00000200 /* DB_SYSTEM_MEM set */
+#define	ENV_THREAD		0x00000400 /* DB_THREAD set */
+#define ENV_FORCE_TXN_BULK	0x00000800 /* Txns use bulk mode-for testing */
+	u_int32_t flags;
+};
+
+/*******************************************************
+ * Database Access Methods.
+ *******************************************************/
+/*
+ * DB_IS_THREADED --
+ *	The database handle is free-threaded (was opened with DB_THREAD).
+ */
+#define	DB_IS_THREADED(dbp)						\
+	((dbp)->mutex != MUTEX_INVALID)
+
+/* Initialization methods are often illegal before/after open is called. */
+#define	DB_ILLEGAL_AFTER_OPEN(dbp, name)				\
+	if (F_ISSET((dbp), DB_AM_OPEN_CALLED))				\
+		return (__db_mi_open((dbp)->env, name, 1));
+#define	DB_ILLEGAL_BEFORE_OPEN(dbp, name)				\
+	if (!F_ISSET((dbp), DB_AM_OPEN_CALLED))				\
+		return (__db_mi_open((dbp)->env, name, 0));
+/* Some initialization methods are illegal if environment isn't local. */
+#define	DB_ILLEGAL_IN_ENV(dbp, name)					\
+	if (!F_ISSET((dbp)->env, ENV_DBLOCAL))				\
+		return (__db_mi_env((dbp)->env, name));
+#define	DB_ILLEGAL_METHOD(dbp, flags) {					\
+	int __ret;							\
+	if ((__ret = __dbh_am_chk(dbp, flags)) != 0)			\
+		return (__ret);						\
+}
+
+/*
+ * Common DBC->internal fields.  Each access method adds additional fields
+ * to this list, but the initial fields are common.
+ */
+#define	__DBC_INTERNAL							\
+	DBC	 *opd;			/* Off-page duplicate cursor. */\
+	DBC	 *pdbc;			/* Pointer to parent cursor. */ \
+									\
+	void	 *page;			/* Referenced page. */		\
+	u_int32_t part;			/* Partition number. */		\
+	db_pgno_t root;			/* Tree root. */		\
+	db_pgno_t pgno;			/* Referenced page number. */	\
+	db_indx_t indx;			/* Referenced key item index. */\
+									\
+	/* Streaming -- cache last position. */				\
+	db_pgno_t stream_start_pgno;	/* Last start pgno. */		\
+	u_int32_t stream_off;		/* Current offset. */		\
+	db_pgno_t stream_curr_pgno;	/* Current overflow page. */	\
+									\
+	DB_LOCK		lock;		/* Cursor lock. */		\
+	db_lockmode_t	lock_mode;	/* Lock mode. */
+
+struct __dbc_internal {
+	__DBC_INTERNAL
+};
+
+/* Actions that __db_master_update can take. */
+typedef enum { MU_REMOVE, MU_RENAME, MU_OPEN, MU_MOVE } mu_action;
+
+/*
+ * Access-method-common macro for determining whether a cursor
+ * has been initialized.
+ */
+#ifdef HAVE_PARTITION
+#define	IS_INITIALIZED(dbc)	(DB_IS_PARTITIONED((dbc)->dbp) ?	\
+		((PART_CURSOR *)(dbc)->internal)->sub_cursor != NULL && \
+		((PART_CURSOR *)(dbc)->internal)->sub_cursor->		\
+		    internal->pgno != PGNO_INVALID :			\
+		(dbc)->internal->pgno != PGNO_INVALID)
+#else
+#define	IS_INITIALIZED(dbc)	((dbc)->internal->pgno != PGNO_INVALID)
+#endif
+
+/* Free the callback-allocated buffer, if necessary, hanging off of a DBT. */
+#define	FREE_IF_NEEDED(env, dbt)					\
+	if (F_ISSET((dbt), DB_DBT_APPMALLOC)) {				\
+		__os_ufree((env), (dbt)->data);				\
+		F_CLR((dbt), DB_DBT_APPMALLOC);				\
+	}
+
+/*
+ * Use memory belonging to object "owner" to return the results of
+ * any no-DBT-flag get ops on cursor "dbc".
+ */
+#define	SET_RET_MEM(dbc, owner)				\
+	do {						\
+		(dbc)->rskey = &(owner)->my_rskey;	\
+		(dbc)->rkey = &(owner)->my_rkey;	\
+		(dbc)->rdata = &(owner)->my_rdata;	\
+	} while (0)
+
+/* Use the return-data memory src is currently set to use in dest as well. */
+#define	COPY_RET_MEM(src, dest)				\
+	do {						\
+		(dest)->rskey = (src)->rskey;		\
+		(dest)->rkey = (src)->rkey;		\
+		(dest)->rdata = (src)->rdata;		\
+	} while (0)
+
+/* Reset the returned-memory pointers to their defaults. */
+#define	RESET_RET_MEM(dbc)				\
+	do {						\
+		(dbc)->rskey = &(dbc)->my_rskey;	\
+		(dbc)->rkey = &(dbc)->my_rkey;		\
+		(dbc)->rdata = &(dbc)->my_rdata;	\
+	} while (0)
+
+#define	COMPACT_TRUNCATE(c_data) do {			\
+	if (c_data->compact_truncate > 1)		\
+		c_data->compact_truncate--;		\
+} while (0)
+
+/*******************************************************
+ * Mpool.
+ *******************************************************/
+/*
+ * File types for DB access methods.  Negative numbers are reserved to DB.
+ */
+#define	DB_FTYPE_SET		-1		/* Call pgin/pgout functions. */
+#define	DB_FTYPE_NOTSET		 0		/* Don't call... */
+#define	DB_LSN_OFF_NOTSET	-1		/* Not yet set. */
+#define	DB_CLEARLEN_NOTSET	UINT32_MAX	/* Not yet set. */
+
+/* Structure used as the DB pgin/pgout pgcookie. */
+typedef struct __dbpginfo {
+	u_int32_t db_pagesize;		/* Underlying page size. */
+	u_int32_t flags;		/* Some DB_AM flags needed. */
+	DBTYPE  type;			/* DB type */
+} DB_PGINFO;
+
+/*******************************************************
+ * Log.
+ *******************************************************/
+/* Initialize an LSN to 'zero'. */
+#define	ZERO_LSN(LSN) do {						\
+	(LSN).file = 0;							\
+	(LSN).offset = 0;						\
+} while (0)
+#define	IS_ZERO_LSN(LSN)	((LSN).file == 0 && (LSN).offset == 0)
+
+#define	IS_INIT_LSN(LSN)	((LSN).file == 1 && (LSN).offset == 0)
+#define	INIT_LSN(LSN)		do {					\
+	(LSN).file = 1;							\
+	(LSN).offset = 0;						\
+} while (0)
+
+#define	MAX_LSN(LSN) do {						\
+	(LSN).file = UINT32_MAX;					\
+	(LSN).offset = UINT32_MAX;					\
+} while (0)
+#define	IS_MAX_LSN(LSN) \
+	((LSN).file == UINT32_MAX && (LSN).offset == UINT32_MAX)
+
+/* If logging is turned off, smash the lsn. */
+#define	LSN_NOT_LOGGED(LSN) do {					\
+	(LSN).file = 0;							\
+	(LSN).offset = 1;						\
+} while (0)
+#define	IS_NOT_LOGGED_LSN(LSN) \
+	((LSN).file == 0 && (LSN).offset == 1)
+
+/*
+ * LOG_COMPARE -- compare two LSNs.
+ */
+
+#define	LOG_COMPARE(lsn0, lsn1)						\
+	((lsn0)->file != (lsn1)->file ?					\
+	((lsn0)->file < (lsn1)->file ? -1 : 1) :			\
+	((lsn0)->offset != (lsn1)->offset ?				\
+	((lsn0)->offset < (lsn1)->offset ? -1 : 1) : 0))
+
+/*******************************************************
+ * Txn.
+ *******************************************************/
+#define	DB_NONBLOCK(C)	((C)->txn != NULL && F_ISSET((C)->txn, TXN_NOWAIT))
+#define	NOWAIT_FLAG(txn) \
+	((txn) != NULL && F_ISSET((txn), TXN_NOWAIT) ? DB_LOCK_NOWAIT : 0)
+#define	IS_REAL_TXN(txn)						\
+	((txn) != NULL && !F_ISSET(txn, TXN_FAMILY))
+#define	IS_SUBTRANSACTION(txn)						\
+	((txn) != NULL && (txn)->parent != NULL)
+
+/* Checks for existence of an XA transaction in access method interfaces. */
+#define	XA_CHECK_TXN(ip, txn) 						\
+	if ((ip) != NULL && (txn) == NULL) {				\
+		(txn) = SH_TAILQ_FIRST(&(ip)->dbth_xatxn, __db_txn);	\
+		DB_ASSERT(env, txn == NULL ||				\
+		    txn->xa_thr_status == TXN_XA_THREAD_ASSOCIATED);	\
+	}
+
+/* Ensure that there is no XA transaction active. */
+#define	XA_NO_TXN(ip, retval) {						\
+	DB_TXN *__txn;							\
+	retval = 0;							\
+	if ((ip) != NULL) {						\
+		__txn = SH_TAILQ_FIRST(&(ip)->dbth_xatxn, __db_txn);	\
+		if (__txn != NULL &&					\
+		    __txn->xa_thr_status == TXN_XA_THREAD_ASSOCIATED)	\
+		    	retval = EINVAL;				\
+	}								\
+}
+
+/*******************************************************
+ * Crypto.
+ *******************************************************/
+#define	DB_IV_BYTES     16		/* Bytes per IV */
+#define	DB_MAC_KEY	20		/* Bytes per MAC checksum */
+
+/*******************************************************
+ * Compression
+ *******************************************************/
+#define	CMP_INT_SPARE_VAL	0xFC	/* Smallest byte value that the integer
+					   compression algorithm doesn't use */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*******************************************************
+ * Remaining general DB includes.
+ *******************************************************/
+
+
+#include "dbinc/globals.h"
+#include "dbinc/clock.h"
+#include "dbinc/debug.h"
+#include "dbinc/region.h"
+#include "dbinc_auto/env_ext.h"
+#include "dbinc/mutex.h"
+#ifdef HAVE_REPLICATION_THREADS
+#include "dbinc/repmgr.h"
+#endif
+#include "dbinc/rep.h"
+#include "dbinc/os.h"
+#include "dbinc_auto/clib_ext.h"
+#include "dbinc_auto/common_ext.h"
+
+/*******************************************************
+ * Remaining Log.
+ * These need to be defined after the general includes
+ * because they need rep.h from above.
+ *******************************************************/
+/*
+ * Test if the environment is currently logging changes.  If we're in recovery
+ * or we're a replication client, we don't need to log changes because they're
+ * already in the log, even though we have a fully functional log system.
+ */
+#define	DBENV_LOGGING(env)						\
+	(LOGGING_ON(env) && !IS_REP_CLIENT(env) && (!IS_RECOVERING(env)))
+
+/*
+ * Test if we need to log a change.  By default, we don't log operations without
+ * associated transactions, unless DIAGNOSTIC, DEBUG_ROP or DEBUG_WOP are on.
+ * This is because we want to get log records for read/write operations, and, if
+ * we are trying to debug something, more information is always better.
+ *
+ * The DBC_RECOVER flag is set when we're in abort, as well as during recovery;
+ * thus DBC_LOGGING may be false for a particular dbc even when DBENV_LOGGING
+ * is true.
+ *
+ * We explicitly use LOGGING_ON/IS_REP_CLIENT here because we don't want to pull
+ * in the log headers, which IS_RECOVERING (and thus DBENV_LOGGING) rely on, and
+ * because DBC_RECOVER should be set anytime IS_RECOVERING would be true.
+ *
+ * If we're not in recovery (master - doing an abort or a client applying
+ * a txn), then a client's only path through here is on an internal
+ * operation, and a master's only path through here is a transactional
+ * operation.  Detect if either is not the case.
+ */
+#if defined(DIAGNOSTIC) || defined(DEBUG_ROP)  || defined(DEBUG_WOP)
+#define	DBC_LOGGING(dbc)	__dbc_logging(dbc)
+#else
+#define	DBC_LOGGING(dbc)						\
+	((dbc)->txn != NULL && LOGGING_ON((dbc)->env) &&		\
+	    !F_ISSET((dbc), DBC_RECOVER) && !IS_REP_CLIENT((dbc)->env))
+#endif
+
+#endif /* !_DB_INT_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/db_dump.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,556 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+
+#ifndef lint
+static const char copyright[] =
+    "Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.\n";
+#endif
+
+int	 db_init __P((DB_ENV *, char *, int, u_int32_t, int *));
+int	 dump_sub __P((DB_ENV *, DB *, char *, int, int));
+int	 main __P((int, char *[]));
+int	 show_subs __P((DB *));
+int	 usage __P((void));
+int	 version_check __P((void));
+
+const char *progname;
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	extern char *optarg;
+	extern int optind;
+	DB_ENV	*dbenv;
+	DB *dbp;
+	db_pgno_t first, last;
+	u_int32_t cache;
+	int ch;
+	int exitval, keyflag, lflag, mflag, nflag, pflag, sflag, private;
+	int ret, Rflag, rflag, resize;
+	char *data_len, *dbname, *dopt, *filename, *home, *passwd;
+
+	if ((progname = __db_rpath(argv[0])) == NULL)
+		progname = argv[0];
+	else
+		++progname;
+
+	if ((ret = version_check()) != 0)
+		return (ret);
+
+	dbenv = NULL;
+	dbp = NULL;
+	exitval = lflag = mflag = nflag = pflag = rflag = Rflag = sflag = 0;
+	first = last = PGNO_INVALID;
+	keyflag = 0;
+	cache = MEGABYTE;
+	private = 0;
+	data_len = dbname = dopt = filename = home = passwd = NULL;
+	while ((ch = getopt(argc, argv, "d:D:f:F:h:klL:m:NpP:rRs:V")) != EOF)
+		switch (ch) {
+		case 'd':
+			dopt = optarg;
+			break;
+		case 'D':
+			data_len = optarg;
+			break;
+		case 'f':
+			if (freopen(optarg, "w", stdout) == NULL) {
+				fprintf(stderr, DB_STR_A("5108",
+				    "%s: %s: reopen: %s\n", "%s %s %s\n"),
+				    progname, optarg, strerror(errno));
+				return (EXIT_FAILURE);
+			}
+			break;
+		case 'F':
+			first = (db_pgno_t)strtoul(optarg, NULL, 10);
+			break;
+		case 'h':
+			home = optarg;
+			break;
+		case 'k':
+			keyflag = 1;
+			break;
+		case 'l':
+			lflag = 1;
+			break;
+		case 'L':
+			last = (db_pgno_t)strtoul(optarg, NULL, 10);
+			break;
+		case 'm':
+			mflag = 1;
+			dbname = optarg;
+			break;
+		case 'N':
+			nflag = 1;
+			break;
+		case 'P':
+			if (passwd != NULL) {
+				fprintf(stderr, DB_STR("5130",
+					"Password may not be specified twice"));
+				free(passwd);
+				return (EXIT_FAILURE);
+			}
+			passwd = strdup(optarg);
+			memset(optarg, 0, strlen(optarg));
+			if (passwd == NULL) {
+				fprintf(stderr, DB_STR_A("5109",
+				    "%s: strdup: %s\n", "%s %s\n"),
+				    progname, strerror(errno));
+				return (EXIT_FAILURE);
+			}
+			break;
+		case 'p':
+			pflag = 1;
+			break;
+		case 's':
+			sflag = 1;
+			dbname = optarg;
+			break;
+		case 'R':
+			Rflag = 1;
+			/* DB_AGGRESSIVE requires DB_SALVAGE */
+			/* FALLTHROUGH */
+		case 'r':
+			rflag = 1;
+			break;
+		case 'V':
+			printf("%s\n", db_version(NULL, NULL, NULL));
+			return (EXIT_SUCCESS);
+		case '?':
+		default:
+			return (usage());
+		}
+	argc -= optind;
+	argv += optind;
+
+	/*
+	 * A file name must be specified, unless we're looking for an in-memory
+	 * db,  in which case it must not.
+	 */
+	if (argc == 0 && mflag)
+		filename = NULL;
+	else if (argc == 1 && !mflag)
+		filename = argv[0];
+	else
+		return (usage());
+
+	if (dopt != NULL && pflag) {
+		fprintf(stderr, DB_STR_A("5110",
+		    "%s: the -d and -p options may not both be specified\n",
+		    "%s\n"), progname);
+		return (EXIT_FAILURE);
+	}
+	if (lflag && sflag) {
+		fprintf(stderr, DB_STR_A("5111",
+		    "%s: the -l and -s options may not both be specified\n",
+		    "%s\n"), progname);
+		return (EXIT_FAILURE);
+	}
+	if ((lflag || sflag) && mflag) {
+		fprintf(stderr, DB_STR_A("5112",
+		    "%s: the -m option may not be specified with -l or -s\n",
+		    "%s\n"), progname);
+		return (EXIT_FAILURE);
+	}
+
+	if (keyflag && rflag) {
+		fprintf(stderr, DB_STR_A("5113",
+	    "%s: the -k and -r or -R options may not both be specified\n",
+		    "%s\n"), progname);
+		return (EXIT_FAILURE);
+	}
+
+	if (sflag && rflag) {
+		fprintf(stderr, DB_STR_A("5114",
+	    "%s: the -r or R options may not be specified with -s\n",
+		    "%s\n"), progname);
+		return (EXIT_FAILURE);
+	}
+
+	/* Handle possible interruptions. */
+	__db_util_siginit();
+
+	/*
+	 * Create an environment object and initialize it for error
+	 * reporting.
+	 */
+retry:	if ((ret = db_env_create(&dbenv, 0)) != 0) {
+		fprintf(stderr,
+		    "%s: db_env_create: %s\n", progname, db_strerror(ret));
+		goto err;
+	}
+
+	dbenv->set_errfile(dbenv, stderr);
+	dbenv->set_errpfx(dbenv, progname);
+	if (data_len != NULL)
+		(void)dbenv->set_data_len(dbenv, (u_int32_t)atol(data_len));
+
+	if (nflag) {
+		if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) {
+			dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING");
+			goto err;
+		}
+		if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) {
+			dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC");
+			goto err;
+		}
+	}
+	if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv,
+	    passwd, DB_ENCRYPT_AES)) != 0) {
+		dbenv->err(dbenv, ret, "set_passwd");
+		goto err;
+	}
+
+	/* Initialize the environment. */
+	if (db_init(dbenv, home, rflag, cache, &private) != 0)
+		goto err;
+
+	/* Create the DB object and open the file. */
+	if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
+		dbenv->err(dbenv, ret, "db_create");
+		goto err;
+	}
+
+#if 0
+	Set application-specific btree compression functions here. For example:
+	if ((ret = dbp->set_bt_compress(
+	    dbp, local_compress_func, local_decompress_func)) != 0) {
+		dbp->err(dbp, ret, "DB->set_bt_compress");
+		goto err;
+	}
+#endif
+
+	/*
+	 * If we're salvaging, don't do an open;  it might not be safe.
+	 * Dispatch now into the salvager.
+	 */
+	if (rflag) {
+		/* The verify method is a destructor. */
+		ret = dbp->verify(dbp, filename, dbname, stdout,
+		    DB_SALVAGE |
+		    (Rflag ? DB_AGGRESSIVE : 0) |
+		    (pflag ? DB_PRINTABLE : 0));
+		dbp = NULL;
+		if (ret != 0)
+			goto err;
+		goto done;
+	}
+
+	if ((ret = dbp->open(dbp, NULL,
+	    filename, dbname, DB_UNKNOWN, DB_RDWRMASTER|DB_RDONLY, 0)) != 0) {
+		dbp->err(dbp, ret, DB_STR_A("5115", "open: %s", "%s"),
+		    filename == NULL ? dbname : filename);
+		goto err;
+	}
+	if (private != 0) {
+		if ((ret = __db_util_cache(dbp, &cache, &resize)) != 0)
+			goto err;
+		if (resize) {
+			(void)dbp->close(dbp, 0);
+			dbp = NULL;
+
+			(void)dbenv->close(dbenv, 0);
+			dbenv = NULL;
+			goto retry;
+		}
+	}
+
+	if (dopt != NULL) {
+		if ((ret =
+		    __db_dumptree(dbp, NULL, dopt, NULL, first, last)) != 0) {
+			dbp->err(dbp, ret, "__db_dumptree: %s", filename);
+			goto err;
+		}
+	} else if (lflag) {
+		if (dbp->get_multiple(dbp)) {
+			if (show_subs(dbp))
+				goto err;
+		} else {
+			dbp->errx(dbp, DB_STR_A("5116",
+			    "%s: does not contain multiple databases", "%s"),
+			    filename);
+			goto err;
+		}
+	} else {
+		if (dbname == NULL && dbp->get_multiple(dbp)) {
+			if (dump_sub(dbenv, dbp, filename, pflag, keyflag))
+				goto err;
+		} else
+			if (dbp->dump(dbp, NULL,
+			    __db_pr_callback, stdout, pflag, keyflag))
+				goto err;
+	}
+
+	if (0) {
+err:		exitval = 1;
+	}
+done:	if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) {
+		exitval = 1;
+		dbenv->err(dbenv, ret, DB_STR("5117", "close"));
+	}
+	if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) {
+		exitval = 1;
+		fprintf(stderr,
+		    "%s: dbenv->close: %s\n", progname, db_strerror(ret));
+	}
+
+	if (passwd != NULL)
+		free(passwd);
+
+	/* Resend any caught signal. */
+	__db_util_sigresend();
+
+	return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+/*
+ * db_init --
+ *	Initialize the environment.
+ */
+int
+db_init(dbenv, home, is_salvage, cache, is_privatep)
+	DB_ENV *dbenv;
+	char *home;
+	int is_salvage;
+	u_int32_t cache;
+	int *is_privatep;
+{
+	int ret;
+
+	/*
+	 * Try and use the underlying environment when opening a database.
+	 * We wish to use the buffer pool so our information is as up-to-date
+	 * as possible, even if the mpool cache hasn't been flushed.
+	 *
+	 * If we are not doing a salvage, we want to join the environment;
+	 * if a locking system is present, this will let us use it and be
+	 * safe to run concurrently with other threads of control.  (We never
+	 * need to use transactions explicitly, as we're read-only.)  Note
+	 * that in CDB, too, this will configure our environment
+	 * appropriately, and our cursors will (correctly) do locking as CDB
+	 * read cursors.
+	 *
+	 * If we are doing a salvage, the verification code will protest
+	 * if we initialize transactions, logging, or locking;  do an
+	 * explicit DB_INIT_MPOOL to try to join any existing environment
+	 * before we create our own.
+	 */
+	*is_privatep = 0;
+	if ((ret = dbenv->open(dbenv, home,
+	    DB_USE_ENVIRON | (is_salvage ? DB_INIT_MPOOL : 0), 0)) == 0)
+		return (0);
+	if (ret == DB_VERSION_MISMATCH)
+		goto err;
+
+	/*
+	 * An environment is required because we may be trying to look at
+	 * databases in directories other than the current one.  We could
+	 * avoid using an environment iff the -h option wasn't specified,
+	 * but that seems like more work than it's worth.
+	 *
+	 * No environment exists (or, at least no environment that includes
+	 * an mpool region exists).  Create one, but make it private so that
+	 * no files are actually created.
+	 */
+	*is_privatep = 1;
+	if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) == 0 &&
+	    (ret = dbenv->open(dbenv, home,
+	    DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0)) == 0)
+		return (0);
+
+	/* An environment is required. */
+err:	dbenv->err(dbenv, ret, "DB_ENV->open");
+	return (1);
+}
+
+/*
+ * dump_sub --
+ *	Dump out the records for a DB containing subdatabases.
+ */
+int
+dump_sub(dbenv, parent_dbp, parent_name, pflag, keyflag)
+	DB_ENV *dbenv;
+	DB *parent_dbp;
+	char *parent_name;
+	int pflag, keyflag;
+{
+	DB *dbp;
+	DBC *dbcp;
+	DBT key, data;
+	int ret;
+	char *subdb;
+
+	/*
+	 * Get a cursor and step through the database, dumping out each
+	 * subdatabase.
+	 */
+	if ((ret = parent_dbp->cursor(parent_dbp, NULL, &dbcp, 0)) != 0) {
+		dbenv->err(dbenv, ret, "DB->cursor");
+		return (1);
+	}
+
+	memset(&key, 0, sizeof(key));
+	memset(&data, 0, sizeof(data));
+	while ((ret = dbcp->get(dbcp, &key, &data,
+	    DB_IGNORE_LEASE | DB_NEXT)) == 0) {
+		/* Nul terminate the subdatabase name. */
+		if ((subdb = malloc(key.size + 1)) == NULL) {
+			dbenv->err(dbenv, ENOMEM, NULL);
+			return (1);
+		}
+		memcpy(subdb, key.data, key.size);
+		subdb[key.size] = '\0';
+
+		/* Create the DB object and open the file. */
+		if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
+			dbenv->err(dbenv, ret, "db_create");
+			free(subdb);
+			return (1);
+		}
+
+#if 0
+		Set application-specific btree compression functions here.
+		For example:
+
+		if ((ret = dbp->set_bt_compress(
+		    dbp, local_compress_func, local_decompress_func)) != 0) {
+			dbp->err(dbp, ret, "DB->set_bt_compress");
+			goto err;
+		}
+#endif
+
+		if ((ret = dbp->open(dbp, NULL,
+		    parent_name, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0)
+			dbp->err(dbp, ret,
+			    "DB->open: %s:%s", parent_name, subdb);
+		if (ret == 0 && dbp->dump(
+		    dbp, subdb, __db_pr_callback, stdout, pflag, keyflag))
+			ret = 1;
+		(void)dbp->close(dbp, 0);
+		free(subdb);
+		if (ret != 0)
+			return (1);
+	}
+	if (ret != DB_NOTFOUND) {
+		parent_dbp->err(parent_dbp, ret, "DBcursor->get");
+		return (1);
+	}
+
+	if ((ret = dbcp->close(dbcp)) != 0) {
+		parent_dbp->err(parent_dbp, ret, "DBcursor->close");
+		return (1);
+	}
+
+	return (0);
+}
+
+/*
+ * show_subs --
+ *	Display the subdatabases for a database.
+ */
+int
+show_subs(dbp)
+	DB *dbp;
+{
+	DBC *dbcp;
+	DBT key, data;
+	int ret;
+
+	/*
+	 * Get a cursor and step through the database, printing out the key
+	 * of each key/data pair.
+	 */
+	if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) {
+		dbp->err(dbp, ret, "DB->cursor");
+		return (1);
+	}
+
+	memset(&key, 0, sizeof(key));
+	memset(&data, 0, sizeof(data));
+	while ((ret = dbcp->get(dbcp, &key, &data,
+	    DB_IGNORE_LEASE | DB_NEXT)) == 0) {
+		if ((ret = dbp->dbenv->prdbt(
+		    &key, 1, NULL, stdout, __db_pr_callback, 0, 0)) != 0) {
+			dbp->errx(dbp, NULL);
+			return (1);
+		}
+	}
+	if (ret != DB_NOTFOUND) {
+		dbp->err(dbp, ret, "DBcursor->get");
+		return (1);
+	}
+
+	if ((ret = dbcp->close(dbcp)) != 0) {
+		dbp->err(dbp, ret, "DBcursor->close");
+		return (1);
+	}
+	return (0);
+}
+
+/*
+ * usage --
+ *	Display the usage message.
+ */
+int
+usage()
+{
+	(void)fprintf(stderr, "usage: %s [-klNprRV]\n\t%s\n",
+	    progname,
+    "[-d ahr] [-f output] [-h home] [-P password] [-s database] db_file");
+	(void)fprintf(stderr, "usage: %s [-kNpV] %s\n",
+	    progname, "[-d ahr] [-f output] [-h home] -m database");
+	return (EXIT_FAILURE);
+}
+
+int
+version_check()
+{
+	int v_major, v_minor, v_patch;
+
+	/* Make sure we're loaded with the right version of the DB library. */
+	(void)db_version(&v_major, &v_minor, &v_patch);
+	if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
+		fprintf(stderr, DB_STR_A("5118",
+		    "%s: version %d.%d doesn't match library version %d.%d\n",
+		    "%s %d %d %d %d\n"), progname,
+		    DB_VERSION_MAJOR, DB_VERSION_MINOR,
+		    v_major, v_minor);
+		return (EXIT_FAILURE);
+	}
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/db_load.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,1420 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+#include "dbinc/db_page.h"
+#include "dbinc/db_am.h"
+
+#ifndef lint
+static const char copyright[] =
+    "Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.\n";
+#endif
+
+typedef struct {			/* XXX: Globals. */
+	const char *progname;		/* Program name. */
+	char	*hdrbuf;		/* Input file header. */
+	u_long	lineno;			/* Input file line number. */
+	u_long	origline;		/* Original file line number. */
+	int	endodata;		/* Reached the end of a database. */
+	int	endofile;		/* Reached the end of the input. */
+	int	version;		/* Input version. */
+	char	*home;			/* Env home. */
+	char	*passwd;		/* Env passwd. */
+	int	private;		/* Private env. */
+	u_int32_t cache;		/* Env cache size. */
+} LDG;
+
+int	badend __P((DB_ENV *));
+void	badnum __P((DB_ENV *));
+int	configure __P((DB_ENV *, DB *, char **, char **, int *));
+int	convprintable __P((DB_ENV *, char *, char **));
+int	db_init __P((DB_ENV *, char *, u_int32_t, int *));
+int	dbt_rdump __P((DB_ENV *, DBT *));
+int	dbt_rprint __P((DB_ENV *, DBT *));
+int	dbt_rrecno __P((DB_ENV *, DBT *, int));
+int	dbt_to_recno __P((DB_ENV *, DBT *, db_recno_t *));
+int	env_create __P((DB_ENV **, LDG *));
+void	free_keys __P((DBT *part_keys));
+int	load __P((DB_ENV *, char *, DBTYPE, char **, u_int, LDG *, int *));
+int	main __P((int, char *[]));
+int	rheader __P((DB_ENV *, DB *, DBTYPE *, char **, int *, int *, DBT **));
+int	usage __P((void));
+int	version_check __P((void));
+
+const char *progname;
+
+#define	G(f)	((LDG *)dbenv->app_private)->f
+
+					/* Flags to the load function. */
+#define	LDF_NOHEADER	0x01		/* No dump header. */
+#define	LDF_NOOVERWRITE	0x02		/* Don't overwrite existing rows. */
+#define	LDF_PASSWORD	0x04		/* Encrypt created databases. */
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	enum { NOTSET, STANDARD_LOAD } mode;
+	extern char *optarg;
+	extern int optind;
+	DBTYPE dbtype;
+	DB_ENV	*dbenv;
+	LDG ldg;
+	u_int ldf;
+	int ch, existed, exitval, ret;
+	char **clist, **clp;
+
+	if ((progname = __db_rpath(argv[0])) == NULL)
+		progname = argv[0];
+	else
+		++progname;
+
+	clist = NULL;
+	ldg.progname = progname;
+	ldg.lineno = 0;
+	ldg.endodata = ldg.endofile = 0;
+	ldg.version = 1;
+	ldg.cache = MEGABYTE;
+	ldg.hdrbuf = NULL;
+	ldg.home = NULL;
+	ldg.passwd = NULL;
+
+	if ((exitval = version_check()) != 0)
+		goto done;
+
+	mode = NOTSET;
+	ldf = 0;
+	exitval = existed = 0;
+	dbtype = DB_UNKNOWN;
+
+	/* Allocate enough room for configuration arguments. */
+	if ((clp = clist =
+	    (char **)calloc((size_t)argc + 1, sizeof(char *))) == NULL) {
+		fprintf(stderr, "%s: %s\n", ldg.progname, strerror(ENOMEM));
+		exitval = 1;
+		goto done;
+	}
+
+	/*
+	 * There are two modes for db_load: -r and everything else.  The -r
+	 * option zeroes out the database LSN's or resets the file ID, it
+	 * doesn't really "load" a new database.  The functionality is in
+	 * db_load because we don't have a better place to put it, and we
+	 * don't want to create a new utility for just that functionality.
+	 */
+	while ((ch = getopt(argc, argv, "c:f:h:nP:Tt:V")) != EOF)
+		switch (ch) {
+		case 'c':
+			if (mode != NOTSET && mode != STANDARD_LOAD) {
+				exitval = usage();
+				goto done;
+			}
+			mode = STANDARD_LOAD;
+
+			*clp++ = optarg;
+			break;
+		case 'f':
+			if (mode != NOTSET && mode != STANDARD_LOAD) {
+				exitval = usage();
+				goto done;
+			}
+			mode = STANDARD_LOAD;
+
+			if (freopen(optarg, "r", stdin) == NULL) {
+				fprintf(stderr, DB_STR_A("5072",
+				"%s: %s: reopen: %s\n", "%s %s %s\n"),
+				    ldg.progname, optarg, strerror(errno));
+				exitval = usage();
+				goto done;
+			}
+			break;
+		case 'h':
+			ldg.home = optarg;
+			break;
+		case 'n':
+			if (mode != NOTSET && mode != STANDARD_LOAD) {
+				exitval = usage();
+				goto done;
+			}
+			mode = STANDARD_LOAD;
+
+			ldf |= LDF_NOOVERWRITE;
+			break;
+		case 'P':
+			ldg.passwd = strdup(optarg);
+			memset(optarg, 0, strlen(optarg));
+			if (ldg.passwd == NULL) {
+				fprintf(stderr, DB_STR_A("5073",
+				    "%s: strdup: %s\n", "%s %s\n"),
+				    ldg.progname, strerror(errno));
+				exitval = usage();
+				goto done;
+			}
+			ldf |= LDF_PASSWORD;
+			break;
+		case 'T':
+			if (mode != NOTSET && mode != STANDARD_LOAD) {
+				exitval = usage();
+				goto done;
+			}
+			mode = STANDARD_LOAD;
+
+			ldf |= LDF_NOHEADER;
+			break;
+		case 't':
+			if (mode != NOTSET && mode != STANDARD_LOAD) {
+				exitval = usage();
+				goto done;
+			}
+			mode = STANDARD_LOAD;
+
+			if (strcmp(optarg, "btree") == 0) {
+				dbtype = DB_BTREE;
+				break;
+			}
+			if (strcmp(optarg, "hash") == 0) {
+				dbtype = DB_HASH;
+				break;
+			}
+			if (strcmp(optarg, "recno") == 0) {
+				dbtype = DB_RECNO;
+				break;
+			}
+			if (strcmp(optarg, "queue") == 0) {
+				dbtype = DB_QUEUE;
+				break;
+			}
+			exitval = usage();
+			goto done;
+		case 'V':
+			printf("%s\n", db_version(NULL, NULL, NULL));
+			exitval = (EXIT_SUCCESS);
+			goto done;
+		case '?':
+		default:
+			exitval = usage();
+			goto done;
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 1) {
+		exitval = usage();
+		goto done;
+	}
+
+	/* Handle possible interruptions. */
+	__db_util_siginit();
+
+	/*
+	 * Create an environment object initialized for error reporting, and
+	 * then open it.
+	 */
+	if (env_create(&dbenv, &ldg) != 0)
+		goto err;
+
+	/* If we're resetting the LSNs, that's an entirely separate path. */
+	switch (mode) {
+	case NOTSET:
+	case STANDARD_LOAD:
+		while (!ldg.endofile)
+			if (load(dbenv, argv[0], dbtype, clist, ldf,
+			    &ldg, &existed) != 0)
+				goto err;
+		break;
+	}
+
+	if (0) {
+err:		exitval = 1;
+	}
+	if ((ret = dbenv->close(dbenv, 0)) != 0) {
+		exitval = 1;
+		fprintf(stderr,
+		    "%s: dbenv->close: %s\n", ldg.progname, db_strerror(ret));
+	}
+
+	/* Resend any caught signal. */
+	__db_util_sigresend();
+
+done:
+	if (clist != NULL)
+		free(clist);
+	if (ldg.passwd != NULL)
+		free(ldg.passwd);
+
+	/*
+	 * Return 0 on success, 1 if keys existed already, and 2 on failure.
+	 *
+	 * Technically, this is wrong, because exit of anything other than
+	 * 0 is implementation-defined by the ANSI C standard.  I don't see
+	 * any good solutions that don't involve API changes.
+	 */
+	return (exitval == 0 ? (existed == 0 ? 0 : 1) : 2);
+}
+
+/*
+ * load --
+ *	Load a database.
+ */
+int
+load(dbenv, name, argtype, clist, flags, ldg, existedp)
+	DB_ENV *dbenv;
+	char *name, **clist;
+	DBTYPE argtype;
+	u_int flags;
+	LDG *ldg;
+	int *existedp;
+{
+	DB *dbp;
+	DBC *dbc;
+	DBT key, rkey, data, *part_keys, *readp, *writep;
+	DBTYPE dbtype;
+	DB_HEAP_RID rid;
+	DB_TXN *ctxn, *txn;
+	db_recno_t recno, datarecno;
+	u_int32_t put_flags;
+	int ascii_recno, checkprint, hexkeys, keyflag, keys, resize, ret, rval;
+	char *subdb;
+
+	put_flags = LF_ISSET(LDF_NOOVERWRITE) ? DB_NOOVERWRITE : 0;
+	G(endodata) = 0;
+
+	dbc = NULL;
+	subdb = NULL;
+	ctxn = txn = NULL;
+	part_keys = NULL;
+	memset(&key, 0, sizeof(DBT));
+	memset(&data, 0, sizeof(DBT));
+	memset(&rkey, 0, sizeof(DBT));
+
+retry_db:
+	dbtype = DB_UNKNOWN;
+	keys = -1;
+	hexkeys = -1;
+	keyflag = -1;
+
+	/* Create the DB object. */
+	if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
+		dbenv->err(dbenv, ret, "db_create");
+		goto err;
+	}
+
+	/* Read the header -- if there's no header, we expect flat text. */
+	if (LF_ISSET(LDF_NOHEADER)) {
+		checkprint = 1;
+		dbtype = argtype;
+	} else {
+		if (rheader(dbenv,
+		    dbp, &dbtype, &subdb, &checkprint, &keys, &part_keys) != 0)
+			goto err;
+		if (G(endofile))
+			goto done;
+	}
+
+	/*
+	 * Apply command-line configuration changes.  (We apply command-line
+	 * configuration changes to all databases that are loaded, e.g., all
+	 * subdatabases.)
+	 */
+	if (configure(dbenv, dbp, clist, &subdb, &keyflag))
+		goto err;
+
+	if (keys != 1) {
+		if (keyflag == 1) {
+			dbp->err(dbp, EINVAL, DB_STR("5074",
+			    "No keys specified in file"));
+			goto err;
+		}
+	}
+	else if (keyflag == 0) {
+		dbp->err(dbp, EINVAL, DB_STR("5075",
+		    "Keys specified in file"));
+		goto err;
+	}
+	else
+		keyflag = 1;
+
+	if (dbtype == DB_BTREE || dbtype == DB_HASH) {
+		if (keyflag == 0)
+			dbp->err(dbp,
+			    EINVAL, DB_STR("5076",
+			    "Btree and Hash must specify keys"));
+		else
+			keyflag = 1;
+	}
+
+	if (dbtype == DB_HEAP && keyflag == 1) {
+		dbp->err(dbp,
+		    EINVAL, DB_STR("5127", "Heap must not specify keys"));
+		goto err;
+	}
+
+	if (argtype != DB_UNKNOWN) {
+		if (dbtype == DB_HEAP) {
+			dbenv->errx(dbenv, DB_STR("5128",
+			    "improper database type conversion specified"));
+			goto err;
+		}
+
+		if (dbtype == DB_RECNO || dbtype == DB_QUEUE)
+			if (keyflag != 1 && argtype != DB_RECNO &&
+			    argtype != DB_QUEUE) {
+				dbenv->errx(dbenv, DB_STR("5077",
+			    "improper database type conversion specified"));
+				goto err;
+			}
+		dbtype = argtype;
+	}
+
+	if (dbtype == DB_UNKNOWN) {
+		dbenv->errx(dbenv, DB_STR("5078",
+		    "no database type specified"));
+		goto err;
+	}
+
+	if (dbtype == DB_HEAP)
+		put_flags = DB_APPEND;
+
+	if (keyflag == -1)
+		keyflag = 0;
+
+	/*
+	 * Recno keys have only been printed in hexadecimal starting
+	 * with db_dump format version 3 (DB 3.2).
+	 *
+	 * !!!
+	 * Note that version is set in rheader(), which must be called before
+	 * this assignment.
+	 */
+	hexkeys = (G(version) >= 3 && keyflag == 1 && checkprint == 0);
+
+	if (keyflag == 1 && (dbtype == DB_RECNO || dbtype == DB_QUEUE))
+		ascii_recno = 1;
+	else
+		ascii_recno = 0;
+
+	/* If configured with a password, encrypt databases we create. */
+	if (LF_ISSET(LDF_PASSWORD) &&
+	    (ret = dbp->set_flags(dbp, DB_ENCRYPT)) != 0) {
+		dbp->err(dbp, ret, "DB->set_flags: DB_ENCRYPT");
+		goto err;
+	}
+
+#if 0
+	Set application-specific btree comparison, compression, or hash
+	functions here. For example:
+
+	if ((ret = dbp->set_bt_compare(dbp, local_comparison_func)) != 0) {
+		dbp->err(dbp, ret, "DB->set_bt_compare");
+		goto err;
+	}
+	if ((ret = dbp->set_bt_compress(dbp, local_compress_func,
+	    local_decompress_func)) != 0) {
+		dbp->err(dbp, ret, "DB->set_bt_compress");
+		goto err;
+	}
+	if ((ret = dbp->set_h_hash(dbp, local_hash_func)) != 0) {
+		dbp->err(dbp, ret, "DB->set_h_hash");
+		goto err;
+	}
+#endif
+
+	/* Open the DB file. */
+	if ((ret = dbp->open(dbp, NULL, name, subdb, dbtype,
+	    DB_CREATE | (TXN_ON(dbenv->env) ? DB_AUTO_COMMIT : 0),
+	    DB_MODE_666)) != 0) {
+		dbp->err(dbp, ret, "DB->open: %s", name);
+		goto err;
+	}
+	if (ldg->private != 0) {
+		if ((ret = __db_util_cache(dbp, &ldg->cache, &resize)) != 0)
+			goto err;
+		if (resize) {
+			if ((ret = dbp->close(dbp, 0)) != 0)
+				goto err;
+			dbp = NULL;
+			if ((ret = dbenv->close(dbenv, 0)) != 0)
+				goto err;
+			if ((ret = env_create(&dbenv, ldg)) != 0)
+				goto err;
+			goto retry_db;
+		}
+	}
+
+	/* Initialize the key/data pair. */
+	readp = writep = &key;
+	if (dbtype == DB_RECNO || dbtype == DB_QUEUE) {
+		key.size = sizeof(recno);
+		if (keyflag) {
+			key.data = &datarecno;
+			if (checkprint) {
+				readp = &rkey;
+				goto key_data;
+			}
+		} else
+			key.data = &recno;
+	} else if (dbtype == DB_HEAP) {
+		key.size = sizeof(DB_HEAP_RID);
+		key.data = &rid;
+	} else
+key_data:	if ((readp->data = malloc(readp->ulen = 1024)) == NULL) {
+			dbenv->err(dbenv, ENOMEM, NULL);
+			goto err;
+		}
+	if ((data.data = malloc(data.ulen = 1024)) == NULL) {
+		dbenv->err(dbenv, ENOMEM, NULL);
+		goto err;
+	}
+
+	if (put_flags == 0 && (ret = dbp->cursor(dbp,
+	    txn, &dbc, DB_CURSOR_BULK)) != 0)
+		goto err;
+
+	/* Get each key/data pair and add them to the database. */
+	for (recno = 1; !__db_util_interrupted(); ++recno) {
+		if (!keyflag) {
+			if (checkprint) {
+				if (dbt_rprint(dbenv, &data))
+					goto err;
+			} else {
+				if (dbt_rdump(dbenv, &data))
+					goto err;
+			}
+		} else {
+			if (checkprint) {
+				if (dbt_rprint(dbenv, readp))
+					goto err;
+				if (ascii_recno &&
+				    dbt_to_recno(dbenv, readp, &datarecno) != 0)
+					goto err;
+
+				if (!G(endodata) && dbt_rprint(dbenv, &data))
+					goto odd_count;
+			} else {
+				if (ascii_recno) {
+					if (dbt_rrecno(dbenv, readp, hexkeys))
+						goto err;
+				} else
+					if (dbt_rdump(dbenv, readp))
+						goto err;
+
+				if (!G(endodata) && dbt_rdump(dbenv, &data)) {
+odd_count:				dbenv->errx(dbenv, DB_STR("5079",
+					    "odd number of key/data pairs"));
+					goto err;
+				}
+			}
+		}
+		if (G(endodata))
+			break;
+
+		switch (ret = ((put_flags == 0) ?
+		    dbc->put(dbc, writep, &data, DB_KEYLAST) :
+		    dbp->put(dbp, ctxn, writep, &data, put_flags))) {
+		case 0:
+			break;
+		case DB_KEYEXIST:
+			*existedp = 1;
+			dbenv->errx(dbenv, DB_STR_A("5080",
+			    "%s: line %d: key already exists, not loaded:",
+			    "%s %d"), name,
+			    !keyflag ? recno : recno * 2 - 1);
+
+			(void)dbenv->prdbt(&key,
+			    checkprint, 0, stderr, __db_pr_callback, 0, 0);
+			break;
+		default:
+			dbenv->err(dbenv, ret, NULL);
+			goto err;
+		}
+	}
+done:	rval = 0;
+	if (dbc != NULL && (ret = dbc->close(dbc)) != 0) {
+		dbc = NULL;
+		goto err;
+	}
+
+	if (0) {
+err:		rval = 1;
+		if (dbc != NULL)
+			(void)dbc->close(dbc);
+	}
+
+	/* Close the database. */
+	if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) {
+		dbenv->err(dbenv, ret, "DB->close");
+		rval = 1;
+	}
+
+	if (G(hdrbuf) != NULL)
+		free(G(hdrbuf));
+	G(hdrbuf) = NULL;
+	/* Free allocated memory. */
+	if (subdb != NULL)
+		free(subdb);
+	if (dbtype != DB_HEAP && 
+	    dbtype != DB_RECNO && dbtype != DB_QUEUE && key.data != NULL)
+		free(key.data);
+	if (rkey.data != NULL)
+		free(rkey.data);
+	free(data.data);
+	free_keys(part_keys);
+	return (rval);
+}
+
+/*
+ * env_create --
+ *	Create the environment and initialize it for error reporting.
+ */
+int
+env_create(dbenvp, ldg)
+	DB_ENV **dbenvp;
+	LDG *ldg;
+{
+	DB_ENV *dbenv;
+	int ret;
+
+	if ((ret = db_env_create(dbenvp, 0)) != 0) {
+		fprintf(stderr, "%s: db_env_create: %s\n",
+		    ldg->progname, db_strerror(ret));
+		return (ret);
+	}
+	dbenv = *dbenvp;
+	dbenv->set_errfile(dbenv, stderr);
+	dbenv->set_errpfx(dbenv, ldg->progname);
+	if (ldg->passwd != NULL && (ret = dbenv->set_encrypt(dbenv,
+	    ldg->passwd, DB_ENCRYPT_AES)) != 0) {
+		dbenv->err(dbenv, ret, "set_passwd");
+		return (ret);
+	}
+	if ((ret = db_init(dbenv, ldg->home, ldg->cache, &ldg->private)) != 0)
+		return (ret);
+	dbenv->app_private = ldg;
+
+	return (0);
+}
+
+/*
+ * db_init --
+ *	Initialize the environment.
+ */
+int
+db_init(dbenv, home, cache, is_private)
+	DB_ENV *dbenv;
+	char *home;
+	u_int32_t cache;
+	int *is_private;
+{
+	u_int32_t flags;
+	int ret;
+
+	*is_private = 0;
+	/* We may be loading into a live environment.  Try and join. */
+	flags = DB_USE_ENVIRON |
+	    DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN;
+	if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0)
+		return (0);
+	if (ret == DB_VERSION_MISMATCH)
+		goto err;
+
+	/*
+	 * We're trying to load a database.
+	 *
+	 * An environment is required because we may be trying to look at
+	 * databases in directories other than the current one.  We could
+	 * avoid using an environment iff the -h option wasn't specified,
+	 * but that seems like more work than it's worth.
+	 *
+	 * No environment exists (or, at least no environment that includes
+	 * an mpool region exists).  Create one, but make it private so that
+	 * no files are actually created.
+	 */
+	LF_CLR(DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN);
+	LF_SET(DB_CREATE | DB_PRIVATE);
+	*is_private = 1;
+	if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) {
+		dbenv->err(dbenv, ret, "set_cachesize");
+		return (1);
+	}
+	if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0)
+		return (0);
+
+	/* An environment is required. */
+err:	dbenv->err(dbenv, ret, "DB_ENV->open");
+	return (1);
+}
+
+#define	FLAG(name, value, keyword, flag)				\
+	if (strcmp(name, keyword) == 0) {				\
+		switch (*value) {					\
+		case '1':						\
+			if ((ret = dbp->set_flags(dbp, flag)) != 0) {	\
+				dbp->err(dbp, ret, "%s: set_flags: %s",	\
+				    G(progname), name);			\
+				goto err;				\
+			}						\
+			break;						\
+		case '0':						\
+			break;						\
+		default:						\
+			badnum(dbenv);					\
+			goto err;					\
+		}							\
+		continue;						\
+	}
+#define	NUMBER(name, value, keyword, func, t)				\
+	if (strcmp(name, keyword) == 0) {				\
+		if ((ret = __db_getlong(dbenv,				\
+		    NULL, value, 0, LONG_MAX, &val)) != 0 ||		\
+		    (ret = dbp->func(dbp, (t)val)) != 0)		\
+			goto nameerr;					\
+		continue;						\
+	}
+#define	STRING(name, value, keyword, func)				\
+	if (strcmp(name, keyword) == 0) {				\
+		if ((ret = dbp->func(dbp, value[0])) != 0)		\
+			goto nameerr;					\
+		continue;						\
+	}
+
+/*
+ * The code to check a command-line or input header argument against a list
+ * of configuration options.  It's #defined because it's used in two places
+ * and the two places have gotten out of sync more than once.
+ */
+#define	CONFIGURATION_LIST_COMPARE					\
+	NUMBER(name, value, "bt_minkey", set_bt_minkey, u_int32_t);	\
+	  FLAG(name, value, "chksum", DB_CHKSUM);			\
+	NUMBER(name, value, "db_lorder", set_lorder, int);		\
+	NUMBER(name, value, "db_pagesize", set_pagesize, u_int32_t);	\
+	  FLAG(name, value, "duplicates", DB_DUP);			\
+	  FLAG(name, value, "dupsort", DB_DUPSORT);			\
+	NUMBER(name, value, "re_len", set_re_len, u_int32_t);		\
+	STRING(name, value, "re_pad", set_re_pad);			\
+	  FLAG(name, value, "recnum", DB_RECNUM);			\
+	  FLAG(name, value, "renumber", DB_RENUMBER);
+
+/*
+ * configure --
+ *	Handle command-line configuration options.
+ */
+int
+configure(dbenv, dbp, clp, subdbp, keysp)
+	DB_ENV *dbenv;
+	DB *dbp;
+	char **clp, **subdbp;
+	int *keysp;
+{
+	long val;
+	int ret, savech;
+	char *name, *value;
+	u_int32_t heap_bytes, heap_gbytes;
+
+	heap_bytes = heap_gbytes = 0;
+
+	for (; (name = *clp) != NULL; *--value = savech, ++clp) {
+		if ((value = strchr(name, '=')) == NULL) {
+			dbp->errx(dbp, DB_STR("5081",
+		    "command-line configuration uses name=value format"));
+			return (1);
+		}
+		savech = *value;
+		*value++ = '\0';
+
+		if (strcmp(name, "database") == 0 ||
+		    strcmp(name, "subdatabase") == 0) {
+			if (*subdbp != NULL)
+				free(*subdbp);
+			if ((*subdbp = strdup(value)) == NULL) {
+				dbp->err(dbp, ENOMEM, NULL);
+				return (1);
+			}
+			continue;
+		}
+		if (strcmp(name, "keys") == 0) {
+			if (strcmp(value, "1") == 0)
+				*keysp = 1;
+			else if (strcmp(value, "0") == 0)
+				*keysp = 0;
+			else {
+				badnum(dbenv);
+				return (1);
+			}
+			continue;
+		}
+
+		CONFIGURATION_LIST_COMPARE;
+
+		dbp->errx(dbp, DB_STR_A("5082",
+		    "unknown command-line configuration keyword \"%s\"",
+		    "%s"), name);
+		return (1);
+	}
+	return (0);
+
+nameerr:
+	dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value);
+err:	return (1);
+}
+
+/*
+ * rheader --
+ *	Read the header message.
+ */
+int
+rheader(dbenv, dbp, dbtypep, subdbp, checkprintp, keysp, part_keyp)
+	DB_ENV *dbenv;
+	DB *dbp;
+	DBTYPE *dbtypep;
+	char **subdbp;
+	int *checkprintp, *keysp;
+	DBT **part_keyp;
+{
+	DBT *keys, *kp;
+	size_t buflen, linelen, start;
+	long val;
+	int ch, first, hdr, ret;
+	char *buf, *name, *p, *value;
+	u_int32_t heap_bytes, heap_gbytes, i, nparts;
+
+	*dbtypep = DB_UNKNOWN;
+	*checkprintp = 0;
+	name = NULL;
+	*part_keyp = NULL;
+	keys = NULL;
+	heap_bytes = heap_gbytes = 0;
+
+	/*
+	 * We start with a smallish buffer;  most headers are small.
+	 * We may need to realloc it for a large subdatabase name.
+	 */
+	buflen = 4096;
+	if (G(hdrbuf) == NULL) {
+		hdr = 0;
+		if ((buf = malloc(buflen)) == NULL)
+			goto memerr;
+		G(hdrbuf) = buf;
+		G(origline) = G(lineno);
+	} else {
+		hdr = 1;
+		buf = G(hdrbuf);
+		G(lineno) = G(origline);
+	}
+
+	start = 0;
+	for (first = 1;; first = 0) {
+		++G(lineno);
+
+		/* Read a line, which may be of arbitrary length, into buf. */
+		linelen = 0;
+		buf = &G(hdrbuf)[start];
+		if (hdr == 0) {
+			for (;;) {
+				if ((ch = getchar()) == EOF) {
+					if (!first || ferror(stdin))
+						goto badfmt;
+					G(endofile) = 1;
+					break;
+				}
+
+				/*
+				 * If the buffer is too small, double it.
+				 */
+				if (linelen + start == buflen) {
+					G(hdrbuf) =
+					    realloc(G(hdrbuf), buflen *= 2);
+					if (G(hdrbuf) == NULL)
+						goto memerr;
+					buf = &G(hdrbuf)[start];
+				}
+
+				if (ch == '\n')
+					break;
+
+				buf[linelen++] = ch;
+			}
+			if (G(endofile) == 1)
+				break;
+			buf[linelen++] = '\0';
+		} else
+			linelen = strlen(buf) + 1;
+		start += linelen;
+
+		if (name != NULL) {
+			free(name);
+			name = NULL;
+		}
+		/* If we don't see the expected information, it's an error. */
+		if ((name = strdup(buf)) == NULL)
+			goto memerr;
+		if ((p = strchr(name, '=')) == NULL)
+			goto badfmt;
+		*p++ = '\0';
+
+		value = p--;
+
+		if (name[0] == '\0')
+			goto badfmt;
+
+		/*
+		 * The only values that may be zero-length are database names.
+		 * In the original Berkeley DB code it was possible to create
+		 * zero-length database names, and the db_load code was then
+		 * changed to allow such databases to be be dumped and loaded.
+		 * [#8204]
+		 */
+		if (strcmp(name, "database") == 0 ||
+		    strcmp(name, "subdatabase") == 0) {
+			if ((ret = convprintable(dbenv, value, subdbp)) != 0) {
+				dbp->err(dbp, ret, DB_STR("5083",
+				    "error reading db name"));
+				goto err;
+			}
+			continue;
+		}
+
+		/* No other values may be zero-length. */
+		if (value[0] == '\0')
+			goto badfmt;
+
+		if (strcmp(name, "HEADER") == 0)
+			break;
+		if (strcmp(name, "VERSION") == 0) {
+			/*
+			 * Version 1 didn't have a "VERSION" header line.  We
+			 * only support versions 1, 2, and 3 of the dump format.
+			 */
+			G(version) = atoi(value);
+
+			if (G(version) > 3) {
+				dbp->errx(dbp, DB_STR_A("5084",
+				    "line %lu: VERSION %d is unsupported",
+				    "%lu %d"), G(lineno), G(version));
+				goto err;
+			}
+			continue;
+		}
+		if (strcmp(name, "format") == 0) {
+			if (strcmp(value, "bytevalue") == 0) {
+				*checkprintp = 0;
+				continue;
+			}
+			if (strcmp(value, "print") == 0) {
+				*checkprintp = 1;
+				continue;
+			}
+			goto badfmt;
+		}
+		if (strcmp(name, "type") == 0) {
+			if (strcmp(value, "btree") == 0) {
+				*dbtypep = DB_BTREE;
+				continue;
+			}
+			if (strcmp(value, "hash") == 0) {
+				*dbtypep = DB_HASH;
+				continue;
+			}
+			if (strcmp(value, "heap") == 0) {
+				*dbtypep = DB_HEAP;
+				continue;
+			}
+			if (strcmp(value, "recno") == 0) {
+				*dbtypep = DB_RECNO;
+				continue;
+			}
+			if (strcmp(value, "queue") == 0) {
+				*dbtypep = DB_QUEUE;
+				continue;
+			}
+			dbp->errx(dbp, DB_STR_A("5085",
+			    "line %lu: unknown type", "%lu"), G(lineno));
+			goto err;
+		}
+		if (strcmp(name, "keys") == 0) {
+			if (strcmp(value, "1") == 0)
+				*keysp = 1;
+			else if (strcmp(value, "0") == 0)
+				*keysp = 0;
+			else {
+				badnum(dbenv);
+				goto err;
+			}
+			continue;
+		}
+		if (strcmp(name, "nparts") == 0) {
+			if ((ret = __db_getlong(dbenv,
+			    NULL, value, 0, LONG_MAX, &val)) != 0) {
+				badnum(dbenv);
+				goto err;
+			}
+			nparts = (u_int32_t) val;
+			if ((keys =
+			    malloc(nparts * sizeof(DBT))) == NULL) {
+				dbenv->err(dbenv, ENOMEM, NULL);
+				goto err;
+			}
+			keys[nparts - 1].data = NULL;
+			kp = keys;
+			for (i = 1; i < nparts; kp++, i++) {
+				if ((kp->data =
+				     malloc(kp->ulen = 1024)) == NULL) {
+					dbenv->err(dbenv, ENOMEM, NULL);
+					goto err;
+				}
+				if (*checkprintp) {
+					if (dbt_rprint(dbenv, kp))
+						goto err;
+				} else {
+					if (dbt_rdump(dbenv, kp))
+						goto err;
+				}
+			}
+			if ((ret = dbp->set_partition(
+			     dbp, nparts, keys, NULL)) != 0)
+				goto err;
+
+			*part_keyp = keys;
+
+			continue;
+		}
+
+		CONFIGURATION_LIST_COMPARE;
+
+		/* Have to special case heap size, because we need 2 values. */
+		if (strcmp(name, "heap_bytes") == 0) {
+			if ((ret = __db_getlong(dbenv,
+			    NULL, value, 0, LONG_MAX, &val)) != 0)
+				goto nameerr;
+			heap_bytes = (u_int32_t)val;
+		}
+		if (strcmp(name, "heap_gbytes") == 0) {
+			if ((ret = __db_getlong(dbenv,
+			    NULL, value, 0, LONG_MAX, &val)) != 0)
+				goto nameerr;
+			heap_gbytes = (u_int32_t)val;
+		}
+
+		dbp->errx(dbp, DB_STR_A("5086",
+		    "unknown input-file header configuration keyword \"%s\"",
+		    "%s"), name);
+		goto err;
+	}
+	ret = 0;
+
+
+	if (0) {
+nameerr:	dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value);
+		ret = 1;
+	}
+	if (0) {
+badfmt:		dbp->errx(dbp, DB_STR_A("5087",
+			    "line %lu: unexpected format", "%lu"), G(lineno));
+		ret = 1;
+	}
+	if (0) {
+memerr:		dbp->errx(dbp, DB_STR("5088",
+			    "unable to allocate memory"));
+err:		ret = 1;
+	}
+	if (name != NULL)
+		free(name);
+	if (ret != 0) {
+		*part_keyp = NULL;
+		free_keys(keys);
+	}
+	return (ret);
+}
+
+void free_keys(part_keys)
+	DBT *part_keys;
+{
+	DBT *kp;
+	if (part_keys != NULL) {
+		for (kp = part_keys; kp->data != NULL; kp++)
+			free(kp->data);
+		free(part_keys);
+	}
+}
+
+/*
+ * Macro to convert a pair of hex bytes to a decimal value.
+ *
+ * !!!
+ * Note that this macro is side-effect safe.  This was done deliberately,
+ * callers depend on it.
+ */
+#define	DIGITIZE(store, v1, v2) {					\
+	char _v1, _v2;							\
+	_v1 = (v1);							\
+	_v2 = (v2);							\
+	if ((_v1) > 'f' || (_v2) > 'f')					\
+		return (badend(dbenv));					\
+	(store) =							\
+	((_v1) == '0' ? 0 :						\
+	((_v1) == '1' ? 1 :						\
+	((_v1) == '2' ? 2 :						\
+	((_v1) == '3' ? 3 :						\
+	((_v1) == '4' ? 4 :						\
+	((_v1) == '5' ? 5 :						\
+	((_v1) == '6' ? 6 :						\
+	((_v1) == '7' ? 7 :						\
+	((_v1) == '8' ? 8 :						\
+	((_v1) == '9' ? 9 :						\
+	((_v1) == 'a' ? 10 :						\
+	((_v1) == 'b' ? 11 :						\
+	((_v1) == 'c' ? 12 :						\
+	((_v1) == 'd' ? 13 :						\
+	((_v1) == 'e' ? 14 : 15))))))))))))))) << 4 |			\
+	((_v2) == '0' ? 0 :						\
+	((_v2) == '1' ? 1 :						\
+	((_v2) == '2' ? 2 :						\
+	((_v2) == '3' ? 3 :						\
+	((_v2) == '4' ? 4 :						\
+	((_v2) == '5' ? 5 :						\
+	((_v2) == '6' ? 6 :						\
+	((_v2) == '7' ? 7 :						\
+	((_v2) == '8' ? 8 :						\
+	((_v2) == '9' ? 9 :						\
+	((_v2) == 'a' ? 10 :						\
+	((_v2) == 'b' ? 11 :						\
+	((_v2) == 'c' ? 12 :						\
+	((_v2) == 'd' ? 13 :						\
+	((_v2) == 'e' ? 14 : 15)))))))))))))));				\
+}
+
+/*
+ * convprintable --
+ *	Convert a printable-encoded string into a newly allocated string.
+ *
+ * In an ideal world, this would probably share code with dbt_rprint but
+ * that's set up to read character-by-character (to avoid large memory
+ * allocations that aren't likely to be a problem here), and this has fewer
+ * special cases to deal with.
+ *
+ * Note that despite the printable encoding, the char * interface to this
+ * function (which is, not coincidentally, also used for database naming)
+ * means that outstr cannot contain any nuls.
+ */
+int
+convprintable(dbenv, instr, outstrp)
+	DB_ENV *dbenv;
+	char *instr, **outstrp;
+{
+	char *outstr;
+
+	/*
+	 * Just malloc a string big enough for the whole input string;
+	 * the output string will be smaller (or of equal length).
+	 *
+	 * Note that we may be passed a zero-length string and need to
+	 * be able to duplicate it.
+	 */
+	if ((outstr = malloc(strlen(instr) + 1)) == NULL)
+		return (ENOMEM);
+
+	*outstrp = outstr;
+
+	for ( ; *instr != '\0'; instr++)
+		if (*instr == '\\') {
+			if (*++instr == '\\') {
+				*outstr++ = '\\';
+				continue;
+			}
+			DIGITIZE(*outstr++, *instr, *++instr);
+		} else
+			*outstr++ = *instr;
+
+	*outstr = '\0';
+
+	return (0);
+}
+
+/*
+ * dbt_rprint --
+ *	Read a printable line into a DBT structure.
+ */
+int
+dbt_rprint(dbenv, dbtp)
+	DB_ENV *dbenv;
+	DBT *dbtp;
+{
+	u_int32_t len;
+	u_int8_t *p;
+	int c1, c2, escape, first;
+	char buf[32];
+
+	++G(lineno);
+
+	first = 1;
+	escape = 0;
+	for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {
+		if (c1 == EOF) {
+			if (len == 0) {
+				G(endofile) = G(endodata) = 1;
+				return (0);
+			}
+			return (badend(dbenv));
+		}
+		if (first) {
+			first = 0;
+			if (G(version) > 1) {
+				if (c1 != ' ') {
+					buf[0] = c1;
+					if (fgets(buf + 1,
+					    sizeof(buf) - 1, stdin) == NULL ||
+					    strcmp(buf, "DATA=END\n") != 0)
+						return (badend(dbenv));
+					G(endodata) = 1;
+					return (0);
+				}
+				continue;
+			}
+		}
+		if (escape) {
+			if (c1 != '\\') {
+				if ((c2 = getchar()) == EOF)
+					return (badend(dbenv));
+				DIGITIZE(c1, c1, c2);
+			}
+			escape = 0;
+		} else
+			if (c1 == '\\') {
+				escape = 1;
+				continue;
+			}
+		if (len >= dbtp->ulen - 10) {
+			dbtp->ulen *= 2;
+			if ((dbtp->data =
+			    realloc(dbtp->data, dbtp->ulen)) == NULL) {
+				dbenv->err(dbenv, ENOMEM, NULL);
+				return (1);
+			}
+			p = (u_int8_t *)dbtp->data + len;
+		}
+		++len;
+		*p++ = c1;
+	}
+	dbtp->size = len;
+
+	return (0);
+}
+
+/*
+ * dbt_rdump --
+ *	Read a byte dump line into a DBT structure.
+ */
+int
+dbt_rdump(dbenv, dbtp)
+	DB_ENV *dbenv;
+	DBT *dbtp;
+{
+	u_int32_t len;
+	u_int8_t *p;
+	int c1, c2, first;
+	char buf[32];
+
+	++G(lineno);
+
+	first = 1;
+	for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {
+		if (c1 == EOF) {
+			if (len == 0) {
+				G(endofile) = G(endodata) = 1;
+				return (0);
+			}
+			return (badend(dbenv));
+		}
+		if (first) {
+			first = 0;
+			if (G(version) > 1) {
+				if (c1 != ' ') {
+					buf[0] = c1;
+					if (fgets(buf + 1,
+					    sizeof(buf) - 1, stdin) == NULL ||
+					    strcmp(buf, "DATA=END\n") != 0)
+						return (badend(dbenv));
+					G(endodata) = 1;
+					return (0);
+				}
+				continue;
+			}
+		}
+		if ((c2 = getchar()) == EOF)
+			return (badend(dbenv));
+		if (len >= dbtp->ulen - 10) {
+			dbtp->ulen *= 2;
+			if ((dbtp->data =
+			    realloc(dbtp->data, dbtp->ulen)) == NULL) {
+				dbenv->err(dbenv, ENOMEM, NULL);
+				return (1);
+			}
+			p = (u_int8_t *)dbtp->data + len;
+		}
+		++len;
+		DIGITIZE(*p++, c1, c2);
+	}
+	dbtp->size = len;
+
+	return (0);
+}
+
+/*
+ * dbt_rrecno --
+ *	Read a record number dump line into a DBT structure.
+ */
+int
+dbt_rrecno(dbenv, dbtp, ishex)
+	DB_ENV *dbenv;
+	DBT *dbtp;
+	int ishex;
+{
+	char buf[32], *p, *q;
+	u_long recno;
+
+	++G(lineno);
+
+	if (fgets(buf, sizeof(buf), stdin) == NULL) {
+		G(endofile) = G(endodata) = 1;
+		return (0);
+	}
+
+	if (strcmp(buf, "DATA=END\n") == 0) {
+		G(endodata) = 1;
+		return (0);
+	}
+
+	if (buf[0] != ' ')
+		goto err;
+
+	/*
+	 * If we're expecting a hex key, do an in-place conversion
+	 * of hex to straight ASCII before calling __db_getulong().
+	 */
+	if (ishex) {
+		for (p = q = buf + 1; *q != '\0' && *q != '\n';) {
+			/*
+			 * 0-9 in hex are 0x30-0x39, so this is easy.
+			 * We should alternate between 3's and [0-9], and
+			 * if the [0-9] are something unexpected,
+			 * __db_getulong will fail, so we only need to catch
+			 * end-of-string conditions.
+			 */
+			if (*q++ != '3')
+				goto err;
+			if (*q == '\n' || *q == '\0')
+				goto err;
+			*p++ = *q++;
+		}
+		*p = '\0';
+	}
+
+	if (__db_getulong(dbenv, G(progname), buf + 1, 0, 0, &recno))
+		goto err;
+
+	*((db_recno_t *)dbtp->data) = recno;
+	dbtp->size = sizeof(db_recno_t);
+	return (0);
+
+err:	return (badend(dbenv));
+}
+
+int
+dbt_to_recno(dbenv, dbt, recnop)
+	DB_ENV *dbenv;
+	DBT *dbt;
+	db_recno_t *recnop;
+{
+	char buf[32];				/* Large enough for 2^64. */
+
+	memcpy(buf, dbt->data, dbt->size);
+	buf[dbt->size] = '\0';
+
+	return (__db_getulong(dbenv, G(progname), buf, 0, 0, (u_long *)recnop));
+}
+
+/*
+ * badnum --
+ *	Display the bad number message.
+ */
+void
+badnum(dbenv)
+	DB_ENV *dbenv;
+{
+	dbenv->errx(dbenv, DB_STR("5089",
+	    "boolean name=value pairs require a value of 0 or 1"));
+}
+
+/*
+ * badend --
+ *	Display the bad end to input message.
+ */
+int
+badend(dbenv)
+	DB_ENV *dbenv;
+{
+	dbenv->errx(dbenv, DB_STR("5090",
+	    "unexpected end of input data or key/data pair"));
+	return (1);
+}
+
+/*
+ * usage --
+ *	Display the usage message.
+ */
+int
+usage()
+{
+	(void)fprintf(stderr, "usage: %s %s\n\t%s\n", progname,
+	    "[-nTV] [-c name=value] [-f file]",
+    "[-h home] [-P password] [-t btree | hash | recno | queue] db_file");
+	(void)fprintf(stderr, "usage: %s %s\n",
+	    progname, "-r lsn | fileid [-h home] [-P password] db_file");
+	return (EXIT_FAILURE);
+}
+
+int
+version_check()
+{
+	int v_major, v_minor, v_patch;
+
+	/* Make sure we're loaded with the right version of the DB library. */
+	(void)db_version(&v_major, &v_minor, &v_patch);
+	if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
+		fprintf(stderr, DB_STR_A("5091",
+		    "%s: version %d.%d doesn't match library version %d.%d\n",
+		    "%s %d %d %d %d\n"), progname, DB_VERSION_MAJOR,
+		    DB_VERSION_MINOR, v_major, v_minor);
+		return (EXIT_FAILURE);
+	}
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/db_stat.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,488 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+#ifndef lint
+static const char copyright[] =
+    "Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.\n";
+#endif
+
+typedef enum { T_NOTSET, T_DB,
+    T_ENV, T_LOCK, T_LOG, T_MPOOL, T_MUTEX, T_REP, T_TXN } test_t;
+
+int	 db_init __P((DB_ENV *, char *, test_t, u_int32_t, int *));
+int	 main __P((int, char *[]));
+int	 usage __P((void));
+int	 version_check __P((void));
+
+const char *progname;
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	extern char *optarg;
+	extern int optind;
+	DB_ENV	*dbenv;
+	DB *dbp;
+	test_t ttype;
+	u_int32_t cache, flags;
+	int ch, exitval;
+	int nflag, private, resize, ret;
+	char *db, *home, *p, *passwd, *subdb;
+
+	if ((progname = __db_rpath(argv[0])) == NULL)
+		progname = argv[0];
+	else
+		++progname;
+
+	if ((ret = version_check()) != 0)
+		return (ret);
+
+	dbenv = NULL;
+	dbp = NULL;
+	ttype = T_NOTSET;
+	cache = MEGABYTE;
+	exitval = flags = nflag = private = 0;
+	db = home = passwd = subdb = NULL;
+
+	while ((ch = getopt(argc,
+	    argv, "aC:cd:Eefgh:L:lM:mNP:R:rs:tVxX:Z")) != EOF)
+		switch (ch) {
+		case 'a':
+			LF_SET(DB_STAT_ALLOC);
+			break;
+		case 'C': case 'c':
+			if (ttype != T_NOTSET && ttype != T_LOCK)
+				goto argcombo;
+			ttype = T_LOCK;
+			if (ch != 'c')
+				for (p = optarg; *p; ++p)
+					switch (*p) {
+					case 'A':
+						LF_SET(DB_STAT_ALL);
+						break;
+					case 'c':
+						LF_SET(DB_STAT_LOCK_CONF);
+						break;
+					case 'l':
+						LF_SET(DB_STAT_LOCK_LOCKERS);
+						break;
+					case 'm': /* Backward compatible. */
+						break;
+					case 'o':
+						LF_SET(DB_STAT_LOCK_OBJECTS);
+						break;
+					case 'p':
+						LF_SET(DB_STAT_LOCK_PARAMS);
+						break;
+					default:
+						return (usage());
+					}
+			break;
+		case 'd':
+			if (ttype != T_NOTSET && ttype != T_DB)
+				goto argcombo;
+			ttype = T_DB;
+			db = optarg;
+			break;
+		case 'E': case 'e':
+			if (ttype != T_NOTSET && ttype != T_ENV)
+				goto argcombo;
+			ttype = T_ENV;
+			LF_SET(DB_STAT_SUBSYSTEM);
+			if (ch == 'E')
+				LF_SET(DB_STAT_ALL);
+			break;
+		case 'f':
+			if (ttype != T_NOTSET && ttype != T_DB)
+				goto argcombo;
+			ttype = T_DB;
+			LF_SET(DB_FAST_STAT);
+			break;
+		case 'h':
+			home = optarg;
+			break;
+		case 'L': case 'l':
+			if (ttype != T_NOTSET && ttype != T_LOG)
+				goto argcombo;
+			ttype = T_LOG;
+			if (ch != 'l')
+				for (p = optarg; *p; ++p)
+					switch (*p) {
+					case 'A':
+						LF_SET(DB_STAT_ALL);
+						break;
+					default:
+						return (usage());
+					}
+			break;
+		case 'M': case 'm':
+			if (ttype != T_NOTSET && ttype != T_MPOOL)
+				goto argcombo;
+			ttype = T_MPOOL;
+			if (ch != 'm')
+				for (p = optarg; *p; ++p)
+					switch (*p) {
+					case 'A':
+						LF_SET(DB_STAT_ALL);
+						break;
+					case 'h':
+						LF_SET(DB_STAT_MEMP_HASH);
+						break;
+					case 'm': /* Backward compatible. */
+						break;
+					default:
+						return (usage());
+					}
+			break;
+		case 'N':
+			nflag = 1;
+			break;
+		case 'P':
+			if (passwd != NULL) {
+				fprintf(stderr, DB_STR("5139",
+					"Password may not be specified twice"));
+				free(passwd);
+				return (EXIT_FAILURE);
+			}
+			passwd = strdup(optarg);
+			memset(optarg, 0, strlen(optarg));
+			if (passwd == NULL) {
+				fprintf(stderr, DB_STR_A("5005",
+				    "%s: strdup: %s\n", "%s %s\n"),
+				    progname, strerror(errno));
+				return (EXIT_FAILURE);
+			}
+			break;
+		case 'R': case 'r':
+			if (ttype != T_NOTSET && ttype != T_REP)
+				goto argcombo;
+			ttype = T_REP;
+			if (ch != 'r')
+				for (p = optarg; *p; ++p)
+					switch (*p) {
+					case 'A':
+						LF_SET(DB_STAT_ALL);
+						break;
+					default:
+						return (usage());
+					}
+			break;
+		case 's':
+			if (ttype != T_NOTSET && ttype != T_DB)
+				goto argcombo;
+			ttype = T_DB;
+			subdb = optarg;
+			break;
+		case 't':
+			if (ttype != T_NOTSET) {
+argcombo:			fprintf(stderr, DB_STR_A("5006",
+				    "%s: illegal option combination\n",
+				    "%s\n"), progname);
+				return (usage());
+			}
+			ttype = T_TXN;
+			break;
+		case 'V':
+			printf("%s\n", db_version(NULL, NULL, NULL));
+			return (EXIT_SUCCESS);
+		case 'X': case 'x':
+			if (ttype != T_NOTSET && ttype != T_MUTEX)
+				goto argcombo;
+			ttype = T_MUTEX;
+			if (ch != 'x')
+				for (p = optarg; *p; ++p)
+					switch (*p) {
+						case 'A':
+							LF_SET(DB_STAT_ALL);
+							break;
+						default:
+							return (usage());
+					}
+			break;
+		case 'Z':
+			LF_SET(DB_STAT_CLEAR);
+			break;
+		case '?':
+		default:
+			return (usage());
+		}
+	argc -= optind;
+	argv += optind;
+
+	switch (ttype) {
+	case T_DB:
+		if (db == NULL)
+			return (usage());
+		break;
+	case T_ENV:
+	case T_LOCK:
+	case T_LOG:
+	case T_MPOOL:
+	case T_MUTEX:
+	case T_REP:
+	case T_TXN:
+		break;
+	case T_NOTSET:
+		return (usage());
+	}
+
+	if (LF_ISSET(DB_STAT_ALL | DB_STAT_ALLOC) == DB_STAT_ALLOC)
+		return (usage());
+
+	/* Handle possible interruptions. */
+	__db_util_siginit();
+
+	/*
+	 * Create an environment object and initialize it for error
+	 * reporting.
+	 */
+retry:	if ((ret = db_env_create(&dbenv, 0)) != 0) {
+		fprintf(stderr,
+		    "%s: db_env_create: %s\n", progname, db_strerror(ret));
+		goto err;
+	}
+
+	dbenv->set_errfile(dbenv, stderr);
+	dbenv->set_errpfx(dbenv, progname);
+
+	if (nflag) {
+		if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) {
+			dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING");
+			goto err;
+		}
+		if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) {
+			dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC");
+			goto err;
+		}
+	}
+
+	if (passwd != NULL &&
+	    (ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES)) != 0) {
+		dbenv->err(dbenv, ret, "set_passwd");
+		goto err;
+	}
+
+	/* Initialize the environment. */
+	if (db_init(dbenv, home, ttype, cache, &private) != 0)
+		goto err;
+
+	switch (ttype) {
+	case T_DB:
+		/* Create the DB object and open the file. */
+		if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
+			dbenv->err(dbenv, ret, "db_create");
+			goto err;
+		}
+
+		/*
+		 * We open the database for writing so we can update the cached
+		 * statistics, but it's OK to fail, we can open read-only and
+		 * proceed.
+		 *
+		 * Turn off error messages for now -- we can't open lots of
+		 * databases read-write (for example, master databases and
+		 * hash databases for which we don't know the hash function).
+		 */
+		dbenv->set_errfile(dbenv, NULL);
+		ret = dbp->open(dbp, NULL, db, subdb, DB_UNKNOWN, 0, 0);
+		dbenv->set_errfile(dbenv, stderr);
+		if (ret != 0) {
+			/* Handles cannot be reused after a failed DB->open. */
+			(void)dbp->close(dbp, 0);
+			if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
+				dbenv->err(dbenv, ret, "db_create");
+				goto err;
+			}
+
+			if ((ret = dbp->open(dbp,
+			    NULL, db, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) {
+				dbenv->err(dbenv, ret, "DB->open: %s", db);
+				goto err;
+			}
+		}
+
+		/* Check if cache is too small for this DB's pagesize. */
+		if (private) {
+			if ((ret = __db_util_cache(dbp, &cache, &resize)) != 0)
+				goto err;
+			if (resize) {
+				(void)dbp->close(dbp, DB_NOSYNC);
+				dbp = NULL;
+
+				(void)dbenv->close(dbenv, 0);
+				dbenv = NULL;
+				goto retry;
+			}
+		}
+
+		if (dbp->stat_print(dbp, flags))
+			goto err;
+		break;
+	case T_ENV:
+		if (dbenv->stat_print(dbenv, flags))
+			goto err;
+		break;
+	case T_MPOOL:
+		if (dbenv->memp_stat_print(dbenv, flags))
+			goto err;
+		break;
+	case T_LOCK:
+	case T_LOG:
+	case T_MUTEX:
+	case T_REP:
+	case T_TXN:
+		dbenv->errx(dbenv, "This build does not support that subsystem");
+		break;
+	case T_NOTSET:
+		dbenv->errx(dbenv, DB_STR("5007",
+		    "Unknown statistics flag"));
+		goto err;
+	}
+
+	if (0) {
+err:		exitval = 1;
+	}
+	if (dbp != NULL && (ret = dbp->close(dbp, DB_NOSYNC)) != 0) {
+		exitval = 1;
+		dbenv->err(dbenv, ret, DB_STR("5008", "close"));
+	}
+	if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) {
+		exitval = 1;
+		fprintf(stderr,
+		    "%s: dbenv->close: %s\n", progname, db_strerror(ret));
+	}
+
+	if (passwd != NULL)
+		free(passwd);
+
+	/* Resend any caught signal. */
+	__db_util_sigresend();
+
+	return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+/*
+ * db_init --
+ *	Initialize the environment.
+ */
+int
+db_init(dbenv, home, ttype, cache, is_private)
+	DB_ENV *dbenv;
+	char *home;
+	test_t ttype;
+	u_int32_t cache;
+	int *is_private;
+{
+	u_int32_t oflags;
+	int ret;
+
+	/*
+	 * If our environment open fails, and we're trying to look at a
+	 * shared region, it's a hard failure.
+	 *
+	 * We will probably just drop core if the environment we join does
+	 * not include a memory pool.  This is probably acceptable; trying
+	 * to use an existing environment that does not contain a memory
+	 * pool to look at a database can be safely construed as operator
+	 * error, I think.
+	 */
+	*is_private = 0;
+	if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) == 0)
+		return (0);
+	if (ret == DB_VERSION_MISMATCH)
+		goto err;
+	if (ttype != T_DB && ttype != T_LOG) {
+		dbenv->err(dbenv, ret, "DB_ENV->open%s%s",
+		    home == NULL ? "" : ": ", home == NULL ? "" : home);
+		return (1);
+	}
+
+	/*
+	 * We're looking at a database or set of log files and no environment
+	 * exists.  Create one, but make it private so no files are actually
+	 * created.  Declare a reasonably large cache so that we don't fail
+	 * when reporting statistics on large databases.
+	 *
+	 * An environment is required to look at databases because we may be
+	 * trying to look at databases in directories other than the current
+	 * one.
+	 */
+	if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) {
+		dbenv->err(dbenv, ret, "set_cachesize");
+		return (1);
+	}
+	*is_private = 1;
+	oflags = DB_CREATE | DB_PRIVATE | DB_USE_ENVIRON;
+	if (ttype == T_DB)
+		oflags |= DB_INIT_MPOOL;
+	if (ttype == T_LOG)
+		oflags |= DB_INIT_LOG;
+	if ((ret = dbenv->open(dbenv, home, oflags, 0)) == 0)
+		return (0);
+
+	/* An environment is required. */
+err:	dbenv->err(dbenv, ret, "DB_ENV->open");
+	return (1);
+}
+
+int
+usage()
+{
+	fprintf(stderr, "usage: %s %s\n", progname,
+	    "-d file [-fN] [-h home] [-P password] [-s database]");
+	fprintf(stderr, "usage: %s %s\n\t%s\n", progname,
+	    "[-cEelmrtVx] [-C Aclop]",
+	    "[-h home] [-L A] [-M A] [-P password] [-R A] [-X A] [-aNZ]");
+	return (EXIT_FAILURE);
+}
+
+int
+version_check()
+{
+	int v_major, v_minor, v_patch;
+
+	/* Make sure we're loaded with the right version of the DB library. */
+	(void)db_version(&v_major, &v_minor, &v_patch);
+	if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
+		fprintf(stderr, DB_STR_A("5009",
+		    "%s: version %d.%d doesn't match library version %d.%d\n",
+		    "%s %d %d %d %d\n"), progname,
+		    DB_VERSION_MAJOR, DB_VERSION_MINOR,
+		    v_major, v_minor);
+		return (EXIT_FAILURE);
+	}
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/db_verify.c	Fri May 11 10:42:02 2012 +0100
@@ -0,0 +1,311 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+#ifndef lint
+static const char copyright[] =
+    "Copyright (c) 1996, 2012 Oracle and/or its affiliates.  All rights reserved.\n";
+#endif
+
+int main __P((int, char *[]));
+int usage __P((void));
+int version_check __P((void));
+
+const char *progname;
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	extern char *optarg;
+	extern int optind;
+	DB *dbp, *dbp1;
+	DB_ENV *dbenv;
+	u_int32_t flags, cache;
+	int ch, exitval, mflag, nflag, private;
+	int quiet, resize, ret;
+	char *dname, *fname, *home, *passwd;
+
+	if ((progname = __db_rpath(argv[0])) == NULL)
+		progname = argv[0];
+	else
+		++progname;
+
+	if ((ret = version_check()) != 0)
+		return (ret);
+
+	dbenv = NULL;
+	dbp = NULL;
+	cache = MEGABYTE;
+	exitval = mflag = nflag = quiet = 0;
+	flags = 0;
+	home = passwd = NULL;
+	while ((ch = getopt(argc, argv, "h:mNoP:quV")) != EOF)
+		switch (ch) {
+		case 'h':
+			home = optarg;
+			break;
+		case 'm':
+			mflag = 1;
+			break;
+		case 'N':
+			nflag = 1;
+			break;
+		case 'P':
+			if (passwd != NULL) {
+				fprintf(stderr, DB_STR("5132",
+					"Password may not be specified twice"));
+				free(passwd);
+				return (EXIT_FAILURE);
+			}
+			passwd = strdup(optarg);
+			memset(optarg, 0, strlen(optarg));
+			if (passwd == NULL) {
+				fprintf(stderr, "%s: strdup: %s\n",
+				    progname, strerror(errno));
+				return (EXIT_FAILURE);
+			}
+			break;
+		case 'o':
+			LF_SET(DB_NOORDERCHK);
+			break;
+		case 'q':
+			quiet = 1;
+			break;
+		case 'u':			/* Undocumented. */
+			LF_SET(DB_UNREF);
+			break;
+		case 'V':
+			printf("%s\n", db_version(NULL, NULL, NULL));
+			return (EXIT_SUCCESS);
+		case '?':
+		default:
+			return (usage());
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc <= 0)
+		return (usage());
+
+	if (mflag) {
+		dname = argv[0];
+		fname = NULL;
+	} else {
+		fname = argv[0];
+		dname = NULL;
+	}
+
+	/* Handle possible interruptions. */
+	__db_util_siginit();
+
+	/*
+	 * Create an environment object and initialize it for error
+	 * reporting.
+	 */
+retry:	if ((ret = db_env_create(&dbenv, 0)) != 0) {
+		fprintf(stderr,
+		    "%s: db_env_create: %s\n", progname, db_strerror(ret));
+		goto err;
+	}
+
+	if (!quiet) {
+		dbenv->set_errfile(dbenv, stderr);
+		dbenv->set_errpfx(dbenv, progname);
+	}
+
+	if (nflag) {
+		if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) {
+			dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING");
+			goto err;
+		}
+		if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) {
+			dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC");
+			goto err;
+		}
+	}
+
+	if (passwd != NULL &&
+	    (ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES)) != 0) {
+		dbenv->err(dbenv, ret, "set_passwd");
+		goto err;
+	}
+	/*
+	 * Attach to an mpool if it exists, but if that fails, attach to a
+	 * private region.  In the latter case, declare a reasonably large
+	 * cache so that we don't fail when verifying large databases.
+	 */
+	private = 0;
+	if ((ret =
+	    dbenv->open(dbenv, home, DB_INIT_MPOOL | DB_USE_ENVIRON, 0)) != 0) {
+		if (ret != DB_VERSION_MISMATCH) {
+			if ((ret =
+			    dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) {
+				dbenv->err(dbenv, ret, "set_cachesize");
+				goto err;
+			}
+			private = 1;
+			ret = dbenv->open(dbenv, home, DB_CREATE |
+			    DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0);
+		}
+		if (ret != 0) {
+			dbenv->err(dbenv, ret, "DB_ENV->open");
+			goto err;
+		}
+	}
+
+	/*
+	 * Find out if we have a transactional environment so that we can
+	 * make sure that we don't open the verify database with logging
+	 * enabled.
+	 */
+	for (; !__db_util_interrupted() && argv[0] != NULL; ++argv) {
+		if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
+			dbenv->err(dbenv, ret, "%s: db_create", progname);
+			goto err;
+		}
+
+		if (TXN_ON(dbenv->env) &&
+		    (ret = dbp->set_flags(dbp, DB_TXN_NOT_DURABLE)) != 0) {
+			dbenv->err(
+			    dbenv, ret, "%s: db_set_flags", progname);
+			goto err;
+		}
+
+		/*
+		 * We create a 2nd dbp to this database to get its pagesize
+		 * because the dbp we're using for verify cannot be opened.
+		 *
+		 * If the database is corrupted, we may not be able to open
+		 * it, of course.  In that case, just continue, using the
+		 * cache size we have.
+		 */
+		if (private) {
+			if ((ret = db_create(&dbp1, dbenv, 0)) != 0) {
+				dbenv->err(
+				    dbenv, ret, "%s: db_create", progname);
+				goto err;
+			}
+
+			if (TXN_ON(dbenv->env) && (ret =
+			    dbp1->set_flags(dbp1, DB_TXN_NOT_DURABLE)) != 0) {
+				dbenv->err(
+				    dbenv, ret, "%s: db_set_flags", progname);
+				goto err;
+			}
+
+			ret = dbp1->open(dbp1,
+			    NULL, fname, dname, DB_UNKNOWN, DB_RDONLY, 0);
+
+			/*
+			 * If we get here, we can check the cache/page.
+			 * !!!
+			 * If we have to retry with an env with a larger
+			 * cache, we jump out of this loop.  However, we
+			 * will still be working on the same argv when we
+			 * get back into the for-loop.
+			 */
+			if (ret == 0) {
+				if (__db_util_cache(
+				    dbp1, &cache, &resize) == 0 && resize) {
+					(void)dbp1->close(dbp1, 0);
+					(void)dbp->close(dbp, 0);
+					dbp = NULL;
+
+					(void)dbenv->close(dbenv, 0);
+					dbenv = NULL;
+					goto retry;
+				}
+			}
+			(void)dbp1->close(dbp1, 0);
+		}
+
+		/* The verify method is a destructor. */
+		ret = dbp->verify(dbp, fname, dname, NULL, flags);
+		dbp = NULL;
+		if (ret != 0)
+			exitval = 1;
+		if (!quiet)
+			printf(DB_STR_A("5105", "Verification of %s %s.\n",
+			    "%s %s\n"), argv[0], ret == 0 ? 
+			    DB_STR_P("succeeded") : DB_STR_P("failed"));
+	}
+
+	if (0) {
+err:		exitval = 1;
+	}
+
+	if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) {
+		exitval = 1;
+		dbenv->err(dbenv, ret, DB_STR("5106", "close"));
+	}
+	if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) {
+		exitval = 1;
+		fprintf(stderr,
+		    "%s: dbenv->close: %s\n", progname, db_strerror(ret));
+	}
+
+	if (passwd != NULL)
+		free(passwd);
+
+	/* Resend any caught signal. */
+	__db_util_sigresend();
+
+	return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+int
+usage()
+{
+	fprintf(stderr, "usage: %s %s\n", progname,
+	    "[-NoqV] [-h home] [-P password] db_file ...");
+	return (EXIT_FAILURE);
+}
+
+int
+version_check()
+{
+	int v_major, v_minor, v_patch;
+
+	/* Make sure we're loaded with the right version of the DB library. */
+	(void)db_version(&v_major, &v_minor, &v_patch);
+	if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
+		fprintf(stderr, DB_STR_A("5107",
+		    "%s: version %d.%d doesn't match library version %d.%d\n",
+		    "%s %d %d %d %d\n"), progname, DB_VERSION_MAJOR,
+		    DB_VERSION_MINOR, v_major, v_minor);
+		return (EXIT_FAILURE);
+	}
+	return (0);
+}