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

db_server_cxxproc.cpp

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 2001-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: db_server_cxxproc.cpp,v 12.6 2005/07/21 18:21:34 bostic Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 
00015 #include <rpc/rpc.h>
00016 
00017 #include <string.h>
00018 #endif
00019 
00020 #include "db_server.h"
00021 
00022 #include "db_int.h"
00023 #include "db_cxx.h"
00024 
00025 extern "C" {
00026 #include "dbinc/db_server_int.h"
00027 #include "dbinc_auto/rpc_server_ext.h"
00028 }
00029 
00030 extern "C" void
00031 __env_get_cachesize_proc(
00032         u_int dbenvcl_id,
00033         __env_get_cachesize_reply *replyp)
00034 {
00035         DbEnv *dbenv;
00036         ct_entry *dbenv_ctp;
00037 
00038         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00039         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00040 
00041         replyp->status = dbenv->get_cachesize(&replyp->gbytes,
00042             &replyp->bytes, (int *)&replyp->ncache);
00043 }
00044 
00045 extern "C" void
00046 __env_set_cachesize_proc(
00047         u_int dbenvcl_id,
00048         u_int32_t gbytes,
00049         u_int32_t bytes,
00050         u_int32_t ncache,
00051         __env_set_cachesize_reply *replyp)
00052 {
00053         DbEnv *dbenv;
00054         ct_entry *dbenv_ctp;
00055         int ret;
00056 
00057         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00058         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00059 
00060         ret = dbenv->set_cachesize(gbytes, bytes, ncache);
00061 
00062         replyp->status = ret;
00063         return;
00064 }
00065 
00066 extern "C" void
00067 __env_close_proc(
00068         u_int dbenvcl_id,
00069         u_int32_t flags,
00070         __env_close_reply *replyp)
00071 {
00072         ct_entry *dbenv_ctp;
00073 
00074         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00075         replyp->status = __env_close_int(dbenvcl_id, flags, 0);
00076         return;
00077 }
00078 
00079 extern "C" void
00080 __env_create_proc(
00081         u_int32_t timeout,
00082         __env_create_reply *replyp)
00083 {
00084         DbEnv *dbenv;
00085         ct_entry *ctp;
00086 
00087         ctp = new_ct_ent(&replyp->status);
00088         if (ctp == NULL)
00089                 return;
00090 
00091         dbenv = new DbEnv(DB_CXX_NO_EXCEPTIONS);
00092         ctp->ct_envp = dbenv;
00093         ctp->ct_type = CT_ENV;
00094         ctp->ct_parent = NULL;
00095         ctp->ct_envparent = ctp;
00096         __dbsrv_settimeout(ctp, timeout);
00097         __dbsrv_active(ctp);
00098         replyp->envcl_id = ctp->ct_id;
00099 
00100         replyp->status = 0;
00101         return;
00102 }
00103 
00104 extern "C" void
00105 __env_dbremove_proc(
00106         u_int dbenvcl_id,
00107         u_int txnpcl_id,
00108         char *name,
00109         char *subdb,
00110         u_int32_t flags,
00111         __env_dbremove_reply *replyp)
00112 {
00113         int ret;
00114         DbEnv *dbenv;
00115         DbTxn *txnp;
00116         ct_entry *dbenv_ctp, *txnp_ctp;
00117 
00118         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00119         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00120 
00121         if (txnpcl_id != 0) {
00122                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
00123                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
00124         } else
00125                 txnp = NULL;
00126 
00127         ret = dbenv->dbremove(txnp, name, subdb, flags);
00128 
00129         replyp->status = ret;
00130         return;
00131 }
00132 
00133 void
00134 __env_dbrename_proc(
00135         u_int dbenvcl_id,
00136         u_int txnpcl_id,
00137         char *name,
00138         char *subdb,
00139         char *newname,
00140         u_int32_t flags,
00141         __env_dbrename_reply *replyp)
00142 {
00143         int ret;
00144         DbEnv *dbenv;
00145         DbTxn *txnp;
00146         ct_entry *dbenv_ctp, *txnp_ctp;
00147 
00148         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00149         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00150 
00151         if (txnpcl_id != 0) {
00152                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
00153                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
00154         } else
00155                 txnp = NULL;
00156 
00157         ret = dbenv->dbrename(txnp, name, subdb, newname, flags);
00158 
00159         replyp->status = ret;
00160         return;
00161 }
00162 
00163 extern "C" void
00164 __env_get_encrypt_flags_proc(
00165         u_int dbenvcl_id,
00166         __env_get_encrypt_flags_reply *replyp)
00167 {
00168         DbEnv *dbenv;
00169         ct_entry *dbenv_ctp;
00170 
00171         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00172         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00173 
00174         replyp->status = dbenv->get_encrypt_flags(&replyp->flags);
00175 }
00176 
00177 extern "C" void
00178 __env_set_encrypt_proc(
00179         u_int dbenvcl_id,
00180         char *passwd,
00181         u_int32_t flags,
00182         __env_set_encrypt_reply *replyp)
00183 {
00184         DbEnv *dbenv;
00185         ct_entry *dbenv_ctp;
00186         int ret;
00187 
00188         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00189         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00190 
00191         ret = dbenv->set_encrypt(passwd, flags);
00192 
00193         replyp->status = ret;
00194         return;
00195 }
00196 
00197 extern "C" void
00198 __env_get_flags_proc(
00199         u_int dbenvcl_id,
00200         __env_get_flags_reply *replyp)
00201 {
00202         DbEnv *dbenv;
00203         ct_entry *dbenv_ctp;
00204 
00205         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00206         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00207 
00208         replyp->status = dbenv->get_flags(&replyp->flags);
00209 }
00210 
00211 extern "C" void
00212 __env_set_flags_proc(
00213         u_int dbenvcl_id,
00214         u_int32_t flags,
00215         u_int32_t onoff,
00216         __env_set_flags_reply *replyp)
00217 {
00218         DbEnv *dbenv;
00219         ct_entry *dbenv_ctp;
00220         int ret;
00221 
00222         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00223         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00224 
00225         ret = dbenv->set_flags(flags, onoff);
00226         if (onoff)
00227                 dbenv_ctp->ct_envdp.onflags = flags;
00228         else
00229                 dbenv_ctp->ct_envdp.offflags = flags;
00230 
00231         replyp->status = ret;
00232         return;
00233 }
00234 
00235 extern "C" void
00236 __env_get_home_proc(
00237         u_int dbenvcl_id,
00238         __env_get_home_reply *replyp)
00239 {
00240         DbEnv *dbenv;
00241         ct_entry *dbenv_ctp;
00242 
00243         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00244         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00245 
00246         replyp->status = dbenv->get_home((const char **)&replyp->home);
00247 }
00248 
00249 extern "C" void
00250 __env_get_open_flags_proc(
00251         u_int dbenvcl_id,
00252         __env_get_open_flags_reply *replyp)
00253 {
00254         DbEnv *dbenv;
00255         ct_entry *dbenv_ctp;
00256 
00257         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00258         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00259 
00260         replyp->status = dbenv->get_open_flags(&replyp->flags);
00261 }
00262 
00263 extern "C" void
00264 __env_open_proc(
00265         u_int dbenvcl_id,
00266         char *home,
00267         u_int32_t flags,
00268         u_int32_t mode,
00269         __env_open_reply *replyp)
00270 {
00271         DbEnv *dbenv;
00272         ct_entry *dbenv_ctp, *new_ctp;
00273         u_int32_t newflags, shareflags;
00274         int ret;
00275         home_entry *fullhome;
00276 
00277         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00278         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00279         fullhome = get_fullhome(home);
00280         if (fullhome == NULL) {
00281                 ret = DB_NOSERVER_HOME;
00282                 goto out;
00283         }
00284 
00285         /*
00286          * If they are using locking do deadlock detection for them,
00287          * internally.
00288          */
00289         if ((flags & DB_INIT_LOCK) &&
00290             (ret = dbenv->set_lk_detect(DB_LOCK_DEFAULT)) != 0)
00291                 goto out;
00292 
00293         if (__dbsrv_verbose) {
00294                 dbenv->set_errfile(stderr);
00295                 dbenv->set_errpfx(fullhome->home);
00296         }
00297 
00298         /*
00299          * Mask off flags we ignore
00300          */
00301         newflags = (flags & ~DB_SERVER_FLAGMASK);
00302         shareflags = (newflags & DB_SERVER_ENVFLAGS);
00303         /*
00304          * Check now whether we can share a handle for this env.
00305          */
00306         replyp->envcl_id = dbenvcl_id;
00307         if ((new_ctp = __dbsrv_shareenv(dbenv_ctp, fullhome, shareflags))
00308             != NULL) {
00309                 /*
00310                  * We can share, clean up old  ID, set new one.
00311                  */
00312                 if (__dbsrv_verbose)
00313                         printf("Sharing env ID %ld\n", new_ctp->ct_id);
00314                 replyp->envcl_id = new_ctp->ct_id;
00315                 ret = __env_close_int(dbenvcl_id, 0, 0);
00316         } else {
00317                 ret = dbenv->open(fullhome->home, newflags, mode);
00318                 dbenv_ctp->ct_envdp.home = fullhome;
00319                 dbenv_ctp->ct_envdp.envflags = shareflags;
00320         }
00321 out:    replyp->status = ret;
00322         return;
00323 }
00324 
00325 extern "C" void
00326 __env_remove_proc(
00327         u_int dbenvcl_id,
00328         char *home,
00329         u_int32_t flags,
00330         __env_remove_reply *replyp)
00331 {
00332         DbEnv *dbenv;
00333         ct_entry *dbenv_ctp;
00334         int ret;
00335         home_entry *fullhome;
00336 
00337         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00338         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00339         fullhome = get_fullhome(home);
00340         if (fullhome == NULL) {
00341                 replyp->status = DB_NOSERVER_HOME;
00342                 return;
00343         }
00344 
00345         ret = dbenv->remove(fullhome->home, flags);
00346         __dbdel_ctp(dbenv_ctp);
00347         replyp->status = ret;
00348         return;
00349 }
00350 
00351 extern "C" void
00352 __txn_abort_proc(
00353         u_int txnpcl_id,
00354         __txn_abort_reply *replyp)
00355 {
00356         DbTxn *txnp;
00357         ct_entry *txnp_ctp;
00358         int ret;
00359 
00360         ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
00361         txnp = (DbTxn *)txnp_ctp->ct_anyp;
00362 
00363         ret = txnp->abort();
00364         __dbdel_ctp(txnp_ctp);
00365         replyp->status = ret;
00366         return;
00367 }
00368 
00369 extern "C" void
00370 __env_txn_begin_proc(
00371         u_int dbenvcl_id,
00372         u_int parentcl_id,
00373         u_int32_t flags,
00374         __env_txn_begin_reply *replyp)
00375 {
00376         DbEnv *dbenv;
00377         DbTxn *parent, *txnp;
00378         ct_entry *ctp, *dbenv_ctp, *parent_ctp;
00379         int ret;
00380 
00381         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00382         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00383         parent_ctp = NULL;
00384 
00385         ctp = new_ct_ent(&replyp->status);
00386         if (ctp == NULL)
00387                 return;
00388 
00389         if (parentcl_id != 0) {
00390                 ACTIVATE_CTP(parent_ctp, parentcl_id, CT_TXN);
00391                 parent = (DbTxn *)parent_ctp->ct_anyp;
00392                 ctp->ct_activep = parent_ctp->ct_activep;
00393         } else
00394                 parent = NULL;
00395 
00396         ret = dbenv->txn_begin(parent, &txnp, flags | DB_TXN_NOWAIT);
00397         if (ret == 0) {
00398                 ctp->ct_txnp = txnp;
00399                 ctp->ct_type = CT_TXN;
00400                 ctp->ct_parent = parent_ctp;
00401                 ctp->ct_envparent = dbenv_ctp;
00402                 replyp->txnidcl_id = ctp->ct_id;
00403                 __dbsrv_settimeout(ctp, dbenv_ctp->ct_timeout);
00404                 __dbsrv_active(ctp);
00405         } else
00406                 __dbclear_ctp(ctp);
00407 
00408         replyp->status = ret;
00409         return;
00410 }
00411 
00412 extern "C" void
00413 __txn_commit_proc(
00414         u_int txnpcl_id,
00415         u_int32_t flags,
00416         __txn_commit_reply *replyp)
00417 {
00418         DbTxn *txnp;
00419         ct_entry *txnp_ctp;
00420         int ret;
00421 
00422         ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
00423         txnp = (DbTxn *)txnp_ctp->ct_anyp;
00424 
00425         ret = txnp->commit(flags);
00426         __dbdel_ctp(txnp_ctp);
00427 
00428         replyp->status = ret;
00429         return;
00430 }
00431 
00432 extern "C" void
00433 __txn_discard_proc(
00434         u_int txnpcl_id,
00435         u_int32_t flags,
00436         __txn_discard_reply *replyp)
00437 {
00438         DbTxn *txnp;
00439         ct_entry *txnp_ctp;
00440         int ret;
00441 
00442         ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
00443         txnp = (DbTxn *)txnp_ctp->ct_anyp;
00444 
00445         ret = txnp->discard(flags);
00446         __dbdel_ctp(txnp_ctp);
00447 
00448         replyp->status = ret;
00449         return;
00450 }
00451 
00452 extern "C" void
00453 __txn_prepare_proc(
00454         u_int txnpcl_id,
00455         u_int8_t *gid,
00456         __txn_prepare_reply *replyp)
00457 {
00458         DbTxn *txnp;
00459         ct_entry *txnp_ctp;
00460         int ret;
00461 
00462         ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
00463         txnp = (DbTxn *)txnp_ctp->ct_anyp;
00464 
00465         ret = txnp->prepare(gid);
00466         replyp->status = ret;
00467         return;
00468 }
00469 
00470 extern "C" void
00471 __env_txn_recover_proc(
00472         u_int dbenvcl_id,
00473         u_int32_t count,
00474         u_int32_t flags,
00475         __env_txn_recover_reply *replyp,
00476         int * freep)
00477 {
00478         DbEnv *dbenv;
00479         DbPreplist *dbprep, *p;
00480         ct_entry *dbenv_ctp, *ctp;
00481         long erri, i, retcount;
00482         u_int32_t *txnidp;
00483         int ret;
00484         char *gid;
00485 
00486         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00487         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00488         *freep = 0;
00489 
00490         if ((ret = __os_malloc(
00491             dbenv->get_DB_ENV(), count * sizeof(DbPreplist), &dbprep)) != 0)
00492                 goto out;
00493         if ((ret = dbenv->txn_recover(dbprep, count, &retcount, flags)) != 0)
00494                 goto out;
00495         /*
00496          * If there is nothing, success, but it's easy.
00497          */
00498         replyp->retcount = retcount; // TODO: fix C++ txn_recover
00499         if (retcount == 0) {
00500                 replyp->txn.txn_val = NULL;
00501                 replyp->txn.txn_len = 0;
00502                 replyp->gid.gid_val = NULL;
00503                 replyp->gid.gid_len = 0;
00504         }
00505 
00506         /*
00507          * We have our txn list.  Now we need to allocate the space for
00508          * the txn ID array and the GID array and set them up.
00509          */
00510         if ((ret = __os_calloc(dbenv->get_DB_ENV(), retcount, sizeof(u_int32_t),
00511             &replyp->txn.txn_val)) != 0)
00512                 goto out;
00513         replyp->txn.txn_len = retcount * sizeof(u_int32_t);
00514         if ((ret = __os_calloc(dbenv->get_DB_ENV(), retcount, DB_XIDDATASIZE,
00515             &replyp->gid.gid_val)) != 0) {
00516                 __os_free(dbenv->get_DB_ENV(), replyp->txn.txn_val);
00517                 goto out;
00518         }
00519         replyp->gid.gid_len = retcount * DB_XIDDATASIZE;
00520 
00521         /*
00522          * Now walk through our results, creating parallel arrays
00523          * to send back.  For each entry we need to create a new
00524          * txn ctp and then fill in the array info.
00525          */
00526         i = 0;
00527         p = dbprep;
00528         gid = replyp->gid.gid_val;
00529         txnidp = replyp->txn.txn_val;
00530         while (i++ < retcount) {
00531                 ctp = new_ct_ent(&ret);
00532                 if (ret != 0) {
00533                         i--;
00534                         goto out2;
00535                 }
00536                 ctp->ct_txnp = p->txn;
00537                 ctp->ct_type = CT_TXN;
00538                 ctp->ct_parent = NULL;
00539                 ctp->ct_envparent = dbenv_ctp;
00540                 __dbsrv_settimeout(ctp, dbenv_ctp->ct_timeout);
00541                 __dbsrv_active(ctp);
00542 
00543                 *txnidp = ctp->ct_id;
00544                 memcpy(gid, p->gid, DB_XIDDATASIZE);
00545 
00546                 p++;
00547                 txnidp++;
00548                 gid += DB_XIDDATASIZE;
00549         }
00550         /*
00551          * If we get here, we have success and we have to set freep
00552          * so it'll get properly freed next time.
00553          */
00554         *freep = 1;
00555 out:
00556         if (dbprep != NULL)
00557                 __os_free(dbenv->get_DB_ENV(), dbprep);
00558         replyp->status = ret;
00559         return;
00560 out2:
00561         /*
00562          * We had an error in the middle of creating our new txn
00563          * ct entries.  We have to unwind all that we have done.  Ugh.
00564          */
00565         for (txnidp = replyp->txn.txn_val, erri = 0;
00566             erri < i; erri++, txnidp++) {
00567                 ctp = get_tableent(*txnidp);
00568                 __dbclear_ctp(ctp);
00569         }
00570         __os_free(dbenv->get_DB_ENV(), replyp->txn.txn_val);
00571         __os_free(dbenv->get_DB_ENV(), replyp->gid.gid_val);
00572         __os_free(dbenv->get_DB_ENV(), dbprep);
00573         replyp->status = ret;
00574         return;
00575 }
00576 
00577 extern "C" void
00578 __db_associate_proc(
00579         u_int dbpcl_id,
00580         u_int txnpcl_id,
00581         u_int sdbpcl_id,
00582         u_int32_t flags,
00583         __db_associate_reply *replyp)
00584 {
00585         Db *dbp, *sdbp;
00586         DbTxn *txnp;
00587         ct_entry *dbp_ctp, *sdbp_ctp, *txnp_ctp;
00588         int ret;
00589 
00590         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00591         dbp = (Db *)dbp_ctp->ct_anyp;
00592         ACTIVATE_CTP(sdbp_ctp, sdbpcl_id, CT_DB);
00593         sdbp = (Db *)sdbp_ctp->ct_anyp;
00594         if (txnpcl_id != 0) {
00595                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
00596                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
00597         } else
00598                 txnp = NULL;
00599 
00600         /*
00601          * We do not support DB_CREATE for associate or the callbacks
00602          * implemented in the Java and JE RPC servers.   Users can only
00603          * access secondary indices on a read-only basis, so whatever they
00604          * are looking for needs to be there already.
00605          */
00606         if (LF_ISSET(DB_RPC2ND_MASK | DB_CREATE))
00607                 ret = EINVAL;
00608         else
00609                 ret = dbp->associate(txnp, sdbp, NULL, flags);
00610 
00611         replyp->status = ret;
00612         return;
00613 }
00614 
00615 extern "C" void
00616 __db_get_bt_minkey_proc(
00617         u_int dbpcl_id,
00618         __db_get_bt_minkey_reply *replyp)
00619 {
00620         Db *dbp;
00621         ct_entry *dbp_ctp;
00622 
00623         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00624         dbp = (Db *)dbp_ctp->ct_anyp;
00625 
00626         replyp->status = dbp->get_bt_minkey(&replyp->minkey);
00627 }
00628 
00629 extern "C" void
00630 __db_set_bt_minkey_proc(
00631         u_int dbpcl_id,
00632         u_int32_t minkey,
00633         __db_set_bt_minkey_reply *replyp)
00634 {
00635         Db *dbp;
00636         ct_entry *dbp_ctp;
00637         int ret;
00638 
00639         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00640         dbp = (Db *)dbp_ctp->ct_anyp;
00641 
00642         ret = dbp->set_bt_minkey(minkey);
00643 
00644         replyp->status = ret;
00645         return;
00646 }
00647 
00648 extern "C" void
00649 __db_close_proc(
00650         u_int dbpcl_id,
00651         u_int32_t flags,
00652         __db_close_reply *replyp)
00653 {
00654         ct_entry *dbp_ctp;
00655 
00656         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00657         replyp->status = __db_close_int(dbpcl_id, flags);
00658         return;
00659 }
00660 
00661 extern "C" void
00662 __db_create_proc(
00663         u_int dbenvcl_id,
00664         u_int32_t flags,
00665         __db_create_reply *replyp)
00666 {
00667         Db *dbp;
00668         DbEnv *dbenv;
00669         ct_entry *dbenv_ctp, *dbp_ctp;
00670 
00671         ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
00672         dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
00673 
00674         dbp_ctp = new_ct_ent(&replyp->status);
00675         if (dbp_ctp == NULL)
00676                 return ;
00677         /*
00678          * We actually require env's for databases.  The client should
00679          * have caught it, but just in case.
00680          */
00681         DB_ASSERT(dbenv != NULL);
00682         dbp = new Db(dbenv, flags);
00683         dbp_ctp->ct_dbp = dbp;
00684         dbp_ctp->ct_type = CT_DB;
00685         dbp_ctp->ct_parent = dbenv_ctp;
00686         dbp_ctp->ct_envparent = dbenv_ctp;
00687         replyp->dbcl_id = dbp_ctp->ct_id;
00688         replyp->status = 0;
00689         return;
00690 }
00691 
00692 extern "C" void
00693 __db_del_proc(
00694         u_int dbpcl_id,
00695         u_int txnpcl_id,
00696         u_int32_t keydlen,
00697         u_int32_t keydoff,
00698         u_int32_t keyulen,
00699         u_int32_t keyflags,
00700         void *keydata,
00701         u_int32_t keysize,
00702         u_int32_t flags,
00703         __db_del_reply *replyp)
00704 {
00705         Db *dbp;
00706         DbTxn *txnp;
00707         ct_entry *dbp_ctp, *txnp_ctp;
00708         int ret;
00709 
00710         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00711         dbp = (Db *)dbp_ctp->ct_anyp;
00712         if (txnpcl_id != 0) {
00713                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
00714                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
00715         } else
00716                 txnp = NULL;
00717 
00718         /* Set up key */
00719         Dbt key(keydata, keysize);
00720         key.set_dlen(keydlen);
00721         key.set_ulen(keyulen);
00722         key.set_doff(keydoff);
00723         key.set_flags(keyflags);
00724 
00725         ret = dbp->del(txnp, &key, flags);
00726 
00727         replyp->status = ret;
00728         return;
00729 }
00730 
00731 extern "C" void
00732 __db_get_encrypt_flags_proc(
00733         u_int dbpcl_id,
00734         __db_get_encrypt_flags_reply *replyp)
00735 {
00736         Db *dbp;
00737         ct_entry *dbp_ctp;
00738 
00739         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00740         dbp = (Db *)dbp_ctp->ct_anyp;
00741 
00742         replyp->status = dbp->get_encrypt_flags(&replyp->flags);
00743 }
00744 
00745 extern "C" void
00746 __db_set_encrypt_proc(
00747         u_int dbpcl_id,
00748         char *passwd,
00749         u_int32_t flags,
00750         __db_set_encrypt_reply *replyp)
00751 {
00752         Db *dbp;
00753         ct_entry *dbp_ctp;
00754         int ret;
00755 
00756         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00757         dbp = (Db *)dbp_ctp->ct_anyp;
00758 
00759         ret = dbp->set_encrypt(passwd, flags);
00760         replyp->status = ret;
00761         return;
00762 }
00763 
00764 extern "C" void
00765 __db_get_q_extentsize_proc(
00766         u_int dbpcl_id,
00767         __db_get_q_extentsize_reply *replyp)
00768 {
00769         Db *dbp;
00770         ct_entry *dbp_ctp;
00771 
00772         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00773         dbp = (Db *)dbp_ctp->ct_anyp;
00774 
00775         replyp->status = dbp->get_q_extentsize(&replyp->extentsize);
00776 }
00777 
00778 extern "C" void
00779 __db_set_q_extentsize_proc(
00780         u_int dbpcl_id,
00781         u_int32_t extentsize,
00782         __db_set_q_extentsize_reply *replyp)
00783 {
00784         Db *dbp;
00785         ct_entry *dbp_ctp;
00786         int ret;
00787 
00788         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00789         dbp = (Db *)dbp_ctp->ct_anyp;
00790 
00791         ret = dbp->set_q_extentsize(extentsize);
00792 
00793         replyp->status = ret;
00794         return;
00795 }
00796 
00797 extern "C" void
00798 __db_get_flags_proc(
00799         u_int dbpcl_id,
00800         __db_get_flags_reply *replyp)
00801 {
00802         Db *dbp;
00803         ct_entry *dbp_ctp;
00804 
00805         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00806         dbp = (Db *)dbp_ctp->ct_anyp;
00807 
00808         replyp->status = dbp->get_flags(&replyp->flags);
00809 }
00810 
00811 extern "C" void
00812 __db_set_flags_proc(
00813         u_int dbpcl_id,
00814         u_int32_t flags,
00815         __db_set_flags_reply *replyp)
00816 {
00817         Db *dbp;
00818         ct_entry *dbp_ctp;
00819         int ret;
00820 
00821         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00822         dbp = (Db *)dbp_ctp->ct_anyp;
00823 
00824         ret = dbp->set_flags(flags);
00825         dbp_ctp->ct_dbdp.setflags = flags;
00826 
00827         replyp->status = ret;
00828         return;
00829 }
00830 
00831 extern "C" void
00832 __db_get_proc(
00833         u_int dbpcl_id,
00834         u_int txnpcl_id,
00835         u_int32_t keydlen,
00836         u_int32_t keydoff,
00837         u_int32_t keyulen,
00838         u_int32_t keyflags,
00839         void *keydata,
00840         u_int32_t keysize,
00841         u_int32_t datadlen,
00842         u_int32_t datadoff,
00843         u_int32_t dataulen,
00844         u_int32_t dataflags,
00845         void *datadata,
00846         u_int32_t datasize,
00847         u_int32_t flags,
00848         __db_get_reply *replyp,
00849         int * freep)
00850 {
00851         Db *dbp;
00852         DbTxn *txnp;
00853         ct_entry *dbp_ctp, *txnp_ctp;
00854         int ret;
00855         void *tmpdata;
00856 
00857         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00858         dbp = (Db *)dbp_ctp->ct_anyp;
00859         if (txnpcl_id != 0) {
00860                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
00861                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
00862         } else
00863                 txnp = NULL;
00864 
00865         replyp->keydata.keydata_val = NULL;
00866         replyp->datadata.datadata_val = NULL;
00867         *freep = 0;
00868 
00869         /* Set up key and data */
00870         Dbt key(keydata, keysize);
00871         key.set_dlen(keydlen);
00872         key.set_ulen(keyulen);
00873         key.set_doff(keydoff);
00874         /*
00875          * Ignore memory related flags on server.
00876          */
00877         key.set_flags(DB_DBT_MALLOC | (keyflags & DB_DBT_PARTIAL));
00878 
00879         Dbt data(datadata, datasize);
00880         data.set_dlen(datadlen);
00881         data.set_ulen(dataulen);
00882         data.set_doff(datadoff);
00883         /*
00884          * Ignore memory related flags on server.
00885          */
00886         dataflags &= DB_DBT_PARTIAL;
00887         if (flags & DB_MULTIPLE) {
00888                 if (data.get_data() == 0) {
00889                         ret = __os_umalloc(dbp->get_DB()->dbenv,
00890                             dataulen, &tmpdata);
00891                         if (ret != 0)
00892                                 goto err;
00893                         data.set_data(tmpdata);
00894                 }
00895                 dataflags |= DB_DBT_USERMEM;
00896         } else
00897                 dataflags |= DB_DBT_MALLOC;
00898         data.set_flags(dataflags);
00899 
00900         /* Got all our stuff, now do the get */
00901         ret = dbp->get(txnp, &key, &data, flags);
00902         /*
00903          * Otherwise just status.
00904          */
00905         if (ret == 0) {
00906                 /*
00907                  * XXX
00908                  * We need to xdr_free whatever we are returning, next time.
00909                  * However, DB does not allocate a new key if one was given
00910                  * and we'd be free'ing up space allocated in the request.
00911                  * So, allocate a new key/data pointer if it is the same one
00912                  * as in the request.
00913                  */
00914                 *freep = 1;
00915                 /*
00916                  * Key
00917                  */
00918                 if (key.get_data() == keydata) {
00919                         ret = __os_umalloc(dbp->get_DB()->dbenv,
00920                             key.get_size(), &replyp->keydata.keydata_val);
00921                         if (ret != 0)
00922                                 goto err;
00923                         memcpy(replyp->keydata.keydata_val,
00924                             key.get_data(), key.get_size());
00925                 } else
00926                         replyp->keydata.keydata_val = (char *)key.get_data();
00927 
00928                 replyp->keydata.keydata_len = key.get_size();
00929 
00930                 /*
00931                  * Data
00932                  */
00933                 if (data.get_data() == datadata) {
00934                         ret = __os_umalloc(dbp->get_DB()->dbenv,
00935                              data.get_size(), &replyp->datadata.datadata_val);
00936                         if (ret != 0)
00937                                 goto err;
00938                         memcpy(replyp->datadata.datadata_val, data.get_data(),
00939                             data.get_size());
00940                 } else
00941                         replyp->datadata.datadata_val = (char *)data.get_data();
00942                 replyp->datadata.datadata_len = data.get_size();
00943         } else {
00944 err:            FREE_IF_CHANGED(dbp->get_DB()->dbenv,
00945                     key.get_data(), keydata);
00946                 FREE_IF_CHANGED(dbp->get_DB()->dbenv,
00947                     data.get_data(), datadata);
00948                 FREE_IF_CHANGED(dbp->get_DB()->dbenv,
00949                     replyp->keydata.keydata_val, key.get_data());
00950                 replyp->keydata.keydata_val = NULL;
00951                 replyp->keydata.keydata_len = 0;
00952                 replyp->datadata.datadata_val = NULL;
00953                 replyp->datadata.datadata_len = 0;
00954                 *freep = 0;
00955         }
00956         replyp->status = ret;
00957         return;
00958 }
00959 
00960 extern "C" void
00961 __db_get_h_ffactor_proc(
00962         u_int dbpcl_id,
00963         __db_get_h_ffactor_reply *replyp)
00964 {
00965         Db *dbp;
00966         ct_entry *dbp_ctp;
00967 
00968         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00969         dbp = (Db *)dbp_ctp->ct_anyp;
00970 
00971         replyp->status = dbp->get_h_ffactor(&replyp->ffactor);
00972 }
00973 
00974 extern "C" void
00975 __db_set_h_ffactor_proc(
00976         u_int dbpcl_id,
00977         u_int32_t ffactor,
00978         __db_set_h_ffactor_reply *replyp)
00979 {
00980         Db *dbp;
00981         ct_entry *dbp_ctp;
00982         int ret;
00983 
00984         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
00985         dbp = (Db *)dbp_ctp->ct_anyp;
00986 
00987         ret = dbp->set_h_ffactor(ffactor);
00988 
00989         replyp->status = ret;
00990         return;
00991 }
00992 
00993 extern "C" void
00994 __db_get_h_nelem_proc(
00995         u_int dbpcl_id,
00996         __db_get_h_nelem_reply *replyp)
00997 {
00998         Db *dbp;
00999         ct_entry *dbp_ctp;
01000 
01001         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01002         dbp = (Db *)dbp_ctp->ct_anyp;
01003 
01004         replyp->status = dbp->get_h_nelem(&replyp->nelem);
01005 }
01006 
01007 extern "C" void
01008 __db_set_h_nelem_proc(
01009         u_int dbpcl_id,
01010         u_int32_t nelem,
01011         __db_set_h_nelem_reply *replyp)
01012 {
01013         Db *dbp;
01014         ct_entry *dbp_ctp;
01015         int ret;
01016 
01017         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01018         dbp = (Db *)dbp_ctp->ct_anyp;
01019 
01020         ret = dbp->set_h_nelem(nelem);
01021 
01022         replyp->status = ret;
01023         return;
01024 }
01025 
01026 extern "C" void
01027 __db_key_range_proc(
01028         u_int dbpcl_id,
01029         u_int txnpcl_id,
01030         u_int32_t keydlen,
01031         u_int32_t keydoff,
01032         u_int32_t keyulen,
01033         u_int32_t keyflags,
01034         void *keydata,
01035         u_int32_t keysize,
01036         u_int32_t flags,
01037         __db_key_range_reply *replyp)
01038 {
01039         Db *dbp;
01040         DB_KEY_RANGE range;
01041         DbTxn *txnp;
01042         ct_entry *dbp_ctp, *txnp_ctp;
01043         int ret;
01044 
01045         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01046         dbp = (Db *)dbp_ctp->ct_anyp;
01047         if (txnpcl_id != 0) {
01048                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
01049                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
01050         } else
01051                 txnp = NULL;
01052 
01053         /* Set up key */
01054         Dbt key(keydata, keysize);
01055         key.set_dlen(keydlen);
01056         key.set_ulen(keyulen);
01057         key.set_doff(keydoff);
01058         key.set_flags(keyflags);
01059 
01060         ret = dbp->key_range(txnp, &key, &range, flags);
01061 
01062         replyp->status = ret;
01063         replyp->less = range.less;
01064         replyp->equal = range.equal;
01065         replyp->greater = range.greater;
01066         return;
01067 }
01068 
01069 extern "C" void
01070 __db_get_lorder_proc(
01071         u_int dbpcl_id,
01072         __db_get_lorder_reply *replyp)
01073 {
01074         Db *dbp;
01075         ct_entry *dbp_ctp;
01076 
01077         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01078         dbp = (Db *)dbp_ctp->ct_anyp;
01079 
01080         replyp->status = dbp->get_lorder((int *)&replyp->lorder);
01081 }
01082 
01083 extern "C" void
01084 __db_set_lorder_proc(
01085         u_int dbpcl_id,
01086         u_int32_t lorder,
01087         __db_set_lorder_reply *replyp)
01088 {
01089         Db *dbp;
01090         ct_entry *dbp_ctp;
01091         int ret;
01092 
01093         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01094         dbp = (Db *)dbp_ctp->ct_anyp;
01095 
01096         ret = dbp->set_lorder(lorder);
01097 
01098         replyp->status = ret;
01099         return;
01100 }
01101 
01102 extern "C" void
01103 __db_get_dbname_proc(
01104         u_int dbpcl_id,
01105         __db_get_dbname_reply *replyp)
01106 {
01107         Db *dbp;
01108         ct_entry *dbp_ctp;
01109 
01110         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01111         dbp = (Db *)dbp_ctp->ct_anyp;
01112 
01113         replyp->status = dbp->get_dbname(
01114             (const char **)&replyp->filename, (const char **)&replyp->dbname);
01115 }
01116 
01117 extern "C" void
01118 __db_get_open_flags_proc(
01119         u_int dbpcl_id,
01120         __db_get_open_flags_reply *replyp)
01121 {
01122         Db *dbp;
01123         ct_entry *dbp_ctp;
01124 
01125         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01126         dbp = (Db *)dbp_ctp->ct_anyp;
01127 
01128         replyp->status = dbp->get_open_flags(&replyp->flags);
01129 }
01130 
01131 extern "C" void
01132 __db_open_proc(
01133         u_int dbpcl_id,
01134         u_int txnpcl_id,
01135         char *name,
01136         char *subdb,
01137         u_int32_t type,
01138         u_int32_t flags,
01139         u_int32_t mode,
01140         __db_open_reply *replyp)
01141 {
01142         Db *dbp;
01143         DbTxn *txnp;
01144         DBTYPE dbtype;
01145         ct_entry *dbp_ctp, *new_ctp, *txnp_ctp;
01146         int isswapped, ret;
01147 
01148         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01149         dbp = (Db *)dbp_ctp->ct_anyp;
01150         if (txnpcl_id != 0) {
01151                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
01152                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
01153         } else
01154                 txnp = NULL;
01155 
01156         replyp->dbcl_id = dbpcl_id;
01157         if ((new_ctp = __dbsrv_sharedb(
01158             dbp_ctp, name, subdb, (DBTYPE)type, flags)) != NULL) {
01159                 /*
01160                  * We can share, clean up old ID, set new one.
01161                  */
01162                 if (__dbsrv_verbose)
01163                         printf("Sharing db ID %ld\n", new_ctp->ct_id);
01164                 replyp->dbcl_id = new_ctp->ct_id;
01165                 ret = __db_close_int(dbpcl_id, 0);
01166                 goto out;
01167         }
01168         ret = dbp->open(txnp, name, subdb, (DBTYPE)type, flags, mode);
01169         if (ret == 0) {
01170                 (void)dbp->get_type(&dbtype);
01171                 replyp->type = dbtype;
01172                 /*
01173                  * We need to determine the byte order of the database
01174                  * and send it back to the client.  Determine it by
01175                  * the server's native order and the swapped value of
01176                  * the DB itself.
01177                  */
01178                 (void)dbp->get_byteswapped(&isswapped);
01179                 if (__db_byteorder(NULL, 1234) == 0) {
01180                         if (isswapped == 0)
01181                                 replyp->lorder = 1234;
01182                         else
01183                                 replyp->lorder = 4321;
01184                 } else {
01185                         if (isswapped == 0)
01186                                 replyp->lorder = 4321;
01187                         else
01188                                 replyp->lorder = 1234;
01189                 }
01190                 dbp_ctp->ct_dbdp.type = dbtype;
01191                 dbp_ctp->ct_dbdp.dbflags = LF_ISSET(DB_SERVER_DBFLAGS);
01192                 if (name == NULL)
01193                         dbp_ctp->ct_dbdp.db = NULL;
01194                 else if ((ret = __os_strdup(dbp->get_DB()->dbenv, name,
01195                     &dbp_ctp->ct_dbdp.db)) != 0)
01196                         goto out;
01197                 if (subdb == NULL)
01198                         dbp_ctp->ct_dbdp.subdb = NULL;
01199                 else if ((ret = __os_strdup(dbp->get_DB()->dbenv, subdb,
01200                     &dbp_ctp->ct_dbdp.subdb)) != 0)
01201                         goto out;
01202         }
01203 out:
01204         replyp->status = ret;
01205         return;
01206 }
01207 
01208 extern "C" void
01209 __db_get_pagesize_proc(
01210         u_int dbpcl_id,
01211         __db_get_pagesize_reply *replyp)
01212 {
01213         Db *dbp;
01214         ct_entry *dbp_ctp;
01215 
01216         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01217         dbp = (Db *)dbp_ctp->ct_anyp;
01218 
01219         replyp->status = dbp->get_pagesize(&replyp->pagesize);
01220 }
01221 
01222 extern "C" void
01223 __db_set_pagesize_proc(
01224         u_int dbpcl_id,
01225         u_int32_t pagesize,
01226         __db_set_pagesize_reply *replyp)
01227 {
01228         Db *dbp;
01229         ct_entry *dbp_ctp;
01230         int ret;
01231 
01232         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01233         dbp = (Db *)dbp_ctp->ct_anyp;
01234 
01235         ret = dbp->set_pagesize(pagesize);
01236 
01237         replyp->status = ret;
01238         return;
01239 }
01240 
01241 extern "C" void
01242 __db_pget_proc(
01243         u_int dbpcl_id,
01244         u_int txnpcl_id,
01245         u_int32_t skeydlen,
01246         u_int32_t skeydoff,
01247         u_int32_t skeyulen,
01248         u_int32_t skeyflags,
01249         void *skeydata,
01250         u_int32_t skeysize,
01251         u_int32_t pkeydlen,
01252         u_int32_t pkeydoff,
01253         u_int32_t pkeyulen,
01254         u_int32_t pkeyflags,
01255         void *pkeydata,
01256         u_int32_t pkeysize,
01257         u_int32_t datadlen,
01258         u_int32_t datadoff,
01259         u_int32_t dataulen,
01260         u_int32_t dataflags,
01261         void *datadata,
01262         u_int32_t datasize,
01263         u_int32_t flags,
01264         __db_pget_reply *replyp,
01265         int * freep)
01266 {
01267         Db *dbp;
01268         DbTxn *txnp;
01269         ct_entry *dbp_ctp, *txnp_ctp;
01270         int ret;
01271 
01272         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01273         dbp = (Db *)dbp_ctp->ct_anyp;
01274         if (txnpcl_id != 0) {
01275                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
01276                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
01277         } else
01278                 txnp = NULL;
01279 
01280         replyp->skeydata.skeydata_val = NULL;
01281         replyp->pkeydata.pkeydata_val = NULL;
01282         replyp->datadata.datadata_val = NULL;
01283         *freep = 0;
01284 
01285         /*
01286          * Ignore memory related flags on server.
01287          */
01288         /* Set up key and data */
01289         Dbt skey(skeydata, skeysize);
01290         skey.set_dlen(skeydlen);
01291         skey.set_ulen(skeyulen);
01292         skey.set_doff(skeydoff);
01293         skey.set_flags(DB_DBT_MALLOC | (skeyflags & DB_DBT_PARTIAL));
01294 
01295         Dbt pkey(pkeydata, pkeysize);
01296         pkey.set_dlen(pkeydlen);
01297         pkey.set_ulen(pkeyulen);
01298         pkey.set_doff(pkeydoff);
01299         pkey.set_flags(DB_DBT_MALLOC | (pkeyflags & DB_DBT_PARTIAL));
01300 
01301         Dbt data(datadata, datasize);
01302         data.set_dlen(datadlen);
01303         data.set_ulen(dataulen);
01304         data.set_doff(datadoff);
01305         data.set_flags(DB_DBT_MALLOC | (dataflags & DB_DBT_PARTIAL));
01306 
01307         /* Got all our stuff, now do the get */
01308         ret = dbp->pget(txnp, &skey, &pkey, &data, flags);
01309         /*
01310          * Otherwise just status.
01311          */
01312         if (ret == 0) {
01313                 /*
01314                  * XXX
01315                  * We need to xdr_free whatever we are returning, next time.
01316                  * However, DB does not allocate a new key if one was given
01317                  * and we'd be free'ing up space allocated in the request.
01318                  * So, allocate a new key/data pointer if it is the same one
01319                  * as in the request.
01320                  */
01321                 *freep = 1;
01322                 /*
01323                  * Key
01324                  */
01325                 if (skey.get_data() == skeydata) {
01326                         ret = __os_umalloc(dbp->get_DB()->dbenv,
01327                             skey.get_size(), &replyp->skeydata.skeydata_val);
01328                         if (ret != 0)
01329                                 goto err;
01330                         memcpy(replyp->skeydata.skeydata_val, skey.get_data(),
01331                             skey.get_size());
01332                 } else
01333                         replyp->skeydata.skeydata_val = (char *)skey.get_data();
01334 
01335                 replyp->skeydata.skeydata_len = skey.get_size();
01336 
01337                 /*
01338                  * Primary key
01339                  */
01340                 if (pkey.get_data() == pkeydata) {
01341                         ret = __os_umalloc(dbp->get_DB()->dbenv,
01342                              pkey.get_size(), &replyp->pkeydata.pkeydata_val);
01343                         if (ret != 0)
01344                                 goto err;
01345                         memcpy(replyp->pkeydata.pkeydata_val, pkey.get_data(),
01346                             pkey.get_size());
01347                 } else
01348                         replyp->pkeydata.pkeydata_val = (char *)pkey.get_data();
01349                 replyp->pkeydata.pkeydata_len = pkey.get_size();
01350 
01351                 /*
01352                  * Data
01353                  */
01354                 if (data.get_data() == datadata) {
01355                         ret = __os_umalloc(dbp->get_DB()->dbenv,
01356                              data.get_size(), &replyp->datadata.datadata_val);
01357                         if (ret != 0)
01358                                 goto err;
01359                         memcpy(replyp->datadata.datadata_val, data.get_data(),
01360                             data.get_size());
01361                 } else
01362                         replyp->datadata.datadata_val = (char *)data.get_data();
01363                 replyp->datadata.datadata_len = data.get_size();
01364         } else {
01365 err:            FREE_IF_CHANGED(dbp->get_DB()->dbenv,
01366                     skey.get_data(), skeydata);
01367                 FREE_IF_CHANGED(dbp->get_DB()->dbenv,
01368                     pkey.get_data(), pkeydata);
01369                 FREE_IF_CHANGED(dbp->get_DB()->dbenv,
01370                     data.get_data(), datadata);
01371                 FREE_IF_CHANGED(dbp->get_DB()->dbenv,
01372                     replyp->skeydata.skeydata_val, skey.get_data());
01373                 FREE_IF_CHANGED(dbp->get_DB()->dbenv,
01374                     replyp->pkeydata.pkeydata_val, pkey.get_data());
01375                 FREE_IF_CHANGED(dbp->get_DB()->dbenv,
01376                     replyp->datadata.datadata_val, data.get_data());
01377                 replyp->skeydata.skeydata_val = NULL;
01378                 replyp->skeydata.skeydata_len = 0;
01379                 replyp->pkeydata.pkeydata_val = NULL;
01380                 replyp->pkeydata.pkeydata_len = 0;
01381                 replyp->datadata.datadata_val = NULL;
01382                 replyp->datadata.datadata_len = 0;
01383                 *freep = 0;
01384         }
01385         replyp->status = ret;
01386         return;
01387 }
01388 
01389 extern "C" void
01390 __db_put_proc(
01391         u_int dbpcl_id,
01392         u_int txnpcl_id,
01393         u_int32_t keydlen,
01394         u_int32_t keydoff,
01395         u_int32_t keyulen,
01396         u_int32_t keyflags,
01397         void *keydata,
01398         u_int32_t keysize,
01399         u_int32_t datadlen,
01400         u_int32_t datadoff,
01401         u_int32_t dataulen,
01402         u_int32_t dataflags,
01403         void *datadata,
01404         u_int32_t datasize,
01405         u_int32_t flags,
01406         __db_put_reply *replyp,
01407         int * freep)
01408 {
01409         Db *dbp;
01410         DbTxn *txnp;
01411         ct_entry *dbp_ctp, *txnp_ctp;
01412         int ret;
01413 
01414         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01415         dbp = (Db *)dbp_ctp->ct_anyp;
01416         if (txnpcl_id != 0) {
01417                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
01418                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
01419         } else
01420                 txnp = NULL;
01421 
01422         replyp->keydata.keydata_val = NULL;
01423         *freep = 0;
01424 
01425         /* Set up key and data */
01426         Dbt key(keydata, keysize);
01427         key.set_dlen(keydlen);
01428         key.set_ulen(keyulen);
01429         key.set_doff(keydoff);
01430         key.set_flags(DB_DBT_MALLOC | (keyflags & DB_DBT_PARTIAL));
01431 
01432         Dbt data(datadata, datasize);
01433         data.set_dlen(datadlen);
01434         data.set_ulen(dataulen);
01435         data.set_doff(datadoff);
01436         data.set_flags(dataflags);
01437 
01438         /* Got all our stuff, now do the put */
01439         ret = dbp->put(txnp, &key, &data, flags);
01440         /*
01441          * If the client did a DB_APPEND, set up key in reply.
01442          * Otherwise just status.
01443          */
01444         if (ret == 0 && (flags == DB_APPEND)) {
01445                 /*
01446                  * XXX
01447                  * We need to xdr_free whatever we are returning, next time.
01448                  * However, DB does not allocate a new key if one was given
01449                  * and we'd be free'ing up space allocated in the request.
01450                  * So, allocate a new key/data pointer if it is the same one
01451                  * as in the request.
01452                  */
01453                 *freep = 1;
01454                 /*
01455                  * Key
01456                  */
01457                 if (key.get_data() == keydata) {
01458                         ret = __os_umalloc(dbp->get_DB()->dbenv,
01459                             key.get_size(), &replyp->keydata.keydata_val);
01460                         if (ret != 0)
01461                                 goto err;
01462                         memcpy(replyp->keydata.keydata_val,
01463                             key.get_data(), key.get_size());
01464                 } else
01465                         replyp->keydata.keydata_val = (char *)key.get_data();
01466 
01467                 replyp->keydata.keydata_len = key.get_size();
01468         } else {
01469 err:            FREE_IF_CHANGED(dbp->get_DB()->dbenv,
01470                     key.get_data(), keydata);
01471                 FREE_IF_CHANGED(dbp->get_DB()->dbenv,
01472                     replyp->keydata.keydata_val, key.get_data());
01473                 replyp->keydata.keydata_val = NULL;
01474                 replyp->keydata.keydata_len = 0;
01475                 *freep = 0;
01476         }
01477         replyp->status = ret;
01478         return;
01479 }
01480 
01481 extern "C" void
01482 __db_get_re_delim_proc(
01483         u_int dbpcl_id,
01484         __db_get_re_delim_reply *replyp)
01485 {
01486         Db *dbp;
01487         ct_entry *dbp_ctp;
01488 
01489         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01490         dbp = (Db *)dbp_ctp->ct_anyp;
01491 
01492         replyp->status = dbp->get_re_delim((int *)&replyp->delim);
01493 }
01494 
01495 extern "C" void
01496 __db_set_re_delim_proc(
01497         u_int dbpcl_id,
01498         u_int32_t delim,
01499         __db_set_re_delim_reply *replyp)
01500 {
01501         Db *dbp;
01502         ct_entry *dbp_ctp;
01503         int ret;
01504 
01505         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01506         dbp = (Db *)dbp_ctp->ct_anyp;
01507 
01508         ret = dbp->set_re_delim(delim);
01509 
01510         replyp->status = ret;
01511         return;
01512 }
01513 
01514 extern "C" void
01515 __db_get_re_len_proc(
01516         u_int dbpcl_id,
01517         __db_get_re_len_reply *replyp)
01518 {
01519         Db *dbp;
01520         ct_entry *dbp_ctp;
01521 
01522         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01523         dbp = (Db *)dbp_ctp->ct_anyp;
01524 
01525         replyp->status = dbp->get_re_len(&replyp->len);
01526 }
01527 
01528 extern "C" void
01529 __db_set_re_len_proc(
01530         u_int dbpcl_id,
01531         u_int32_t len,
01532         __db_set_re_len_reply *replyp)
01533 {
01534         Db *dbp;
01535         ct_entry *dbp_ctp;
01536         int ret;
01537 
01538         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01539         dbp = (Db *)dbp_ctp->ct_anyp;
01540 
01541         ret = dbp->set_re_len(len);
01542 
01543         replyp->status = ret;
01544         return;
01545 }
01546 
01547 void
01548 __db_get_re_pad_proc(
01549         u_int dbpcl_id,
01550         __db_get_re_pad_reply *replyp)
01551 {
01552         Db *dbp;
01553         ct_entry *dbp_ctp;
01554 
01555         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01556         dbp = (Db *)dbp_ctp->ct_anyp;
01557 
01558         replyp->status = dbp->get_re_pad((int *)&replyp->pad);
01559 }
01560 
01561 extern "C" void
01562 __db_set_re_pad_proc(
01563         u_int dbpcl_id,
01564         u_int32_t pad,
01565         __db_set_re_pad_reply *replyp)
01566 {
01567         Db *dbp;
01568         ct_entry *dbp_ctp;
01569         int ret;
01570 
01571         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01572         dbp = (Db *)dbp_ctp->ct_anyp;
01573 
01574         ret = dbp->set_re_pad(pad);
01575 
01576         replyp->status = ret;
01577         return;
01578 }
01579 
01580 extern "C" void
01581 __db_remove_proc(
01582         u_int dbpcl_id,
01583         char *name,
01584         char *subdb,
01585         u_int32_t flags,
01586         __db_remove_reply *replyp)
01587 {
01588         Db *dbp;
01589         ct_entry *dbp_ctp;
01590         int ret;
01591 
01592         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01593         dbp = (Db *)dbp_ctp->ct_anyp;
01594 
01595         ret = dbp->remove(name, subdb, flags);
01596         __dbdel_ctp(dbp_ctp);
01597 
01598         replyp->status = ret;
01599         return;
01600 }
01601 
01602 extern "C" void
01603 __db_rename_proc(
01604         u_int dbpcl_id,
01605         char *name,
01606         char *subdb,
01607         char *newname,
01608         u_int32_t flags,
01609         __db_rename_reply *replyp)
01610 {
01611         Db *dbp;
01612         ct_entry *dbp_ctp;
01613         int ret;
01614 
01615         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01616         dbp = (Db *)dbp_ctp->ct_anyp;
01617 
01618         ret = dbp->rename(name, subdb, newname, flags);
01619         __dbdel_ctp(dbp_ctp);
01620 
01621         replyp->status = ret;
01622         return;
01623 }
01624 
01625 extern "C" void
01626 __db_stat_proc(
01627         u_int dbpcl_id,
01628         u_int txnpcl_id,
01629         u_int32_t flags,
01630         __db_stat_reply *replyp,
01631         int * freep)
01632 {
01633         Db *dbp;
01634         DbTxn *txnp;
01635         DBTYPE type;
01636         ct_entry *dbp_ctp, *txnp_ctp;
01637         u_int32_t *q, *p, *retsp;
01638         int i, len, ret;
01639         void *sp;
01640 
01641         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01642         dbp = (Db *)dbp_ctp->ct_anyp;
01643         if (txnpcl_id != 0) {
01644                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
01645                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
01646         } else
01647                 txnp = NULL;
01648 
01649         ret = dbp->stat(txnp, &sp, flags);
01650         replyp->status = ret;
01651         if (ret != 0)
01652                 return;
01653         /*
01654          * We get here, we have success.  Allocate an array so that
01655          * we can use the list generator.  Generate the reply, free
01656          * up the space.
01657          */
01658         /*
01659          * XXX This assumes that all elements of all stat structures
01660          * are u_int32_t fields.  They are, currently.
01661          */
01662         (void)dbp->get_type(&type);
01663         if (type == DB_HASH)
01664                 len = sizeof(DB_HASH_STAT);
01665         else if (type == DB_QUEUE)
01666                 len = sizeof(DB_QUEUE_STAT);
01667         else            /* BTREE or RECNO are same stats */
01668                 len = sizeof(DB_BTREE_STAT);
01669         replyp->stats.stats_len = len / sizeof(u_int32_t);
01670 
01671         if ((ret = __os_umalloc(dbp->get_DB()->dbenv,
01672             len * replyp->stats.stats_len, &retsp)) != 0)
01673                 goto out;
01674         for (i = 0, q = retsp, p = (u_int32_t *)sp; i < len;
01675             i++, q++, p++)
01676                 *q = *p;
01677         replyp->stats.stats_val = retsp;
01678         __os_ufree(dbp->get_DB()->dbenv, sp);
01679         if (ret == 0)
01680                 *freep = 1;
01681 out:
01682         replyp->status = ret;
01683         return;
01684 }
01685 
01686 extern "C" void
01687 __db_sync_proc(
01688         u_int dbpcl_id,
01689         u_int32_t flags,
01690         __db_sync_reply *replyp)
01691 {
01692         Db *dbp;
01693         ct_entry *dbp_ctp;
01694         int ret;
01695 
01696         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01697         dbp = (Db *)dbp_ctp->ct_anyp;
01698 
01699         ret = dbp->sync(flags);
01700 
01701         replyp->status = ret;
01702         return;
01703 }
01704 
01705 extern "C" void
01706 __db_truncate_proc(
01707         u_int dbpcl_id,
01708         u_int txnpcl_id,
01709         u_int32_t flags,
01710         __db_truncate_reply *replyp)
01711 {
01712         Db *dbp;
01713         DbTxn *txnp;
01714         ct_entry *dbp_ctp, *txnp_ctp;
01715         u_int32_t count;
01716         int ret;
01717 
01718         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01719         dbp = (Db *)dbp_ctp->ct_anyp;
01720         if (txnpcl_id != 0) {
01721                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
01722                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
01723         } else
01724                 txnp = NULL;
01725 
01726         ret = dbp->truncate(txnp, &count, flags);
01727         replyp->status = ret;
01728         if (ret == 0)
01729                 replyp->count = count;
01730         return;
01731 }
01732 
01733 extern "C" void
01734 __db_cursor_proc(
01735         u_int dbpcl_id,
01736         u_int txnpcl_id,
01737         u_int32_t flags,
01738         __db_cursor_reply *replyp)
01739 {
01740         Db *dbp;
01741         Dbc *dbc;
01742         DbTxn *txnp;
01743         ct_entry *dbc_ctp, *env_ctp, *dbp_ctp, *txnp_ctp;
01744         int ret;
01745 
01746         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01747         dbp = (Db *)dbp_ctp->ct_anyp;
01748         dbc_ctp = new_ct_ent(&replyp->status);
01749         if (dbc_ctp == NULL)
01750                 return;
01751 
01752         if (txnpcl_id != 0) {
01753                 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
01754                 txnp = (DbTxn *)txnp_ctp->ct_anyp;
01755                 dbc_ctp->ct_activep = txnp_ctp->ct_activep;
01756         } else
01757                 txnp = NULL;
01758 
01759         if ((ret = dbp->cursor(txnp, &dbc, flags)) == 0) {
01760                 dbc_ctp->ct_dbc = dbc;
01761                 dbc_ctp->ct_type = CT_CURSOR;
01762                 dbc_ctp->ct_parent = dbp_ctp;
01763                 env_ctp = dbp_ctp->ct_envparent;
01764                 dbc_ctp->ct_envparent = env_ctp;
01765                 __dbsrv_settimeout(dbc_ctp, env_ctp->ct_timeout);
01766                 __dbsrv_active(dbc_ctp);
01767                 replyp->dbcidcl_id = dbc_ctp->ct_id;
01768         } else
01769                 __dbclear_ctp(dbc_ctp);
01770 
01771         replyp->status = ret;
01772         return;
01773 }
01774 
01775 extern "C" void
01776 __db_join_proc(
01777         u_int dbpcl_id,
01778         u_int32_t *curs,
01779         u_int32_t curslen,
01780         u_int32_t flags,
01781         __db_join_reply *replyp)
01782 {
01783         Db *dbp;
01784         Dbc **jcurs, **c;
01785         Dbc *dbc;
01786         ct_entry *dbc_ctp, *ctp, *dbp_ctp;
01787         size_t size;
01788         u_int32_t *cl, i;
01789         int ret;
01790 
01791         ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
01792         dbp = (Db *)dbp_ctp->ct_anyp;
01793 
01794         dbc_ctp = new_ct_ent(&replyp->status);
01795         if (dbc_ctp == NULL)
01796                 return;
01797 
01798         size = (curslen + 1) * sizeof(Dbc *);
01799         if ((ret = __os_calloc(dbp->get_DB()->dbenv,
01800             curslen + 1, sizeof(Dbc *), &jcurs)) != 0) {
01801                 replyp->status = ret;
01802                 __dbclear_ctp(dbc_ctp);
01803                 return;
01804         }
01805         /*
01806          * If our curslist has a parent txn, we need to use it too
01807          * for the activity timeout.  All cursors must be part of
01808          * the same transaction, so just check the first.
01809          */
01810         ctp = get_tableent(*curs);
01811         DB_ASSERT(ctp->ct_type == CT_CURSOR);
01812         /*
01813          * If we are using a transaction, set the join activity timer
01814          * to point to the parent transaction.
01815          */
01816         if (ctp->ct_activep != &ctp->ct_active)
01817                 dbc_ctp->ct_activep = ctp->ct_activep;
01818         for (i = 0, cl = curs, c = jcurs; i < curslen; i++, cl++, c++) {
01819                 ctp = get_tableent(*cl);
01820                 if (ctp == NULL) {
01821                         replyp->status = DB_NOSERVER_ID;
01822                         goto out;
01823                 }
01824                 /*
01825                  * If we are using a txn, the join cursor points to the
01826                  * transaction timeout.  If we are not using a transaction,
01827                  * then all the curslist cursors must point to the join
01828                  * cursor's timeout so that we do not timeout any of the
01829                  * curlist cursors while the join cursor is active.
01830                  * Change the type of the curslist ctps to CT_JOIN so that
01831                  * we know they are part of a join list and we can distinguish
01832                  * them and later restore them when the join cursor is closed.
01833                  */
01834                 DB_ASSERT(ctp->ct_type == CT_CURSOR);
01835                 ctp->ct_type |= CT_JOIN;
01836                 ctp->ct_origp = ctp->ct_activep;
01837                 /*
01838                  * Setting this to the ct_active field of the dbc_ctp is
01839                  * really just a way to distinguish which join dbc this
01840                  * cursor is part of.  The ct_activep of this cursor is
01841                  * not used at all during its lifetime as part of a join
01842                  * cursor.
01843                  */
01844                 ctp->ct_activep = &dbc_ctp->ct_active;
01845                 *c = ctp->ct_dbc;
01846         }
01847         *c = NULL;
01848         if ((ret = dbp->join(jcurs, &dbc, flags)) == 0) {
01849                 dbc_ctp->ct_dbc = dbc;
01850                 dbc_ctp->ct_type = (CT_JOINCUR | CT_CURSOR);
01851                 dbc_ctp->ct_parent = dbp_ctp;
01852                 dbc_ctp->ct_envparent = dbp_ctp->ct_envparent;
01853                 __dbsrv_settimeout(dbc_ctp, dbp_ctp->ct_envparent->ct_timeout);
01854                 __dbsrv_active(dbc_ctp);
01855                 replyp->dbcidcl_id = dbc_ctp->ct_id;
01856         } else {
01857                 __dbclear_ctp(dbc_ctp);
01858                 /*
01859                  * If we get an error, undo what we did above to any cursors.
01860                  */
01861                 for (cl = curs; *cl != 0; cl++) {
01862                         ctp = get_tableent(*cl);
01863                         ctp->ct_type = CT_CURSOR;
01864                         ctp->ct_activep = ctp->ct_origp;
01865                 }
01866         }
01867 
01868         replyp->status = ret;
01869 out:
01870         __os_free(dbp->get_DB()->dbenv, jcurs);
01871         return;
01872 }
01873 
01874 extern "C" void
01875 __dbc_c_close_proc(
01876         u_int dbccl_id,
01877         __dbc_c_close_reply *replyp)
01878 {
01879         ct_entry *dbc_ctp;
01880 
01881         ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
01882         replyp->status = __dbc_close_int(dbc_ctp);
01883         return;
01884 }
01885 
01886 extern "C" void
01887 __dbc_c_count_proc(
01888         u_int dbccl_id,
01889         u_int32_t flags,
01890         __dbc_c_count_reply *replyp)
01891 {
01892         Dbc *dbc;
01893         ct_entry *dbc_ctp;
01894         db_recno_t num;
01895         int ret;
01896 
01897         ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
01898         dbc = (Dbc *)dbc_ctp->ct_anyp;
01899 
01900         ret = dbc->count(&num, flags);
01901         replyp->status = ret;
01902         if (ret == 0)
01903                 replyp->dupcount = num;
01904         return;
01905 }
01906 
01907 extern "C" void
01908 __dbc_c_del_proc(
01909         u_int dbccl_id,
01910         u_int32_t flags,
01911         __dbc_c_del_reply *replyp)
01912 {
01913         Dbc *dbc;
01914         ct_entry *dbc_ctp;
01915         int ret;
01916 
01917         ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
01918         dbc = (Dbc *)dbc_ctp->ct_anyp;
01919 
01920         ret = dbc->del(flags);
01921 
01922         replyp->status = ret;
01923         return;
01924 }
01925 
01926 extern "C" void
01927 __dbc_c_dup_proc(
01928         u_int dbccl_id,
01929         u_int32_t flags,
01930         __dbc_c_dup_reply *replyp)
01931 {
01932         Dbc *dbc, *newdbc;
01933         ct_entry *dbc_ctp, *new_ctp;
01934         int ret;
01935 
01936         ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
01937         dbc = (Dbc *)dbc_ctp->ct_anyp;
01938 
01939         new_ctp = new_ct_ent(&replyp->status);
01940         if (new_ctp == NULL)
01941                 return;
01942 
01943         if ((ret = dbc->dup(&newdbc, flags)) == 0) {
01944                 new_ctp->ct_dbc = newdbc;
01945                 new_ctp->ct_type = CT_CURSOR;
01946                 new_ctp->ct_parent = dbc_ctp->ct_parent;
01947                 new_ctp->ct_envparent = dbc_ctp->ct_envparent;
01948                 /*
01949                  * If our cursor has a parent txn, we need to use it too.
01950                  */
01951                 if (dbc_ctp->ct_activep != &dbc_ctp->ct_active)
01952                         new_ctp->ct_activep = dbc_ctp->ct_activep;
01953                 __dbsrv_settimeout(new_ctp, dbc_ctp->ct_timeout);
01954                 __dbsrv_active(new_ctp);
01955                 replyp->dbcidcl_id = new_ctp->ct_id;
01956         } else
01957                 __dbclear_ctp(new_ctp);
01958 
01959         replyp->status = ret;
01960         return;
01961 }
01962 
01963 extern "C" void
01964 __dbc_c_get_proc(
01965         u_int dbccl_id,
01966         u_int32_t keydlen,
01967         u_int32_t keydoff,
01968         u_int32_t keyulen,
01969         u_int32_t keyflags,
01970         void *keydata,
01971         u_int32_t keysize,
01972         u_int32_t datadlen,
01973         u_int32_t datadoff,
01974         u_int32_t dataulen,
01975         u_int32_t dataflags,
01976         void *datadata,
01977         u_int32_t datasize,
01978         u_int32_t flags,
01979         __dbc_c_get_reply *replyp,
01980         int * freep)
01981 {
01982         Dbc *dbc;
01983         DbEnv *dbenv;
01984         ct_entry *dbc_ctp;
01985         int ret;
01986         void *tmpdata;
01987 
01988         ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
01989         dbc = (Dbc *)dbc_ctp->ct_anyp;
01990         dbenv = DbEnv::get_DbEnv(((DBC *)dbc)->dbp->dbenv);
01991 
01992         replyp->keydata.keydata_val = NULL;
01993         replyp->datadata.datadata_val = NULL;
01994         *freep = 0;
01995 
01996         /* Set up key and data */
01997         Dbt key(keydata, keysize);
01998         key.set_dlen(keydlen);
01999         key.set_ulen(keyulen);
02000         key.set_doff(keydoff);
02001         key.set_flags(DB_DBT_MALLOC | (keyflags & DB_DBT_PARTIAL));
02002 
02003         Dbt data(datadata, datasize);
02004         data.set_dlen(datadlen);
02005         data.set_ulen(dataulen);
02006         data.set_doff(datadoff);
02007         dataflags &= DB_DBT_PARTIAL;
02008         if (flags & DB_MULTIPLE || flags & DB_MULTIPLE_KEY) {
02009                 if (data.get_data() == NULL) {
02010                         ret = __os_umalloc(dbenv->get_DB_ENV(),
02011                             data.get_ulen(), &tmpdata);
02012                         if (ret != 0)
02013                                 goto err;
02014                         data.set_data(tmpdata);
02015                 }
02016                 dataflags |= DB_DBT_USERMEM;
02017         } else
02018                 dataflags |= DB_DBT_MALLOC;
02019         data.set_flags(dataflags);
02020 
02021         /* Got all our stuff, now do the get */
02022         ret = dbc->get(&key, &data, flags);
02023 
02024         /*
02025          * Otherwise just status.
02026          */
02027         if (ret == 0) {
02028                 /*
02029                  * XXX
02030                  * We need to xdr_free whatever we are returning, next time.
02031                  * However, DB does not allocate a new key if one was given
02032                  * and we'd be free'ing up space allocated in the request.
02033                  * So, allocate a new key/data pointer if it is the same one
02034                  * as in the request.
02035                  */
02036                 *freep = 1;
02037                 /*
02038                  * Key
02039                  */
02040                 if (key.get_data() == keydata) {
02041                         ret = __os_umalloc(dbenv->get_DB_ENV(), key.get_size(),
02042                             &replyp->keydata.keydata_val);
02043                         if (ret != 0)
02044                                 goto err;
02045                         memcpy(replyp->keydata.keydata_val,
02046                             key.get_data(), key.get_size());
02047                 } else
02048                         replyp->keydata.keydata_val = (char *)key.get_data();
02049 
02050                 replyp->keydata.keydata_len = key.get_size();
02051 
02052                 /*
02053                  * Data
02054                  */
02055                 if (data.get_data() == datadata) {
02056                         ret = __os_umalloc(dbenv->get_DB_ENV(), data.get_size(),
02057                             &replyp->datadata.datadata_val);
02058                         if (ret != 0)
02059                                 goto err;
02060                         memcpy(replyp->datadata.datadata_val, data.get_data(),
02061                             data.get_size());
02062                 } else
02063                         replyp->datadata.datadata_val = (char *)data.get_data();
02064                 replyp->datadata.datadata_len = data.get_size();
02065         } else {
02066 err:            FREE_IF_CHANGED(dbenv->get_DB_ENV(),
02067                     key.get_data(), keydata);
02068                 FREE_IF_CHANGED(dbenv->get_DB_ENV(),
02069                     data.get_data(), datadata);
02070                 FREE_IF_CHANGED(dbenv->get_DB_ENV(),
02071                     replyp->keydata.keydata_val, key.get_data());
02072                 FREE_IF_CHANGED(dbenv->get_DB_ENV(),
02073                     replyp->datadata.datadata_val, data.get_data());
02074                 replyp->keydata.keydata_val = NULL;
02075                 replyp->keydata.keydata_len = 0;
02076                 replyp->datadata.datadata_val = NULL;
02077                 replyp->datadata.datadata_len = 0;
02078                 *freep = 0;
02079         }
02080         replyp->status = ret;
02081         return;
02082 }
02083 
02084 extern "C" void
02085 __dbc_c_pget_proc(
02086         u_int dbccl_id,
02087         u_int32_t skeydlen,
02088         u_int32_t skeydoff,
02089         u_int32_t skeyulen,
02090         u_int32_t skeyflags,
02091         void *skeydata,
02092         u_int32_t skeysize,
02093         u_int32_t pkeydlen,
02094         u_int32_t pkeydoff,
02095         u_int32_t pkeyulen,
02096         u_int32_t pkeyflags,
02097         void *pkeydata,
02098         u_int32_t pkeysize,
02099         u_int32_t datadlen,
02100         u_int32_t datadoff,
02101         u_int32_t dataulen,
02102         u_int32_t dataflags,
02103         void *datadata,
02104         u_int32_t datasize,
02105         u_int32_t flags,
02106         __dbc_c_pget_reply *replyp,
02107         int * freep)
02108 {
02109         Dbc *dbc;
02110         DbEnv *dbenv;
02111         ct_entry *dbc_ctp;
02112         int ret;
02113 
02114         ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
02115         dbc = (Dbc *)dbc_ctp->ct_anyp;
02116         dbenv = DbEnv::get_DbEnv(((DBC *)dbc)->dbp->dbenv);
02117 
02118         replyp->skeydata.skeydata_val = NULL;
02119         replyp->pkeydata.pkeydata_val = NULL;
02120         replyp->datadata.datadata_val = NULL;
02121         *freep = 0;
02122 
02123         /*
02124          * Ignore memory related flags on server.
02125          */
02126         /* Set up key and data */
02127         Dbt skey(skeydata, skeysize);
02128         skey.set_dlen(skeydlen);
02129         skey.set_ulen(skeyulen);
02130         skey.set_doff(skeydoff);
02131         skey.set_flags(DB_DBT_MALLOC | (skeyflags & DB_DBT_PARTIAL));
02132 
02133         Dbt pkey(pkeydata, pkeysize);
02134         pkey.set_dlen(pkeydlen);
02135         pkey.set_ulen(pkeyulen);
02136         pkey.set_doff(pkeydoff);
02137         pkey.set_flags(DB_DBT_MALLOC | (pkeyflags & DB_DBT_PARTIAL));
02138 
02139         Dbt data(datadata, datasize);
02140         data.set_dlen(datadlen);
02141         data.set_ulen(dataulen);
02142         data.set_doff(datadoff);
02143         data.set_flags(DB_DBT_MALLOC | (dataflags & DB_DBT_PARTIAL));
02144 
02145         /* Got all our stuff, now do the get */
02146         ret = dbc->pget(&skey, &pkey, &data, flags);
02147         /*
02148          * Otherwise just status.
02149          */
02150         if (ret == 0) {
02151                 /*
02152                  * XXX
02153                  * We need to xdr_free whatever we are returning, next time.
02154                  * However, DB does not allocate a new key if one was given
02155                  * and we'd be free'ing up space allocated in the request.
02156                  * So, allocate a new key/data pointer if it is the same one
02157                  * as in the request.
02158                  */
02159                 *freep = 1;
02160                 /*
02161                  * Key
02162                  */
02163                 if (skey.get_data() == skeydata) {
02164                         ret = __os_umalloc(dbenv->get_DB_ENV(),
02165                             skey.get_size(), &replyp->skeydata.skeydata_val);
02166                         if (ret != 0)
02167                                 goto err;
02168                         memcpy(replyp->skeydata.skeydata_val, skey.get_data(),
02169                             skey.get_size());
02170                 } else
02171                         replyp->skeydata.skeydata_val = (char *)skey.get_data();
02172                 replyp->skeydata.skeydata_len = skey.get_size();
02173 
02174                 /*
02175                  * Primary key
02176                  */
02177                 if (pkey.get_data() == pkeydata) {
02178                         ret = __os_umalloc(dbenv->get_DB_ENV(),
02179                              pkey.get_size(), &replyp->pkeydata.pkeydata_val);
02180                         if (ret != 0)
02181                                 goto err;
02182                         memcpy(replyp->pkeydata.pkeydata_val, pkey.get_data(),
02183                             pkey.get_size());
02184                 } else
02185                         replyp->pkeydata.pkeydata_val = (char *)pkey.get_data();
02186                 replyp->pkeydata.pkeydata_len = pkey.get_size();
02187 
02188                 /*
02189                  * Data
02190                  */
02191                 if (data.get_data() == datadata) {
02192                         ret = __os_umalloc(dbenv->get_DB_ENV(),
02193                              data.get_size(), &replyp->datadata.datadata_val);
02194                         if (ret != 0)
02195                                 goto err;
02196                         memcpy(replyp->datadata.datadata_val, data.get_data(),
02197                             data.get_size());
02198                 } else
02199                         replyp->datadata.datadata_val = (char *)data.get_data();
02200                 replyp->datadata.datadata_len = data.get_size();
02201         } else {
02202 err:            FREE_IF_CHANGED(dbenv->get_DB_ENV(),
02203                     skey.get_data(), skeydata);
02204                 FREE_IF_CHANGED(dbenv->get_DB_ENV(),
02205                     pkey.get_data(), pkeydata);
02206                 FREE_IF_CHANGED(dbenv->get_DB_ENV(),
02207                     data.get_data(), datadata);
02208                 FREE_IF_CHANGED(dbenv->get_DB_ENV(),
02209                     replyp->skeydata.skeydata_val, skey.get_data());
02210                 FREE_IF_CHANGED(dbenv->get_DB_ENV(),
02211                     replyp->pkeydata.pkeydata_val, pkey.get_data());
02212                 FREE_IF_CHANGED(dbenv->get_DB_ENV(),
02213                     replyp->datadata.datadata_val, data.get_data());
02214                 replyp->skeydata.skeydata_val = NULL;
02215                 replyp->skeydata.skeydata_len = 0;
02216                 replyp->pkeydata.pkeydata_val = NULL;
02217                 replyp->pkeydata.pkeydata_len = 0;
02218                 replyp->datadata.datadata_val = NULL;
02219                 replyp->datadata.datadata_len = 0;
02220                 *freep = 0;
02221         }
02222         replyp->status = ret;
02223         return;
02224 }
02225 
02226 extern "C" void
02227 __dbc_c_put_proc(
02228         u_int dbccl_id,
02229         u_int32_t keydlen,
02230         u_int32_t keydoff,
02231         u_int32_t keyulen,
02232         u_int32_t keyflags,
02233         void *keydata,
02234         u_int32_t keysize,
02235         u_int32_t datadlen,
02236         u_int32_t datadoff,
02237         u_int32_t dataulen,
02238         u_int32_t dataflags,
02239         void *datadata,
02240         u_int32_t datasize,
02241         u_int32_t flags,
02242         __dbc_c_put_reply *replyp,
02243         int * freep)
02244 {
02245         Db *dbp;
02246         Dbc *dbc;
02247         ct_entry *dbc_ctp;
02248         int ret;
02249         DBTYPE dbtype;
02250 
02251         ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
02252         dbc = (Dbc *)dbc_ctp->ct_anyp;
02253         dbp = (Db *)dbc_ctp->ct_parent->ct_anyp;
02254 
02255         /* Set up key and data */
02256         Dbt key(keydata, keysize);
02257         key.set_dlen(keydlen);
02258         key.set_ulen(keyulen);
02259         key.set_doff(keydoff);
02260         /*
02261          * Ignore memory related flags on server.
02262          */
02263         key.set_flags(DB_DBT_MALLOC | (keyflags & DB_DBT_PARTIAL));
02264 
02265         Dbt data(datadata, datasize);
02266         data.set_dlen(datadlen);
02267         data.set_ulen(dataulen);
02268         data.set_doff(datadoff);
02269         data.set_flags(dataflags);
02270 
02271         /* Got all our stuff, now do the put */
02272         ret = dbc->put(&key, &data, flags);
02273 
02274         *freep = 0;
02275         replyp->keydata.keydata_val = NULL;
02276         replyp->keydata.keydata_len = 0;
02277         if (ret == 0 && (flags == DB_AFTER || flags == DB_BEFORE)) {
02278                 ret = dbp->get_type(&dbtype);
02279                 if (ret == 0 && dbtype == DB_RECNO) {
02280                         /*
02281                          * We need to xdr_free whatever we are returning, next
02282                          * time.
02283                          */
02284                         replyp->keydata.keydata_val = (char *)key.get_data();
02285                         replyp->keydata.keydata_len = key.get_size();
02286                 }
02287         }
02288         replyp->status = ret;
02289         return;
02290 }

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