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

db_server_proc.c

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

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