diff options
author | tim@threads.polyesthetic.msg <> | 2001-03-04 19:42:05 -0500 |
---|---|---|
committer | tim@threads.polyesthetic.msg <> | 2001-03-04 19:42:05 -0500 |
commit | 89dad52004ecba5a380aeebb0e2a9beaae88eb86 (patch) | |
tree | 9dd732e08dba156ee3d7635caedc0dc3107ecac6 /bdb/rpc_server | |
parent | 639a1069d313843288ba6d9cb54b290073a748a7 (diff) | |
download | mariadb-git-89dad52004ecba5a380aeebb0e2a9beaae88eb86.tar.gz |
Import changeset
Diffstat (limited to 'bdb/rpc_server')
-rw-r--r-- | bdb/rpc_server/clsrv.html | 453 | ||||
-rw-r--r-- | bdb/rpc_server/db_server.sed | 5 | ||||
-rw-r--r-- | bdb/rpc_server/db_server.x | 492 | ||||
-rw-r--r-- | bdb/rpc_server/db_server_proc.c | 1546 | ||||
-rw-r--r-- | bdb/rpc_server/db_server_proc.sed | 418 | ||||
-rw-r--r-- | bdb/rpc_server/db_server_svc.c | 359 | ||||
-rw-r--r-- | bdb/rpc_server/db_server_svc.sed | 5 | ||||
-rw-r--r-- | bdb/rpc_server/db_server_util.c | 612 | ||||
-rw-r--r-- | bdb/rpc_server/db_server_xdr.c | 1149 | ||||
-rw-r--r-- | bdb/rpc_server/gen_db_server.c | 703 | ||||
-rw-r--r-- | bdb/rpc_server/rpc.src | 599 |
11 files changed, 6341 insertions, 0 deletions
diff --git a/bdb/rpc_server/clsrv.html b/bdb/rpc_server/clsrv.html new file mode 100644 index 00000000000..ae089c4b382 --- /dev/null +++ b/bdb/rpc_server/clsrv.html @@ -0,0 +1,453 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<HTML> +<HEAD> + <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> + <META NAME="GENERATOR" CONTENT="Mozilla/4.08 [en] (X11; I; FreeBSD 3.3-RELEASE i386) [Netscape]"> +</HEAD> +<BODY> + +<CENTER> +<H1> +Client/Server Interface for Berkeley DB</H1></CENTER> + +<CENTER><I>Susan LoVerso</I> +<BR><I>sue@sleepycat.com</I> +<BR><I>Rev 1.3</I> +<BR><I>1999 Nov 29</I></CENTER> + +<P>We provide an interface allowing client/server access to Berkeley DB. +Our goal is to provide a client and server library to allow users to separate +the functionality of their applications yet still have access to the full +benefits of Berkeley DB. The goal is to provide a totally seamless +interface with minimal modification to existing applications as well. +<P>The client/server interface for Berkeley DB can be broken up into several +layers. At the lowest level there is the transport mechanism to send +out the messages over the network. Above that layer is the messaging +layer to interpret what comes over the wire, and bundle/unbundle message +contents. The next layer is Berkeley DB itself. +<P>The transport layer uses ONC RPC (RFC 1831) and XDR (RFC 1832). +We declare our message types and operations supported by our program and +the RPC library and utilities pretty much take care of the rest. +The +<I>rpcgen</I> program generates all of the low level code needed. +We need to define both sides of the RPC. +<BR> +<H2> +<A NAME="DB Modifications"></A>DB Modifications</H2> +To achieve the goal of a seamless interface, it is necessary to impose +a constraint on the application. That constraint is simply that all database +access must be done through an open environment. I.e. this model +does not support standalone databases. The reason for this constraint +is so that we have an environment structure internally to store our connection +to the server. Imposing this constraint means that we can provide +the seamless interface just by adding a single environment method: <A HREF="../docs/api_c/env_set_server.html">DBENV->set_server()</A>. +<P>The planned interface for this method is: +<PRE>DBENV->set_server(dbenv, /* DB_ENV structure */ + hostname /* Host of server */ + cl_timeout, /* Client timeout (sec) */ + srv_timeout,/* Server timeout (sec) */ + flags); /* Flags: unused */</PRE> +This new method takes the hostname of the server, establishes our connection +and an environment on the server. If a server timeout is specified, +then we send that to the server as well (and the server may or may not +choose to use that value). This timeout is how long the server will +allow the environment to remain idle before declaring it dead and releasing +resources on the server. The pointer to the connection is stored +on the client in the DBENV structure and is used by all other methods to +figure out with whom to communicate. If a client timeout is specified, +it indicates how long the client is willing to wait for a reply from the +server. If the values are 0, then defaults are used. Flags +is currently unused, but exists because we always need to have a placeholder +for flags and it would be used for specifying authentication desired (were +we to provide an authentication scheme at some point) or other uses not +thought of yet! +<P>This client code is part of the monolithic DB library. The user +accesses the client functions via a new flag to <A HREF="../docs/api_c/db_env_create.html">db_env_create()</A>. +That flag is DB_CLIENT. By using this flag the user indicates they +want to have the client methods rather than the standard methods for the +environment. Also by issuing this flag, the user needs to connect +to the server via the <A HREF="../docs/api_c/env_set_server.html">DBENV->set_server()</A> +method. +<P>We need two new fields in the <I>DB_ENV </I>structure. One is +the socket descriptor to communicate to the server, the other field is +the client identifier the server gives to us. The <I>DB, </I>and<I> +DBC </I>only need one additional field, the client identifier. The +<I>DB_TXN</I> +structure does not need modification, we are overloading the <I>txn_id +</I>field. +<H2> +Issues</H2> +We need to figure out what to do in case of client and server crashes. +Both the client library and the server program are stateful. They +both consume local resources during the lifetime of the connection. +Should one end drop that connection, the other side needs to release those +resources. +<P>If the server crashes, then the client will get an error back. +I have chosen to implement time-outs on the client side, using a default +or allowing the application to specify one through the <A HREF="../docs/api_c/env_set_server.html">DBENV->set_server()</A> +method. Either the current operation will time-out waiting for the +reply or the next operation called will time out (or get back some other +kind of error regarding the server's non-existence). In any case, +if the client application gets back such an error, it should abort any +open transactions locally, close any databases, and close its environment. +It may then decide to retry to connect to the server periodically or whenever +it comes back. If the last operation a client did was a transaction +commit that did not return or timed out from the server, the client cannot +determine if the transaction was committed or not but must release the +local transaction resources. Once the server is back up, recovery must +be run on the server. If the transaction commit completed on +the server before the crash, then the operation is redone, if the transaction +commit did not get to the server, the pieces of the transaction are undone +on recover. The client can then re-establish its connection and begin +again. This is effectively like beginning over. The client +cannot use ID's from its previous connection to the server. However, +if recovery is run, then consistency is assured. +<P>If the client crashes, the server needs to somehow figure this out. +The server is just sitting there waiting for a request to come in. +A server must be able to time-out a client. Similar to ftpd, if a +connection is idle for N seconds, then the server decides the client is +dead and releases that client's resources, aborting any open transactions, +closing any open databases and environments. The server timing +out a client is not a trivial issue however. The generated function +for the server just calls <I>svc_run()</I>. The server code I write +contains procedures to do specific things. We do not have access +to the code calling <I>select()</I>. Timing out the select is not +good enough even if we could do so. We want to time-out idle environments, +not simply cause a time-out if the server is idle a while. See the +discussion of the <A HREF="#The Server Program">server program</A> for +a description of how we accomplish this. +<P>Since rpcgen generates the main() function of the server, I do not yet +know how we are going to have the server multi-threaded or multi-process +without changing the generated code. The RPC book indicates that +the only way to accomplish this is through modifying the generated code +in the server. <B>For the moment we will ignore this issue while +we get the core server working, as it is only a performance issue.</B> +<P>We do not do any security or authentication. Someone could get +the code and modify it to spoof messages, trick the server, etc. +RPC has some amount of authentication built into it. I haven't yet +looked into it much to know if we want to use it or just point a user at +it. The changes to the client code are fairly minor, the changes +to our server procs are fairly minor. We would have to add code to +a <I>sed</I> script or <I>awk</I> script to change the generated server +code (yet again) in the dispatch routine to perform authentication. +<P>We will need to get an official program number from Sun. We can +get this by sending mail to <I>rpc@sun.com</I> and presumably at some point +they will send us back a program number that we will encode into our XDR +description file. Until we release this we can use a program number +in the "user defined" number space. +<BR> +<H2> +<A NAME="The Server Program"></A>The Server Program</H2> +The server is a standalone program that the user builds and runs, probably +as a daemon like process. This program is linked against the Berkeley +DB library and the RPC library (which is part of the C library on my FreeBSD +machine, others may have/need <I>-lrpclib</I>). The server basically +is a slave to the client process. All messages from the client are +synchronous and two-way. The server handles messages one at a time, +and sends a reply back before getting another message. There are +no asynchronous messages generated by the server to the client. +<P>We have made a choice to modify the generated code for the server. +The changes will be minimal, generally calling functions we write, that +are in other source files. The first change is adding a call to our +time-out function as described below. The second change is changing +the name of the generated <I>main()</I> function to <I>__dbsrv_main()</I>, +and adding our own <I>main()</I> function so that we can parse options, +and set up other initialization we require. I have a <I>sed</I> script +that is run from the distribution scripts that massages the generated code +to make these minor changes. +<P>Primarily the code needed for the server is the collection of the specified +RPC functions. Each function receives the structure indicated, and +our code takes out what it needs and passes the information into DB itself. +The server needs to maintain a translation table for identifiers that we +pass back to the client for the environment, transaction and database handles. +<P>The table that the server maintains, assuming one client per server +process/thread, should contain the handle to the environment, database +or transaction, a link to maintain parent/child relationships between transactions, +or databases and cursors, this handle's identifier, a type so that we can +error if the client passes us a bad id for this call, and a link to this +handle's environment entry (for time out/activity purposes). The +table contains, in entries used by environments, a time-out value and an +activity time stamp. Its use is described below for timing out idle +clients. +<P>Here is how we time out clients in the server. We have to modify +the generated server code, but only to add one line during the dispatch +function to run the time-out function. The call is made right before +the return of the dispatch function, after the reply is sent to the client, +so that client's aren't kept waiting for server bookkeeping activities. +This time-out function then runs every time the server processes a request. +In the time-out function we maintain a time-out hint that is the youngest +environment to time-out. If the current time is less than the hint +we know we do not need to run through the list of open handles. If +the hint is expired, then we go through the list of open environment handles, +and if they are past their expiration, then we close them and clean up. +If they are not, we set up the hint for the next time. +<P>Each entry in the open handle table has a pointer back to its environment's +entry. Every operation within this environment can then update the +single environment activity record. Every environment can have a +different time-out. The <A HREF="../docs/api_c/env_set_server.html">DBENV->set_server +</A>call +takes a server time-out value. If this value is 0 then a default +(currently 5 minutes) is used. This time-out value is only a hint +to the server. It may choose to disregard this value or set the time-out +based on its own implementation. +<P>For completeness, the flaws of this time-out implementation should be +pointed out. First, it is possible that a client could crash with +open handles, and no other requests come in to the server. Therefore +the time-out function never gets run and those resources are not released +(until a request does come in). Similarly, this time-out is not exact. +The time-out function uses its hint and if it computes a hint on one run, +an earlier time-out might be created before that time-out expires. +This issue simply yields a handle that doesn't get released until that +original hint expires. To illustrate, consider that at the time that +the time-out function is run, the youngest time-out is 5 minutes in the +future. Soon after, a new environment is opened that has a time-out +of 1 minute. If this environment becomes idle (and other operations +are going on), the time-out function will not release that environment +until the original 5 minute hint expires. This is not a problem since +the resources will eventually be released. +<P>On a similar note, if a client crashes during an RPC, our reply generates +a SIGPIPE, and our server crashes unless we catch it. Using <I>signal(SIGPIPE, +SIG_IGN) </I>we can ignore it, and the server will go on. This is +a call in our <I>main()</I> function that we write. Eventually +this client's handles would be timed out as described above. We need +this only for the unfortunate window of a client crashing during the RPC. +<P>The options below are primarily for control of the program itself,. +Details relating to databases and environments should be passed from the +client to the server, since the server can serve many clients, many environments +and many databases. Therefore it makes more sense for the client +to set the cache size of its own environment, rather than setting a default +cachesize on the server that applies as a blanket to any environment it +may be called upon to open. Options are: +<UL> +<LI> +<B>-t </B> to set the default time-out given to an environment.</LI> + +<LI> +<B>-T</B> to set the maximum time-out allowed for the server.</LI> + +<LI> +<B>-L</B> to log the execution of the server process to a specified file.</LI> + +<LI> +<B>-v</B> to run in verbose mode.</LI> + +<LI> +<B>-M</B> to specify the maximum number of outstanding child server +processes/threads we can have at any given time. The default is 10. +<B>[We +are not yet doing multiple threads/processes.]</B></LI> +</UL> + +<H2> +The Client Code</H2> +The client code contains all of the supported functions and methods used +in this model. There are several methods in the <I>__db_env +</I>and +<I>__db</I> +structures that currently do not apply, such as the callbacks. Those +fields that are not applicable to the client model point to NULL to notify +the user of their error. Some method functions remain unchanged, +as well such as the error calls. +<P>The client code contains each method function that goes along with the +<A HREF="#Remote Procedure Calls">RPC +calls</A> described elsewhere. The client library also contains its +own version of <A HREF="../docs/api_c/env_create.html">db_env_create()</A>, +which does not result in any messages going over to the server (since we +do not yet know what server we are talking to). This function sets +up the pointers to the correct client functions. +<P>All of the method functions that handle the messaging have a basic flow +similar to this: +<UL> +<LI> +Local arg parsing that may be needed</LI> + +<LI> +Marshalling the message header and the arguments we need to send to the +server</LI> + +<LI> +Sending the message</LI> + +<LI> +Receiving a reply</LI> + +<LI> +Unmarshalling the reply</LI> + +<LI> +Local results processing that may be needed</LI> +</UL> + +<H2> +Generated Code</H2> +Almost all of the code is generated from a source file describing the interface +and an <I>awk</I> script. This awk script generates six (6) +files for us. It also modifies one. The files are: +<OL> +<LI> +Client file - The C source file created containing the client code.</LI> + +<LI> +Client template file - The C template source file created containing interfaces +for handling client-local issues such as resource allocation, but with +a consistent interface with the client code generated.</LI> + +<LI> +Server file - The C source file created containing the server code.</LI> + +<LI> +Server template file - The C template source file created containing interfaces +for handling server-local issues such as resource allocation, calling into +the DB library but with a consistent interface with the server code generated.</LI> + +<LI> +XDR file - The XDR message description file created.</LI> + +<LI> +Server sed file - A sed script that contains commands to apply to the server +procedure file (i.e. the real source file that the server template file +becomes) so that minor interface changes can be consistently and easily +applied to the real code.</LI> + +<LI> +Server procedure file - This is the file that is modified by the sed script +generated. It originated from the server template file.</LI> +</OL> +The awk script reads a source file, <I>db_server/rpc.src </I>that describes +each operation and what sorts of arguments it takes and what it returns +from the server. The syntax of the source file describes the interface +to that operation. There are four (4) parts to the syntax: +<OL> +<LI> +<B>BEGIN</B> <B><I>function version# codetype</I></B> - begins a new functional +interface for the given <B><I>function</I></B>. Each function has +a <B><I>version number</I></B>, currently all of them are at version number +one (1). The <B><I>code type</I></B> indicates to the awk script +what kind of code to generate. The choices are:</LI> + +<UL> +<LI> +<B>CODE </B>- Generate all code, and return a status value. If specified, +the client code will simply return the status to the user upon completion +of the RPC call.</LI> + +<LI> +<B>RETCODE </B>- Generate all code and call a return function in the client +template file to deal with client issues or with other returned items. +If specified, the client code generated will call a function of the form +<I>__dbcl_<name>_ret() +</I>where +<name> is replaced with the function name given here. This function +is placed in the template file because this indicates that something special +must occur on return. The arguments to this function are the same +as those for the client function, with the addition of the reply message +structure.</LI> + +<LI> +<B>NOCLNTCODE - </B>Generate XDR and server code, but no corresponding +client code. (This is used for functions that are not named the same thing +on both sides. The only use of this at the moment is db_env_create +and db_create. The environment create call to the server is actually +called from the <A HREF="../docs/api_c/env_set_server.html">DBENV->set_server()</A> +method. The db_create code exists elsewhere in the library and we +modify that code for the client call.)</LI> +</UL> + +<LI> +<B>ARG <I>RPC-type C-type varname [list-type]</I></B>- each line of this +describes an argument to the function. The argument is called <B><I>varname</I></B>. +The <B><I>C-type</I></B> given is what it should look like in the C code +generated, such as <B>DB *, u_int32_t, const char *</B>. The +<B><I>RPC-type</I></B> +is an indication about how the RPC request message should be constructed. +The RPC-types allowed are described below.</LI> + +<LI> +<B>RET <I>RPC-type C-type varname [list-type]</I></B>- each line of this +describes what the server should return from this procedure call (in addition +to a status, which is always returned and should not be specified). +The argument is called <B><I>varname</I></B>. The <B><I>C-type</I></B> +given is what it should look like in the C code generated, such as <B>DB +*, u_int32_t, const char *</B>. The <B><I>RPC-type</I></B> is an +indication about how the RPC reply message should be constructed. +The RPC-types are described below.</LI> + +<LI> +<B>END </B>- End the description of this function. The result is +that when the awk script encounters the <B>END</B> tag, it now has all +the information it needs to construct the generated code for this function.</LI> +</OL> +The <B><I>RPC-type</I></B> must be one of the following: +<UL> +<LI> +<B>IGNORE </B>- This argument is not passed to the server and should be +ignored when constructing the XDR code. <B>Only allowed for an ARG +specfication.</B></LI> + +<LI> +<B>STRING</B> - This argument is a string.</LI> + +<LI> +<B>INT </B>- This argument is an integer of some sort.</LI> + +<LI> +<B>DBT </B>- This argument is a DBT, resulting in its decomposition into +the request message.</LI> + +<LI> +<B>LIST</B> - This argument is an opaque list passed to the server (NULL-terminated). +If an argument of this type is given, it must have a <B><I>list-type</I></B> +specified that is one of:</LI> + +<UL> +<LI> +<B>STRING</B></LI> + +<LI> +<B>INT</B></LI> + +<LI> +<B>ID</B>.</LI> +</UL> + +<LI> +<B>ID</B> - This argument is an identifier.</LI> +</UL> +So, for example, the source for the DB->join RPC call looks like: +<PRE>BEGIN dbjoin 1 RETCODE +ARG ID DB * dbp +ARG LIST DBC ** curs ID +ARG IGNORE DBC ** dbcpp +ARG INT u_int32_t flags +RET ID long dbcid +END</PRE> +Our first line tells us we are writing the dbjoin function. It requires +special code on the client so we indicate that with the RETCODE. +This method takes four arguments. For the RPC request we need the +database ID from the dbp, we construct a NULL-terminated list of IDs for +the cursor list, we ignore the argument to return the cursor handle to +the user, and we pass along the flags. On the return, the reply contains +a status, by default, and additionally, it contains the ID of the newly +created cursor. +<H2> +Building and Installing</H2> +I need to verify with Don Anderson, but I believe we should just build +the server program, just like we do for db_stat, db_checkpoint, etc. +Basically it can be treated as a utility program from the building and +installation perspective. +<P>As mentioned early on, in the section on <A HREF="#DB Modifications">DB +Modifications</A>, we have a single library, but allowing the user to access +the client portion by sending a flag to <A HREF="../docs/api_c/env_create.html">db_env_create()</A>. +The Makefile is modified to include the new files. +<P>Testing is performed in two ways. First I have a new example program, +that should become part of the example directory. It is basically +a merging of ex_access.c and ex_env.c. This example is adequate to +test basic functionality, as it does just does database put/get calls and +appropriate open and close calls. However, in order to test the full +set of functions a more generalized scheme is required. For the moment, +I am going to modify the Tcl interface to accept the server information. +Nothing else should need to change in Tcl. Then we can either write +our own test modules or use a subset of the existing ones to test functionality +on a regular basis. +</BODY> +</HTML> diff --git a/bdb/rpc_server/db_server.sed b/bdb/rpc_server/db_server.sed new file mode 100644 index 00000000000..f028f778e21 --- /dev/null +++ b/bdb/rpc_server/db_server.sed @@ -0,0 +1,5 @@ +1i\ +\#include "db_config.h"\ +\#ifdef HAVE_RPC +$a\ +\#endif /* HAVE_RPC */ diff --git a/bdb/rpc_server/db_server.x b/bdb/rpc_server/db_server.x new file mode 100644 index 00000000000..6bdff201f5a --- /dev/null +++ b/bdb/rpc_server/db_server.x @@ -0,0 +1,492 @@ +/* Do not edit: automatically built by gen_rpc.awk. */ + +struct __env_cachesize_msg { + unsigned int dbenvcl_id; + unsigned int gbytes; + unsigned int bytes; + unsigned int ncache; +}; + +struct __env_cachesize_reply { + unsigned int status; +}; + +struct __env_close_msg { + unsigned int dbenvcl_id; + unsigned int flags; +}; + +struct __env_close_reply { + unsigned int status; +}; + +struct __env_create_msg { + unsigned int timeout; +}; + +struct __env_create_reply { + unsigned int status; + unsigned int envcl_id; +}; + +struct __env_flags_msg { + unsigned int dbenvcl_id; + unsigned int flags; + unsigned int onoff; +}; + +struct __env_flags_reply { + unsigned int status; +}; + +struct __env_open_msg { + unsigned int dbenvcl_id; + string home<>; + unsigned int flags; + unsigned int mode; +}; + +struct __env_open_reply { + unsigned int status; +}; + +struct __env_remove_msg { + unsigned int dbenvcl_id; + string home<>; + unsigned int flags; +}; + +struct __env_remove_reply { + unsigned int status; +}; + +struct __txn_abort_msg { + unsigned int txnpcl_id; +}; + +struct __txn_abort_reply { + unsigned int status; +}; + +struct __txn_begin_msg { + unsigned int envpcl_id; + unsigned int parentcl_id; + unsigned int flags; +}; + +struct __txn_begin_reply { + unsigned int status; + unsigned int txnidcl_id; +}; + +struct __txn_commit_msg { + unsigned int txnpcl_id; + unsigned int flags; +}; + +struct __txn_commit_reply { + unsigned int status; +}; + +struct __db_bt_maxkey_msg { + unsigned int dbpcl_id; + unsigned int maxkey; +}; + +struct __db_bt_maxkey_reply { + unsigned int status; +}; + +struct __db_bt_minkey_msg { + unsigned int dbpcl_id; + unsigned int minkey; +}; + +struct __db_bt_minkey_reply { + unsigned int status; +}; + +struct __db_close_msg { + unsigned int dbpcl_id; + unsigned int flags; +}; + +struct __db_close_reply { + unsigned int status; +}; + +struct __db_create_msg { + unsigned int flags; + unsigned int envpcl_id; +}; + +struct __db_create_reply { + unsigned int status; + unsigned int dbpcl_id; +}; + +struct __db_del_msg { + unsigned int dbpcl_id; + unsigned int txnpcl_id; + unsigned int keydlen; + unsigned int keydoff; + unsigned int keyflags; + opaque keydata<>; + unsigned int flags; +}; + +struct __db_del_reply { + unsigned int status; +}; + +struct __db_extentsize_msg { + unsigned int dbpcl_id; + unsigned int extentsize; +}; + +struct __db_extentsize_reply { + unsigned int status; +}; + +struct __db_flags_msg { + unsigned int dbpcl_id; + unsigned int flags; +}; + +struct __db_flags_reply { + unsigned int status; +}; + +struct __db_get_msg { + unsigned int dbpcl_id; + unsigned int txnpcl_id; + unsigned int keydlen; + unsigned int keydoff; + unsigned int keyflags; + opaque keydata<>; + unsigned int datadlen; + unsigned int datadoff; + unsigned int dataflags; + opaque datadata<>; + unsigned int flags; +}; + +struct __db_get_reply { + unsigned int status; + opaque keydata<>; + opaque datadata<>; +}; + +struct __db_h_ffactor_msg { + unsigned int dbpcl_id; + unsigned int ffactor; +}; + +struct __db_h_ffactor_reply { + unsigned int status; +}; + +struct __db_h_nelem_msg { + unsigned int dbpcl_id; + unsigned int nelem; +}; + +struct __db_h_nelem_reply { + unsigned int status; +}; + +struct __db_key_range_msg { + unsigned int dbpcl_id; + unsigned int txnpcl_id; + unsigned int keydlen; + unsigned int keydoff; + unsigned int keyflags; + opaque keydata<>; + unsigned int flags; +}; + +struct __db_key_range_reply { + unsigned int status; + double less; + double equal; + double greater; +}; + +struct __db_lorder_msg { + unsigned int dbpcl_id; + unsigned int lorder; +}; + +struct __db_lorder_reply { + unsigned int status; +}; + +struct __db_open_msg { + unsigned int dbpcl_id; + string name<>; + string subdb<>; + unsigned int type; + unsigned int flags; + unsigned int mode; +}; + +struct __db_open_reply { + unsigned int status; + unsigned int type; + unsigned int dbflags; +}; + +struct __db_pagesize_msg { + unsigned int dbpcl_id; + unsigned int pagesize; +}; + +struct __db_pagesize_reply { + unsigned int status; +}; + +struct __db_put_msg { + unsigned int dbpcl_id; + unsigned int txnpcl_id; + unsigned int keydlen; + unsigned int keydoff; + unsigned int keyflags; + opaque keydata<>; + unsigned int datadlen; + unsigned int datadoff; + unsigned int dataflags; + opaque datadata<>; + unsigned int flags; +}; + +struct __db_put_reply { + unsigned int status; + opaque keydata<>; +}; + +struct __db_re_delim_msg { + unsigned int dbpcl_id; + unsigned int delim; +}; + +struct __db_re_delim_reply { + unsigned int status; +}; + +struct __db_re_len_msg { + unsigned int dbpcl_id; + unsigned int len; +}; + +struct __db_re_len_reply { + unsigned int status; +}; + +struct __db_re_pad_msg { + unsigned int dbpcl_id; + unsigned int pad; +}; + +struct __db_re_pad_reply { + unsigned int status; +}; + +struct __db_remove_msg { + unsigned int dbpcl_id; + string name<>; + string subdb<>; + unsigned int flags; +}; + +struct __db_remove_reply { + unsigned int status; +}; + +struct __db_rename_msg { + unsigned int dbpcl_id; + string name<>; + string subdb<>; + string newname<>; + unsigned int flags; +}; + +struct __db_rename_reply { + unsigned int status; +}; + +struct __db_stat_msg { + unsigned int dbpcl_id; + unsigned int flags; +}; + +struct __db_stat_statsreplist { + opaque ent<>; + __db_stat_statsreplist *next; +}; + +struct __db_stat_reply { + unsigned int status; + __db_stat_statsreplist *statslist; +}; + +struct __db_swapped_msg { + unsigned int dbpcl_id; +}; + +struct __db_swapped_reply { + unsigned int status; +}; + +struct __db_sync_msg { + unsigned int dbpcl_id; + unsigned int flags; +}; + +struct __db_sync_reply { + unsigned int status; +}; + +struct __db_cursor_msg { + unsigned int dbpcl_id; + unsigned int txnpcl_id; + unsigned int flags; +}; + +struct __db_cursor_reply { + unsigned int status; + unsigned int dbcidcl_id; +}; + +struct __db_join_curslist { + opaque ent<>; + __db_join_curslist *next; +}; + +struct __db_join_msg { + unsigned int dbpcl_id; + __db_join_curslist *curslist; + unsigned int flags; +}; + +struct __db_join_reply { + unsigned int status; + unsigned int dbcidcl_id; +}; + +struct __dbc_close_msg { + unsigned int dbccl_id; +}; + +struct __dbc_close_reply { + unsigned int status; +}; + +struct __dbc_count_msg { + unsigned int dbccl_id; + unsigned int flags; +}; + +struct __dbc_count_reply { + unsigned int status; + unsigned int dupcount; +}; + +struct __dbc_del_msg { + unsigned int dbccl_id; + unsigned int flags; +}; + +struct __dbc_del_reply { + unsigned int status; +}; + +struct __dbc_dup_msg { + unsigned int dbccl_id; + unsigned int flags; +}; + +struct __dbc_dup_reply { + unsigned int status; + unsigned int dbcidcl_id; +}; + +struct __dbc_get_msg { + unsigned int dbccl_id; + unsigned int keydlen; + unsigned int keydoff; + unsigned int keyflags; + opaque keydata<>; + unsigned int datadlen; + unsigned int datadoff; + unsigned int dataflags; + opaque datadata<>; + unsigned int flags; +}; + +struct __dbc_get_reply { + unsigned int status; + opaque keydata<>; + opaque datadata<>; +}; + +struct __dbc_put_msg { + unsigned int dbccl_id; + unsigned int keydlen; + unsigned int keydoff; + unsigned int keyflags; + opaque keydata<>; + unsigned int datadlen; + unsigned int datadoff; + unsigned int dataflags; + opaque datadata<>; + unsigned int flags; +}; + +struct __dbc_put_reply { + unsigned int status; + opaque keydata<>; +}; +program DB_SERVERPROG { + version DB_SERVERVERS { + __env_cachesize_reply __DB_env_cachesize(__env_cachesize_msg) = 1; + __env_close_reply __DB_env_close(__env_close_msg) = 2; + __env_create_reply __DB_env_create(__env_create_msg) = 3; + __env_flags_reply __DB_env_flags(__env_flags_msg) = 4; + __env_open_reply __DB_env_open(__env_open_msg) = 5; + __env_remove_reply __DB_env_remove(__env_remove_msg) = 6; + __txn_abort_reply __DB_txn_abort(__txn_abort_msg) = 7; + __txn_begin_reply __DB_txn_begin(__txn_begin_msg) = 8; + __txn_commit_reply __DB_txn_commit(__txn_commit_msg) = 9; + __db_bt_maxkey_reply __DB_db_bt_maxkey(__db_bt_maxkey_msg) = 10; + __db_bt_minkey_reply __DB_db_bt_minkey(__db_bt_minkey_msg) = 11; + __db_close_reply __DB_db_close(__db_close_msg) = 12; + __db_create_reply __DB_db_create(__db_create_msg) = 13; + __db_del_reply __DB_db_del(__db_del_msg) = 14; + __db_extentsize_reply __DB_db_extentsize(__db_extentsize_msg) = 15; + __db_flags_reply __DB_db_flags(__db_flags_msg) = 16; + __db_get_reply __DB_db_get(__db_get_msg) = 17; + __db_h_ffactor_reply __DB_db_h_ffactor(__db_h_ffactor_msg) = 18; + __db_h_nelem_reply __DB_db_h_nelem(__db_h_nelem_msg) = 19; + __db_key_range_reply __DB_db_key_range(__db_key_range_msg) = 20; + __db_lorder_reply __DB_db_lorder(__db_lorder_msg) = 21; + __db_open_reply __DB_db_open(__db_open_msg) = 22; + __db_pagesize_reply __DB_db_pagesize(__db_pagesize_msg) = 23; + __db_put_reply __DB_db_put(__db_put_msg) = 24; + __db_re_delim_reply __DB_db_re_delim(__db_re_delim_msg) = 25; + __db_re_len_reply __DB_db_re_len(__db_re_len_msg) = 26; + __db_re_pad_reply __DB_db_re_pad(__db_re_pad_msg) = 27; + __db_remove_reply __DB_db_remove(__db_remove_msg) = 28; + __db_rename_reply __DB_db_rename(__db_rename_msg) = 29; + __db_stat_reply __DB_db_stat(__db_stat_msg) = 30; + __db_swapped_reply __DB_db_swapped(__db_swapped_msg) = 31; + __db_sync_reply __DB_db_sync(__db_sync_msg) = 32; + __db_cursor_reply __DB_db_cursor(__db_cursor_msg) = 33; + __db_join_reply __DB_db_join(__db_join_msg) = 34; + __dbc_close_reply __DB_dbc_close(__dbc_close_msg) = 35; + __dbc_count_reply __DB_dbc_count(__dbc_count_msg) = 36; + __dbc_del_reply __DB_dbc_del(__dbc_del_msg) = 37; + __dbc_dup_reply __DB_dbc_dup(__dbc_dup_msg) = 38; + __dbc_get_reply __DB_dbc_get(__dbc_get_msg) = 39; + __dbc_put_reply __DB_dbc_put(__dbc_put_msg) = 40; + } = 1; +} = 351457; diff --git a/bdb/rpc_server/db_server_proc.c b/bdb/rpc_server/db_server_proc.c new file mode 100644 index 00000000000..108a00fb371 --- /dev/null +++ b/bdb/rpc_server/db_server_proc.c @@ -0,0 +1,1546 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000 + * Sleepycat Software. All rights reserved. + */ + +#include "db_config.h" + +#ifdef HAVE_RPC +#ifndef lint +static const char revid[] = "$Id: db_server_proc.c,v 1.48 2001/01/06 16:08:01 sue Exp $"; +#endif /* not lint */ + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <rpc/rpc.h> + +#include <string.h> +#endif +#include "db_server.h" + +#include "db_int.h" +#include "db_server_int.h" +#include "rpc_server_ext.h" + +static int __db_stats_list __P((DB_ENV *, + __db_stat_statsreplist **, u_int32_t *, int)); + +/* BEGIN __env_cachesize_1_proc */ +void +__env_cachesize_1_proc(dbenvcl_id, gbytes, bytes, + ncache, replyp) + long dbenvcl_id; + u_int32_t gbytes; + u_int32_t bytes; + u_int32_t ncache; + __env_cachesize_reply *replyp; +/* END __env_cachesize_1_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + ret = dbenv->set_cachesize(dbenv, gbytes, bytes, ncache); + + replyp->status = ret; + return; +} + +/* BEGIN __env_close_1_proc */ +void +__env_close_1_proc(dbenvcl_id, flags, replyp) + long dbenvcl_id; + u_int32_t flags; + __env_close_reply *replyp; +/* END __env_close_1_proc */ +{ + replyp->status = __dbenv_close_int(dbenvcl_id, flags); + return; +} + +/* BEGIN __env_create_1_proc */ +void +__env_create_1_proc(timeout, replyp) + u_int32_t timeout; + __env_create_reply *replyp; +/* END __env_create_1_proc */ +{ + int ret; + DB_ENV *dbenv; + ct_entry *ctp; + + ctp = new_ct_ent(&replyp->status); + if (ctp == NULL) + return; + if ((ret = db_env_create(&dbenv, 0)) == 0) { + ctp->ct_envp = dbenv; + ctp->ct_type = CT_ENV; + ctp->ct_parent = NULL; + ctp->ct_envparent = ctp; + __dbsrv_settimeout(ctp, timeout); + __dbsrv_active(ctp); + replyp->envcl_id = ctp->ct_id; + } else + __dbclear_ctp(ctp); + + replyp->status = ret; + return; +} + +/* BEGIN __env_flags_1_proc */ +void +__env_flags_1_proc(dbenvcl_id, flags, onoff, replyp) + long dbenvcl_id; + u_int32_t flags; + u_int32_t onoff; + __env_flags_reply *replyp; +/* END __env_flags_1_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + + ret = dbenv->set_flags(dbenv, flags, onoff); + + replyp->status = ret; + return; +} +/* BEGIN __env_open_1_proc */ +void +__env_open_1_proc(dbenvcl_id, home, flags, + mode, replyp) + long dbenvcl_id; + char *home; + u_int32_t flags; + u_int32_t mode; + __env_open_reply *replyp; +/* END __env_open_1_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + char *fullhome; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + fullhome = get_home(home); + if (fullhome == NULL) { + replyp->status = DB_NOSERVER_HOME; + return; + } + + ret = dbenv->open(dbenv, fullhome, flags, mode); + replyp->status = ret; + return; +} + +/* BEGIN __env_remove_1_proc */ +void +__env_remove_1_proc(dbenvcl_id, home, flags, replyp) + long dbenvcl_id; + char *home; + u_int32_t flags; + __env_remove_reply *replyp; +/* END __env_remove_1_proc */ +{ + int ret; + DB_ENV * dbenv; + ct_entry *dbenv_ctp; + char *fullhome; + + ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); + dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; + fullhome = get_home(home); + if (fullhome == NULL) { + replyp->status = DB_NOSERVER_HOME; + return; + } + + ret = dbenv->remove(dbenv, fullhome, flags); + __dbdel_ctp(dbenv_ctp); + replyp->status = ret; + return; +} + +/* BEGIN __txn_abort_1_proc */ +void +__txn_abort_1_proc(txnpcl_id, replyp) + long txnpcl_id; + __txn_abort_reply *replyp; +/* END __txn_abort_1_proc */ +{ + DB_TXN * txnp; + ct_entry *txnp_ctp; + int ret; + + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + ret = txn_abort(txnp); + __dbdel_ctp(txnp_ctp); + replyp->status = ret; + return; +} + +/* BEGIN __txn_begin_1_proc */ +void +__txn_begin_1_proc(envpcl_id, parentcl_id, + flags, replyp) + long envpcl_id; + long parentcl_id; + u_int32_t flags; + __txn_begin_reply *replyp; +/* END __txn_begin_1_proc */ +{ + int ret; + DB_ENV * envp; + ct_entry *envp_ctp; + DB_TXN * parent; + ct_entry *parent_ctp; + DB_TXN *txnp; + ct_entry *ctp; + + ACTIVATE_CTP(envp_ctp, envpcl_id, CT_ENV); + envp = (DB_ENV *)envp_ctp->ct_anyp; + parent_ctp = NULL; + + ctp = new_ct_ent(&replyp->status); + if (ctp == NULL) + return; + + if (parentcl_id != 0) { + ACTIVATE_CTP(parent_ctp, parentcl_id, CT_TXN); + parent = (DB_TXN *)parent_ctp->ct_anyp; + ctp->ct_activep = parent_ctp->ct_activep; + } else + parent = NULL; + + ret = txn_begin(envp, parent, &txnp, flags); + if (ret == 0) { + ctp->ct_txnp = txnp; + ctp->ct_type = CT_TXN; + ctp->ct_parent = parent_ctp; + ctp->ct_envparent = envp_ctp; + replyp->txnidcl_id = ctp->ct_id; + __dbsrv_settimeout(ctp, envp_ctp->ct_timeout); + __dbsrv_active(ctp); + } else + __dbclear_ctp(ctp); + + replyp->status = ret; + return; +} + +/* BEGIN __txn_commit_1_proc */ +void +__txn_commit_1_proc(txnpcl_id, flags, replyp) + long txnpcl_id; + u_int32_t flags; + __txn_commit_reply *replyp; +/* END __txn_commit_1_proc */ +{ + int ret; + DB_TXN * txnp; + ct_entry *txnp_ctp; + + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + + ret = txn_commit(txnp, flags); + __dbdel_ctp(txnp_ctp); + + replyp->status = ret; + return; +} + +/* BEGIN __db_bt_maxkey_1_proc */ +void +__db_bt_maxkey_1_proc(dbpcl_id, maxkey, replyp) + long dbpcl_id; + u_int32_t maxkey; + __db_bt_maxkey_reply *replyp; +/* END __db_bt_maxkey_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->set_bt_maxkey(dbp, maxkey); + + replyp->status = ret; + return; +} + +/* BEGIN __db_bt_minkey_1_proc */ +void +__db_bt_minkey_1_proc(dbpcl_id, minkey, replyp) + long dbpcl_id; + u_int32_t minkey; + __db_bt_minkey_reply *replyp; +/* END __db_bt_minkey_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->set_bt_minkey(dbp, minkey); + + replyp->status = ret; + return; +} + +/* BEGIN __db_close_1_proc */ +void +__db_close_1_proc(dbpcl_id, flags, replyp) + long dbpcl_id; + u_int32_t flags; + __db_close_reply *replyp; +/* END __db_close_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->close(dbp, flags); + __dbdel_ctp(dbp_ctp); + + replyp-> status= ret; + return; +} + +/* BEGIN __db_create_1_proc */ +void +__db_create_1_proc(flags, envpcl_id, replyp) + u_int32_t flags; + long envpcl_id; + __db_create_reply *replyp; +/* END __db_create_1_proc */ +{ + int ret; + DB_ENV * envp; + DB *dbp; + ct_entry *envp_ctp, *dbp_ctp; + + ACTIVATE_CTP(envp_ctp, envpcl_id, CT_ENV); + envp = (DB_ENV *)envp_ctp->ct_anyp; + + dbp_ctp = new_ct_ent(&replyp->status); + if (dbp_ctp == NULL) + return ; + /* + * We actually require env's for databases. The client should + * have caught it, but just in case. + */ + DB_ASSERT(envp != NULL); + if ((ret = db_create(&dbp, envp, flags)) == 0) { + dbp_ctp->ct_dbp = dbp; + dbp_ctp->ct_type = CT_DB; + dbp_ctp->ct_parent = envp_ctp; + dbp_ctp->ct_envparent = envp_ctp; + replyp->dbpcl_id = dbp_ctp->ct_id; + } else + __dbclear_ctp(dbp_ctp); + replyp->status = ret; + return; +} + +/* BEGIN __db_del_1_proc */ +void +__db_del_1_proc(dbpcl_id, txnpcl_id, keydlen, + keydoff, keyflags, keydata, keysize, + flags, replyp) + long dbpcl_id; + long txnpcl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t flags; + __db_del_reply *replyp; +/* END __db_del_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + DBT key; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + if (txnpcl_id != 0) { + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + } else + txnp = NULL; + + memset(&key, 0, sizeof(key)); + + /* Set up key DBT */ + key.dlen = keydlen; + key.doff = keydoff; + key.flags = keyflags; + key.size = keysize; + key.data = keydata; + + ret = dbp->del(dbp, txnp, &key, flags); + + replyp->status = ret; + return; +} + +/* BEGIN __db_extentsize_1_proc */ +void +__db_extentsize_1_proc(dbpcl_id, extentsize, replyp) + long dbpcl_id; + u_int32_t extentsize; + __db_extentsize_reply *replyp; +/* END __db_extentsize_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->set_q_extentsize(dbp, extentsize); + + replyp->status = ret; + return; +} + +/* BEGIN __db_flags_1_proc */ +void +__db_flags_1_proc(dbpcl_id, flags, replyp) + long dbpcl_id; + u_int32_t flags; + __db_flags_reply *replyp; +/* END __db_flags_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->set_flags(dbp, flags); + + replyp->status = ret; + return; +} + +/* BEGIN __db_get_1_proc */ +void +__db_get_1_proc(dbpcl_id, txnpcl_id, keydlen, + keydoff, keyflags, keydata, keysize, + datadlen, datadoff, dataflags, datadata, + datasize, flags, replyp, freep) + long dbpcl_id; + long txnpcl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t datadlen; + u_int32_t datadoff; + u_int32_t dataflags; + void *datadata; + u_int32_t datasize; + u_int32_t flags; + __db_get_reply *replyp; + int * freep; +/* END __db_get_1_proc */ +{ + int key_alloc, ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + DBT key, data; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + if (txnpcl_id != 0) { + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + } else + txnp = NULL; + + *freep = 0; + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + + /* Set up key and data DBT */ + key.dlen = keydlen; + key.doff = keydoff; + /* + * Ignore memory related flags on server. + */ + key.flags = DB_DBT_MALLOC; + if (keyflags & DB_DBT_PARTIAL) + key.flags |= DB_DBT_PARTIAL; + key.size = keysize; + key.data = keydata; + + data.dlen = datadlen; + data.doff = datadoff; + /* + * Ignore memory related flags on server. + */ + data.flags = DB_DBT_MALLOC; + if (dataflags & DB_DBT_PARTIAL) + data.flags |= DB_DBT_PARTIAL; + data.size = datasize; + data.data = datadata; + + /* Got all our stuff, now do the get */ + ret = dbp->get(dbp, txnp, &key, &data, flags); + /* + * Otherwise just status. + */ + if (ret == 0) { + /* + * XXX + * We need to xdr_free whatever we are returning, next time. + * However, DB does not allocate a new key if one was given + * and we'd be free'ing up space allocated in the request. + * So, allocate a new key/data pointer if it is the same one + * as in the request. + */ + *freep = 1; + /* + * Key + */ + key_alloc = 0; + if (key.data == keydata) { + ret = __os_malloc(dbp->dbenv, + key.size, NULL, &replyp->keydata.keydata_val); + if (ret != 0) { + __os_free(key.data, key.size); + __os_free(data.data, data.size); + goto err; + } + key_alloc = 1; + memcpy(replyp->keydata.keydata_val, key.data, key.size); + } else + replyp->keydata.keydata_val = key.data; + + replyp->keydata.keydata_len = key.size; + + /* + * Data + */ + if (data.data == datadata) { + ret = __os_malloc(dbp->dbenv, + data.size, NULL, &replyp->datadata.datadata_val); + if (ret != 0) { + __os_free(key.data, key.size); + __os_free(data.data, data.size); + if (key_alloc) + __os_free(replyp->keydata.keydata_val, + key.size); + goto err; + } + memcpy(replyp->datadata.datadata_val, data.data, + data.size); + } else + replyp->datadata.datadata_val = data.data; + replyp->datadata.datadata_len = data.size; + } else { +err: replyp->keydata.keydata_val = NULL; + replyp->keydata.keydata_len = 0; + replyp->datadata.datadata_val = NULL; + replyp->datadata.datadata_len = 0; + *freep = 0; + } + replyp->status = ret; + return; +} + +/* BEGIN __db_h_ffactor_1_proc */ +void +__db_h_ffactor_1_proc(dbpcl_id, ffactor, replyp) + long dbpcl_id; + u_int32_t ffactor; + __db_h_ffactor_reply *replyp; +/* END __db_h_ffactor_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->set_h_ffactor(dbp, ffactor); + + replyp->status = ret; + return; +} + +/* BEGIN __db_h_nelem_1_proc */ +void +__db_h_nelem_1_proc(dbpcl_id, nelem, replyp) + long dbpcl_id; + u_int32_t nelem; + __db_h_nelem_reply *replyp; +/* END __db_h_nelem_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->set_h_nelem(dbp, nelem); + + replyp->status = ret; + return; +} + +/* BEGIN __db_key_range_1_proc */ +void +__db_key_range_1_proc(dbpcl_id, txnpcl_id, keydlen, + keydoff, keyflags, keydata, keysize, + flags, replyp) + long dbpcl_id; + long txnpcl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t flags; + __db_key_range_reply *replyp; +/* END __db_key_range_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + DBT key; + DB_KEY_RANGE range; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + if (txnpcl_id != 0) { + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + } else + txnp = NULL; + + memset(&key, 0, sizeof(key)); + /* Set up key and data DBT */ + key.dlen = keydlen; + key.doff = keydoff; + key.size = keysize; + key.data = keydata; + key.flags = keyflags; + + ret = dbp->key_range(dbp, txnp, &key, &range, flags); + + replyp->status = ret; + replyp->less = range.less; + replyp->equal = range.equal; + replyp->greater = range.greater; + return; +} + +/* BEGIN __db_lorder_1_proc */ +void +__db_lorder_1_proc(dbpcl_id, lorder, replyp) + long dbpcl_id; + u_int32_t lorder; + __db_lorder_reply *replyp; +/* END __db_lorder_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->set_lorder(dbp, lorder); + + replyp->status = ret; + return; +} + +/* BEGIN __dbopen_1_proc */ +void +__db_open_1_proc(dbpcl_id, name, subdb, + type, flags, mode, replyp) + long dbpcl_id; + char *name; + char *subdb; + u_int32_t type; + u_int32_t flags; + u_int32_t mode; + __db_open_reply *replyp; +/* END __db_open_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->open(dbp, name, subdb, (DBTYPE)type, flags, mode); + if (ret == 0) { + replyp->type = (int) dbp->get_type(dbp); + /* XXX + * Tcl needs to peek at dbp->flags for DB_AM_DUP. Send + * this dbp's flags back. + */ + replyp->dbflags = (int) dbp->flags; + } + replyp->status = ret; + return; +} + +/* BEGIN __db_pagesize_1_proc */ +void +__db_pagesize_1_proc(dbpcl_id, pagesize, replyp) + long dbpcl_id; + u_int32_t pagesize; + __db_pagesize_reply *replyp; +/* END __db_pagesize_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->set_pagesize(dbp, pagesize); + + replyp->status = ret; + return; +} + +/* BEGIN __db_put_1_proc */ +void +__db_put_1_proc(dbpcl_id, txnpcl_id, keydlen, + keydoff, keyflags, keydata, keysize, + datadlen, datadoff, dataflags, datadata, + datasize, flags, replyp, freep) + long dbpcl_id; + long txnpcl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t datadlen; + u_int32_t datadoff; + u_int32_t dataflags; + void *datadata; + u_int32_t datasize; + u_int32_t flags; + __db_put_reply *replyp; + int * freep; +/* END __db_put_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + DBT key, data; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + if (txnpcl_id != 0) { + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + } else + txnp = NULL; + + *freep = 0; + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + + /* Set up key and data DBT */ + key.dlen = keydlen; + key.doff = keydoff; + /* + * Ignore memory related flags on server. + */ + key.flags = DB_DBT_MALLOC; + if (keyflags & DB_DBT_PARTIAL) + key.flags |= DB_DBT_PARTIAL; + key.size = keysize; + key.data = keydata; + + data.dlen = datadlen; + data.doff = datadoff; + data.flags = dataflags; + data.size = datasize; + data.data = datadata; + + /* Got all our stuff, now do the put */ + ret = dbp->put(dbp, txnp, &key, &data, flags); + /* + * If the client did a DB_APPEND, set up key in reply. + * Otherwise just status. + */ + if (ret == 0 && (flags == DB_APPEND)) { + /* + * XXX + * We need to xdr_free whatever we are returning, next time. + * However, DB does not allocate a new key if one was given + * and we'd be free'ing up space allocated in the request. + * So, allocate a new key/data pointer if it is the same one + * as in the request. + */ + *freep = 1; + /* + * Key + */ + if (key.data == keydata) { + ret = __os_malloc(dbp->dbenv, + key.size, NULL, &replyp->keydata.keydata_val); + if (ret != 0) { + __os_free(key.data, key.size); + goto err; + } + memcpy(replyp->keydata.keydata_val, key.data, key.size); + } else + replyp->keydata.keydata_val = key.data; + + replyp->keydata.keydata_len = key.size; + } else { +err: replyp->keydata.keydata_val = NULL; + replyp->keydata.keydata_len = 0; + *freep = 0; + } + replyp->status = ret; + return; +} + +/* BEGIN __db_re_delim_1_proc */ +void +__db_re_delim_1_proc(dbpcl_id, delim, replyp) + long dbpcl_id; + u_int32_t delim; + __db_re_delim_reply *replyp; +/* END __db_re_delim_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->set_re_delim(dbp, delim); + + replyp->status = ret; + return; +} + +/* BEGIN __db_re_len_1_proc */ +void +__db_re_len_1_proc(dbpcl_id, len, replyp) + long dbpcl_id; + u_int32_t len; + __db_re_len_reply *replyp; +/* END __db_re_len_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->set_re_len(dbp, len); + + replyp->status = ret; + return; +} + +/* BEGIN __db_re_pad_1_proc */ +void +__db_re_pad_1_proc(dbpcl_id, pad, replyp) + long dbpcl_id; + u_int32_t pad; + __db_re_pad_reply *replyp; +/* END __db_re_pad_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->set_re_pad(dbp, pad); + + replyp->status = ret; + return; +} + +/* BEGIN __db_remove_1_proc */ +void +__db_remove_1_proc(dbpcl_id, name, subdb, + flags, replyp) + long dbpcl_id; + char *name; + char *subdb; + u_int32_t flags; + __db_remove_reply *replyp; +/* END __db_remove_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->remove(dbp, name, subdb, flags); + __dbdel_ctp(dbp_ctp); + + replyp->status = ret; + return; +} + +/* BEGIN __db_rename_1_proc */ +void +__db_rename_1_proc(dbpcl_id, name, subdb, + newname, flags, replyp) + long dbpcl_id; + char *name; + char *subdb; + char *newname; + u_int32_t flags; + __db_rename_reply *replyp; +/* END __db_rename_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->rename(dbp, name, subdb, newname, flags); + __dbdel_ctp(dbp_ctp); + + replyp->status = ret; + return; +} + +/* BEGIN __db_stat_1_proc */ +void +__db_stat_1_proc(dbpcl_id, + flags, replyp, freep) + long dbpcl_id; + u_int32_t flags; + __db_stat_reply *replyp; + int * freep; +/* END __db_stat_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DBTYPE type; + void *sp; + int len; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->stat(dbp, &sp, NULL, flags); + replyp->status = ret; + if (ret != 0) + return; + /* + * We get here, we have success. Allocate an array so that + * we can use the list generator. Generate the reply, free + * up the space. + */ + /* + * XXX This assumes that all elements of all stat structures + * are u_int32_t fields. They are, currently. + */ + type = dbp->get_type(dbp); + if (type == DB_HASH) + len = sizeof(DB_HASH_STAT) / sizeof(u_int32_t); + else if (type == DB_QUEUE) + len = sizeof(DB_QUEUE_STAT) / sizeof(u_int32_t); + else /* BTREE or RECNO are same stats */ + len = sizeof(DB_BTREE_STAT) / sizeof(u_int32_t); + /* + * Set up our list of stats. + */ + ret = __db_stats_list(dbp->dbenv, + &replyp->statslist, (u_int32_t*)sp, len); + + __os_free(sp, 0); + if (ret == 0) + *freep = 1; + replyp->status = ret; + return; +} + +int +__db_stats_list(dbenv, locp, pp, len) + DB_ENV *dbenv; + __db_stat_statsreplist **locp; + u_int32_t *pp; + int len; +{ + u_int32_t *p, *q; + int i, ret; + __db_stat_statsreplist *nl, **nlp; + + nlp = locp; + for (i = 0; i < len; i++) { + p = pp+i; + if ((ret = __os_malloc(dbenv, sizeof(*nl), NULL, nlp)) != 0) + goto out; + nl = *nlp; + nl->next = NULL; + if ((ret = __os_malloc(dbenv, + sizeof(u_int32_t), NULL, &nl->ent.ent_val)) != 0) + goto out; + q = (u_int32_t *)nl->ent.ent_val; + *q = *p; + nl->ent.ent_len = sizeof(u_int32_t); + nlp = &nl->next; + } + return (0); +out: + __db_stats_freelist(locp); + return (ret); +} + +/* + * PUBLIC: void __db_stats_freelist __P((__db_stat_statsreplist **)); + */ +void +__db_stats_freelist(locp) + __db_stat_statsreplist **locp; +{ + __db_stat_statsreplist *nl, *nl1; + + for (nl = *locp; nl != NULL; nl = nl1) { + nl1 = nl->next; + if (nl->ent.ent_val) + __os_free(nl->ent.ent_val, nl->ent.ent_len); + __os_free(nl, sizeof(*nl)); + } + *locp = NULL; +} + +/* BEGIN __db_swapped_1_proc */ +void +__db_swapped_1_proc(dbpcl_id, replyp) + long dbpcl_id; + __db_swapped_reply *replyp; +/* END __db_swapped_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->get_byteswapped(dbp); + + replyp->status = ret; + return; +} + +/* BEGIN __db_sync_1_proc */ +void +__db_sync_1_proc(dbpcl_id, flags, replyp) + long dbpcl_id; + u_int32_t flags; + __db_sync_reply *replyp; +/* END __db_sync_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + ret = dbp->sync(dbp, flags); + + replyp->status = ret; + return; +} + +/* BEGIN __db_cursor_1_proc */ +void +__db_cursor_1_proc(dbpcl_id, txnpcl_id, + flags, replyp) + long dbpcl_id; + long txnpcl_id; + u_int32_t flags; + __db_cursor_reply *replyp; +/* END __db_cursor_1_proc */ +{ + int ret; + DB * dbp; + ct_entry *dbp_ctp; + DB_TXN * txnp; + ct_entry *txnp_ctp; + DBC *dbc; + ct_entry *dbc_ctp, *env_ctp; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + dbc_ctp = new_ct_ent(&replyp->status); + if (dbc_ctp == NULL) + return; + + if (txnpcl_id != 0) { + ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); + txnp = (DB_TXN *)txnp_ctp->ct_anyp; + dbc_ctp->ct_activep = txnp_ctp->ct_activep; + } else + txnp = NULL; + + if ((ret = dbp->cursor(dbp, txnp, &dbc, flags)) == 0) { + dbc_ctp->ct_dbc = dbc; + dbc_ctp->ct_type = CT_CURSOR; + dbc_ctp->ct_parent = dbp_ctp; + env_ctp = dbp_ctp->ct_envparent; + dbc_ctp->ct_envparent = env_ctp; + __dbsrv_settimeout(dbc_ctp, env_ctp->ct_timeout); + __dbsrv_active(dbc_ctp); + replyp->dbcidcl_id = dbc_ctp->ct_id; + } else + __dbclear_ctp(dbc_ctp); + + replyp->status = ret; + return; +} + +/* BEGIN __db_join_1_proc */ +void +__db_join_1_proc(dbpcl_id, curslist, + flags, replyp) + long dbpcl_id; + u_int32_t * curslist; + u_int32_t flags; + __db_join_reply *replyp; +/* END __db_join_1_proc */ +{ + DB * dbp; + ct_entry *dbp_ctp; + DBC *dbc; + DBC **jcurs, **c; + ct_entry *dbc_ctp, *ctp; + size_t size; + int ret; + u_int32_t *cl; + + ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); + dbp = (DB *)dbp_ctp->ct_anyp; + + dbc_ctp = new_ct_ent(&replyp->status); + if (dbc_ctp == NULL) + return; + + for (size = sizeof(DBC *), cl = curslist; *cl != 0; size += sizeof(DBC *), cl++) + ; + if ((ret = __os_malloc(dbp->dbenv, size, NULL, &jcurs)) != 0) { + replyp->status = ret; + __dbclear_ctp(dbc_ctp); + return; + } + /* + * If our curslist has a parent txn, we need to use it too + * for the activity timeout. All cursors must be part of + * the same transaction, so just check the first. + */ + ctp = get_tableent(*curslist); + DB_ASSERT(ctp->ct_type == CT_CURSOR); + /* + * If we are using a transaction, set the join activity timer + * to point to the parent transaction. + */ + if (ctp->ct_activep != &ctp->ct_active) + dbc_ctp->ct_activep = ctp->ct_activep; + for (cl = curslist, c = jcurs; *cl != 0; cl++, c++) { + ctp = get_tableent(*cl); + if (ctp == NULL) { + replyp->status = DB_NOSERVER_ID; + goto out; + } + /* + * If we are using a txn, the join cursor points to the + * transaction timeout. If we are not using a transaction, + * then all the curslist cursors must point to the join + * cursor's timeout so that we do not timeout any of the + * curlist cursors while the join cursor is active. + * Change the type of the curslist ctps to CT_JOIN so that + * we know they are part of a join list and we can distinguish + * them and later restore them when the join cursor is closed. + */ + DB_ASSERT(ctp->ct_type == CT_CURSOR); + ctp->ct_type |= CT_JOIN; + ctp->ct_origp = ctp->ct_activep; + /* + * Setting this to the ct_active field of the dbc_ctp is + * really just a way to distinguish which join dbc this + * cursor is part of. The ct_activep of this cursor is + * not used at all during its lifetime as part of a join + * cursor. + */ + ctp->ct_activep = &dbc_ctp->ct_active; + *c = ctp->ct_dbc; + } + *c = NULL; + if ((ret = dbp->join(dbp, jcurs, &dbc, flags)) == 0) { + dbc_ctp->ct_dbc = dbc; + dbc_ctp->ct_type = (CT_JOINCUR | CT_CURSOR); + dbc_ctp->ct_parent = dbp_ctp; + dbc_ctp->ct_envparent = dbp_ctp->ct_envparent; + __dbsrv_settimeout(dbc_ctp, dbp_ctp->ct_envparent->ct_timeout); + __dbsrv_active(dbc_ctp); + replyp->dbcidcl_id = dbc_ctp->ct_id; + } else { + __dbclear_ctp(dbc_ctp); + /* + * If we get an error, undo what we did above to any cursors. + */ + for (cl = curslist; *cl != 0; cl++) { + ctp = get_tableent(*cl); + ctp->ct_type = CT_CURSOR; + ctp->ct_activep = ctp->ct_origp; + } + } + + replyp->status = ret; +out: + __os_free(jcurs, size); + return; +} + +/* BEGIN __dbc_close_1_proc */ +void +__dbc_close_1_proc(dbccl_id, replyp) + long dbccl_id; + __dbc_close_reply *replyp; +/* END __dbc_close_1_proc */ +{ + ct_entry *dbc_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + replyp->status = __dbc_close_int(dbc_ctp); + return; +} + +/* BEGIN __dbc_count_1_proc */ +void +__dbc_count_1_proc(dbccl_id, flags, replyp) + long dbccl_id; + u_int32_t flags; + __dbc_count_reply *replyp; +/* END __dbc_count_1_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + db_recno_t num; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + ret = dbc->c_count(dbc, &num, flags); + replyp->status = ret; + if (ret == 0) + replyp->dupcount = num; + return; +} + +/* BEGIN __dbc_del_1_proc */ +void +__dbc_del_1_proc(dbccl_id, flags, replyp) + long dbccl_id; + u_int32_t flags; + __dbc_del_reply *replyp; +/* END __dbc_del_1_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + ret = dbc->c_del(dbc, flags); + + replyp->status = ret; + return; +} + +/* BEGIN __dbc_dup_1_proc */ +void +__dbc_dup_1_proc(dbccl_id, flags, replyp) + long dbccl_id; + u_int32_t flags; + __dbc_dup_reply *replyp; +/* END __dbc_dup_1_proc */ +{ + int ret; + DBC * dbc; + ct_entry *dbc_ctp; + DBC *newdbc; + ct_entry *new_ctp; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + + new_ctp = new_ct_ent(&replyp->status); + if (new_ctp == NULL) + return; + + if ((ret = dbc->c_dup(dbc, &newdbc, flags)) == 0) { + new_ctp->ct_dbc = newdbc; + new_ctp->ct_type = CT_CURSOR; + new_ctp->ct_parent = dbc_ctp->ct_parent; + new_ctp->ct_envparent = dbc_ctp->ct_envparent; + /* + * If our cursor has a parent txn, we need to use it too. + */ + if (dbc_ctp->ct_activep != &dbc_ctp->ct_active) + new_ctp->ct_activep = dbc_ctp->ct_activep; + __dbsrv_settimeout(new_ctp, dbc_ctp->ct_timeout); + __dbsrv_active(new_ctp); + replyp->dbcidcl_id = new_ctp->ct_id; + } else + __dbclear_ctp(new_ctp); + + replyp->status = ret; + return; +} + +/* BEGIN __dbc_get_1_proc */ +void +__dbc_get_1_proc(dbccl_id, keydlen, keydoff, + keyflags, keydata, keysize, datadlen, + datadoff, dataflags, datadata, datasize, + flags, replyp, freep) + long dbccl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t datadlen; + u_int32_t datadoff; + u_int32_t dataflags; + void *datadata; + u_int32_t datasize; + u_int32_t flags; + __dbc_get_reply *replyp; + int * freep; +/* END __dbc_get_1_proc */ +{ + DB_ENV *dbenv; + DBC *dbc; + DBT key, data; + ct_entry *dbc_ctp; + int key_alloc, ret; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + dbenv = dbc->dbp->dbenv; + + *freep = 0; + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + + /* Set up key and data DBT */ + key.dlen = keydlen; + key.doff = keydoff; + /* + * Ignore memory related flags on server. + */ + key.flags = DB_DBT_MALLOC; + if (keyflags & DB_DBT_PARTIAL) + key.flags |= DB_DBT_PARTIAL; + key.size = keysize; + key.data = keydata; + + data.dlen = datadlen; + data.doff = datadoff; + data.flags = DB_DBT_MALLOC; + if (dataflags & DB_DBT_PARTIAL) + data.flags |= DB_DBT_PARTIAL; + data.size = datasize; + data.data = datadata; + + /* Got all our stuff, now do the get */ + ret = dbc->c_get(dbc, &key, &data, flags); + + /* + * Otherwise just status. + */ + if (ret == 0) { + /* + * XXX + * We need to xdr_free whatever we are returning, next time. + * However, DB does not allocate a new key if one was given + * and we'd be free'ing up space allocated in the request. + * So, allocate a new key/data pointer if it is the same one + * as in the request. + */ + *freep = 1; + /* + * Key + */ + key_alloc = 0; + if (key.data == keydata) { + ret = __os_malloc(dbenv, key.size, NULL, + &replyp->keydata.keydata_val); + if (ret != 0) { + __os_free(key.data, key.size); + __os_free(data.data, data.size); + goto err; + } + key_alloc = 1; + memcpy(replyp->keydata.keydata_val, key.data, key.size); + } else + replyp->keydata.keydata_val = key.data; + + replyp->keydata.keydata_len = key.size; + + /* + * Data + */ + if (data.data == datadata) { + ret = __os_malloc(dbenv, data.size, NULL, + &replyp->datadata.datadata_val); + if (ret != 0) { + __os_free(key.data, key.size); + __os_free(data.data, data.size); + if (key_alloc) + __os_free(replyp->keydata.keydata_val, + key.size); + goto err; + } + memcpy(replyp->datadata.datadata_val, data.data, + data.size); + } else + replyp->datadata.datadata_val = data.data; + replyp->datadata.datadata_len = data.size; + } else { +err: replyp->keydata.keydata_val = NULL; + replyp->keydata.keydata_len = 0; + replyp->datadata.datadata_val = NULL; + replyp->datadata.datadata_len = 0; + *freep = 0; + } + replyp->status = ret; + return; +} + +/* BEGIN __dbc_put_1_proc */ +void +__dbc_put_1_proc(dbccl_id, keydlen, keydoff, + keyflags, keydata, keysize, datadlen, + datadoff, dataflags, datadata, datasize, + flags, replyp, freep) + long dbccl_id; + u_int32_t keydlen; + u_int32_t keydoff; + u_int32_t keyflags; + void *keydata; + u_int32_t keysize; + u_int32_t datadlen; + u_int32_t datadoff; + u_int32_t dataflags; + void *datadata; + u_int32_t datasize; + u_int32_t flags; + __dbc_put_reply *replyp; + int * freep; +/* END __dbc_put_1_proc */ +{ + int ret; + DBC * dbc; + DB *dbp; + ct_entry *dbc_ctp; + DBT key, data; + + ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); + dbc = (DBC *)dbc_ctp->ct_anyp; + dbp = (DB *)dbc_ctp->ct_parent->ct_anyp; + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + + /* Set up key and data DBT */ + key.dlen = keydlen; + key.doff = keydoff; + /* + * Ignore memory related flags on server. + */ + key.flags = 0; + if (keyflags & DB_DBT_PARTIAL) + key.flags |= DB_DBT_PARTIAL; + key.size = keysize; + key.data = keydata; + + data.dlen = datadlen; + data.doff = datadoff; + data.flags = dataflags; + data.size = datasize; + data.data = datadata; + + /* Got all our stuff, now do the put */ + ret = dbc->c_put(dbc, &key, &data, flags); + + *freep = 0; + if (ret == 0 && (flags == DB_AFTER || flags == DB_BEFORE) && + dbp->type == DB_RECNO) { + /* + * We need to xdr_free whatever we are returning, next time. + */ + replyp->keydata.keydata_val = key.data; + replyp->keydata.keydata_len = key.size; + } else { + replyp->keydata.keydata_val = NULL; + replyp->keydata.keydata_len = 0; + } + replyp->status = ret; + return; +} +#endif /* HAVE_RPC */ diff --git a/bdb/rpc_server/db_server_proc.sed b/bdb/rpc_server/db_server_proc.sed new file mode 100644 index 00000000000..7266275b2b6 --- /dev/null +++ b/bdb/rpc_server/db_server_proc.sed @@ -0,0 +1,418 @@ +/^\/\* BEGIN __env_cachesize_1_proc/,/^\/\* END __env_cachesize_1_proc/c\ +/* BEGIN __env_cachesize_1_proc */\ +void\ +__env_cachesize_1_proc(dbenvcl_id, gbytes, bytes,\ +\ \ ncache, replyp)\ +\ long dbenvcl_id;\ +\ u_int32_t gbytes;\ +\ u_int32_t bytes;\ +\ u_int32_t ncache;\ +\ __env_cachesize_reply *replyp;\ +/* END __env_cachesize_1_proc */ +/^\/\* BEGIN __env_close_1_proc/,/^\/\* END __env_close_1_proc/c\ +/* BEGIN __env_close_1_proc */\ +void\ +__env_close_1_proc(dbenvcl_id, flags, replyp)\ +\ long dbenvcl_id;\ +\ u_int32_t flags;\ +\ __env_close_reply *replyp;\ +/* END __env_close_1_proc */ +/^\/\* BEGIN __env_create_1_proc/,/^\/\* END __env_create_1_proc/c\ +/* BEGIN __env_create_1_proc */\ +void\ +__env_create_1_proc(timeout, replyp)\ +\ u_int32_t timeout;\ +\ __env_create_reply *replyp;\ +/* END __env_create_1_proc */ +/^\/\* BEGIN __env_flags_1_proc/,/^\/\* END __env_flags_1_proc/c\ +/* BEGIN __env_flags_1_proc */\ +void\ +__env_flags_1_proc(dbenvcl_id, flags, onoff, replyp)\ +\ long dbenvcl_id;\ +\ u_int32_t flags;\ +\ u_int32_t onoff;\ +\ __env_flags_reply *replyp;\ +/* END __env_flags_1_proc */ +/^\/\* BEGIN __env_open_1_proc/,/^\/\* END __env_open_1_proc/c\ +/* BEGIN __env_open_1_proc */\ +void\ +__env_open_1_proc(dbenvcl_id, home, flags,\ +\ \ mode, replyp)\ +\ long dbenvcl_id;\ +\ char *home;\ +\ u_int32_t flags;\ +\ u_int32_t mode;\ +\ __env_open_reply *replyp;\ +/* END __env_open_1_proc */ +/^\/\* BEGIN __env_remove_1_proc/,/^\/\* END __env_remove_1_proc/c\ +/* BEGIN __env_remove_1_proc */\ +void\ +__env_remove_1_proc(dbenvcl_id, home, flags, replyp)\ +\ long dbenvcl_id;\ +\ char *home;\ +\ u_int32_t flags;\ +\ __env_remove_reply *replyp;\ +/* END __env_remove_1_proc */ +/^\/\* BEGIN __txn_abort_1_proc/,/^\/\* END __txn_abort_1_proc/c\ +/* BEGIN __txn_abort_1_proc */\ +void\ +__txn_abort_1_proc(txnpcl_id, replyp)\ +\ long txnpcl_id;\ +\ __txn_abort_reply *replyp;\ +/* END __txn_abort_1_proc */ +/^\/\* BEGIN __txn_begin_1_proc/,/^\/\* END __txn_begin_1_proc/c\ +/* BEGIN __txn_begin_1_proc */\ +void\ +__txn_begin_1_proc(envpcl_id, parentcl_id,\ +\ \ flags, replyp)\ +\ long envpcl_id;\ +\ long parentcl_id;\ +\ u_int32_t flags;\ +\ __txn_begin_reply *replyp;\ +/* END __txn_begin_1_proc */ +/^\/\* BEGIN __txn_commit_1_proc/,/^\/\* END __txn_commit_1_proc/c\ +/* BEGIN __txn_commit_1_proc */\ +void\ +__txn_commit_1_proc(txnpcl_id, flags, replyp)\ +\ long txnpcl_id;\ +\ u_int32_t flags;\ +\ __txn_commit_reply *replyp;\ +/* END __txn_commit_1_proc */ +/^\/\* BEGIN __db_bt_maxkey_1_proc/,/^\/\* END __db_bt_maxkey_1_proc/c\ +/* BEGIN __db_bt_maxkey_1_proc */\ +void\ +__db_bt_maxkey_1_proc(dbpcl_id, maxkey, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t maxkey;\ +\ __db_bt_maxkey_reply *replyp;\ +/* END __db_bt_maxkey_1_proc */ +/^\/\* BEGIN __db_bt_minkey_1_proc/,/^\/\* END __db_bt_minkey_1_proc/c\ +/* BEGIN __db_bt_minkey_1_proc */\ +void\ +__db_bt_minkey_1_proc(dbpcl_id, minkey, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t minkey;\ +\ __db_bt_minkey_reply *replyp;\ +/* END __db_bt_minkey_1_proc */ +/^\/\* BEGIN __db_close_1_proc/,/^\/\* END __db_close_1_proc/c\ +/* BEGIN __db_close_1_proc */\ +void\ +__db_close_1_proc(dbpcl_id, flags, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t flags;\ +\ __db_close_reply *replyp;\ +/* END __db_close_1_proc */ +/^\/\* BEGIN __db_create_1_proc/,/^\/\* END __db_create_1_proc/c\ +/* BEGIN __db_create_1_proc */\ +void\ +__db_create_1_proc(flags, envpcl_id, replyp)\ +\ u_int32_t flags;\ +\ long envpcl_id;\ +\ __db_create_reply *replyp;\ +/* END __db_create_1_proc */ +/^\/\* BEGIN __db_del_1_proc/,/^\/\* END __db_del_1_proc/c\ +/* BEGIN __db_del_1_proc */\ +void\ +__db_del_1_proc(dbpcl_id, txnpcl_id, keydlen,\ +\ \ keydoff, keyflags, keydata, keysize,\ +\ \ flags, replyp)\ +\ long dbpcl_id;\ +\ long txnpcl_id;\ +\ u_int32_t keydlen;\ +\ u_int32_t keydoff;\ +\ u_int32_t keyflags;\ +\ void *keydata;\ +\ u_int32_t keysize;\ +\ u_int32_t flags;\ +\ __db_del_reply *replyp;\ +/* END __db_del_1_proc */ +/^\/\* BEGIN __db_extentsize_1_proc/,/^\/\* END __db_extentsize_1_proc/c\ +/* BEGIN __db_extentsize_1_proc */\ +void\ +__db_extentsize_1_proc(dbpcl_id, extentsize, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t extentsize;\ +\ __db_extentsize_reply *replyp;\ +/* END __db_extentsize_1_proc */ +/^\/\* BEGIN __db_flags_1_proc/,/^\/\* END __db_flags_1_proc/c\ +/* BEGIN __db_flags_1_proc */\ +void\ +__db_flags_1_proc(dbpcl_id, flags, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t flags;\ +\ __db_flags_reply *replyp;\ +/* END __db_flags_1_proc */ +/^\/\* BEGIN __db_get_1_proc/,/^\/\* END __db_get_1_proc/c\ +/* BEGIN __db_get_1_proc */\ +void\ +__db_get_1_proc(dbpcl_id, txnpcl_id, keydlen,\ +\ \ keydoff, keyflags, keydata, keysize,\ +\ \ datadlen, datadoff, dataflags, datadata,\ +\ \ datasize, flags, replyp, freep)\ +\ long dbpcl_id;\ +\ long txnpcl_id;\ +\ u_int32_t keydlen;\ +\ u_int32_t keydoff;\ +\ u_int32_t keyflags;\ +\ void *keydata;\ +\ u_int32_t keysize;\ +\ u_int32_t datadlen;\ +\ u_int32_t datadoff;\ +\ u_int32_t dataflags;\ +\ void *datadata;\ +\ u_int32_t datasize;\ +\ u_int32_t flags;\ +\ __db_get_reply *replyp;\ +\ int * freep;\ +/* END __db_get_1_proc */ +/^\/\* BEGIN __db_h_ffactor_1_proc/,/^\/\* END __db_h_ffactor_1_proc/c\ +/* BEGIN __db_h_ffactor_1_proc */\ +void\ +__db_h_ffactor_1_proc(dbpcl_id, ffactor, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t ffactor;\ +\ __db_h_ffactor_reply *replyp;\ +/* END __db_h_ffactor_1_proc */ +/^\/\* BEGIN __db_h_nelem_1_proc/,/^\/\* END __db_h_nelem_1_proc/c\ +/* BEGIN __db_h_nelem_1_proc */\ +void\ +__db_h_nelem_1_proc(dbpcl_id, nelem, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t nelem;\ +\ __db_h_nelem_reply *replyp;\ +/* END __db_h_nelem_1_proc */ +/^\/\* BEGIN __db_key_range_1_proc/,/^\/\* END __db_key_range_1_proc/c\ +/* BEGIN __db_key_range_1_proc */\ +void\ +__db_key_range_1_proc(dbpcl_id, txnpcl_id, keydlen,\ +\ \ keydoff, keyflags, keydata, keysize,\ +\ \ flags, replyp)\ +\ long dbpcl_id;\ +\ long txnpcl_id;\ +\ u_int32_t keydlen;\ +\ u_int32_t keydoff;\ +\ u_int32_t keyflags;\ +\ void *keydata;\ +\ u_int32_t keysize;\ +\ u_int32_t flags;\ +\ __db_key_range_reply *replyp;\ +/* END __db_key_range_1_proc */ +/^\/\* BEGIN __db_lorder_1_proc/,/^\/\* END __db_lorder_1_proc/c\ +/* BEGIN __db_lorder_1_proc */\ +void\ +__db_lorder_1_proc(dbpcl_id, lorder, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t lorder;\ +\ __db_lorder_reply *replyp;\ +/* END __db_lorder_1_proc */ +/^\/\* BEGIN __db_open_1_proc/,/^\/\* END __db_open_1_proc/c\ +/* BEGIN __db_open_1_proc */\ +void\ +__db_open_1_proc(dbpcl_id, name, subdb,\ +\ \ type, flags, mode, replyp)\ +\ long dbpcl_id;\ +\ char *name;\ +\ char *subdb;\ +\ u_int32_t type;\ +\ u_int32_t flags;\ +\ u_int32_t mode;\ +\ __db_open_reply *replyp;\ +/* END __db_open_1_proc */ +/^\/\* BEGIN __db_pagesize_1_proc/,/^\/\* END __db_pagesize_1_proc/c\ +/* BEGIN __db_pagesize_1_proc */\ +void\ +__db_pagesize_1_proc(dbpcl_id, pagesize, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t pagesize;\ +\ __db_pagesize_reply *replyp;\ +/* END __db_pagesize_1_proc */ +/^\/\* BEGIN __db_put_1_proc/,/^\/\* END __db_put_1_proc/c\ +/* BEGIN __db_put_1_proc */\ +void\ +__db_put_1_proc(dbpcl_id, txnpcl_id, keydlen,\ +\ \ keydoff, keyflags, keydata, keysize,\ +\ \ datadlen, datadoff, dataflags, datadata,\ +\ \ datasize, flags, replyp, freep)\ +\ long dbpcl_id;\ +\ long txnpcl_id;\ +\ u_int32_t keydlen;\ +\ u_int32_t keydoff;\ +\ u_int32_t keyflags;\ +\ void *keydata;\ +\ u_int32_t keysize;\ +\ u_int32_t datadlen;\ +\ u_int32_t datadoff;\ +\ u_int32_t dataflags;\ +\ void *datadata;\ +\ u_int32_t datasize;\ +\ u_int32_t flags;\ +\ __db_put_reply *replyp;\ +\ int * freep;\ +/* END __db_put_1_proc */ +/^\/\* BEGIN __db_re_delim_1_proc/,/^\/\* END __db_re_delim_1_proc/c\ +/* BEGIN __db_re_delim_1_proc */\ +void\ +__db_re_delim_1_proc(dbpcl_id, delim, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t delim;\ +\ __db_re_delim_reply *replyp;\ +/* END __db_re_delim_1_proc */ +/^\/\* BEGIN __db_re_len_1_proc/,/^\/\* END __db_re_len_1_proc/c\ +/* BEGIN __db_re_len_1_proc */\ +void\ +__db_re_len_1_proc(dbpcl_id, len, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t len;\ +\ __db_re_len_reply *replyp;\ +/* END __db_re_len_1_proc */ +/^\/\* BEGIN __db_re_pad_1_proc/,/^\/\* END __db_re_pad_1_proc/c\ +/* BEGIN __db_re_pad_1_proc */\ +void\ +__db_re_pad_1_proc(dbpcl_id, pad, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t pad;\ +\ __db_re_pad_reply *replyp;\ +/* END __db_re_pad_1_proc */ +/^\/\* BEGIN __db_remove_1_proc/,/^\/\* END __db_remove_1_proc/c\ +/* BEGIN __db_remove_1_proc */\ +void\ +__db_remove_1_proc(dbpcl_id, name, subdb,\ +\ \ flags, replyp)\ +\ long dbpcl_id;\ +\ char *name;\ +\ char *subdb;\ +\ u_int32_t flags;\ +\ __db_remove_reply *replyp;\ +/* END __db_remove_1_proc */ +/^\/\* BEGIN __db_rename_1_proc/,/^\/\* END __db_rename_1_proc/c\ +/* BEGIN __db_rename_1_proc */\ +void\ +__db_rename_1_proc(dbpcl_id, name, subdb,\ +\ \ newname, flags, replyp)\ +\ long dbpcl_id;\ +\ char *name;\ +\ char *subdb;\ +\ char *newname;\ +\ u_int32_t flags;\ +\ __db_rename_reply *replyp;\ +/* END __db_rename_1_proc */ +/^\/\* BEGIN __db_stat_1_proc/,/^\/\* END __db_stat_1_proc/c\ +/* BEGIN __db_stat_1_proc */\ +void\ +__db_stat_1_proc(dbpcl_id,\ +\ \ flags, replyp, freep)\ +\ long dbpcl_id;\ +\ u_int32_t flags;\ +\ __db_stat_reply *replyp;\ +\ int * freep;\ +/* END __db_stat_1_proc */ +/^\/\* BEGIN __db_swapped_1_proc/,/^\/\* END __db_swapped_1_proc/c\ +/* BEGIN __db_swapped_1_proc */\ +void\ +__db_swapped_1_proc(dbpcl_id, replyp)\ +\ long dbpcl_id;\ +\ __db_swapped_reply *replyp;\ +/* END __db_swapped_1_proc */ +/^\/\* BEGIN __db_sync_1_proc/,/^\/\* END __db_sync_1_proc/c\ +/* BEGIN __db_sync_1_proc */\ +void\ +__db_sync_1_proc(dbpcl_id, flags, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t flags;\ +\ __db_sync_reply *replyp;\ +/* END __db_sync_1_proc */ +/^\/\* BEGIN __db_cursor_1_proc/,/^\/\* END __db_cursor_1_proc/c\ +/* BEGIN __db_cursor_1_proc */\ +void\ +__db_cursor_1_proc(dbpcl_id, txnpcl_id,\ +\ \ flags, replyp)\ +\ long dbpcl_id;\ +\ long txnpcl_id;\ +\ u_int32_t flags;\ +\ __db_cursor_reply *replyp;\ +/* END __db_cursor_1_proc */ +/^\/\* BEGIN __db_join_1_proc/,/^\/\* END __db_join_1_proc/c\ +/* BEGIN __db_join_1_proc */\ +void\ +__db_join_1_proc(dbpcl_id, curslist,\ +\ \ flags, replyp)\ +\ long dbpcl_id;\ +\ u_int32_t * curslist;\ +\ u_int32_t flags;\ +\ __db_join_reply *replyp;\ +/* END __db_join_1_proc */ +/^\/\* BEGIN __dbc_close_1_proc/,/^\/\* END __dbc_close_1_proc/c\ +/* BEGIN __dbc_close_1_proc */\ +void\ +__dbc_close_1_proc(dbccl_id, replyp)\ +\ long dbccl_id;\ +\ __dbc_close_reply *replyp;\ +/* END __dbc_close_1_proc */ +/^\/\* BEGIN __dbc_count_1_proc/,/^\/\* END __dbc_count_1_proc/c\ +/* BEGIN __dbc_count_1_proc */\ +void\ +__dbc_count_1_proc(dbccl_id, flags, replyp)\ +\ long dbccl_id;\ +\ u_int32_t flags;\ +\ __dbc_count_reply *replyp;\ +/* END __dbc_count_1_proc */ +/^\/\* BEGIN __dbc_del_1_proc/,/^\/\* END __dbc_del_1_proc/c\ +/* BEGIN __dbc_del_1_proc */\ +void\ +__dbc_del_1_proc(dbccl_id, flags, replyp)\ +\ long dbccl_id;\ +\ u_int32_t flags;\ +\ __dbc_del_reply *replyp;\ +/* END __dbc_del_1_proc */ +/^\/\* BEGIN __dbc_dup_1_proc/,/^\/\* END __dbc_dup_1_proc/c\ +/* BEGIN __dbc_dup_1_proc */\ +void\ +__dbc_dup_1_proc(dbccl_id, flags, replyp)\ +\ long dbccl_id;\ +\ u_int32_t flags;\ +\ __dbc_dup_reply *replyp;\ +/* END __dbc_dup_1_proc */ +/^\/\* BEGIN __dbc_get_1_proc/,/^\/\* END __dbc_get_1_proc/c\ +/* BEGIN __dbc_get_1_proc */\ +void\ +__dbc_get_1_proc(dbccl_id, keydlen, keydoff,\ +\ \ keyflags, keydata, keysize, datadlen,\ +\ \ datadoff, dataflags, datadata, datasize,\ +\ \ flags, replyp, freep)\ +\ long dbccl_id;\ +\ u_int32_t keydlen;\ +\ u_int32_t keydoff;\ +\ u_int32_t keyflags;\ +\ void *keydata;\ +\ u_int32_t keysize;\ +\ u_int32_t datadlen;\ +\ u_int32_t datadoff;\ +\ u_int32_t dataflags;\ +\ void *datadata;\ +\ u_int32_t datasize;\ +\ u_int32_t flags;\ +\ __dbc_get_reply *replyp;\ +\ int * freep;\ +/* END __dbc_get_1_proc */ +/^\/\* BEGIN __dbc_put_1_proc/,/^\/\* END __dbc_put_1_proc/c\ +/* BEGIN __dbc_put_1_proc */\ +void\ +__dbc_put_1_proc(dbccl_id, keydlen, keydoff,\ +\ \ keyflags, keydata, keysize, datadlen,\ +\ \ datadoff, dataflags, datadata, datasize,\ +\ \ flags, replyp, freep)\ +\ long dbccl_id;\ +\ u_int32_t keydlen;\ +\ u_int32_t keydoff;\ +\ u_int32_t keyflags;\ +\ void *keydata;\ +\ u_int32_t keysize;\ +\ u_int32_t datadlen;\ +\ u_int32_t datadoff;\ +\ u_int32_t dataflags;\ +\ void *datadata;\ +\ u_int32_t datasize;\ +\ u_int32_t flags;\ +\ __dbc_put_reply *replyp;\ +\ int * freep;\ +/* END __dbc_put_1_proc */ diff --git a/bdb/rpc_server/db_server_svc.c b/bdb/rpc_server/db_server_svc.c new file mode 100644 index 00000000000..96d8a4a5dd9 --- /dev/null +++ b/bdb/rpc_server/db_server_svc.c @@ -0,0 +1,359 @@ +#include "db_config.h" +#ifdef HAVE_RPC +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "db_server.h" +#include <stdio.h> +#include <stdlib.h> /* getenv, exit */ +#include <memory.h> +#include <sys/socket.h> +#include <netinet/in.h> +extern void __dbsrv_timeout(); + +#ifdef DEBUG +#define RPC_SVC_FG +#endif + +static void +db_serverprog_1(rqstp, transp) + struct svc_req *rqstp; + register SVCXPRT *transp; +{ + union { + __env_cachesize_msg __db_env_cachesize_1_arg; + __env_close_msg __db_env_close_1_arg; + __env_create_msg __db_env_create_1_arg; + __env_flags_msg __db_env_flags_1_arg; + __env_open_msg __db_env_open_1_arg; + __env_remove_msg __db_env_remove_1_arg; + __txn_abort_msg __db_txn_abort_1_arg; + __txn_begin_msg __db_txn_begin_1_arg; + __txn_commit_msg __db_txn_commit_1_arg; + __db_bt_maxkey_msg __db_db_bt_maxkey_1_arg; + __db_bt_minkey_msg __db_db_bt_minkey_1_arg; + __db_close_msg __db_db_close_1_arg; + __db_create_msg __db_db_create_1_arg; + __db_del_msg __db_db_del_1_arg; + __db_extentsize_msg __db_db_extentsize_1_arg; + __db_flags_msg __db_db_flags_1_arg; + __db_get_msg __db_db_get_1_arg; + __db_h_ffactor_msg __db_db_h_ffactor_1_arg; + __db_h_nelem_msg __db_db_h_nelem_1_arg; + __db_key_range_msg __db_db_key_range_1_arg; + __db_lorder_msg __db_db_lorder_1_arg; + __db_open_msg __db_db_open_1_arg; + __db_pagesize_msg __db_db_pagesize_1_arg; + __db_put_msg __db_db_put_1_arg; + __db_re_delim_msg __db_db_re_delim_1_arg; + __db_re_len_msg __db_db_re_len_1_arg; + __db_re_pad_msg __db_db_re_pad_1_arg; + __db_remove_msg __db_db_remove_1_arg; + __db_rename_msg __db_db_rename_1_arg; + __db_stat_msg __db_db_stat_1_arg; + __db_swapped_msg __db_db_swapped_1_arg; + __db_sync_msg __db_db_sync_1_arg; + __db_cursor_msg __db_db_cursor_1_arg; + __db_join_msg __db_db_join_1_arg; + __dbc_close_msg __db_dbc_close_1_arg; + __dbc_count_msg __db_dbc_count_1_arg; + __dbc_del_msg __db_dbc_del_1_arg; + __dbc_dup_msg __db_dbc_dup_1_arg; + __dbc_get_msg __db_dbc_get_1_arg; + __dbc_put_msg __db_dbc_put_1_arg; + } argument; + char *result; + bool_t (*xdr_argument)(), (*xdr_result)(); + char *(*local)(); + + switch (rqstp->rq_proc) { + case NULLPROC: + (void) svc_sendreply(transp, xdr_void, + (char *)NULL); + return; + + case __DB_env_cachesize: + xdr_argument = xdr___env_cachesize_msg; + xdr_result = xdr___env_cachesize_reply; + local = (char *(*)()) __db_env_cachesize_1; + break; + + case __DB_env_close: + xdr_argument = xdr___env_close_msg; + xdr_result = xdr___env_close_reply; + local = (char *(*)()) __db_env_close_1; + break; + + case __DB_env_create: + xdr_argument = xdr___env_create_msg; + xdr_result = xdr___env_create_reply; + local = (char *(*)()) __db_env_create_1; + break; + + case __DB_env_flags: + xdr_argument = xdr___env_flags_msg; + xdr_result = xdr___env_flags_reply; + local = (char *(*)()) __db_env_flags_1; + break; + + case __DB_env_open: + xdr_argument = xdr___env_open_msg; + xdr_result = xdr___env_open_reply; + local = (char *(*)()) __db_env_open_1; + break; + + case __DB_env_remove: + xdr_argument = xdr___env_remove_msg; + xdr_result = xdr___env_remove_reply; + local = (char *(*)()) __db_env_remove_1; + break; + + case __DB_txn_abort: + xdr_argument = xdr___txn_abort_msg; + xdr_result = xdr___txn_abort_reply; + local = (char *(*)()) __db_txn_abort_1; + break; + + case __DB_txn_begin: + xdr_argument = xdr___txn_begin_msg; + xdr_result = xdr___txn_begin_reply; + local = (char *(*)()) __db_txn_begin_1; + break; + + case __DB_txn_commit: + xdr_argument = xdr___txn_commit_msg; + xdr_result = xdr___txn_commit_reply; + local = (char *(*)()) __db_txn_commit_1; + break; + + case __DB_db_bt_maxkey: + xdr_argument = xdr___db_bt_maxkey_msg; + xdr_result = xdr___db_bt_maxkey_reply; + local = (char *(*)()) __db_db_bt_maxkey_1; + break; + + case __DB_db_bt_minkey: + xdr_argument = xdr___db_bt_minkey_msg; + xdr_result = xdr___db_bt_minkey_reply; + local = (char *(*)()) __db_db_bt_minkey_1; + break; + + case __DB_db_close: + xdr_argument = xdr___db_close_msg; + xdr_result = xdr___db_close_reply; + local = (char *(*)()) __db_db_close_1; + break; + + case __DB_db_create: + xdr_argument = xdr___db_create_msg; + xdr_result = xdr___db_create_reply; + local = (char *(*)()) __db_db_create_1; + break; + + case __DB_db_del: + xdr_argument = xdr___db_del_msg; + xdr_result = xdr___db_del_reply; + local = (char *(*)()) __db_db_del_1; + break; + + case __DB_db_extentsize: + xdr_argument = xdr___db_extentsize_msg; + xdr_result = xdr___db_extentsize_reply; + local = (char *(*)()) __db_db_extentsize_1; + break; + + case __DB_db_flags: + xdr_argument = xdr___db_flags_msg; + xdr_result = xdr___db_flags_reply; + local = (char *(*)()) __db_db_flags_1; + break; + + case __DB_db_get: + xdr_argument = xdr___db_get_msg; + xdr_result = xdr___db_get_reply; + local = (char *(*)()) __db_db_get_1; + break; + + case __DB_db_h_ffactor: + xdr_argument = xdr___db_h_ffactor_msg; + xdr_result = xdr___db_h_ffactor_reply; + local = (char *(*)()) __db_db_h_ffactor_1; + break; + + case __DB_db_h_nelem: + xdr_argument = xdr___db_h_nelem_msg; + xdr_result = xdr___db_h_nelem_reply; + local = (char *(*)()) __db_db_h_nelem_1; + break; + + case __DB_db_key_range: + xdr_argument = xdr___db_key_range_msg; + xdr_result = xdr___db_key_range_reply; + local = (char *(*)()) __db_db_key_range_1; + break; + + case __DB_db_lorder: + xdr_argument = xdr___db_lorder_msg; + xdr_result = xdr___db_lorder_reply; + local = (char *(*)()) __db_db_lorder_1; + break; + + case __DB_db_open: + xdr_argument = xdr___db_open_msg; + xdr_result = xdr___db_open_reply; + local = (char *(*)()) __db_db_open_1; + break; + + case __DB_db_pagesize: + xdr_argument = xdr___db_pagesize_msg; + xdr_result = xdr___db_pagesize_reply; + local = (char *(*)()) __db_db_pagesize_1; + break; + + case __DB_db_put: + xdr_argument = xdr___db_put_msg; + xdr_result = xdr___db_put_reply; + local = (char *(*)()) __db_db_put_1; + break; + + case __DB_db_re_delim: + xdr_argument = xdr___db_re_delim_msg; + xdr_result = xdr___db_re_delim_reply; + local = (char *(*)()) __db_db_re_delim_1; + break; + + case __DB_db_re_len: + xdr_argument = xdr___db_re_len_msg; + xdr_result = xdr___db_re_len_reply; + local = (char *(*)()) __db_db_re_len_1; + break; + + case __DB_db_re_pad: + xdr_argument = xdr___db_re_pad_msg; + xdr_result = xdr___db_re_pad_reply; + local = (char *(*)()) __db_db_re_pad_1; + break; + + case __DB_db_remove: + xdr_argument = xdr___db_remove_msg; + xdr_result = xdr___db_remove_reply; + local = (char *(*)()) __db_db_remove_1; + break; + + case __DB_db_rename: + xdr_argument = xdr___db_rename_msg; + xdr_result = xdr___db_rename_reply; + local = (char *(*)()) __db_db_rename_1; + break; + + case __DB_db_stat: + xdr_argument = xdr___db_stat_msg; + xdr_result = xdr___db_stat_reply; + local = (char *(*)()) __db_db_stat_1; + break; + + case __DB_db_swapped: + xdr_argument = xdr___db_swapped_msg; + xdr_result = xdr___db_swapped_reply; + local = (char *(*)()) __db_db_swapped_1; + break; + + case __DB_db_sync: + xdr_argument = xdr___db_sync_msg; + xdr_result = xdr___db_sync_reply; + local = (char *(*)()) __db_db_sync_1; + break; + + case __DB_db_cursor: + xdr_argument = xdr___db_cursor_msg; + xdr_result = xdr___db_cursor_reply; + local = (char *(*)()) __db_db_cursor_1; + break; + + case __DB_db_join: + xdr_argument = xdr___db_join_msg; + xdr_result = xdr___db_join_reply; + local = (char *(*)()) __db_db_join_1; + break; + + case __DB_dbc_close: + xdr_argument = xdr___dbc_close_msg; + xdr_result = xdr___dbc_close_reply; + local = (char *(*)()) __db_dbc_close_1; + break; + + case __DB_dbc_count: + xdr_argument = xdr___dbc_count_msg; + xdr_result = xdr___dbc_count_reply; + local = (char *(*)()) __db_dbc_count_1; + break; + + case __DB_dbc_del: + xdr_argument = xdr___dbc_del_msg; + xdr_result = xdr___dbc_del_reply; + local = (char *(*)()) __db_dbc_del_1; + break; + + case __DB_dbc_dup: + xdr_argument = xdr___dbc_dup_msg; + xdr_result = xdr___dbc_dup_reply; + local = (char *(*)()) __db_dbc_dup_1; + break; + + case __DB_dbc_get: + xdr_argument = xdr___dbc_get_msg; + xdr_result = xdr___dbc_get_reply; + local = (char *(*)()) __db_dbc_get_1; + break; + + case __DB_dbc_put: + xdr_argument = xdr___dbc_put_msg; + xdr_result = xdr___dbc_put_reply; + local = (char *(*)()) __db_dbc_put_1; + break; + + default: + svcerr_noproc(transp); + return; + } + (void) memset((char *)&argument, 0, sizeof (argument)); + if (!svc_getargs(transp, xdr_argument, &argument)) { + svcerr_decode(transp); + return; + } + result = (*local)(&argument, rqstp); + if (result != NULL && !svc_sendreply(transp, xdr_result, result)) { + svcerr_systemerr(transp); + } + if (!svc_freeargs(transp, xdr_argument, &argument)) { + fprintf(stderr, "unable to free arguments"); + exit(1); + } + __dbsrv_timeout(0); + return; +} + +void __dbsrv_main() +{ + register SVCXPRT *transp; + + (void) pmap_unset(DB_SERVERPROG, DB_SERVERVERS); + + transp = svctcp_create(RPC_ANYSOCK, 0, 0); + if (transp == NULL) { + fprintf(stderr, "cannot create tcp service."); + exit(1); + } + if (!svc_register(transp, DB_SERVERPROG, DB_SERVERVERS, db_serverprog_1, IPPROTO_TCP)) { + fprintf(stderr, "unable to register (DB_SERVERPROG, DB_SERVERVERS, tcp)."); + exit(1); + } + + svc_run(); + fprintf(stderr, "svc_run returned"); + exit(1); + /* NOTREACHED */ +} +#endif /* HAVE_RPC */ diff --git a/bdb/rpc_server/db_server_svc.sed b/bdb/rpc_server/db_server_svc.sed new file mode 100644 index 00000000000..9d540e51af6 --- /dev/null +++ b/bdb/rpc_server/db_server_svc.sed @@ -0,0 +1,5 @@ +/^#include <netinet.in.h>/a\ +\extern void __dbsrv_timeout(); +/^ return;/i\ +\ __dbsrv_timeout(0); +s/^main/void __dbsrv_main/ diff --git a/bdb/rpc_server/db_server_util.c b/bdb/rpc_server/db_server_util.c new file mode 100644 index 00000000000..862bbd05efb --- /dev/null +++ b/bdb/rpc_server/db_server_util.c @@ -0,0 +1,612 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2000 + * Sleepycat Software. All rights reserved. + */ + +#include "db_config.h" + +#ifndef lint +static const char revid[] = "$Id: db_server_util.c,v 1.32 2001/01/18 18:36:59 bostic Exp $"; +#endif /* not lint */ + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#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 + +#include <rpc/rpc.h> + +#include <limits.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#endif +#include "db_server.h" + +#include "db_int.h" +#include "clib_ext.h" +#include "db_server_int.h" +#include "rpc_server_ext.h" +#include "common_ext.h" + +extern int __dbsrv_main __P((void)); +static int add_home __P((char *)); +static int env_recover __P((char *)); +static void __dbclear_child __P((ct_entry *)); + +static LIST_HEAD(cthead, ct_entry) __dbsrv_head; +static LIST_HEAD(homehead, home_entry) __dbsrv_home; +static long __dbsrv_defto = DB_SERVER_TIMEOUT; +static long __dbsrv_maxto = DB_SERVER_MAXTIMEOUT; +static long __dbsrv_idleto = DB_SERVER_IDLETIMEOUT; +static char *logfile = NULL; +static char *prog; + +static void usage __P((char *)); +static void version_check __P((void)); + +int __dbsrv_verbose = 0; + +int +main(argc, argv) + int argc; + char **argv; +{ + extern char *optarg; + extern int optind; + CLIENT *cl; + int ch, ret; + + prog = argv[0]; + + version_check(); + + /* + * Check whether another server is running or not. There + * is a race condition where two servers could be racing to + * register with the portmapper. The goal of this check is to + * forbid running additional servers (like those started from + * the test suite) if the user is already running one. + * + * XXX + * This does not solve nor prevent two servers from being + * started at the same time and running recovery at the same + * time on the same environments. + */ + if ((cl = clnt_create("localhost", + DB_SERVERPROG, DB_SERVERVERS, "tcp")) != NULL) { + fprintf(stderr, + "%s: Berkeley DB RPC server already running.\n", prog); + clnt_destroy(cl); + exit(1); + } + + LIST_INIT(&__dbsrv_home); + while ((ch = getopt(argc, argv, "h:I:L:t:T:Vv")) != EOF) + switch (ch) { + case 'h': + (void)add_home(optarg); + break; + case 'I': + (void)__db_getlong(NULL, prog, optarg, 1, + LONG_MAX, &__dbsrv_idleto); + break; + case 'L': + logfile = optarg; + break; + case 't': + (void)__db_getlong(NULL, prog, optarg, 1, + LONG_MAX, &__dbsrv_defto); + break; + case 'T': + (void)__db_getlong(NULL, prog, optarg, 1, + LONG_MAX, &__dbsrv_maxto); + break; + case 'V': + printf("%s\n", db_version(NULL, NULL, NULL)); + exit(0); + case 'v': + __dbsrv_verbose = 1; + break; + default: + usage(prog); + } + /* + * Check default timeout against maximum timeout + */ + if (__dbsrv_defto > __dbsrv_maxto) + __dbsrv_defto = __dbsrv_maxto; + + /* + * Check default timeout against idle timeout + * It would be bad to timeout environments sooner than txns. + */ + if (__dbsrv_defto > __dbsrv_idleto) +printf("%s: WARNING: Idle timeout %ld is less than resource timeout %ld\n", + prog, __dbsrv_idleto, __dbsrv_defto); + + LIST_INIT(&__dbsrv_head); + + /* + * If a client crashes during an RPC, our reply to it + * generates a SIGPIPE. Ignore SIGPIPE so we don't exit unnecessarily. + */ +#ifdef SIGPIPE + signal(SIGPIPE, SIG_IGN); +#endif + + if (logfile != NULL && __db_util_logset("berkeley_db_svc", logfile)) + exit(1); + + /* + * Now that we are ready to start, run recovery on all the + * environments specified. + */ + if ((ret = env_recover(prog)) != 0) + exit(1); + + /* + * We've done our setup, now call the generated server loop + */ + if (__dbsrv_verbose) + printf("%s: Ready to receive requests\n", prog); + __dbsrv_main(); + + /* NOTREACHED */ + abort(); +} + +static void +usage(prog) + char *prog; +{ + fprintf(stderr, "usage: %s %s\n\t%s\n", prog, + "[-Vv] [-h home]", + "[-I idletimeout] [-L logfile] [-t def_timeout] [-T maxtimeout]"); + exit(1); +} + +static void +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 || v_patch != DB_VERSION_PATCH) { + fprintf(stderr, + "%s: version %d.%d.%d doesn't match library version %d.%d.%d\n", + prog, DB_VERSION_MAJOR, DB_VERSION_MINOR, + DB_VERSION_PATCH, v_major, v_minor, v_patch); + exit (1); + } +} + +/* + * PUBLIC: void __dbsrv_settimeout __P((ct_entry *, u_int32_t)); + */ +void +__dbsrv_settimeout(ctp, to) + ct_entry *ctp; + u_int32_t to; +{ + if (to > (u_int32_t)__dbsrv_maxto) + ctp->ct_timeout = __dbsrv_maxto; + else if (to <= 0) + ctp->ct_timeout = __dbsrv_defto; + else + ctp->ct_timeout = to; +} + +/* + * PUBLIC: void __dbsrv_timeout __P((int)); + */ +void +__dbsrv_timeout(force) + int force; +{ + static long to_hint = -1; + DBC *dbcp; + time_t t; + long to; + ct_entry *ctp, *nextctp; + + if ((t = time(NULL)) == -1) + return; + + /* + * Check hint. If hint is further in the future + * than now, no work to do. + */ + if (!force && to_hint > 0 && t < to_hint) + return; + to_hint = -1; + /* + * Timeout transactions or cursors holding DB resources. + * Do this before timing out envs to properly release resources. + * + * !!! + * We can just loop through this list looking for cursors and txns. + * We do not need to verify txn and cursor relationships at this + * point because we maintain the list in LIFO order *and* we + * maintain activity in the ultimate txn parent of any cursor + * so either everything in a txn is timing out, or nothing. + * So, since we are LIFO, we will correctly close/abort all the + * appropriate handles, in the correct order. + */ + for (ctp = LIST_FIRST(&__dbsrv_head); ctp != NULL; ctp = nextctp) { + nextctp = LIST_NEXT(ctp, entries); + switch (ctp->ct_type) { + case CT_TXN: + to = *(ctp->ct_activep) + ctp->ct_timeout; + /* TIMEOUT */ + if (to < t) { + if (__dbsrv_verbose) + printf("Timing out txn id %ld\n", + ctp->ct_id); + (void)txn_abort((DB_TXN *)ctp->ct_anyp); + __dbdel_ctp(ctp); + /* + * If we timed out an txn, we may have closed + * all sorts of ctp's. + * So start over with a guaranteed good ctp. + */ + nextctp = LIST_FIRST(&__dbsrv_head); + } else if ((to_hint > 0 && to_hint > to) || + to_hint == -1) + to_hint = to; + break; + case CT_CURSOR: + case (CT_JOINCUR | CT_CURSOR): + to = *(ctp->ct_activep) + ctp->ct_timeout; + /* TIMEOUT */ + if (to < t) { + if (__dbsrv_verbose) + printf("Timing out cursor %ld\n", + ctp->ct_id); + dbcp = (DBC *)ctp->ct_anyp; + (void)__dbc_close_int(ctp); + /* + * Start over with a guaranteed good ctp. + */ + nextctp = LIST_FIRST(&__dbsrv_head); + } else if ((to_hint > 0 && to_hint > to) || + to_hint == -1) + to_hint = to; + break; + default: + break; + } + } + /* + * Timeout idle handles. + * If we are forcing a timeout, we'll close all env handles. + */ + for (ctp = LIST_FIRST(&__dbsrv_head); ctp != NULL; ctp = nextctp) { + nextctp = LIST_NEXT(ctp, entries); + if (ctp->ct_type != CT_ENV) + continue; + to = *(ctp->ct_activep) + ctp->ct_idle; + /* TIMEOUT */ + if (to < t || force) { + if (__dbsrv_verbose) + printf("Timing out env id %ld\n", ctp->ct_id); + (void)__dbenv_close_int(ctp->ct_id, 0); + /* + * If we timed out an env, we may have closed + * all sorts of ctp's (maybe even all of them. + * So start over with a guaranteed good ctp. + */ + nextctp = LIST_FIRST(&__dbsrv_head); + } + } +} + +/* + * RECURSIVE FUNCTION. We need to clear/free any number of levels of nested + * layers. + */ +static void +__dbclear_child(parent) + ct_entry *parent; +{ + ct_entry *ctp, *nextctp; + + for (ctp = LIST_FIRST(&__dbsrv_head); ctp != NULL; + ctp = nextctp) { + nextctp = LIST_NEXT(ctp, entries); + if (ctp->ct_type == 0) + continue; + if (ctp->ct_parent == parent) { + __dbclear_child(ctp); + /* + * Need to do this here because le_next may + * have changed with the recursive call and we + * don't want to point to a removed entry. + */ + nextctp = LIST_NEXT(ctp, entries); + __dbclear_ctp(ctp); + } + } +} + +/* + * PUBLIC: void __dbclear_ctp __P((ct_entry *)); + */ +void +__dbclear_ctp(ctp) + ct_entry *ctp; +{ + LIST_REMOVE(ctp, entries); + __os_free(ctp, sizeof(ct_entry)); +} + +/* + * PUBLIC: void __dbdel_ctp __P((ct_entry *)); + */ +void +__dbdel_ctp(parent) + ct_entry *parent; +{ + __dbclear_child(parent); + __dbclear_ctp(parent); +} + +/* + * PUBLIC: ct_entry *new_ct_ent __P((u_int32_t *)); + */ +ct_entry * +new_ct_ent(errp) + u_int32_t *errp; +{ + time_t t; + ct_entry *ctp, *octp; + int ret; + + if ((ret = __os_malloc(NULL, sizeof(ct_entry), NULL, &ctp)) != 0) { + *errp = ret; + return (NULL); + } + /* + * Get the time as ID. We may service more than one request per + * second however. If we are, then increment id value until we + * find an unused one. We insert entries in LRU fashion at the + * head of the list. So, if the first entry doesn't match, then + * we know for certain that we can use our entry. + */ + if ((t = time(NULL)) == -1) { + *errp = t; + __os_free(ctp, sizeof(ct_entry)); + return (NULL); + } + octp = LIST_FIRST(&__dbsrv_head); + if (octp != NULL && octp->ct_id >= t) + t = octp->ct_id + 1; + ctp->ct_id = t; + ctp->ct_idle = __dbsrv_idleto; + ctp->ct_activep = &ctp->ct_active; + ctp->ct_origp = NULL; + + LIST_INSERT_HEAD(&__dbsrv_head, ctp, entries); + return (ctp); +} + +/* + * PUBLIC: ct_entry *get_tableent __P((long)); + */ +ct_entry * +get_tableent(id) + long id; +{ + ct_entry *ctp; + + for (ctp = LIST_FIRST(&__dbsrv_head); ctp != NULL; + ctp = LIST_NEXT(ctp, entries)) + if (ctp->ct_id == id) + return (ctp); + return (NULL); +} + +/* + * PUBLIC: void __dbsrv_active __P((ct_entry *)); + */ +void +__dbsrv_active(ctp) + ct_entry *ctp; +{ + time_t t; + ct_entry *envctp; + + if (ctp == NULL) + return; + if ((t = time(NULL)) == -1) + return; + *(ctp->ct_activep) = t; + if ((envctp = ctp->ct_envparent) == NULL) + return; + *(envctp->ct_activep) = t; + return; +} + +/* + * PUBLIC: int __dbc_close_int __P((ct_entry *)); + */ +int +__dbc_close_int(dbc_ctp) + ct_entry *dbc_ctp; +{ + DBC *dbc; + int ret; + ct_entry *ctp; + + dbc = (DBC *)dbc_ctp->ct_anyp; + + ret = dbc->c_close(dbc); + /* + * If this cursor is a join cursor then we need to fix up the + * cursors that it was joined from so that they are independent again. + */ + if (dbc_ctp->ct_type & CT_JOINCUR) + for (ctp = LIST_FIRST(&__dbsrv_head); ctp != NULL; + ctp = LIST_NEXT(ctp, entries)) { + /* + * Test if it is a join cursor, and if it is part + * of this one. + */ + if ((ctp->ct_type & CT_JOIN) && + ctp->ct_activep == &dbc_ctp->ct_active) { + ctp->ct_type &= ~CT_JOIN; + ctp->ct_activep = ctp->ct_origp; + __dbsrv_active(ctp); + } + } + __dbclear_ctp(dbc_ctp); + return (ret); + +} + +/* + * PUBLIC: int __dbenv_close_int __P((long, int)); + */ +int +__dbenv_close_int(id, flags) + long id; + int flags; +{ + DB_ENV *dbenv; + int ret; + ct_entry *ctp; + + ctp = get_tableent(id); + if (ctp == NULL) + return (DB_NOSERVER_ID); + DB_ASSERT(ctp->ct_type == CT_ENV); + dbenv = ctp->ct_envp; + + ret = dbenv->close(dbenv, flags); + __dbdel_ctp(ctp); + return (ret); +} + +static int +add_home(home) + char *home; +{ + home_entry *hp, *homep; + int ret; + + if ((ret = __os_malloc(NULL, sizeof(home_entry), NULL, &hp)) != 0) + return (ret); + if ((ret = __os_malloc(NULL, strlen(home)+1, NULL, &hp->home)) != 0) + return (ret); + memcpy(hp->home, home, strlen(home)+1); + hp->dir = home; + /* + * This loop is to remove any trailing path separators, + * to assure hp->name points to the last component. + */ + hp->name = __db_rpath(home); + *(hp->name) = '\0'; + hp->name++; + while (*(hp->name) == '\0') { + hp->name = __db_rpath(home); + *(hp->name) = '\0'; + hp->name++; + } + /* + * Now we have successfully added it. Make sure there are no + * identical names. + */ + for (homep = LIST_FIRST(&__dbsrv_home); homep != NULL; + homep = LIST_NEXT(homep, entries)) + if (strcmp(homep->name, hp->name) == 0) { + printf("Already added home name %s, at directory %s\n", + hp->name, homep->dir); + return (-1); + } + LIST_INSERT_HEAD(&__dbsrv_home, hp, entries); + if (__dbsrv_verbose) + printf("Added home %s in dir %s\n", hp->name, hp->dir); + return (0); +} + +/* + * PUBLIC: char *get_home __P((char *)); + */ +char * +get_home(name) + char *name; +{ + home_entry *hp; + + for (hp = LIST_FIRST(&__dbsrv_home); hp != NULL; + hp = LIST_NEXT(hp, entries)) + if (strcmp(name, hp->name) == 0) + return (hp->home); + return (NULL); +} + +static int +env_recover(progname) + char *progname; +{ + DB_ENV *dbenv; + home_entry *hp; + u_int32_t flags; + int exitval, ret; + + for (hp = LIST_FIRST(&__dbsrv_home); hp != NULL; + hp = LIST_NEXT(hp, entries)) { + exitval = 0; + if ((ret = db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, "%s: db_env_create: %s\n", + progname, db_strerror(ret)); + exit(1); + } + if (__dbsrv_verbose == 1) { + (void)dbenv->set_verbose(dbenv, DB_VERB_RECOVERY, 1); + (void)dbenv->set_verbose(dbenv, DB_VERB_CHKPOINT, 1); + } + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, progname); + + /* + * Initialize the env with DB_RECOVER. That is all we + * have to do to run recovery. + */ + if (__dbsrv_verbose) + printf("Running recovery on %s\n", hp->home); + flags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | + DB_INIT_TXN | DB_PRIVATE | DB_USE_ENVIRON | DB_RECOVER; + if ((ret = dbenv->open(dbenv, hp->home, flags, 0)) != 0) { + dbenv->err(dbenv, ret, "DBENV->open"); + goto error; + } + + if (0) { +error: exitval = 1; + } + if ((ret = dbenv->close(dbenv, 0)) != 0) { + exitval = 1; + fprintf(stderr, "%s: dbenv->close: %s\n", + progname, db_strerror(ret)); + } + if (exitval) + return (exitval); + } + return (0); +} diff --git a/bdb/rpc_server/db_server_xdr.c b/bdb/rpc_server/db_server_xdr.c new file mode 100644 index 00000000000..f403f862e5d --- /dev/null +++ b/bdb/rpc_server/db_server_xdr.c @@ -0,0 +1,1149 @@ +#include "db_config.h" +#ifdef HAVE_RPC +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "db_server.h" + +bool_t +xdr___env_cachesize_msg(xdrs, objp) + register XDR *xdrs; + __env_cachesize_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbenvcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->gbytes)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->bytes)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->ncache)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___env_cachesize_reply(xdrs, objp) + register XDR *xdrs; + __env_cachesize_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___env_close_msg(xdrs, objp) + register XDR *xdrs; + __env_close_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbenvcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___env_close_reply(xdrs, objp) + register XDR *xdrs; + __env_close_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___env_create_msg(xdrs, objp) + register XDR *xdrs; + __env_create_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->timeout)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___env_create_reply(xdrs, objp) + register XDR *xdrs; + __env_create_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->envcl_id)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___env_flags_msg(xdrs, objp) + register XDR *xdrs; + __env_flags_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbenvcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->onoff)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___env_flags_reply(xdrs, objp) + register XDR *xdrs; + __env_flags_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___env_open_msg(xdrs, objp) + register XDR *xdrs; + __env_open_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbenvcl_id)) + return (FALSE); + if (!xdr_string(xdrs, &objp->home, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->mode)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___env_open_reply(xdrs, objp) + register XDR *xdrs; + __env_open_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___env_remove_msg(xdrs, objp) + register XDR *xdrs; + __env_remove_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbenvcl_id)) + return (FALSE); + if (!xdr_string(xdrs, &objp->home, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___env_remove_reply(xdrs, objp) + register XDR *xdrs; + __env_remove_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___txn_abort_msg(xdrs, objp) + register XDR *xdrs; + __txn_abort_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->txnpcl_id)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___txn_abort_reply(xdrs, objp) + register XDR *xdrs; + __txn_abort_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___txn_begin_msg(xdrs, objp) + register XDR *xdrs; + __txn_begin_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->envpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->parentcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___txn_begin_reply(xdrs, objp) + register XDR *xdrs; + __txn_begin_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->txnidcl_id)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___txn_commit_msg(xdrs, objp) + register XDR *xdrs; + __txn_commit_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->txnpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___txn_commit_reply(xdrs, objp) + register XDR *xdrs; + __txn_commit_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_bt_maxkey_msg(xdrs, objp) + register XDR *xdrs; + __db_bt_maxkey_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->maxkey)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_bt_maxkey_reply(xdrs, objp) + register XDR *xdrs; + __db_bt_maxkey_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_bt_minkey_msg(xdrs, objp) + register XDR *xdrs; + __db_bt_minkey_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->minkey)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_bt_minkey_reply(xdrs, objp) + register XDR *xdrs; + __db_bt_minkey_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_close_msg(xdrs, objp) + register XDR *xdrs; + __db_close_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_close_reply(xdrs, objp) + register XDR *xdrs; + __db_close_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_create_msg(xdrs, objp) + register XDR *xdrs; + __db_create_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->envpcl_id)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_create_reply(xdrs, objp) + register XDR *xdrs; + __db_create_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_del_msg(xdrs, objp) + register XDR *xdrs; + __db_del_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->txnpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydlen)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydoff)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keyflags)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->keydata.keydata_val, (u_int *) &objp->keydata.keydata_len, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_del_reply(xdrs, objp) + register XDR *xdrs; + __db_del_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_extentsize_msg(xdrs, objp) + register XDR *xdrs; + __db_extentsize_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->extentsize)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_extentsize_reply(xdrs, objp) + register XDR *xdrs; + __db_extentsize_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_flags_msg(xdrs, objp) + register XDR *xdrs; + __db_flags_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_flags_reply(xdrs, objp) + register XDR *xdrs; + __db_flags_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_get_msg(xdrs, objp) + register XDR *xdrs; + __db_get_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->txnpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydlen)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydoff)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keyflags)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->keydata.keydata_val, (u_int *) &objp->keydata.keydata_len, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->datadlen)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->datadoff)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->dataflags)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->datadata.datadata_val, (u_int *) &objp->datadata.datadata_len, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_get_reply(xdrs, objp) + register XDR *xdrs; + __db_get_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->keydata.keydata_val, (u_int *) &objp->keydata.keydata_len, ~0)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->datadata.datadata_val, (u_int *) &objp->datadata.datadata_len, ~0)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_h_ffactor_msg(xdrs, objp) + register XDR *xdrs; + __db_h_ffactor_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->ffactor)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_h_ffactor_reply(xdrs, objp) + register XDR *xdrs; + __db_h_ffactor_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_h_nelem_msg(xdrs, objp) + register XDR *xdrs; + __db_h_nelem_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->nelem)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_h_nelem_reply(xdrs, objp) + register XDR *xdrs; + __db_h_nelem_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_key_range_msg(xdrs, objp) + register XDR *xdrs; + __db_key_range_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->txnpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydlen)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydoff)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keyflags)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->keydata.keydata_val, (u_int *) &objp->keydata.keydata_len, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_key_range_reply(xdrs, objp) + register XDR *xdrs; + __db_key_range_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_double(xdrs, &objp->less)) + return (FALSE); + if (!xdr_double(xdrs, &objp->equal)) + return (FALSE); + if (!xdr_double(xdrs, &objp->greater)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_lorder_msg(xdrs, objp) + register XDR *xdrs; + __db_lorder_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->lorder)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_lorder_reply(xdrs, objp) + register XDR *xdrs; + __db_lorder_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_open_msg(xdrs, objp) + register XDR *xdrs; + __db_open_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_string(xdrs, &objp->name, ~0)) + return (FALSE); + if (!xdr_string(xdrs, &objp->subdb, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->type)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->mode)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_open_reply(xdrs, objp) + register XDR *xdrs; + __db_open_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->type)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->dbflags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_pagesize_msg(xdrs, objp) + register XDR *xdrs; + __db_pagesize_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->pagesize)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_pagesize_reply(xdrs, objp) + register XDR *xdrs; + __db_pagesize_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_put_msg(xdrs, objp) + register XDR *xdrs; + __db_put_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->txnpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydlen)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydoff)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keyflags)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->keydata.keydata_val, (u_int *) &objp->keydata.keydata_len, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->datadlen)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->datadoff)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->dataflags)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->datadata.datadata_val, (u_int *) &objp->datadata.datadata_len, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_put_reply(xdrs, objp) + register XDR *xdrs; + __db_put_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->keydata.keydata_val, (u_int *) &objp->keydata.keydata_len, ~0)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_re_delim_msg(xdrs, objp) + register XDR *xdrs; + __db_re_delim_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->delim)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_re_delim_reply(xdrs, objp) + register XDR *xdrs; + __db_re_delim_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_re_len_msg(xdrs, objp) + register XDR *xdrs; + __db_re_len_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->len)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_re_len_reply(xdrs, objp) + register XDR *xdrs; + __db_re_len_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_re_pad_msg(xdrs, objp) + register XDR *xdrs; + __db_re_pad_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->pad)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_re_pad_reply(xdrs, objp) + register XDR *xdrs; + __db_re_pad_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_remove_msg(xdrs, objp) + register XDR *xdrs; + __db_remove_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_string(xdrs, &objp->name, ~0)) + return (FALSE); + if (!xdr_string(xdrs, &objp->subdb, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_remove_reply(xdrs, objp) + register XDR *xdrs; + __db_remove_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_rename_msg(xdrs, objp) + register XDR *xdrs; + __db_rename_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_string(xdrs, &objp->name, ~0)) + return (FALSE); + if (!xdr_string(xdrs, &objp->subdb, ~0)) + return (FALSE); + if (!xdr_string(xdrs, &objp->newname, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_rename_reply(xdrs, objp) + register XDR *xdrs; + __db_rename_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_stat_msg(xdrs, objp) + register XDR *xdrs; + __db_stat_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_stat_statsreplist(xdrs, objp) + register XDR *xdrs; + __db_stat_statsreplist *objp; +{ + + if (!xdr_bytes(xdrs, (char **)&objp->ent.ent_val, (u_int *) &objp->ent.ent_len, ~0)) + return (FALSE); + if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (__db_stat_statsreplist), (xdrproc_t) xdr___db_stat_statsreplist)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_stat_reply(xdrs, objp) + register XDR *xdrs; + __db_stat_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_pointer(xdrs, (char **)&objp->statslist, sizeof (__db_stat_statsreplist), (xdrproc_t) xdr___db_stat_statsreplist)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_swapped_msg(xdrs, objp) + register XDR *xdrs; + __db_swapped_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_swapped_reply(xdrs, objp) + register XDR *xdrs; + __db_swapped_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_sync_msg(xdrs, objp) + register XDR *xdrs; + __db_sync_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_sync_reply(xdrs, objp) + register XDR *xdrs; + __db_sync_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_cursor_msg(xdrs, objp) + register XDR *xdrs; + __db_cursor_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->txnpcl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_cursor_reply(xdrs, objp) + register XDR *xdrs; + __db_cursor_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->dbcidcl_id)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_join_curslist(xdrs, objp) + register XDR *xdrs; + __db_join_curslist *objp; +{ + + if (!xdr_bytes(xdrs, (char **)&objp->ent.ent_val, (u_int *) &objp->ent.ent_len, ~0)) + return (FALSE); + if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof (__db_join_curslist), (xdrproc_t) xdr___db_join_curslist)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_join_msg(xdrs, objp) + register XDR *xdrs; + __db_join_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbpcl_id)) + return (FALSE); + if (!xdr_pointer(xdrs, (char **)&objp->curslist, sizeof (__db_join_curslist), (xdrproc_t) xdr___db_join_curslist)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___db_join_reply(xdrs, objp) + register XDR *xdrs; + __db_join_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->dbcidcl_id)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_close_msg(xdrs, objp) + register XDR *xdrs; + __dbc_close_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbccl_id)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_close_reply(xdrs, objp) + register XDR *xdrs; + __dbc_close_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_count_msg(xdrs, objp) + register XDR *xdrs; + __dbc_count_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbccl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_count_reply(xdrs, objp) + register XDR *xdrs; + __dbc_count_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->dupcount)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_del_msg(xdrs, objp) + register XDR *xdrs; + __dbc_del_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbccl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_del_reply(xdrs, objp) + register XDR *xdrs; + __dbc_del_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_dup_msg(xdrs, objp) + register XDR *xdrs; + __dbc_dup_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbccl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_dup_reply(xdrs, objp) + register XDR *xdrs; + __dbc_dup_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->dbcidcl_id)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_get_msg(xdrs, objp) + register XDR *xdrs; + __dbc_get_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbccl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydlen)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydoff)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keyflags)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->keydata.keydata_val, (u_int *) &objp->keydata.keydata_len, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->datadlen)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->datadoff)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->dataflags)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->datadata.datadata_val, (u_int *) &objp->datadata.datadata_len, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_get_reply(xdrs, objp) + register XDR *xdrs; + __dbc_get_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->keydata.keydata_val, (u_int *) &objp->keydata.keydata_len, ~0)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->datadata.datadata_val, (u_int *) &objp->datadata.datadata_len, ~0)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_put_msg(xdrs, objp) + register XDR *xdrs; + __dbc_put_msg *objp; +{ + + if (!xdr_u_int(xdrs, &objp->dbccl_id)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydlen)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keydoff)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->keyflags)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->keydata.keydata_val, (u_int *) &objp->keydata.keydata_len, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->datadlen)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->datadoff)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->dataflags)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->datadata.datadata_val, (u_int *) &objp->datadata.datadata_len, ~0)) + return (FALSE); + if (!xdr_u_int(xdrs, &objp->flags)) + return (FALSE); + return (TRUE); +} + +bool_t +xdr___dbc_put_reply(xdrs, objp) + register XDR *xdrs; + __dbc_put_reply *objp; +{ + + if (!xdr_u_int(xdrs, &objp->status)) + return (FALSE); + if (!xdr_bytes(xdrs, (char **)&objp->keydata.keydata_val, (u_int *) &objp->keydata.keydata_len, ~0)) + return (FALSE); + return (TRUE); +} +#endif /* HAVE_RPC */ diff --git a/bdb/rpc_server/gen_db_server.c b/bdb/rpc_server/gen_db_server.c new file mode 100644 index 00000000000..20da69c4b1b --- /dev/null +++ b/bdb/rpc_server/gen_db_server.c @@ -0,0 +1,703 @@ +/* Do not edit: automatically built by gen_rpc.awk. */ +#include "db_config.h" + +#ifndef NO_SYSTEM_INCLUDES +#include <sys/types.h> + +#include <rpc/rpc.h> +#include <rpc/xdr.h> + +#include <errno.h> +#include <string.h> +#endif +#include "db_server.h" + +#include "db_int.h" +#include "db_server_int.h" +#include "rpc_server_ext.h" + +#include "gen_server_ext.h" + +__env_cachesize_reply * +__db_env_cachesize_1(req) + __env_cachesize_msg *req; +{ + static __env_cachesize_reply reply; /* must be static */ + + __env_cachesize_1_proc(req->dbenvcl_id, + req->gbytes, + req->bytes, + req->ncache, + &reply); + + return (&reply); +} + +__env_close_reply * +__db_env_close_1(req) + __env_close_msg *req; +{ + static __env_close_reply reply; /* must be static */ + + __env_close_1_proc(req->dbenvcl_id, + req->flags, + &reply); + + return (&reply); +} + +__env_create_reply * +__db_env_create_1(req) + __env_create_msg *req; +{ + static __env_create_reply reply; /* must be static */ + + __env_create_1_proc(req->timeout, + &reply); + + return (&reply); +} + +__env_flags_reply * +__db_env_flags_1(req) + __env_flags_msg *req; +{ + static __env_flags_reply reply; /* must be static */ + + __env_flags_1_proc(req->dbenvcl_id, + req->flags, + req->onoff, + &reply); + + return (&reply); +} + +__env_open_reply * +__db_env_open_1(req) + __env_open_msg *req; +{ + static __env_open_reply reply; /* must be static */ + + __env_open_1_proc(req->dbenvcl_id, + (*req->home == '\0') ? NULL : req->home, + req->flags, + req->mode, + &reply); + + return (&reply); +} + +__env_remove_reply * +__db_env_remove_1(req) + __env_remove_msg *req; +{ + static __env_remove_reply reply; /* must be static */ + + __env_remove_1_proc(req->dbenvcl_id, + (*req->home == '\0') ? NULL : req->home, + req->flags, + &reply); + + return (&reply); +} + +__txn_abort_reply * +__db_txn_abort_1(req) + __txn_abort_msg *req; +{ + static __txn_abort_reply reply; /* must be static */ + + __txn_abort_1_proc(req->txnpcl_id, + &reply); + + return (&reply); +} + +__txn_begin_reply * +__db_txn_begin_1(req) + __txn_begin_msg *req; +{ + static __txn_begin_reply reply; /* must be static */ + + __txn_begin_1_proc(req->envpcl_id, + req->parentcl_id, + req->flags, + &reply); + + return (&reply); +} + +__txn_commit_reply * +__db_txn_commit_1(req) + __txn_commit_msg *req; +{ + static __txn_commit_reply reply; /* must be static */ + + __txn_commit_1_proc(req->txnpcl_id, + req->flags, + &reply); + + return (&reply); +} + +__db_bt_maxkey_reply * +__db_db_bt_maxkey_1(req) + __db_bt_maxkey_msg *req; +{ + static __db_bt_maxkey_reply reply; /* must be static */ + + __db_bt_maxkey_1_proc(req->dbpcl_id, + req->maxkey, + &reply); + + return (&reply); +} + +__db_bt_minkey_reply * +__db_db_bt_minkey_1(req) + __db_bt_minkey_msg *req; +{ + static __db_bt_minkey_reply reply; /* must be static */ + + __db_bt_minkey_1_proc(req->dbpcl_id, + req->minkey, + &reply); + + return (&reply); +} + +__db_close_reply * +__db_db_close_1(req) + __db_close_msg *req; +{ + static __db_close_reply reply; /* must be static */ + + __db_close_1_proc(req->dbpcl_id, + req->flags, + &reply); + + return (&reply); +} + +__db_create_reply * +__db_db_create_1(req) + __db_create_msg *req; +{ + static __db_create_reply reply; /* must be static */ + + __db_create_1_proc(req->flags, + req->envpcl_id, + &reply); + + return (&reply); +} + +__db_del_reply * +__db_db_del_1(req) + __db_del_msg *req; +{ + static __db_del_reply reply; /* must be static */ + + __db_del_1_proc(req->dbpcl_id, + req->txnpcl_id, + req->keydlen, + req->keydoff, + req->keyflags, + req->keydata.keydata_val, + req->keydata.keydata_len, + req->flags, + &reply); + + return (&reply); +} + +__db_extentsize_reply * +__db_db_extentsize_1(req) + __db_extentsize_msg *req; +{ + static __db_extentsize_reply reply; /* must be static */ + + __db_extentsize_1_proc(req->dbpcl_id, + req->extentsize, + &reply); + + return (&reply); +} + +__db_flags_reply * +__db_db_flags_1(req) + __db_flags_msg *req; +{ + static __db_flags_reply reply; /* must be static */ + + __db_flags_1_proc(req->dbpcl_id, + req->flags, + &reply); + + return (&reply); +} + +__db_get_reply * +__db_db_get_1(req) + __db_get_msg *req; +{ + static __db_get_reply reply; /* must be static */ + static int __db_get_free = 0; /* must be static */ + + if (__db_get_free) + xdr_free((xdrproc_t)xdr___db_get_reply, (void *)&reply); + __db_get_free = 0; + + /* Reinitialize allocated fields */ + reply.keydata.keydata_val = NULL; + reply.datadata.datadata_val = NULL; + + __db_get_1_proc(req->dbpcl_id, + req->txnpcl_id, + req->keydlen, + req->keydoff, + req->keyflags, + req->keydata.keydata_val, + req->keydata.keydata_len, + req->datadlen, + req->datadoff, + req->dataflags, + req->datadata.datadata_val, + req->datadata.datadata_len, + req->flags, + &reply, + &__db_get_free); + return (&reply); +} + +__db_h_ffactor_reply * +__db_db_h_ffactor_1(req) + __db_h_ffactor_msg *req; +{ + static __db_h_ffactor_reply reply; /* must be static */ + + __db_h_ffactor_1_proc(req->dbpcl_id, + req->ffactor, + &reply); + + return (&reply); +} + +__db_h_nelem_reply * +__db_db_h_nelem_1(req) + __db_h_nelem_msg *req; +{ + static __db_h_nelem_reply reply; /* must be static */ + + __db_h_nelem_1_proc(req->dbpcl_id, + req->nelem, + &reply); + + return (&reply); +} + +__db_key_range_reply * +__db_db_key_range_1(req) + __db_key_range_msg *req; +{ + static __db_key_range_reply reply; /* must be static */ + + __db_key_range_1_proc(req->dbpcl_id, + req->txnpcl_id, + req->keydlen, + req->keydoff, + req->keyflags, + req->keydata.keydata_val, + req->keydata.keydata_len, + req->flags, + &reply); + + return (&reply); +} + +__db_lorder_reply * +__db_db_lorder_1(req) + __db_lorder_msg *req; +{ + static __db_lorder_reply reply; /* must be static */ + + __db_lorder_1_proc(req->dbpcl_id, + req->lorder, + &reply); + + return (&reply); +} + +__db_open_reply * +__db_db_open_1(req) + __db_open_msg *req; +{ + static __db_open_reply reply; /* must be static */ + + __db_open_1_proc(req->dbpcl_id, + (*req->name == '\0') ? NULL : req->name, + (*req->subdb == '\0') ? NULL : req->subdb, + req->type, + req->flags, + req->mode, + &reply); + + return (&reply); +} + +__db_pagesize_reply * +__db_db_pagesize_1(req) + __db_pagesize_msg *req; +{ + static __db_pagesize_reply reply; /* must be static */ + + __db_pagesize_1_proc(req->dbpcl_id, + req->pagesize, + &reply); + + return (&reply); +} + +__db_put_reply * +__db_db_put_1(req) + __db_put_msg *req; +{ + static __db_put_reply reply; /* must be static */ + static int __db_put_free = 0; /* must be static */ + + if (__db_put_free) + xdr_free((xdrproc_t)xdr___db_put_reply, (void *)&reply); + __db_put_free = 0; + + /* Reinitialize allocated fields */ + reply.keydata.keydata_val = NULL; + + __db_put_1_proc(req->dbpcl_id, + req->txnpcl_id, + req->keydlen, + req->keydoff, + req->keyflags, + req->keydata.keydata_val, + req->keydata.keydata_len, + req->datadlen, + req->datadoff, + req->dataflags, + req->datadata.datadata_val, + req->datadata.datadata_len, + req->flags, + &reply, + &__db_put_free); + return (&reply); +} + +__db_re_delim_reply * +__db_db_re_delim_1(req) + __db_re_delim_msg *req; +{ + static __db_re_delim_reply reply; /* must be static */ + + __db_re_delim_1_proc(req->dbpcl_id, + req->delim, + &reply); + + return (&reply); +} + +__db_re_len_reply * +__db_db_re_len_1(req) + __db_re_len_msg *req; +{ + static __db_re_len_reply reply; /* must be static */ + + __db_re_len_1_proc(req->dbpcl_id, + req->len, + &reply); + + return (&reply); +} + +__db_re_pad_reply * +__db_db_re_pad_1(req) + __db_re_pad_msg *req; +{ + static __db_re_pad_reply reply; /* must be static */ + + __db_re_pad_1_proc(req->dbpcl_id, + req->pad, + &reply); + + return (&reply); +} + +__db_remove_reply * +__db_db_remove_1(req) + __db_remove_msg *req; +{ + static __db_remove_reply reply; /* must be static */ + + __db_remove_1_proc(req->dbpcl_id, + (*req->name == '\0') ? NULL : req->name, + (*req->subdb == '\0') ? NULL : req->subdb, + req->flags, + &reply); + + return (&reply); +} + +__db_rename_reply * +__db_db_rename_1(req) + __db_rename_msg *req; +{ + static __db_rename_reply reply; /* must be static */ + + __db_rename_1_proc(req->dbpcl_id, + (*req->name == '\0') ? NULL : req->name, + (*req->subdb == '\0') ? NULL : req->subdb, + (*req->newname == '\0') ? NULL : req->newname, + req->flags, + &reply); + + return (&reply); +} + +__db_stat_reply * +__db_db_stat_1(req) + __db_stat_msg *req; +{ + static __db_stat_reply reply; /* must be static */ + static int __db_stat_free = 0; /* must be static */ + + if (__db_stat_free) + xdr_free((xdrproc_t)xdr___db_stat_reply, (void *)&reply); + __db_stat_free = 0; + + /* Reinitialize allocated fields */ + reply.statslist = NULL; + + __db_stat_1_proc(req->dbpcl_id, + req->flags, + &reply, + &__db_stat_free); + return (&reply); +} + +__db_swapped_reply * +__db_db_swapped_1(req) + __db_swapped_msg *req; +{ + static __db_swapped_reply reply; /* must be static */ + + __db_swapped_1_proc(req->dbpcl_id, + &reply); + + return (&reply); +} + +__db_sync_reply * +__db_db_sync_1(req) + __db_sync_msg *req; +{ + static __db_sync_reply reply; /* must be static */ + + __db_sync_1_proc(req->dbpcl_id, + req->flags, + &reply); + + return (&reply); +} + +__db_cursor_reply * +__db_db_cursor_1(req) + __db_cursor_msg *req; +{ + static __db_cursor_reply reply; /* must be static */ + + __db_cursor_1_proc(req->dbpcl_id, + req->txnpcl_id, + req->flags, + &reply); + + return (&reply); +} + +int __db_db_join_curslist __P((__db_join_curslist *, u_int32_t **)); +void __db_db_join_cursfree __P((u_int32_t *)); + +__db_join_reply * +__db_db_join_1(req) + __db_join_msg *req; +{ + u_int32_t *__db_curslist; + int ret; + static __db_join_reply reply; /* must be static */ + + if ((ret = __db_db_join_curslist(req->curslist, &__db_curslist)) != 0) + goto out; + + __db_join_1_proc(req->dbpcl_id, + __db_curslist, + req->flags, + &reply); + + __db_db_join_cursfree(__db_curslist); + +out: + return (&reply); +} + +int +__db_db_join_curslist(locp, ppp) + __db_join_curslist *locp; + u_int32_t **ppp; +{ + u_int32_t *pp; + int cnt, ret, size; + __db_join_curslist *nl; + + for (cnt = 0, nl = locp; nl != NULL; cnt++, nl = nl->next) + ; + + if (cnt == 0) { + *ppp = NULL; + return (0); + } + size = sizeof(*pp) * (cnt + 1); + if ((ret = __os_malloc(NULL, size, NULL, ppp)) != 0) + return (ret); + memset(*ppp, 0, size); + for (pp = *ppp, nl = locp; nl != NULL; nl = nl->next, pp++) { + *pp = *(u_int32_t *)nl->ent.ent_val; + } + return (0); +} + +void +__db_db_join_cursfree(pp) + u_int32_t *pp; +{ + size_t size; + u_int32_t *p; + + if (pp == NULL) + return; + size = sizeof(*p); + for (p = pp; *p != 0; p++) { + size += sizeof(*p); + } + __os_free(pp, size); +} + +__dbc_close_reply * +__db_dbc_close_1(req) + __dbc_close_msg *req; +{ + static __dbc_close_reply reply; /* must be static */ + + __dbc_close_1_proc(req->dbccl_id, + &reply); + + return (&reply); +} + +__dbc_count_reply * +__db_dbc_count_1(req) + __dbc_count_msg *req; +{ + static __dbc_count_reply reply; /* must be static */ + + __dbc_count_1_proc(req->dbccl_id, + req->flags, + &reply); + + return (&reply); +} + +__dbc_del_reply * +__db_dbc_del_1(req) + __dbc_del_msg *req; +{ + static __dbc_del_reply reply; /* must be static */ + + __dbc_del_1_proc(req->dbccl_id, + req->flags, + &reply); + + return (&reply); +} + +__dbc_dup_reply * +__db_dbc_dup_1(req) + __dbc_dup_msg *req; +{ + static __dbc_dup_reply reply; /* must be static */ + + __dbc_dup_1_proc(req->dbccl_id, + req->flags, + &reply); + + return (&reply); +} + +__dbc_get_reply * +__db_dbc_get_1(req) + __dbc_get_msg *req; +{ + static __dbc_get_reply reply; /* must be static */ + static int __dbc_get_free = 0; /* must be static */ + + if (__dbc_get_free) + xdr_free((xdrproc_t)xdr___dbc_get_reply, (void *)&reply); + __dbc_get_free = 0; + + /* Reinitialize allocated fields */ + reply.keydata.keydata_val = NULL; + reply.datadata.datadata_val = NULL; + + __dbc_get_1_proc(req->dbccl_id, + req->keydlen, + req->keydoff, + req->keyflags, + req->keydata.keydata_val, + req->keydata.keydata_len, + req->datadlen, + req->datadoff, + req->dataflags, + req->datadata.datadata_val, + req->datadata.datadata_len, + req->flags, + &reply, + &__dbc_get_free); + return (&reply); +} + +__dbc_put_reply * +__db_dbc_put_1(req) + __dbc_put_msg *req; +{ + static __dbc_put_reply reply; /* must be static */ + static int __dbc_put_free = 0; /* must be static */ + + if (__dbc_put_free) + xdr_free((xdrproc_t)xdr___dbc_put_reply, (void *)&reply); + __dbc_put_free = 0; + + /* Reinitialize allocated fields */ + reply.keydata.keydata_val = NULL; + + __dbc_put_1_proc(req->dbccl_id, + req->keydlen, + req->keydoff, + req->keyflags, + req->keydata.keydata_val, + req->keydata.keydata_len, + req->datadlen, + req->datadoff, + req->dataflags, + req->datadata.datadata_val, + req->datadata.datadata_len, + req->flags, + &reply, + &__dbc_put_free); + return (&reply); +} + diff --git a/bdb/rpc_server/rpc.src b/bdb/rpc_server/rpc.src new file mode 100644 index 00000000000..5dd25205136 --- /dev/null +++ b/bdb/rpc_server/rpc.src @@ -0,0 +1,599 @@ +# +# $Id: rpc.src,v 1.30 2000/12/20 21:53:05 ubell Exp $ +# Syntax: +# BEGIN function_name RPC # {CODE | NOCLNTCODE | RETCODE | NOFUNC} +# CODE: generate XDR and client code, return status +# Used for functions that just return a status and nothing else. +# RETCODE:generate XDR and client code, call return function +# (generate template return function) +# Used for functions that returns data. +# NOCLNTCODE: generate only XDR and server functions +# Used for functions that are "different" on the client. +# Primarily used for envcreate (which is called from +# the dbenv->set_server method on the client side) and +# dbcreate, which is called from non-generated code. +# NOFUNC: generate a client "unsupported function" with right args +# Used for unsupported functions. +# +# ARG {IGNORE | STRING | INT | DBT | LIST | ID | CONST} C-type varname +# IGNORE: not passed to server +# STRING: string passed to server +# DBT: DBT arg passed to server +# LIST: opaque list passed to server (NULL-terminated opaque list) +# INT: integer passed to server +# ID: cl_id from arg passed to server +# CONST: do not generate COMPQUIET (for NOFUNC only) +# FUNCPROT prototype +# FUNCARG functiontype +# These two *MUST* go together and FUNCPROT *MUST* be first. These +# are for the tricky user-supplied functions to some methods. They +# are not supported in RPC, so will be ignored, but the complicated +# syntax of their argument requires we have a special flag for them +# that contains the verbatim text to use in the prototype and the +# c-type, respectively. The FUNCARG must include the function, and +# must call it 'funcN', where N is the count of functions. Almost +# always it must be func0. A *very* few methods have more than one +# user-supplied functions, in those cases, it must be func0, func1, etc. +# +# All messages automatically return "status" and return that from +# the call to the function. RET's are additional things the server +# may return. RET is like ARG but does not need the IGNORE option. +# RET {STRING | INT | DBT | LIST | ID} varname [STRING | INT | ID] +# STRING: string from server +# DBT: DBT arg from server +# LIST: opaque list from server (NULL-terminated opaque list) +# Must have list type of STRING, ID or INT specified +# INT: integer from server +# ID: id from server stored in cl_id +# END function end. + +# +# Environment functions +# +BEGIN env_cachesize 1 CODE +ARG ID DB_ENV * dbenv +ARG INT u_int32_t gbytes +ARG INT u_int32_t bytes +ARG INT int ncache +END +BEGIN env_close 1 RETCODE +ARG ID DB_ENV * dbenv +ARG INT u_int32_t flags +END +BEGIN env_create 1 NOCLNTCODE +ARG INT long timeout +RET ID long env +END +BEGIN set_data_dir 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG STRING const char * dir +END +BEGIN env_set_feedback 1 NOFUNC +ARG ID DB_ENV * dbenv +FUNCPROT void (*)(DB_ENV *, int, int) +FUNCARG void (*func0) __P((DB_ENV *, int, int)) +END +BEGIN env_flags 1 CODE +ARG ID DB_ENV * dbenv +ARG INT u_int32_t flags +ARG INT int onoff +END +BEGIN set_lg_bsize 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t bsize +END +BEGIN set_lg_dir 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG STRING const char * dir +END +BEGIN set_lg_max 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t max +END +BEGIN set_lk_conflict 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int8_t * conflicts +ARG INT int modes +END +BEGIN set_lk_detect 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t detect +END +BEGIN set_lk_max 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t max +END +BEGIN set_lk_max_locks 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t max +END +BEGIN set_lk_max_lockers 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t max +END +BEGIN set_lk_max_objects 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t max +END +BEGIN set_mp_mmapsize 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT size_t mmapsize +END +BEGIN set_mutex_locks 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT int do_lock +END +BEGIN env_open 1 RETCODE +ARG ID DB_ENV * dbenv +ARG STRING const char * home +ARG INT u_int32_t flags +ARG INT int mode +END +BEGIN env_paniccall 1 NOFUNC +ARG ID DB_ENV * dbenv +FUNCPROT void (*)(DB_ENV *, int) +FUNCARG void (*func0) __P((DB_ENV *, int)) +END +BEGIN set_recovery_init 1 NOFUNC +ARG ID DB_ENV * dbenv +FUNCPROT int (*)(DB_ENV *) +FUNCARG int (*func0) __P((DB_ENV *)) +END +BEGIN env_remove 1 RETCODE +ARG ID DB_ENV * dbenv +ARG STRING const char * home +ARG INT u_int32_t flags +END +BEGIN set_shm_key 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT long shm_key +END +BEGIN set_tmp_dir 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG STRING const char * dir +END +BEGIN set_tx_recover 1 NOFUNC +ARG ID DB_ENV * dbenv +FUNCPROT int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops) +FUNCARG int (*func0) __P((DB_ENV *, DBT *, DB_LSN *, db_recops)) +END +BEGIN set_tx_max 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t max +END +BEGIN set_tx_timestamp 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT time_t * max +END +BEGIN set_verbose 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t which +ARG INT int onoff +END +# +# Transaction functions +# +BEGIN txn_abort 1 RETCODE +ARG ID DB_TXN * txnp +END +BEGIN txn_begin 1 RETCODE +ARG ID DB_ENV * envp +ARG ID DB_TXN * parent +ARG IGNORE DB_TXN ** txnpp +ARG INT u_int32_t flags +RET ID long txnid +END +BEGIN txn_checkpoint 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t kbyte +ARG INT u_int32_t min +END +BEGIN txn_commit 1 RETCODE +ARG ID DB_TXN * txnp +ARG INT u_int32_t flags +END +BEGIN txn_prepare 1 NOFUNC +ARG ID DB_TXN * txnp +END +BEGIN txn_stat 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG IGNORE DB_TXN_STAT ** statp +FUNCPROT void *(*)(size_t) +FUNCARG void *(*func0) __P((size_t)) +END + +# +# Database functions +# +BEGIN db_bt_compare 1 NOFUNC +ARG ID DB * dbp +FUNCPROT int (*)(DB *, const DBT *, const DBT *) +FUNCARG int (*func0) __P((DB *, const DBT *, const DBT *)) +END +BEGIN db_bt_maxkey 1 CODE +ARG ID DB * dbp +ARG INT u_int32_t maxkey +END +BEGIN db_bt_minkey 1 CODE +ARG ID DB * dbp +ARG INT u_int32_t minkey +END +BEGIN db_bt_prefix 1 NOFUNC +ARG ID DB * dbp +FUNCPROT size_t(*)(DB *, const DBT *, const DBT *) +FUNCARG size_t (*func0) __P((DB *, const DBT *, const DBT *)) +END +BEGIN db_set_append_recno 1 NOFUNC +ARG ID DB * dbp +FUNCPROT int (*)(DB *, DBT *, db_recno_t) +FUNCARG int (*func0) __P((DB *, DBT *, db_recno_t)) +END +BEGIN db_cachesize 1 NOFUNC +ARG ID DB * dbp +ARG INT u_int32_t gbytes +ARG INT u_int32_t bytes +ARG INT int ncache +END +BEGIN db_close 1 RETCODE +ARG ID DB * dbp +ARG INT u_int32_t flags +END +BEGIN db_create 1 NOCLNTCODE +ARG INT u_int32_t flags +ARG ID DB_ENV * envp +RET ID long dbp +END +BEGIN db_del 1 CODE +ARG ID DB * dbp +ARG ID DB_TXN * txnp +ARG DBT DBT * key +ARG INT u_int32_t flags +END +BEGIN db_extentsize 1 CODE +ARG ID DB * dbp +ARG INT u_int32_t extentsize +END +BEGIN db_fd 1 NOFUNC +ARG ID DB * dbp +ARG IGNORE int * fdp +END +BEGIN db_feedback 1 NOFUNC +ARG ID DB * dbp +FUNCPROT void (*)(DB *, int, int) +FUNCARG void (*func0) __P((DB *, int, int)) +END +BEGIN db_flags 1 CODE +ARG ID DB * dbp +ARG INT u_int32_t flags +END +BEGIN db_get 1 RETCODE +ARG ID DB * dbp +ARG ID DB_TXN * txnp +ARG DBT DBT * key +ARG DBT DBT * data +ARG INT u_int32_t flags +RET DBT DBT * key +RET DBT DBT * data +END +BEGIN db_h_ffactor 1 CODE +ARG ID DB * dbp +ARG INT u_int32_t ffactor +END +BEGIN db_h_hash 1 NOFUNC +ARG ID DB * dbp +FUNCPROT u_int32_t(*)(DB *, const void *, u_int32_t) +FUNCARG u_int32_t (*func0) __P((DB *, const void *, u_int32_t)) +END +BEGIN db_h_nelem 1 CODE +ARG ID DB * dbp +ARG INT u_int32_t nelem +END +BEGIN db_key_range 1 RETCODE +ARG ID DB * dbp +ARG ID DB_TXN * txnp +ARG DBT DBT * key +ARG IGNORE DB_KEY_RANGE * range +ARG INT u_int32_t flags +RET DBL double less +RET DBL double equal +RET DBL double greater +END +BEGIN db_lorder 1 CODE +ARG ID DB * dbp +ARG INT int lorder +END +BEGIN db_malloc 1 NOFUNC +ARG ID DB * dbp +FUNCPROT void *(*)(size_t) +FUNCARG void *(*func0) __P((size_t)) +END +# XXX +# The line: +# RET INT u_int32_t dbflags +# should go away when a get_flags method exists. It is +# needed now because Tcl looks at dbp->flags. +# +BEGIN db_open 1 RETCODE +ARG ID DB * dbp +ARG STRING const char * name +ARG STRING const char * subdb +ARG INT DBTYPE type +ARG INT u_int32_t flags +ARG INT int mode +RET INT DBTYPE type +RET INT u_int32_t dbflags +END +BEGIN db_pagesize 1 CODE +ARG ID DB * dbp +ARG INT u_int32_t pagesize +END +BEGIN db_panic 1 NOFUNC +ARG ID DB * dbp +FUNCPROT void (*)(DB_ENV *, int) +FUNCARG void (*func0) __P((DB_ENV *, int)) +END +BEGIN db_put 1 RETCODE +ARG ID DB * dbp +ARG ID DB_TXN * txnp +ARG DBT DBT * key +ARG DBT DBT * data +ARG INT u_int32_t flags +RET DBT DBT * key +END +BEGIN db_realloc 1 NOFUNC +ARG ID DB * dbp +FUNCPROT void *(*)(void *, size_t) +FUNCARG void *(*func0) __P((void *, size_t)) +END +BEGIN db_re_delim 1 CODE +ARG ID DB * dbp +ARG INT int delim +END +BEGIN db_re_len 1 CODE +ARG ID DB * dbp +ARG INT u_int32_t len +END +BEGIN db_re_pad 1 CODE +ARG ID DB * dbp +ARG INT int pad +END +BEGIN db_re_source 1 NOFUNC +ARG ID DB * dbp +ARG STRING const char * re_source +END +BEGIN db_remove 1 RETCODE +ARG ID DB * dbp +ARG STRING const char * name +ARG STRING const char * subdb +ARG INT u_int32_t flags +END +BEGIN db_rename 1 RETCODE +ARG ID DB * dbp +ARG STRING const char * name +ARG STRING const char * subdb +ARG STRING const char * newname +ARG INT u_int32_t flags +END +BEGIN db_stat 1 RETCODE +ARG ID DB * dbp +ARG IGNORE void * sp +FUNCPROT void *(*)(size_t) +FUNCARG void *(*func0) __P((size_t)) +ARG INT u_int32_t flags +RET LIST u_int32_t * stats INT +END +BEGIN db_swapped 1 CODE +ARG ID DB * dbp +END +BEGIN db_sync 1 CODE +ARG ID DB * dbp +ARG INT u_int32_t flags +END +BEGIN db_upgrade 1 NOFUNC +ARG ID DB * dbp +ARG STRING const char * fname +ARG INT u_int32_t flags +END +# +# Cursor functions +# +BEGIN db_cursor 1 RETCODE +ARG ID DB * dbp +ARG ID DB_TXN * txnp +ARG IGNORE DBC ** dbcpp +ARG INT u_int32_t flags +RET ID long dbcid +END +BEGIN db_join 1 RETCODE +ARG ID DB * dbp +ARG LIST DBC ** curs ID +ARG IGNORE DBC ** dbcp +ARG INT u_int32_t flags +RET ID long dbcid +END +BEGIN dbc_close 1 RETCODE +ARG ID DBC * dbc +END +BEGIN dbc_count 1 RETCODE +ARG ID DBC * dbc +ARG IGNORE db_recno_t * countp +ARG INT u_int32_t flags +RET INT db_recno_t dupcount +END +BEGIN dbc_del 1 CODE +ARG ID DBC * dbc +ARG INT u_int32_t flags +END +BEGIN dbc_dup 1 RETCODE +ARG ID DBC * dbc +ARG IGNORE DBC ** dbcp +ARG INT u_int32_t flags +RET ID long dbcid +END +BEGIN dbc_get 1 RETCODE +ARG ID DBC * dbc +ARG DBT DBT * key +ARG DBT DBT * data +ARG INT u_int32_t flags +RET DBT DBT * key +RET DBT DBT * data +END +BEGIN dbc_put 1 RETCODE +ARG ID DBC * dbc +ARG DBT DBT * key +ARG DBT DBT * data +ARG INT u_int32_t flags +RET DBT DBT * key +END + +# +# Unsupported environment subsystems +# +# +# Locking subsystem +# +BEGIN lock_detect 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t flags +ARG INT u_int32_t atype +ARG IGNORE int * aborted +END +BEGIN lock_get 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t locker +ARG INT u_int32_t flags +ARG CONST const DBT * obj +ARG INT db_lockmode_t mode +ARG IGNORE DB_LOCK * lock +END +BEGIN lock_id 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t * idp +END +BEGIN lock_put 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG ID DB_LOCK * lock +END +BEGIN lock_stat 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG IGNORE DB_LOCK_STAT ** statp +FUNCPROT void *(*)(size_t) +FUNCARG void *(*func0) __P((size_t)) +END +BEGIN lock_vec 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT u_int32_t locker +ARG INT u_int32_t flags +ARG IGNORE DB_LOCKREQ * list +ARG INT int nlist +ARG IGNORE DB_LOCKREQ ** elistp +END +# +# Logging subsystem +# +BEGIN log_archive 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG IGNORE char *** listp +ARG INT u_int32_t flags +FUNCPROT void *(*)(size_t) +FUNCARG void *(*func0) __P((size_t)) +END +# +# Don't do log_compare. It doesn't have an env we can get at, +# and it doesn't manipulate DB internal information. +# +BEGIN log_file 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG CONST const DB_LSN * lsn +ARG STRING char * namep +ARG INT size_t len +END +BEGIN log_flush 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG CONST const DB_LSN * lsn +END +BEGIN log_get 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG IGNORE DB_LSN * lsn +ARG DBT DBT * data +ARG INT u_int32_t flags +END +BEGIN log_put 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG IGNORE DB_LSN * lsn +ARG CONST const DBT * data +ARG INT u_int32_t flags +END +BEGIN log_register 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG ID DB * dbp +ARG CONST const char * namep +END +BEGIN log_stat 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG IGNORE DB_LOG_STAT ** statp +FUNCPROT void *(*)(size_t) +FUNCARG void *(*func0) __P((size_t)) +END +BEGIN log_unregister 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG ID DB * dbp +END +# +# Mpool Subsystem +# +BEGIN memp_fclose 1 NOFUNC +ARG ID DB_MPOOLFILE * mpf +END +BEGIN memp_fget 1 NOFUNC +ARG ID DB_MPOOLFILE * mpf +ARG IGNORE db_pgno_t * pgno +ARG INT u_int32_t flags +ARG IGNORE void ** pagep +END +BEGIN memp_fopen 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG CONST const char * file +ARG INT u_int32_t flags +ARG INT int mode +ARG INT size_t pagesize +ARG IGNORE DB_MPOOL_FINFO * finfop +ARG IGNORE DB_MPOOLFILE ** mpf +END +BEGIN memp_fput 1 NOFUNC +ARG ID DB_MPOOLFILE * mpf +ARG IGNORE void * pgaddr +ARG INT u_int32_t flags +END +BEGIN memp_fset 1 NOFUNC +ARG ID DB_MPOOLFILE * mpf +ARG IGNORE void * pgaddr +ARG INT u_int32_t flags +END +BEGIN memp_fsync 1 NOFUNC +ARG ID DB_MPOOLFILE * mpf +END +BEGIN memp_register 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT int ftype +FUNCPROT int (*)(DB_ENV *, db_pgno_t, void *, DBT *) +FUNCARG int (*func0) __P((DB_ENV *, db_pgno_t, void *, DBT *)) +FUNCPROT int (*)(DB_ENV *, db_pgno_t, void *, DBT *) +FUNCARG int (*func1) __P((DB_ENV *, db_pgno_t, void *, DBT *)) +END +BEGIN memp_stat 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG IGNORE DB_MPOOL_STAT ** gstatp +ARG IGNORE DB_MPOOL_FSTAT *** fstatp +FUNCPROT void *(*)(size_t) +FUNCARG void *(*func0) __P((size_t)) +END +BEGIN memp_sync 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG IGNORE DB_LSN * lsn +END +BEGIN memp_trickle 1 NOFUNC +ARG ID DB_ENV * dbenv +ARG INT int pct +ARG IGNORE int * nwrotep +END |