1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2000,2008 Oracle. All rights reserved. 5 * 6 * $Id: db_server_proc.c,v 12.25 2008/01/08 20:58:50 bostic Exp $ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12#ifdef HAVE_SYSTEM_INCLUDE_FILES 13#include <rpc/rpc.h> 14#endif 15#include "db_server.h" 16#include "dbinc/db_server_int.h" 17#include "dbinc_auto/rpc_server_ext.h" 18 19/* 20 * PUBLIC: void __env_get_cachesize_proc __P((u_int, 21 * PUBLIC: __env_get_cachesize_reply *)); 22 */ 23void 24__env_get_cachesize_proc(dbenvcl_id, replyp) 25 u_int dbenvcl_id; 26 __env_get_cachesize_reply *replyp; 27{ 28 DB_ENV *dbenv; 29 ct_entry *dbenv_ctp; 30 31 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 32 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 33 34 replyp->status = dbenv->get_cachesize(dbenv, &replyp->gbytes, 35 &replyp->bytes, (int *)&replyp->ncache); 36} 37 38/* 39 * PUBLIC: void __env_set_cachesize_proc __P((u_int, u_int32_t, u_int32_t, 40 * PUBLIC: u_int32_t, __env_set_cachesize_reply *)); 41 */ 42void 43__env_set_cachesize_proc(dbenvcl_id, gbytes, bytes, ncache, replyp) 44 u_int dbenvcl_id; 45 u_int32_t gbytes; 46 u_int32_t bytes; 47 u_int32_t ncache; 48 __env_set_cachesize_reply *replyp; 49{ 50 DB_ENV *dbenv; 51 ct_entry *dbenv_ctp; 52 int ret; 53 54 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 55 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 56 57 ret = dbenv->set_cachesize(dbenv, gbytes, bytes, ncache); 58 59 replyp->status = ret; 60 return; 61} 62 63/* 64 * PUBLIC: void __env_cdsgroup_begin_proc __P((u_int, 65 * PUBLIC: __env_cdsgroup_begin_reply *)); 66 */ 67void 68__env_cdsgroup_begin_proc(dbenvcl_id, replyp) 69 u_int dbenvcl_id; 70 __env_cdsgroup_begin_reply *replyp; 71{ 72 DB_ENV *dbenv; 73 DB_TXN *txnp; 74 ct_entry *ctp, *dbenv_ctp; 75 int ret; 76 77 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 78 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 79 80 ctp = new_ct_ent(&replyp->status); 81 if (ctp == NULL) 82 return; 83 84 ret = dbenv->cdsgroup_begin(dbenv, &txnp); 85 if (ret == 0) { 86 ctp->ct_txnp = txnp; 87 ctp->ct_type = CT_TXN; 88 ctp->ct_parent = NULL; 89 ctp->ct_envparent = dbenv_ctp; 90 replyp->txnidcl_id = ctp->ct_id; 91 __dbsrv_settimeout(ctp, dbenv_ctp->ct_timeout); 92 __dbsrv_active(ctp); 93 } else 94 __dbclear_ctp(ctp); 95 96 replyp->status = ret; 97 return; 98} 99 100/* 101 * PUBLIC: void __env_close_proc __P((u_int, u_int32_t, __env_close_reply *)); 102 */ 103void 104__env_close_proc(dbenvcl_id, flags, replyp) 105 u_int dbenvcl_id; 106 u_int32_t flags; 107 __env_close_reply *replyp; 108{ 109 ct_entry *dbenv_ctp; 110 111 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 112 replyp->status = __env_close_int(dbenvcl_id, flags, 0); 113 return; 114} 115 116/* 117 * PUBLIC: void __env_create_proc __P((u_int32_t, __env_create_reply *)); 118 */ 119void 120__env_create_proc(timeout, replyp) 121 u_int32_t timeout; 122 __env_create_reply *replyp; 123{ 124 DB_ENV *dbenv; 125 ct_entry *ctp; 126 int ret; 127 128 ctp = new_ct_ent(&replyp->status); 129 if (ctp == NULL) 130 return; 131 if ((ret = db_env_create(&dbenv, 0)) == 0) { 132 ctp->ct_envp = dbenv; 133 ctp->ct_type = CT_ENV; 134 ctp->ct_parent = NULL; 135 ctp->ct_envparent = ctp; 136 __dbsrv_settimeout(ctp, timeout); 137 __dbsrv_active(ctp); 138 replyp->envcl_id = ctp->ct_id; 139 } else 140 __dbclear_ctp(ctp); 141 142 replyp->status = ret; 143 return; 144} 145 146/* 147 * PUBLIC: void __env_dbremove_proc __P((u_int, u_int, char *, char *, 148 * PUBLIC: u_int32_t, __env_dbremove_reply *)); 149 */ 150void 151__env_dbremove_proc(dbenvcl_id, txnpcl_id, name, subdb, flags, replyp) 152 u_int dbenvcl_id; 153 u_int txnpcl_id; 154 char *name; 155 char *subdb; 156 u_int32_t flags; 157 __env_dbremove_reply *replyp; 158{ 159 int ret; 160 DB_ENV * dbenv; 161 ct_entry *dbenv_ctp; 162 DB_TXN * txnp; 163 ct_entry *txnp_ctp; 164 165 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 166 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 167 168 if (txnpcl_id != 0) { 169 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 170 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 171 } else 172 txnp = NULL; 173 174 ret = dbenv->dbremove(dbenv, txnp, name, subdb, flags); 175 176 replyp->status = ret; 177 return; 178} 179 180/* 181 * PUBLIC: void __env_dbrename_proc __P((u_int, u_int, char *, char *, char *, 182 * PUBLIC: u_int32_t, __env_dbrename_reply *)); 183 */ 184void 185__env_dbrename_proc(dbenvcl_id, txnpcl_id, name, subdb, newname, flags, replyp) 186 u_int dbenvcl_id; 187 u_int txnpcl_id; 188 char *name; 189 char *subdb; 190 char *newname; 191 u_int32_t flags; 192 __env_dbrename_reply *replyp; 193{ 194 int ret; 195 DB_ENV * dbenv; 196 ct_entry *dbenv_ctp; 197 DB_TXN * txnp; 198 ct_entry *txnp_ctp; 199 200 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 201 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 202 203 if (txnpcl_id != 0) { 204 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 205 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 206 } else 207 txnp = NULL; 208 209 ret = dbenv->dbrename(dbenv, txnp, name, subdb, newname, flags); 210 211 replyp->status = ret; 212 return; 213} 214 215/* 216 * PUBLIC: void __env_get_encrypt_flags_proc __P((u_int, 217 * PUBLIC: __env_get_encrypt_flags_reply *)); 218 */ 219void 220__env_get_encrypt_flags_proc(dbenvcl_id, replyp) 221 u_int dbenvcl_id; 222 __env_get_encrypt_flags_reply *replyp; 223{ 224 DB_ENV *dbenv; 225 ct_entry *dbenv_ctp; 226 227 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 228 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 229 230 replyp->status = dbenv->get_encrypt_flags(dbenv, &replyp->flags); 231} 232 233/* 234 * PUBLIC: void __env_set_encrypt_proc __P((u_int, char *, u_int32_t, 235 * PUBLIC: __env_set_encrypt_reply *)); 236 */ 237void 238__env_set_encrypt_proc(dbenvcl_id, passwd, flags, replyp) 239 u_int dbenvcl_id; 240 char *passwd; 241 u_int32_t flags; 242 __env_set_encrypt_reply *replyp; 243{ 244 int ret; 245 DB_ENV * dbenv; 246 ct_entry *dbenv_ctp; 247 248 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 249 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 250 251 ret = dbenv->set_encrypt(dbenv, passwd, flags); 252 253 replyp->status = ret; 254 return; 255} 256 257/* 258 * PUBLIC: void __env_get_flags_proc __P((u_int, __env_get_flags_reply *)); 259 */ 260void 261__env_get_flags_proc(dbenvcl_id, replyp) 262 u_int dbenvcl_id; 263 __env_get_flags_reply *replyp; 264{ 265 DB_ENV *dbenv; 266 ct_entry *dbenv_ctp; 267 268 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 269 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 270 271 replyp->status = dbenv->get_flags(dbenv, &replyp->flags); 272} 273 274/* 275 * PUBLIC: void __env_set_flags_proc __P((u_int, u_int32_t, u_int32_t, 276 * PUBLIC: __env_set_flags_reply *)); 277 */ 278void 279__env_set_flags_proc(dbenvcl_id, flags, onoff, replyp) 280 u_int dbenvcl_id; 281 u_int32_t flags; 282 u_int32_t onoff; 283 __env_set_flags_reply *replyp; 284{ 285 DB_ENV *dbenv; 286 ct_entry *dbenv_ctp; 287 int ret; 288 289 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 290 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 291 292 ret = dbenv->set_flags(dbenv, flags, onoff); 293 if (onoff) 294 dbenv_ctp->ct_envdp.onflags = flags; 295 else 296 dbenv_ctp->ct_envdp.offflags = flags; 297 298 replyp->status = ret; 299 return; 300} 301 302/* 303 * PUBLIC: void __env_get_home_proc __P((u_int, __env_get_home_reply *)); 304 */ 305void 306__env_get_home_proc(dbenvcl_id, replyp) 307 u_int dbenvcl_id; 308 __env_get_home_reply *replyp; 309{ 310 DB_ENV *dbenv; 311 ct_entry *dbenv_ctp; 312 313 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 314 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 315 316 replyp->status = dbenv->get_home(dbenv, 317 (const char **)&replyp->home); 318} 319 320/* 321 * PUBLIC: void __env_get_open_flags_proc __P((u_int, 322 * PUBLIC: __env_get_open_flags_reply *)); 323 */ 324void 325__env_get_open_flags_proc(dbenvcl_id, replyp) 326 u_int dbenvcl_id; 327 __env_get_open_flags_reply *replyp; 328{ 329 DB_ENV *dbenv; 330 ct_entry *dbenv_ctp; 331 332 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 333 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 334 335 replyp->status = dbenv->get_open_flags(dbenv, &replyp->flags); 336} 337 338/* 339 * PUBLIC: void __env_open_proc __P((u_int, char *, u_int32_t, u_int32_t, 340 * PUBLIC: __env_open_reply *)); 341 */ 342void 343__env_open_proc(dbenvcl_id, home, flags, mode, replyp) 344 u_int dbenvcl_id; 345 char *home; 346 u_int32_t flags; 347 u_int32_t mode; 348 __env_open_reply *replyp; 349{ 350 DB_ENV *dbenv; 351 ct_entry *dbenv_ctp, *new_ctp; 352 u_int32_t newflags, shareflags; 353 int ret; 354 home_entry *fullhome; 355 356 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 357 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 358 fullhome = get_fullhome(home); 359 if (fullhome == NULL) { 360 ret = DB_NOSERVER_HOME; 361 goto out; 362 } 363 364 /* 365 * If they are using locking do deadlock detection for them, 366 * internally. 367 */ 368 if ((flags & DB_INIT_LOCK) && 369 (ret = dbenv->set_lk_detect(dbenv, DB_LOCK_DEFAULT)) != 0) 370 goto out; 371 372 if (__dbsrv_verbose) { 373 dbenv->set_errfile(dbenv, stderr); 374 dbenv->set_errpfx(dbenv, fullhome->home); 375 } else 376 dbenv->set_errfile(dbenv, NULL); 377 378 /* 379 * Mask off flags we ignore 380 */ 381 newflags = (flags & ~DB_SERVER_FLAGMASK); 382 shareflags = (newflags & DB_SERVER_ENVFLAGS); 383 /* 384 * Check now whether we can share a handle for this env. 385 */ 386 replyp->envcl_id = dbenvcl_id; 387 if ((new_ctp = __dbsrv_shareenv(dbenv_ctp, fullhome, shareflags)) 388 != NULL) { 389 /* 390 * We can share, clean up old ID, set new one. 391 */ 392 if (__dbsrv_verbose) 393 printf("Sharing env ID %ld\n", new_ctp->ct_id); 394 replyp->envcl_id = new_ctp->ct_id; 395 ret = __env_close_int(dbenvcl_id, 0, 0); 396 } else { 397 ret = dbenv->open(dbenv, fullhome->home, newflags, mode); 398 dbenv_ctp->ct_envdp.home = fullhome; 399 dbenv_ctp->ct_envdp.envflags = shareflags; 400 } 401out: replyp->status = ret; 402 return; 403} 404 405/* 406 * PUBLIC: void __env_remove_proc __P((u_int, char *, u_int32_t, 407 * PUBLIC: __env_remove_reply *)); 408 */ 409void 410__env_remove_proc(dbenvcl_id, home, flags, replyp) 411 u_int dbenvcl_id; 412 char *home; 413 u_int32_t flags; 414 __env_remove_reply *replyp; 415{ 416 DB_ENV *dbenv; 417 ct_entry *dbenv_ctp; 418 int ret; 419 home_entry *fullhome; 420 421 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 422 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 423 424 fullhome = get_fullhome(home); 425 if (fullhome == NULL) { 426 replyp->status = DB_NOSERVER_HOME; 427 return; 428 } 429 430 ret = dbenv->remove(dbenv, fullhome->home, flags); 431 __dbdel_ctp(dbenv_ctp); 432 replyp->status = ret; 433 return; 434} 435 436/* 437 * PUBLIC: void __txn_abort_proc __P((u_int, __txn_abort_reply *)); 438 */ 439void 440__txn_abort_proc(txnpcl_id, replyp) 441 u_int txnpcl_id; 442 __txn_abort_reply *replyp; 443{ 444 DB_TXN *txnp; 445 ct_entry *txnp_ctp; 446 int ret; 447 448 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 449 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 450 451 ret = txnp->abort(txnp); 452 __dbdel_ctp(txnp_ctp); 453 replyp->status = ret; 454 return; 455} 456 457/* 458 * PUBLIC: void __env_txn_begin_proc __P((u_int, u_int, u_int32_t, 459 * PUBLIC: __env_txn_begin_reply *)); 460 */ 461void 462__env_txn_begin_proc(dbenvcl_id, parentcl_id, flags, replyp) 463 u_int dbenvcl_id; 464 u_int parentcl_id; 465 u_int32_t flags; 466 __env_txn_begin_reply *replyp; 467{ 468 DB_ENV *dbenv; 469 DB_TXN *parent, *txnp; 470 ct_entry *ctp, *dbenv_ctp, *parent_ctp; 471 int ret; 472 473 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 474 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 475 parent_ctp = NULL; 476 477 ctp = new_ct_ent(&replyp->status); 478 if (ctp == NULL) 479 return; 480 481 if (parentcl_id != 0) { 482 ACTIVATE_CTP(parent_ctp, parentcl_id, CT_TXN); 483 parent = (DB_TXN *)parent_ctp->ct_anyp; 484 ctp->ct_activep = parent_ctp->ct_activep; 485 } else 486 parent = NULL; 487 488 /* 489 * Need to set DB_TXN_NOWAIT or the RPC server may deadlock 490 * itself and no one can break the lock. 491 */ 492 ret = dbenv->txn_begin(dbenv, parent, &txnp, flags | DB_TXN_NOWAIT); 493 if (ret == 0) { 494 ctp->ct_txnp = txnp; 495 ctp->ct_type = CT_TXN; 496 ctp->ct_parent = parent_ctp; 497 ctp->ct_envparent = dbenv_ctp; 498 replyp->txnidcl_id = ctp->ct_id; 499 __dbsrv_settimeout(ctp, dbenv_ctp->ct_timeout); 500 __dbsrv_active(ctp); 501 } else 502 __dbclear_ctp(ctp); 503 504 replyp->status = ret; 505 return; 506} 507 508/* 509 * PUBLIC: void __txn_commit_proc __P((u_int, u_int32_t, 510 * PUBLIC: __txn_commit_reply *)); 511 */ 512void 513__txn_commit_proc(txnpcl_id, flags, replyp) 514 u_int txnpcl_id; 515 u_int32_t flags; 516 __txn_commit_reply *replyp; 517{ 518 DB_TXN *txnp; 519 ct_entry *txnp_ctp; 520 int ret; 521 522 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 523 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 524 525 ret = txnp->commit(txnp, flags); 526 __dbdel_ctp(txnp_ctp); 527 528 replyp->status = ret; 529 return; 530} 531 532/* 533 * PUBLIC: void __txn_discard_proc __P((u_int, u_int32_t, 534 * PUBLIC: __txn_discard_reply *)); 535 */ 536void 537__txn_discard_proc(txnpcl_id, flags, replyp) 538 u_int txnpcl_id; 539 u_int32_t flags; 540 __txn_discard_reply *replyp; 541{ 542 DB_TXN *txnp; 543 ct_entry *txnp_ctp; 544 int ret; 545 546 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 547 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 548 549 ret = txnp->discard(txnp, flags); 550 __dbdel_ctp(txnp_ctp); 551 552 replyp->status = ret; 553 return; 554} 555 556/* 557 * PUBLIC: void __txn_prepare_proc __P((u_int, u_int8_t *, 558 * PUBLIC: __txn_prepare_reply *)); 559 */ 560void 561__txn_prepare_proc(txnpcl_id, gid, replyp) 562 u_int txnpcl_id; 563 u_int8_t *gid; 564 __txn_prepare_reply *replyp; 565{ 566 DB_TXN *txnp; 567 ct_entry *txnp_ctp; 568 int ret; 569 570 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 571 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 572 573 ret = txnp->prepare(txnp, gid); 574 replyp->status = ret; 575 return; 576} 577 578/* 579 * PUBLIC: void __env_txn_recover_proc __P((u_int, u_int32_t, u_int32_t, 580 * PUBLIC: __env_txn_recover_reply *, int *)); 581 */ 582void 583__env_txn_recover_proc(dbenvcl_id, count, flags, replyp, freep) 584 u_int dbenvcl_id; 585 u_int32_t count; 586 u_int32_t flags; 587 __env_txn_recover_reply *replyp; 588 int * freep; 589{ 590 DB_ENV *dbenv; 591 DB_PREPLIST *dbprep, *p; 592 ENV *env; 593 ct_entry *dbenv_ctp, *ctp; 594 long erri, i, retcount; 595 u_int32_t *txnidp; 596 int ret; 597 u_int8_t *gid; 598 599 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 600 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 601 env = dbenv->env; 602 dbprep = NULL; 603 *freep = 0; 604 605 if ((ret = __os_malloc(env, count * sizeof(DB_PREPLIST), &dbprep)) != 0) 606 goto out; 607 if ((ret = 608 dbenv->txn_recover(dbenv, dbprep, count, &retcount, flags)) != 0) 609 goto out; 610 /* 611 * If there is nothing, success, but it's easy. 612 */ 613 replyp->retcount = retcount; 614 if (retcount == 0) { 615 replyp->txn.txn_val = NULL; 616 replyp->txn.txn_len = 0; 617 replyp->gid.gid_val = NULL; 618 replyp->gid.gid_len = 0; 619 } 620 621 /* 622 * We have our txn list. Now we need to allocate the space for 623 * the txn ID array and the GID array and set them up. 624 */ 625 if ((ret = __os_calloc( 626 env, retcount, sizeof(u_int32_t), &replyp->txn.txn_val)) != 0) 627 goto out; 628 replyp->txn.txn_len = retcount * sizeof(u_int32_t); 629 if ((ret = __os_calloc( 630 env, retcount, DB_XIDDATASIZE, &replyp->gid.gid_val)) != 0) { 631 __os_free(env, replyp->txn.txn_val); 632 goto out; 633 } 634 replyp->gid.gid_len = retcount * DB_XIDDATASIZE; 635 636 /* 637 * Now walk through our results, creating parallel arrays 638 * to send back. For each entry we need to create a new 639 * txn ctp and then fill in the array info. 640 */ 641 i = 0; 642 p = dbprep; 643 gid = replyp->gid.gid_val; 644 txnidp = replyp->txn.txn_val; 645 while (i++ < retcount) { 646 ctp = new_ct_ent(&ret); 647 if (ret != 0) { 648 i--; 649 goto out2; 650 } 651 ctp->ct_txnp = p->txn; 652 ctp->ct_type = CT_TXN; 653 ctp->ct_parent = NULL; 654 ctp->ct_envparent = dbenv_ctp; 655 __dbsrv_settimeout(ctp, dbenv_ctp->ct_timeout); 656 __dbsrv_active(ctp); 657 658 *txnidp = ctp->ct_id; 659 memcpy(gid, p->gid, DB_XIDDATASIZE); 660 661 p++; 662 txnidp++; 663 gid += DB_XIDDATASIZE; 664 } 665 /* 666 * If we get here, we have success and we have to set freep 667 * so it'll get properly freed next time. 668 */ 669 *freep = 1; 670out: 671 if (dbprep != NULL) 672 __os_free(env, dbprep); 673 replyp->status = ret; 674 return; 675out2: 676 /* 677 * We had an error in the middle of creating our new txn 678 * ct entries. We have to unwind all that we have done. Ugh. 679 */ 680 for (txnidp = replyp->txn.txn_val, erri = 0; 681 erri < i; erri++, txnidp++) { 682 ctp = get_tableent(*txnidp); 683 __dbclear_ctp(ctp); 684 } 685 __os_free(env, replyp->txn.txn_val); 686 __os_free(env, replyp->gid.gid_val); 687 __os_free(env, dbprep); 688 replyp->status = ret; 689 return; 690} 691 692/* 693 * PUBLIC: void __db_associate_proc __P((u_int, u_int, u_int, u_int32_t, 694 * PUBLIC: __db_associate_reply *)); 695 */ 696void 697__db_associate_proc(dbpcl_id, txnpcl_id, sdbpcl_id, flags, replyp) 698 u_int dbpcl_id; 699 u_int txnpcl_id; 700 u_int sdbpcl_id; 701 u_int32_t flags; 702 __db_associate_reply *replyp; 703{ 704 DB *dbp, *sdbp; 705 DB_TXN *txnp; 706 ct_entry *dbp_ctp, *sdbp_ctp, *txnp_ctp; 707 int ret; 708 709 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 710 dbp = (DB *)dbp_ctp->ct_anyp; 711 ACTIVATE_CTP(sdbp_ctp, sdbpcl_id, CT_DB); 712 sdbp = (DB *)sdbp_ctp->ct_anyp; 713 if (txnpcl_id != 0) { 714 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 715 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 716 } else 717 txnp = NULL; 718 719 /* 720 * We do not support DB_CREATE for associate or the callbacks 721 * implemented in the Java and JE RPC servers. Users can only 722 * access secondary indices on a read-only basis, so whatever they 723 * are looking for needs to be there already. 724 */ 725#ifdef CONFIG_TEST 726 if (LF_ISSET(DB_RPC2ND_MASK | DB_CREATE)) 727#else 728 if (LF_ISSET(DB_CREATE)) 729#endif 730 ret = EINVAL; 731 else 732 ret = dbp->associate(dbp, txnp, sdbp, NULL, flags); 733 734 replyp->status = ret; 735 return; 736} 737 738/* 739 * PUBLIC: void __db_get_bt_minkey_proc __P((u_int, 740 * PUBLIC: __db_get_bt_minkey_reply *)); 741 */ 742void 743__db_get_bt_minkey_proc(dbpcl_id, replyp) 744 u_int dbpcl_id; 745 __db_get_bt_minkey_reply *replyp; 746{ 747 DB *dbp; 748 ct_entry *dbp_ctp; 749 750 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 751 dbp = (DB *)dbp_ctp->ct_anyp; 752 753 replyp->status = dbp->get_bt_minkey(dbp, &replyp->minkey); 754} 755 756/* 757 * PUBLIC: void __db_set_bt_minkey_proc __P((u_int, u_int32_t, 758 * PUBLIC: __db_set_bt_minkey_reply *)); 759 */ 760void 761__db_set_bt_minkey_proc(dbpcl_id, minkey, replyp) 762 u_int dbpcl_id; 763 u_int32_t minkey; 764 __db_set_bt_minkey_reply *replyp; 765{ 766 DB *dbp; 767 ct_entry *dbp_ctp; 768 int ret; 769 770 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 771 dbp = (DB *)dbp_ctp->ct_anyp; 772 773 ret = dbp->set_bt_minkey(dbp, minkey); 774 775 replyp->status = ret; 776 return; 777} 778 779/* 780 * PUBLIC: void __db_close_proc __P((u_int, u_int32_t, __db_close_reply *)); 781 */ 782void 783__db_close_proc(dbpcl_id, flags, replyp) 784 u_int dbpcl_id; 785 u_int32_t flags; 786 __db_close_reply *replyp; 787{ 788 ct_entry *dbp_ctp; 789 790 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 791 replyp->status = __db_close_int(dbpcl_id, flags); 792 return; 793} 794 795/* 796 * PUBLIC: void __db_create_proc __P((u_int, u_int32_t, __db_create_reply *)); 797 */ 798void 799__db_create_proc(dbenvcl_id, flags, replyp) 800 u_int dbenvcl_id; 801 u_int32_t flags; 802 __db_create_reply *replyp; 803{ 804 DB *dbp; 805 DB_ENV *dbenv; 806 ct_entry *dbenv_ctp, *dbp_ctp; 807 int ret; 808 809 ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV); 810 dbenv = (DB_ENV *)dbenv_ctp->ct_anyp; 811 812 dbp_ctp = new_ct_ent(&replyp->status); 813 if (dbp_ctp == NULL) 814 return; 815 816 /* We require env's for databases. */ 817 if ((ret = db_create(&dbp, dbenv, flags)) == 0) { 818 dbp_ctp->ct_dbp = dbp; 819 dbp_ctp->ct_type = CT_DB; 820 dbp_ctp->ct_parent = dbenv_ctp; 821 dbp_ctp->ct_envparent = dbenv_ctp; 822 replyp->dbcl_id = dbp_ctp->ct_id; 823 } else 824 __dbclear_ctp(dbp_ctp); 825 replyp->status = ret; 826} 827 828/* 829 * PUBLIC: void __db_del_proc __P((u_int, u_int, u_int32_t, u_int32_t, 830 * PUBLIC: u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, 831 * PUBLIC: __db_del_reply *)); 832 */ 833void 834__db_del_proc(dbpcl_id, txnpcl_id, keydlen, keydoff, keyulen, keyflags, 835 keydata, keysize, flags, replyp) 836 u_int dbpcl_id; 837 u_int txnpcl_id; 838 u_int32_t keydlen; 839 u_int32_t keydoff; 840 u_int32_t keyulen; 841 u_int32_t keyflags; 842 void *keydata; 843 u_int32_t keysize; 844 u_int32_t flags; 845 __db_del_reply *replyp; 846{ 847 DB *dbp; 848 DBT key; 849 DB_TXN *txnp; 850 ct_entry *dbp_ctp, *txnp_ctp; 851 int ret; 852 853 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 854 dbp = (DB *)dbp_ctp->ct_anyp; 855 if (txnpcl_id != 0) { 856 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 857 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 858 } else 859 txnp = NULL; 860 861 memset(&key, 0, sizeof(key)); 862 863 /* Set up key DBT */ 864 key.dlen = keydlen; 865 key.ulen = keyulen; 866 key.doff = keydoff; 867 key.flags = keyflags; 868 key.size = keysize; 869 key.data = keydata; 870 871 ret = dbp->del(dbp, txnp, &key, flags); 872 873 replyp->status = ret; 874 return; 875} 876 877/* 878 * PUBLIC: void __db_get_encrypt_flags_proc __P((u_int, 879 * PUBLIC: __db_get_encrypt_flags_reply *)); 880 */ 881void 882__db_get_encrypt_flags_proc(dbpcl_id, replyp) 883 u_int dbpcl_id; 884 __db_get_encrypt_flags_reply *replyp; 885{ 886 DB *dbp; 887 ct_entry *dbp_ctp; 888 889 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 890 dbp = (DB *)dbp_ctp->ct_anyp; 891 892 replyp->status = dbp->get_encrypt_flags(dbp, &replyp->flags); 893} 894 895/* 896 * PUBLIC: void __db_set_encrypt_proc __P((u_int, char *, u_int32_t, 897 * PUBLIC: __db_set_encrypt_reply *)); 898 */ 899void 900__db_set_encrypt_proc(dbpcl_id, passwd, flags, replyp) 901 u_int dbpcl_id; 902 char *passwd; 903 u_int32_t flags; 904 __db_set_encrypt_reply *replyp; 905{ 906 int ret; 907 DB * dbp; 908 ct_entry *dbp_ctp; 909 910 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 911 dbp = (DB *)dbp_ctp->ct_anyp; 912 913 ret = dbp->set_encrypt(dbp, passwd, flags); 914 replyp->status = ret; 915 return; 916} 917 918/* 919 * PUBLIC: void __db_get_q_extentsize_proc __P((u_int, 920 * PUBLIC: __db_get_q_extentsize_reply *)); 921 */ 922void 923__db_get_q_extentsize_proc(dbpcl_id, replyp) 924 u_int dbpcl_id; 925 __db_get_q_extentsize_reply *replyp; 926{ 927 DB *dbp; 928 ct_entry *dbp_ctp; 929 930 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 931 dbp = (DB *)dbp_ctp->ct_anyp; 932 933 replyp->status = dbp->get_q_extentsize(dbp, &replyp->extentsize); 934} 935 936/* 937 * PUBLIC: void __db_set_q_extentsize_proc __P((u_int, u_int32_t, 938 * PUBLIC: __db_set_q_extentsize_reply *)); 939 */ 940void 941__db_set_q_extentsize_proc(dbpcl_id, extentsize, replyp) 942 u_int dbpcl_id; 943 u_int32_t extentsize; 944 __db_set_q_extentsize_reply *replyp; 945{ 946 DB *dbp; 947 ct_entry *dbp_ctp; 948 int ret; 949 950 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 951 dbp = (DB *)dbp_ctp->ct_anyp; 952 953 ret = dbp->set_q_extentsize(dbp, extentsize); 954 955 replyp->status = ret; 956 return; 957} 958 959/* 960 * PUBLIC: void __db_get_flags_proc __P((u_int, __db_get_flags_reply *)); 961 */ 962void 963__db_get_flags_proc(dbpcl_id, replyp) 964 u_int dbpcl_id; 965 __db_get_flags_reply *replyp; 966{ 967 DB *dbp; 968 ct_entry *dbp_ctp; 969 970 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 971 dbp = (DB *)dbp_ctp->ct_anyp; 972 973 replyp->status = dbp->get_flags(dbp, &replyp->flags); 974} 975 976/* 977 * PUBLIC: void __db_set_flags_proc 978 * PUBLIC: __P((u_int, u_int32_t, __db_set_flags_reply *)); 979 */ 980void 981__db_set_flags_proc(dbpcl_id, flags, replyp) 982 u_int dbpcl_id; 983 u_int32_t flags; 984 __db_set_flags_reply *replyp; 985{ 986 DB *dbp; 987 ct_entry *dbp_ctp; 988 int ret; 989 990 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 991 dbp = (DB *)dbp_ctp->ct_anyp; 992 993 ret = dbp->set_flags(dbp, flags); 994 dbp_ctp->ct_dbdp.setflags |= flags; 995 996 replyp->status = ret; 997 return; 998} 999 1000/* 1001 * PUBLIC: void __db_get_proc __P((u_int, u_int, u_int32_t, u_int32_t, 1002 * PUBLIC: u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, 1003 * PUBLIC: u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, 1004 * PUBLIC: u_int32_t, __db_get_reply *, int *)); 1005 */ 1006void 1007__db_get_proc(dbpcl_id, txnpcl_id, keydlen, keydoff, keyulen, keyflags, 1008 keydata, keysize, datadlen, datadoff, dataulen, dataflags, datadata, 1009 datasize, flags, replyp, freep) 1010 u_int dbpcl_id; 1011 u_int txnpcl_id; 1012 u_int32_t keydlen; 1013 u_int32_t keydoff; 1014 u_int32_t keyulen; 1015 u_int32_t keyflags; 1016 void *keydata; 1017 u_int32_t keysize; 1018 u_int32_t datadlen; 1019 u_int32_t datadoff; 1020 u_int32_t dataulen; 1021 u_int32_t dataflags; 1022 void *datadata; 1023 u_int32_t datasize; 1024 u_int32_t flags; 1025 __db_get_reply *replyp; 1026 int * freep; 1027{ 1028 DB *dbp; 1029 DBT key, data; 1030 DB_TXN *txnp; 1031 ENV *env; 1032 ct_entry *dbp_ctp, *txnp_ctp; 1033 int ret; 1034 1035 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1036 dbp = (DB *)dbp_ctp->ct_anyp; 1037 if (txnpcl_id != 0) { 1038 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 1039 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 1040 } else 1041 txnp = NULL; 1042 1043 env = dbp->env; 1044 replyp->keydata.keydata_val = NULL; 1045 replyp->datadata.datadata_val = NULL; 1046 *freep = 0; 1047 memset(&key, 0, sizeof(key)); 1048 memset(&data, 0, sizeof(data)); 1049 1050 /* Set up key and data DBT */ 1051 key.dlen = keydlen; 1052 key.doff = keydoff; 1053 /* 1054 * Ignore memory related flags on server. 1055 */ 1056 key.flags = DB_DBT_MALLOC; 1057 if (keyflags & DB_DBT_PARTIAL) 1058 key.flags |= DB_DBT_PARTIAL; 1059 key.size = keysize; 1060 key.ulen = keyulen; 1061 key.data = keydata; 1062 1063 data.dlen = datadlen; 1064 data.doff = datadoff; 1065 data.ulen = dataulen; 1066 /* 1067 * Ignore memory related flags on server. 1068 */ 1069 data.size = datasize; 1070 data.data = datadata; 1071 if (flags & DB_MULTIPLE) { 1072 if (data.data == 0) { 1073 ret = __os_umalloc(env, data.ulen, &data.data); 1074 if (ret != 0) 1075 goto err; 1076 } 1077 data.flags |= DB_DBT_USERMEM; 1078 } else 1079 data.flags |= DB_DBT_MALLOC; 1080 if (dataflags & DB_DBT_PARTIAL) 1081 data.flags |= DB_DBT_PARTIAL; 1082 1083 /* Got all our stuff, now do the get */ 1084 ret = dbp->get(dbp, txnp, &key, &data, flags); 1085 /* 1086 * Otherwise just status. 1087 */ 1088 if (ret == 0) { 1089 /* 1090 * XXX 1091 * We need to xdr_free whatever we are returning, next time. 1092 * However, DB does not allocate a new key if one was given 1093 * and we'd be free'ing up space allocated in the request. 1094 * So, allocate a new key/data pointer if it is the same one 1095 * as in the request. 1096 */ 1097 *freep = 1; 1098 /* 1099 * Key 1100 */ 1101 if (key.data == keydata) { 1102 ret = __os_umalloc(env, 1103 key.size, &replyp->keydata.keydata_val); 1104 if (ret != 0) 1105 goto err; 1106 memcpy(replyp->keydata.keydata_val, key.data, key.size); 1107 } else 1108 replyp->keydata.keydata_val = key.data; 1109 1110 replyp->keydata.keydata_len = key.size; 1111 1112 /* 1113 * Data 1114 */ 1115 if (data.data == datadata) { 1116 ret = __os_umalloc(env, 1117 data.size, &replyp->datadata.datadata_val); 1118 if (ret != 0) 1119 goto err; 1120 memcpy(replyp->datadata.datadata_val, data.data, 1121 data.size); 1122 } else 1123 replyp->datadata.datadata_val = data.data; 1124 replyp->datadata.datadata_len = data.size; 1125 } else { 1126err: FREE_IF_CHANGED(env, key.data, keydata); 1127 FREE_IF_CHANGED(env, data.data, datadata); 1128 FREE_IF_CHANGED(env, replyp->keydata.keydata_val, key.data); 1129 FREE_IF_CHANGED(env, replyp->datadata.datadata_val, data.data); 1130 replyp->keydata.keydata_val = NULL; 1131 replyp->keydata.keydata_len = 0; 1132 replyp->datadata.datadata_val = NULL; 1133 replyp->datadata.datadata_len = 0; 1134 *freep = 0; 1135 } 1136 replyp->status = ret; 1137 return; 1138} 1139 1140/* 1141 * PUBLIC: void __db_get_h_ffactor_proc __P((u_int, 1142 * PUBLIC: __db_get_h_ffactor_reply *)); 1143 */ 1144void 1145__db_get_h_ffactor_proc(dbpcl_id, replyp) 1146 u_int dbpcl_id; 1147 __db_get_h_ffactor_reply *replyp; 1148{ 1149 DB *dbp; 1150 ct_entry *dbp_ctp; 1151 1152 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1153 dbp = (DB *)dbp_ctp->ct_anyp; 1154 1155 replyp->status = dbp->get_h_ffactor(dbp, &replyp->ffactor); 1156} 1157 1158/* 1159 * PUBLIC: void __db_set_h_ffactor_proc __P((u_int, u_int32_t, 1160 * PUBLIC: __db_set_h_ffactor_reply *)); 1161 */ 1162void 1163__db_set_h_ffactor_proc(dbpcl_id, ffactor, replyp) 1164 u_int dbpcl_id; 1165 u_int32_t ffactor; 1166 __db_set_h_ffactor_reply *replyp; 1167{ 1168 DB *dbp; 1169 ct_entry *dbp_ctp; 1170 int ret; 1171 1172 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1173 dbp = (DB *)dbp_ctp->ct_anyp; 1174 1175 ret = dbp->set_h_ffactor(dbp, ffactor); 1176 1177 replyp->status = ret; 1178 return; 1179} 1180 1181/* 1182 * PUBLIC: void __db_get_h_nelem_proc __P((u_int, __db_get_h_nelem_reply *)); 1183 */ 1184void 1185__db_get_h_nelem_proc(dbpcl_id, replyp) 1186 u_int dbpcl_id; 1187 __db_get_h_nelem_reply *replyp; 1188{ 1189 DB *dbp; 1190 ct_entry *dbp_ctp; 1191 1192 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1193 dbp = (DB *)dbp_ctp->ct_anyp; 1194 1195 replyp->status = dbp->get_h_nelem(dbp, &replyp->nelem); 1196} 1197 1198/* 1199 * PUBLIC: void __db_set_h_nelem_proc __P((u_int, u_int32_t, 1200 * PUBLIC: __db_set_h_nelem_reply *)); 1201 */ 1202void 1203__db_set_h_nelem_proc(dbpcl_id, nelem, replyp) 1204 u_int dbpcl_id; 1205 u_int32_t nelem; 1206 __db_set_h_nelem_reply *replyp; 1207{ 1208 DB *dbp; 1209 ct_entry *dbp_ctp; 1210 int ret; 1211 1212 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1213 dbp = (DB *)dbp_ctp->ct_anyp; 1214 1215 ret = dbp->set_h_nelem(dbp, nelem); 1216 1217 replyp->status = ret; 1218 return; 1219} 1220 1221/* 1222 * PUBLIC: void __db_key_range_proc __P((u_int, u_int, u_int32_t, u_int32_t, 1223 * PUBLIC: u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, 1224 * PUBLIC: __db_key_range_reply *)); 1225 */ 1226void 1227__db_key_range_proc(dbpcl_id, txnpcl_id, keydlen, keydoff, keyulen, 1228 keyflags, keydata, keysize, flags, replyp) 1229 u_int dbpcl_id; 1230 u_int txnpcl_id; 1231 u_int32_t keydlen; 1232 u_int32_t keydoff; 1233 u_int32_t keyulen; 1234 u_int32_t keyflags; 1235 void *keydata; 1236 u_int32_t keysize; 1237 u_int32_t flags; 1238 __db_key_range_reply *replyp; 1239{ 1240 DB *dbp; 1241 DBT key; 1242 DB_KEY_RANGE range; 1243 DB_TXN *txnp; 1244 ct_entry *dbp_ctp, *txnp_ctp; 1245 int ret; 1246 1247 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1248 dbp = (DB *)dbp_ctp->ct_anyp; 1249 if (txnpcl_id != 0) { 1250 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 1251 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 1252 } else 1253 txnp = NULL; 1254 1255 memset(&key, 0, sizeof(key)); 1256 /* Set up key and data DBT */ 1257 key.dlen = keydlen; 1258 key.ulen = keyulen; 1259 key.doff = keydoff; 1260 key.size = keysize; 1261 key.data = keydata; 1262 key.flags = keyflags; 1263 1264 ret = dbp->key_range(dbp, txnp, &key, &range, flags); 1265 1266 replyp->status = ret; 1267 replyp->less = range.less; 1268 replyp->equal = range.equal; 1269 replyp->greater = range.greater; 1270 return; 1271} 1272 1273/* 1274 * PUBLIC: void __db_get_lorder_proc __P((u_int, __db_get_lorder_reply *)); 1275 */ 1276void 1277__db_get_lorder_proc(dbpcl_id, replyp) 1278 u_int dbpcl_id; 1279 __db_get_lorder_reply *replyp; 1280{ 1281 DB *dbp; 1282 ct_entry *dbp_ctp; 1283 1284 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1285 dbp = (DB *)dbp_ctp->ct_anyp; 1286 1287 replyp->status = dbp->get_lorder(dbp, (int *)&replyp->lorder); 1288} 1289 1290/* 1291 * PUBLIC: void __db_set_lorder_proc 1292 * PUBLIC: __P((u_int, u_int32_t, __db_set_lorder_reply *)); 1293 */ 1294void 1295__db_set_lorder_proc(dbpcl_id, lorder, replyp) 1296 u_int dbpcl_id; 1297 u_int32_t lorder; 1298 __db_set_lorder_reply *replyp; 1299{ 1300 DB *dbp; 1301 ct_entry *dbp_ctp; 1302 int ret; 1303 1304 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1305 dbp = (DB *)dbp_ctp->ct_anyp; 1306 1307 ret = dbp->set_lorder(dbp, lorder); 1308 1309 replyp->status = ret; 1310 return; 1311} 1312 1313/* 1314 * PUBLIC: void __db_get_dbname_proc __P((u_int, __db_get_dbname_reply *)); 1315 */ 1316void 1317__db_get_dbname_proc(dbpcl_id, replyp) 1318 u_int dbpcl_id; 1319 __db_get_dbname_reply *replyp; 1320{ 1321 DB *dbp; 1322 ct_entry *dbp_ctp; 1323 1324 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1325 dbp = (DB *)dbp_ctp->ct_anyp; 1326 1327 replyp->status = dbp->get_dbname(dbp, 1328 (const char **)&replyp->filename, (const char **)&replyp->dbname); 1329} 1330 1331/* 1332 * PUBLIC: void __db_get_open_flags_proc __P((u_int, 1333 * PUBLIC: __db_get_open_flags_reply *)); 1334 */ 1335void 1336__db_get_open_flags_proc(dbpcl_id, replyp) 1337 u_int dbpcl_id; 1338 __db_get_open_flags_reply *replyp; 1339{ 1340 DB *dbp; 1341 ct_entry *dbp_ctp; 1342 1343 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1344 dbp = (DB *)dbp_ctp->ct_anyp; 1345 1346 replyp->status = dbp->get_open_flags(dbp, &replyp->flags); 1347} 1348 1349/* 1350 * PUBLIC: void __db_open_proc __P((u_int, u_int, char *, char *, u_int32_t, 1351 * PUBLIC: u_int32_t, u_int32_t, __db_open_reply *)); 1352 */ 1353void 1354__db_open_proc(dbpcl_id, txnpcl_id, name, subdb, type, flags, mode, replyp) 1355 u_int dbpcl_id; 1356 u_int txnpcl_id; 1357 char *name; 1358 char *subdb; 1359 u_int32_t type; 1360 u_int32_t flags; 1361 u_int32_t mode; 1362 __db_open_reply *replyp; 1363{ 1364 DB *dbp; 1365 DB_TXN *txnp; 1366 DBTYPE dbtype; 1367 ENV *env; 1368 ct_entry *dbp_ctp, *new_ctp, *txnp_ctp; 1369 int isswapped, ret; 1370 1371 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1372 dbp = (DB *)dbp_ctp->ct_anyp; 1373 if (txnpcl_id != 0) { 1374 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 1375 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 1376 } else 1377 txnp = NULL; 1378 env = dbp->env; 1379 1380 replyp->dbcl_id = dbpcl_id; 1381 if ((new_ctp = __dbsrv_sharedb(dbp_ctp, name, subdb, type, flags)) 1382 != NULL) { 1383 /* 1384 * We can share, clean up old ID, set new one. 1385 */ 1386 if (__dbsrv_verbose) 1387 printf("Sharing db ID %ld\n", new_ctp->ct_id); 1388 replyp->dbcl_id = new_ctp->ct_id; 1389 ret = __db_close_int(dbpcl_id, 0); 1390 goto out; 1391 } 1392 ret = dbp->open(dbp, txnp, name, subdb, (DBTYPE)type, flags, mode); 1393 if (ret == 0) { 1394 (void)dbp->get_type(dbp, &dbtype); 1395 replyp->type = dbtype; 1396 /* 1397 * We need to determine the byte order of the database 1398 * and send it back to the client. Determine it by 1399 * the server's native order and the swapped value of 1400 * the DB itself. 1401 */ 1402 (void)dbp->get_byteswapped(dbp, &isswapped); 1403 if (__db_isbigendian()) { 1404 if (isswapped == 0) 1405 replyp->lorder = 4321; 1406 else 1407 replyp->lorder = 1234; 1408 } else { 1409 if (isswapped == 0) 1410 replyp->lorder = 1234; 1411 else 1412 replyp->lorder = 4321; 1413 } 1414 dbp_ctp->ct_dbdp.type = dbtype; 1415 dbp_ctp->ct_dbdp.dbflags = LF_ISSET(DB_SERVER_DBFLAGS); 1416 if (name == NULL) 1417 dbp_ctp->ct_dbdp.db = NULL; 1418 else if ((ret = __os_strdup(env, name, 1419 &dbp_ctp->ct_dbdp.db)) != 0) 1420 goto out; 1421 if (subdb == NULL) 1422 dbp_ctp->ct_dbdp.subdb = NULL; 1423 else if ((ret = __os_strdup(env, subdb, 1424 &dbp_ctp->ct_dbdp.subdb)) != 0) 1425 goto out; 1426 } 1427out: 1428 replyp->status = ret; 1429 return; 1430} 1431 1432/* 1433 * PUBLIC: void __db_get_pagesize_proc __P((u_int, __db_get_pagesize_reply *)); 1434 */ 1435void 1436__db_get_pagesize_proc(dbpcl_id, replyp) 1437 u_int dbpcl_id; 1438 __db_get_pagesize_reply *replyp; 1439{ 1440 DB *dbp; 1441 ct_entry *dbp_ctp; 1442 1443 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1444 dbp = (DB *)dbp_ctp->ct_anyp; 1445 1446 replyp->status = dbp->get_pagesize(dbp, &replyp->pagesize); 1447} 1448 1449/* 1450 * PUBLIC: void __db_set_pagesize_proc __P((u_int, u_int32_t, 1451 * PUBLIC: __db_set_pagesize_reply *)); 1452 */ 1453void 1454__db_set_pagesize_proc(dbpcl_id, pagesize, replyp) 1455 u_int dbpcl_id; 1456 u_int32_t pagesize; 1457 __db_set_pagesize_reply *replyp; 1458{ 1459 DB *dbp; 1460 ct_entry *dbp_ctp; 1461 int ret; 1462 1463 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1464 dbp = (DB *)dbp_ctp->ct_anyp; 1465 1466 ret = dbp->set_pagesize(dbp, pagesize); 1467 1468 replyp->status = ret; 1469 return; 1470} 1471 1472/* 1473 * PUBLIC: void __db_pget_proc __P((u_int, u_int, u_int32_t, u_int32_t, 1474 * PUBLIC: u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, 1475 * PUBLIC: u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, 1476 * PUBLIC: u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, 1477 * PUBLIC: u_int32_t, u_int32_t, __db_pget_reply *, int *)); 1478 */ 1479void 1480__db_pget_proc(dbpcl_id, txnpcl_id, skeydlen, skeydoff, skeyulen, 1481 skeyflags, skeydata, skeysize, pkeydlen, pkeydoff, pkeyulen, pkeyflags, 1482 pkeydata, pkeysize, datadlen, datadoff, dataulen, dataflags, datadata, 1483 datasize, flags, replyp, freep) 1484 u_int dbpcl_id; 1485 u_int txnpcl_id; 1486 u_int32_t skeydlen; 1487 u_int32_t skeydoff; 1488 u_int32_t skeyulen; 1489 u_int32_t skeyflags; 1490 void *skeydata; 1491 u_int32_t skeysize; 1492 u_int32_t pkeydlen; 1493 u_int32_t pkeydoff; 1494 u_int32_t pkeyulen; 1495 u_int32_t pkeyflags; 1496 void *pkeydata; 1497 u_int32_t pkeysize; 1498 u_int32_t datadlen; 1499 u_int32_t datadoff; 1500 u_int32_t dataulen; 1501 u_int32_t dataflags; 1502 void *datadata; 1503 u_int32_t datasize; 1504 u_int32_t flags; 1505 __db_pget_reply *replyp; 1506 int * freep; 1507{ 1508 DB *dbp; 1509 DBT skey, pkey, data; 1510 DB_TXN *txnp; 1511 ENV *env; 1512 ct_entry *dbp_ctp, *txnp_ctp; 1513 int ret; 1514 1515 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1516 dbp = (DB *)dbp_ctp->ct_anyp; 1517 if (txnpcl_id != 0) { 1518 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 1519 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 1520 } else 1521 txnp = NULL; 1522 1523 env = dbp->env; 1524 replyp->skeydata.skeydata_val = NULL; 1525 replyp->pkeydata.pkeydata_val = NULL; 1526 replyp->datadata.datadata_val = NULL; 1527 *freep = 0; 1528 memset(&skey, 0, sizeof(skey)); 1529 memset(&pkey, 0, sizeof(pkey)); 1530 memset(&data, 0, sizeof(data)); 1531 1532 /* 1533 * Ignore memory related flags on server. 1534 */ 1535 /* Set up key and data DBT */ 1536 skey.flags = DB_DBT_MALLOC; 1537 skey.dlen = skeydlen; 1538 skey.ulen = skeyulen; 1539 skey.doff = skeydoff; 1540 if (skeyflags & DB_DBT_PARTIAL) 1541 skey.flags |= DB_DBT_PARTIAL; 1542 skey.size = skeysize; 1543 skey.data = skeydata; 1544 1545 pkey.flags = DB_DBT_MALLOC; 1546 pkey.dlen = pkeydlen; 1547 pkey.ulen = pkeyulen; 1548 pkey.doff = pkeydoff; 1549 if (pkeyflags & DB_DBT_PARTIAL) 1550 pkey.flags |= DB_DBT_PARTIAL; 1551 pkey.size = pkeysize; 1552 pkey.data = pkeydata; 1553 1554 data.flags = DB_DBT_MALLOC; 1555 data.dlen = datadlen; 1556 data.ulen = dataulen; 1557 data.doff = datadoff; 1558 if (dataflags & DB_DBT_PARTIAL) 1559 data.flags |= DB_DBT_PARTIAL; 1560 data.size = datasize; 1561 data.data = datadata; 1562 1563 /* Got all our stuff, now do the get */ 1564 ret = dbp->pget(dbp, txnp, &skey, &pkey, &data, flags); 1565 /* 1566 * Otherwise just status. 1567 */ 1568 if (ret == 0) { 1569 /* 1570 * XXX 1571 * We need to xdr_free whatever we are returning, next time. 1572 * However, DB does not allocate a new key if one was given 1573 * and we'd be free'ing up space allocated in the request. 1574 * So, allocate a new key/data pointer if it is the same one 1575 * as in the request. 1576 */ 1577 *freep = 1; 1578 /* 1579 * Key 1580 */ 1581 if (skey.data == skeydata) { 1582 ret = __os_umalloc(env, 1583 skey.size, &replyp->skeydata.skeydata_val); 1584 if (ret != 0) 1585 goto err; 1586 memcpy(replyp->skeydata.skeydata_val, skey.data, 1587 skey.size); 1588 } else 1589 replyp->skeydata.skeydata_val = skey.data; 1590 1591 replyp->skeydata.skeydata_len = skey.size; 1592 1593 /* 1594 * Primary key 1595 */ 1596 if (pkey.data == pkeydata) { 1597 ret = __os_umalloc(env, 1598 pkey.size, &replyp->pkeydata.pkeydata_val); 1599 if (ret != 0) 1600 goto err; 1601 /* 1602 * We can set it to 2, because they cannot send the 1603 * pkey over without sending the skey over too. 1604 * So if they did send a pkey, they must have sent 1605 * the skey as well. 1606 */ 1607 memcpy(replyp->pkeydata.pkeydata_val, pkey.data, 1608 pkey.size); 1609 } else 1610 replyp->pkeydata.pkeydata_val = pkey.data; 1611 replyp->pkeydata.pkeydata_len = pkey.size; 1612 1613 /* 1614 * Data 1615 */ 1616 if (data.data == datadata) { 1617 ret = __os_umalloc(env, 1618 data.size, &replyp->datadata.datadata_val); 1619 if (ret != 0) 1620 goto err; 1621 memcpy(replyp->datadata.datadata_val, data.data, 1622 data.size); 1623 } else 1624 replyp->datadata.datadata_val = data.data; 1625 replyp->datadata.datadata_len = data.size; 1626 } else { 1627err: FREE_IF_CHANGED(env, skey.data, skeydata); 1628 FREE_IF_CHANGED(env, pkey.data, pkeydata); 1629 FREE_IF_CHANGED(env, data.data, datadata); 1630 FREE_IF_CHANGED(env, replyp->skeydata.skeydata_val, skey.data); 1631 FREE_IF_CHANGED(env, replyp->pkeydata.pkeydata_val, pkey.data); 1632 FREE_IF_CHANGED(env, replyp->datadata.datadata_val, data.data); 1633 replyp->skeydata.skeydata_val = NULL; 1634 replyp->skeydata.skeydata_len = 0; 1635 replyp->pkeydata.pkeydata_val = NULL; 1636 replyp->pkeydata.pkeydata_len = 0; 1637 replyp->datadata.datadata_val = NULL; 1638 replyp->datadata.datadata_len = 0; 1639 *freep = 0; 1640 } 1641 replyp->status = ret; 1642 return; 1643} 1644 1645/* 1646 * PUBLIC: void __db_put_proc __P((u_int, u_int, u_int32_t, u_int32_t, 1647 * PUBLIC: u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, 1648 * PUBLIC: u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t, 1649 * PUBLIC: u_int32_t, __db_put_reply *, int *)); 1650 */ 1651void 1652__db_put_proc(dbpcl_id, txnpcl_id, keydlen, keydoff, keyulen, keyflags, 1653 keydata, keysize, datadlen, datadoff, dataulen, dataflags, datadata, 1654 datasize, flags, replyp, freep) 1655 u_int dbpcl_id; 1656 u_int txnpcl_id; 1657 u_int32_t keydlen; 1658 u_int32_t keydoff; 1659 u_int32_t keyulen; 1660 u_int32_t keyflags; 1661 void *keydata; 1662 u_int32_t keysize; 1663 u_int32_t datadlen; 1664 u_int32_t datadoff; 1665 u_int32_t dataulen; 1666 u_int32_t dataflags; 1667 void *datadata; 1668 u_int32_t datasize; 1669 u_int32_t flags; 1670 __db_put_reply *replyp; 1671 int * freep; 1672{ 1673 DB *dbp; 1674 DBT key, data; 1675 DB_TXN *txnp; 1676 ENV *env; 1677 ct_entry *dbp_ctp, *txnp_ctp; 1678 int ret; 1679 1680 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1681 dbp = (DB *)dbp_ctp->ct_anyp; 1682 if (txnpcl_id != 0) { 1683 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 1684 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 1685 } else 1686 txnp = NULL; 1687 1688 env = dbp->env; 1689 replyp->keydata.keydata_val = NULL; 1690 *freep = 0; 1691 memset(&key, 0, sizeof(key)); 1692 memset(&data, 0, sizeof(data)); 1693 1694 /* Set up key and data DBT */ 1695 key.dlen = keydlen; 1696 key.ulen = keyulen; 1697 key.doff = keydoff; 1698 /* 1699 * Ignore memory related flags on server. 1700 */ 1701 key.flags = DB_DBT_MALLOC; 1702 if (keyflags & DB_DBT_PARTIAL) 1703 key.flags |= DB_DBT_PARTIAL; 1704 key.size = keysize; 1705 key.data = keydata; 1706 1707 data.dlen = datadlen; 1708 data.ulen = dataulen; 1709 data.doff = datadoff; 1710 data.flags = dataflags; 1711 data.size = datasize; 1712 data.data = datadata; 1713 1714 /* Got all our stuff, now do the put */ 1715 ret = dbp->put(dbp, txnp, &key, &data, flags); 1716 /* 1717 * If the client did a DB_APPEND, set up key in reply. 1718 * Otherwise just status. 1719 */ 1720 if (ret == 0 && (flags == DB_APPEND)) { 1721 /* 1722 * XXX 1723 * We need to xdr_free whatever we are returning, next time. 1724 * However, DB does not allocate a new key if one was given 1725 * and we'd be free'ing up space allocated in the request. 1726 * So, allocate a new key/data pointer if it is the same one 1727 * as in the request. 1728 */ 1729 *freep = 1; 1730 /* 1731 * Key 1732 */ 1733 if (key.data == keydata) { 1734 ret = __os_umalloc(env, 1735 key.size, &replyp->keydata.keydata_val); 1736 if (ret != 0) 1737 goto err; 1738 memcpy(replyp->keydata.keydata_val, key.data, key.size); 1739 } else 1740 replyp->keydata.keydata_val = key.data; 1741 1742 replyp->keydata.keydata_len = key.size; 1743 } else { 1744err: FREE_IF_CHANGED(env, key.data, keydata); 1745 FREE_IF_CHANGED(env, replyp->keydata.keydata_val, key.data); 1746 replyp->keydata.keydata_val = NULL; 1747 replyp->keydata.keydata_len = 0; 1748 *freep = 0; 1749 } 1750 replyp->status = ret; 1751 return; 1752} 1753 1754/* 1755 * PUBLIC: void __db_get_priority_proc __P((u_int, __db_get_priority_reply *)); 1756 */ 1757void 1758__db_get_priority_proc(dbpcl_id, replyp) 1759 u_int dbpcl_id; 1760 __db_get_priority_reply *replyp; 1761{ 1762 DB *dbp; 1763 ct_entry *dbp_ctp; 1764 1765 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1766 dbp = (DB *)dbp_ctp->ct_anyp; 1767 1768 replyp->status = 1769 dbp->get_priority(dbp, (DB_CACHE_PRIORITY *)&replyp->priority); 1770} 1771 1772/* 1773 * PUBLIC: void __db_set_priority_proc __P((u_int, u_int32_t, 1774 * PUBLIC: __db_set_priority_reply *)); 1775 */ 1776void 1777__db_set_priority_proc(dbpcl_id, priority, replyp) 1778 u_int dbpcl_id; 1779 u_int32_t priority; 1780 __db_set_priority_reply *replyp; 1781{ 1782 DB *dbp; 1783 ct_entry *dbp_ctp; 1784 int ret; 1785 1786 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1787 dbp = (DB *)dbp_ctp->ct_anyp; 1788 1789 ret = dbp->set_priority(dbp, (DB_CACHE_PRIORITY)priority); 1790 1791 replyp->status = ret; 1792 return; 1793} 1794 1795/* 1796 * PUBLIC: void __db_get_re_delim_proc __P((u_int, __db_get_re_delim_reply *)); 1797 */ 1798void 1799__db_get_re_delim_proc(dbpcl_id, replyp) 1800 u_int dbpcl_id; 1801 __db_get_re_delim_reply *replyp; 1802{ 1803 DB *dbp; 1804 ct_entry *dbp_ctp; 1805 1806 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1807 dbp = (DB *)dbp_ctp->ct_anyp; 1808 1809 replyp->status = dbp->get_re_delim(dbp, (int *)&replyp->delim); 1810} 1811 1812/* 1813 * PUBLIC: void __db_set_re_delim_proc __P((u_int, u_int32_t, 1814 * PUBLIC: __db_set_re_delim_reply *)); 1815 */ 1816void 1817__db_set_re_delim_proc(dbpcl_id, delim, replyp) 1818 u_int dbpcl_id; 1819 u_int32_t delim; 1820 __db_set_re_delim_reply *replyp; 1821{ 1822 DB *dbp; 1823 ct_entry *dbp_ctp; 1824 int ret; 1825 1826 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1827 dbp = (DB *)dbp_ctp->ct_anyp; 1828 1829 ret = dbp->set_re_delim(dbp, delim); 1830 1831 replyp->status = ret; 1832 return; 1833} 1834 1835/* 1836 * PUBLIC: void __db_get_re_len_proc __P((u_int, __db_get_re_len_reply *)); 1837 */ 1838void 1839__db_get_re_len_proc(dbpcl_id, replyp) 1840 u_int dbpcl_id; 1841 __db_get_re_len_reply *replyp; 1842{ 1843 DB *dbp; 1844 ct_entry *dbp_ctp; 1845 1846 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1847 dbp = (DB *)dbp_ctp->ct_anyp; 1848 1849 replyp->status = dbp->get_re_len(dbp, &replyp->len); 1850} 1851 1852/* 1853 * PUBLIC: void __db_set_re_len_proc 1854 * PUBLIC: __P((u_int, u_int32_t, __db_set_re_len_reply *)); 1855 */ 1856void 1857__db_set_re_len_proc(dbpcl_id, len, replyp) 1858 u_int dbpcl_id; 1859 u_int32_t len; 1860 __db_set_re_len_reply *replyp; 1861{ 1862 DB *dbp; 1863 ct_entry *dbp_ctp; 1864 int ret; 1865 1866 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1867 dbp = (DB *)dbp_ctp->ct_anyp; 1868 1869 ret = dbp->set_re_len(dbp, len); 1870 1871 replyp->status = ret; 1872 return; 1873} 1874 1875/* 1876 * PUBLIC: void __db_get_re_pad_proc __P((u_int, __db_get_re_pad_reply *)); 1877 */ 1878void 1879__db_get_re_pad_proc(dbpcl_id, replyp) 1880 u_int dbpcl_id; 1881 __db_get_re_pad_reply *replyp; 1882{ 1883 DB *dbp; 1884 ct_entry *dbp_ctp; 1885 1886 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1887 dbp = (DB *)dbp_ctp->ct_anyp; 1888 1889 replyp->status = dbp->get_re_pad(dbp, (int *)&replyp->pad); 1890} 1891 1892/* 1893 * PUBLIC: void __db_set_re_pad_proc 1894 * PUBLIC: __P((u_int, u_int32_t, __db_set_re_pad_reply *)); 1895 */ 1896void 1897__db_set_re_pad_proc(dbpcl_id, pad, replyp) 1898 u_int dbpcl_id; 1899 u_int32_t pad; 1900 __db_set_re_pad_reply *replyp; 1901{ 1902 DB *dbp; 1903 ct_entry *dbp_ctp; 1904 int ret; 1905 1906 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1907 dbp = (DB *)dbp_ctp->ct_anyp; 1908 1909 ret = dbp->set_re_pad(dbp, pad); 1910 1911 replyp->status = ret; 1912 return; 1913} 1914 1915/* 1916 * PUBLIC: void __db_remove_proc __P((u_int, char *, char *, u_int32_t, 1917 * PUBLIC: __db_remove_reply *)); 1918 */ 1919void 1920__db_remove_proc(dbpcl_id, name, subdb, flags, replyp) 1921 u_int dbpcl_id; 1922 char *name; 1923 char *subdb; 1924 u_int32_t flags; 1925 __db_remove_reply *replyp; 1926{ 1927 DB *dbp; 1928 ct_entry *dbp_ctp; 1929 int ret; 1930 1931 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1932 dbp = (DB *)dbp_ctp->ct_anyp; 1933 1934 ret = dbp->remove(dbp, name, subdb, flags); 1935 __dbdel_ctp(dbp_ctp); 1936 1937 replyp->status = ret; 1938 return; 1939} 1940 1941/* 1942 * PUBLIC: void __db_rename_proc __P((u_int, char *, char *, char *, u_int32_t, 1943 * PUBLIC: __db_rename_reply *)); 1944 */ 1945void 1946__db_rename_proc(dbpcl_id, name, subdb, newname, flags, replyp) 1947 u_int dbpcl_id; 1948 char *name; 1949 char *subdb; 1950 char *newname; 1951 u_int32_t flags; 1952 __db_rename_reply *replyp; 1953{ 1954 DB *dbp; 1955 ct_entry *dbp_ctp; 1956 int ret; 1957 1958 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1959 dbp = (DB *)dbp_ctp->ct_anyp; 1960 1961 ret = dbp->rename(dbp, name, subdb, newname, flags); 1962 __dbdel_ctp(dbp_ctp); 1963 1964 replyp->status = ret; 1965 return; 1966} 1967 1968/* 1969 * PUBLIC: void __db_stat_proc __P((u_int, u_int, u_int32_t, __db_stat_reply *, 1970 * PUBLIC: int *)); 1971 */ 1972void 1973__db_stat_proc(dbpcl_id, txnpcl_id, flags, replyp, freep) 1974 u_int dbpcl_id; 1975 u_int txnpcl_id; 1976 u_int32_t flags; 1977 __db_stat_reply *replyp; 1978 int * freep; 1979{ 1980 DB *dbp; 1981 DB_TXN *txnp; 1982 DBTYPE type; 1983 ENV *env; 1984 ct_entry *dbp_ctp, *txnp_ctp; 1985 u_int32_t *q, *p, *retsp; 1986 int i, len, ret; 1987 void *sp; 1988 1989 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 1990 dbp = (DB *)dbp_ctp->ct_anyp; 1991 if (txnpcl_id != 0) { 1992 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 1993 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 1994 } else 1995 txnp = NULL; 1996 1997 env = dbp->env; 1998 ret = dbp->stat(dbp, txnp, &sp, flags); 1999 replyp->status = ret; 2000 if (ret != 0) 2001 return; 2002 /* 2003 * We get here, we have success. Allocate an array so that 2004 * we can use the list generator. Generate the reply, free 2005 * up the space. 2006 */ 2007 /* 2008 * XXX This assumes that all elements of all stat structures 2009 * are u_int32_t fields. They are, currently. 2010 */ 2011 (void)dbp->get_type(dbp, &type); 2012 if (type == DB_HASH) 2013 len = sizeof(DB_HASH_STAT); 2014 else if (type == DB_QUEUE) 2015 len = sizeof(DB_QUEUE_STAT); 2016 else /* BTREE or RECNO are same stats */ 2017 len = sizeof(DB_BTREE_STAT); 2018 replyp->stats.stats_len = len / sizeof(u_int32_t); 2019 2020 if ((ret = 2021 __os_umalloc(env, len * replyp->stats.stats_len, &retsp)) != 0) 2022 goto out; 2023 for (i = 0, q = retsp, p = sp; i < len; 2024 i++, q++, p++) 2025 *q = *p; 2026 replyp->stats.stats_val = retsp; 2027 __os_ufree(env, sp); 2028 if (ret == 0) 2029 *freep = 1; 2030out: 2031 replyp->status = ret; 2032 return; 2033} 2034 2035/* 2036 * PUBLIC: void __db_sync_proc __P((u_int, u_int32_t, __db_sync_reply *)); 2037 */ 2038void 2039__db_sync_proc(dbpcl_id, flags, replyp) 2040 u_int dbpcl_id; 2041 u_int32_t flags; 2042 __db_sync_reply *replyp; 2043{ 2044 DB *dbp; 2045 ct_entry *dbp_ctp; 2046 int ret; 2047 2048 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 2049 dbp = (DB *)dbp_ctp->ct_anyp; 2050 2051 ret = dbp->sync(dbp, flags); 2052 2053 replyp->status = ret; 2054 return; 2055} 2056 2057/* 2058 * PUBLIC: void __db_truncate_proc __P((u_int, u_int, u_int32_t, 2059 * PUBLIC: __db_truncate_reply *)); 2060 */ 2061void 2062__db_truncate_proc(dbpcl_id, txnpcl_id, flags, replyp) 2063 u_int dbpcl_id; 2064 u_int txnpcl_id; 2065 u_int32_t flags; 2066 __db_truncate_reply *replyp; 2067{ 2068 DB *dbp; 2069 DB_TXN *txnp; 2070 ct_entry *dbp_ctp, *txnp_ctp; 2071 u_int32_t count; 2072 int ret; 2073 2074 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 2075 dbp = (DB *)dbp_ctp->ct_anyp; 2076 if (txnpcl_id != 0) { 2077 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 2078 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 2079 } else 2080 txnp = NULL; 2081 2082 ret = dbp->truncate(dbp, txnp, &count, flags); 2083 replyp->status = ret; 2084 if (ret == 0) 2085 replyp->count = count; 2086 return; 2087} 2088 2089/* 2090 * PUBLIC: void __db_cursor_proc __P((u_int, u_int, u_int32_t, 2091 * PUBLIC: __db_cursor_reply *)); 2092 */ 2093void 2094__db_cursor_proc(dbpcl_id, txnpcl_id, flags, replyp) 2095 u_int dbpcl_id; 2096 u_int txnpcl_id; 2097 u_int32_t flags; 2098 __db_cursor_reply *replyp; 2099{ 2100 DB *dbp; 2101 DBC *dbc; 2102 DB_TXN *txnp; 2103 ct_entry *dbc_ctp, *env_ctp, *dbp_ctp, *txnp_ctp; 2104 int ret; 2105 2106 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 2107 dbp = (DB *)dbp_ctp->ct_anyp; 2108 dbc_ctp = new_ct_ent(&replyp->status); 2109 if (dbc_ctp == NULL) 2110 return; 2111 2112 if (txnpcl_id != 0) { 2113 ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN); 2114 txnp = (DB_TXN *)txnp_ctp->ct_anyp; 2115 dbc_ctp->ct_activep = txnp_ctp->ct_activep; 2116 } else 2117 txnp = NULL; 2118 2119 if ((ret = dbp->cursor(dbp, txnp, &dbc, flags)) == 0) { 2120 dbc_ctp->ct_dbc = dbc; 2121 dbc_ctp->ct_type = CT_CURSOR; 2122 dbc_ctp->ct_parent = dbp_ctp; 2123 env_ctp = dbp_ctp->ct_envparent; 2124 dbc_ctp->ct_envparent = env_ctp; 2125 __dbsrv_settimeout(dbc_ctp, env_ctp->ct_timeout); 2126 __dbsrv_active(dbc_ctp); 2127 replyp->dbcidcl_id = dbc_ctp->ct_id; 2128 } else 2129 __dbclear_ctp(dbc_ctp); 2130 2131 replyp->status = ret; 2132 return; 2133} 2134 2135/* 2136 * PUBLIC: void __db_join_proc __P((u_int, u_int32_t *, u_int32_t, u_int32_t, 2137 * PUBLIC: __db_join_reply *)); 2138 */ 2139void 2140__db_join_proc(dbpcl_id, curs, curslen, flags, replyp) 2141 u_int dbpcl_id; 2142 u_int32_t * curs; 2143 u_int32_t curslen; 2144 u_int32_t flags; 2145 __db_join_reply *replyp; 2146{ 2147 DB *dbp; 2148 DBC **jcurs, **c; 2149 DBC *dbc; 2150 ENV *env; 2151 ct_entry *dbc_ctp, *ctp, *dbp_ctp; 2152 size_t size; 2153 u_int32_t *cl, i; 2154 int ret; 2155 2156 ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); 2157 dbp = (DB *)dbp_ctp->ct_anyp; 2158 env = dbp->env; 2159 2160 dbc_ctp = new_ct_ent(&replyp->status); 2161 if (dbc_ctp == NULL) 2162 return; 2163 2164 size = (curslen + 1) * sizeof(DBC *); 2165 if ((ret = __os_calloc(env, curslen + 1, sizeof(DBC *), &jcurs)) != 0) { 2166 replyp->status = ret; 2167 __dbclear_ctp(dbc_ctp); 2168 return; 2169 } 2170 /* 2171 * If our curslist has a parent txn, we need to use it too 2172 * for the activity timeout. All cursors must be part of 2173 * the same transaction, so just check the first. 2174 */ 2175 ctp = get_tableent(*curs); 2176 DB_ASSERT(env, ctp->ct_type == CT_CURSOR); 2177 /* 2178 * If we are using a transaction, set the join activity timer 2179 * to point to the parent transaction. 2180 */ 2181 if (ctp->ct_activep != &ctp->ct_active) 2182 dbc_ctp->ct_activep = ctp->ct_activep; 2183 for (i = 0, cl = curs, c = jcurs; i < curslen; i++, cl++, c++) { 2184 ctp = get_tableent(*cl); 2185 if (ctp == NULL) { 2186 replyp->status = DB_NOSERVER_ID; 2187 goto out; 2188 } 2189 /* 2190 * If we are using a txn, the join cursor points to the 2191 * transaction timeout. If we are not using a transaction, 2192 * then all the curslist cursors must point to the join 2193 * cursor's timeout so that we do not timeout any of the 2194 * curlist cursors while the join cursor is active. 2195 * Change the type of the curslist ctps to CT_JOIN so that 2196 * we know they are part of a join list and we can distinguish 2197 * them and later restore them when the join cursor is closed. 2198 */ 2199 DB_ASSERT(env, ctp->ct_type == CT_CURSOR); 2200 ctp->ct_type |= CT_JOIN; 2201 ctp->ct_origp = ctp->ct_activep; 2202 /* 2203 * Setting this to the ct_active field of the dbc_ctp is 2204 * really just a way to distinguish which join dbc this 2205 * cursor is part of. The ct_activep of this cursor is 2206 * not used at all during its lifetime as part of a join 2207 * cursor. 2208 */ 2209 ctp->ct_activep = &dbc_ctp->ct_active; 2210 *c = ctp->ct_dbc; 2211 } 2212 *c = NULL; 2213 if ((ret = dbp->join(dbp, jcurs, &dbc, flags)) == 0) { 2214 dbc_ctp->ct_dbc = dbc; 2215 dbc_ctp->ct_type = (CT_JOINCUR | CT_CURSOR); 2216 dbc_ctp->ct_parent = dbp_ctp; 2217 dbc_ctp->ct_envparent = dbp_ctp->ct_envparent; 2218 __dbsrv_settimeout(dbc_ctp, dbp_ctp->ct_envparent->ct_timeout); 2219 __dbsrv_active(dbc_ctp); 2220 replyp->dbcidcl_id = dbc_ctp->ct_id; 2221 } else { 2222 __dbclear_ctp(dbc_ctp); 2223 /* 2224 * If we get an error, undo what we did above to any cursors. 2225 */ 2226 for (cl = curs; *cl != 0; cl++) { 2227 ctp = get_tableent(*cl); 2228 ctp->ct_type = CT_CURSOR; 2229 ctp->ct_activep = ctp->ct_origp; 2230 } 2231 } 2232 2233 replyp->status = ret; 2234 2235out: __os_free(env, jcurs); 2236 return; 2237} 2238 2239/* 2240 * PUBLIC: void __dbc_close_proc __P((u_int, __dbc_close_reply *)); 2241 */ 2242void 2243__dbc_close_proc(dbccl_id, replyp) 2244 u_int dbccl_id; 2245 __dbc_close_reply *replyp; 2246{ 2247 ct_entry *dbc_ctp; 2248 2249 ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); 2250 replyp->status = __dbc_close_int(dbc_ctp); 2251 return; 2252} 2253 2254/* 2255 * PUBLIC: void __dbc_count_proc 2256 * PUBLIC: __P((u_int, u_int32_t, __dbc_count_reply *)); 2257 */ 2258void 2259__dbc_count_proc(dbccl_id, flags, replyp) 2260 u_int dbccl_id; 2261 u_int32_t flags; 2262 __dbc_count_reply *replyp; 2263{ 2264 DBC *dbc; 2265 ct_entry *dbc_ctp; 2266 db_recno_t num; 2267 int ret; 2268 2269 ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); 2270 dbc = (DBC *)dbc_ctp->ct_anyp; 2271 2272 ret = dbc->count(dbc, &num, flags); 2273 replyp->status = ret; 2274 if (ret == 0) 2275 replyp->dupcount = num; 2276 return; 2277} 2278 2279/* 2280 * PUBLIC: void __dbc_del_proc __P((u_int, u_int32_t, __dbc_del_reply *)); 2281 */ 2282void 2283__dbc_del_proc(dbccl_id, flags, replyp) 2284 u_int dbccl_id; 2285 u_int32_t flags; 2286 __dbc_del_reply *replyp; 2287{ 2288 DBC *dbc; 2289 ct_entry *dbc_ctp; 2290 int ret; 2291 2292 ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); 2293 dbc = (DBC *)dbc_ctp->ct_anyp; 2294 2295 ret = dbc->del(dbc, flags); 2296 2297 replyp->status = ret; 2298 return; 2299} 2300 2301/* 2302 * PUBLIC: void __dbc_dup_proc __P((u_int, u_int32_t, __dbc_dup_reply *)); 2303 */ 2304void 2305__dbc_dup_proc(dbccl_id, flags, replyp) 2306 u_int dbccl_id; 2307 u_int32_t flags; 2308 __dbc_dup_reply *replyp; 2309{ 2310 DBC *dbc, *newdbc; 2311 ct_entry *dbc_ctp, *new_ctp; 2312 int ret; 2313 2314 ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); 2315 dbc = (DBC *)dbc_ctp->ct_anyp; 2316 2317 new_ctp = new_ct_ent(&replyp->status); 2318 if (new_ctp == NULL) 2319 return; 2320 2321 if ((ret = dbc->dup(dbc, &newdbc, flags)) == 0) { 2322 new_ctp->ct_dbc = newdbc; 2323 new_ctp->ct_type = CT_CURSOR; 2324 new_ctp->ct_parent = dbc_ctp->ct_parent; 2325 new_ctp->ct_envparent = dbc_ctp->ct_envparent; 2326 /* 2327 * If our cursor has a parent txn, we need to use it too. 2328 */ 2329 if (dbc_ctp->ct_activep != &dbc_ctp->ct_active) 2330 new_ctp->ct_activep = dbc_ctp->ct_activep; 2331 __dbsrv_settimeout(new_ctp, dbc_ctp->ct_timeout); 2332 __dbsrv_active(new_ctp); 2333 replyp->dbcidcl_id = new_ctp->ct_id; 2334 } else 2335 __dbclear_ctp(new_ctp); 2336 2337 replyp->status = ret; 2338 return; 2339} 2340 2341/* 2342 * PUBLIC: void __dbc_get_proc __P((u_int, u_int32_t, u_int32_t, u_int32_t, 2343 * PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, 2344 * PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, __dbc_get_reply *, 2345 * PUBLIC: int *)); 2346 */ 2347void 2348__dbc_get_proc(dbccl_id, keydlen, keydoff, keyulen, keyflags, keydata, 2349 keysize, datadlen, datadoff, dataulen, dataflags, datadata, datasize, 2350 flags, replyp, freep) 2351 u_int dbccl_id; 2352 u_int32_t keydlen; 2353 u_int32_t keydoff; 2354 u_int32_t keyulen; 2355 u_int32_t keyflags; 2356 void *keydata; 2357 u_int32_t keysize; 2358 u_int32_t datadlen; 2359 u_int32_t datadoff; 2360 u_int32_t dataulen; 2361 u_int32_t dataflags; 2362 void *datadata; 2363 u_int32_t datasize; 2364 u_int32_t flags; 2365 __dbc_get_reply *replyp; 2366 int * freep; 2367{ 2368 DBC *dbc; 2369 DBT key, data; 2370 ENV *env; 2371 ct_entry *dbc_ctp; 2372 int ret; 2373 2374 ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); 2375 dbc = (DBC *)dbc_ctp->ct_anyp; 2376 env = dbc->env; 2377 2378 replyp->keydata.keydata_val = NULL; 2379 replyp->datadata.datadata_val = NULL; 2380 *freep = 0; 2381 memset(&key, 0, sizeof(key)); 2382 memset(&data, 0, sizeof(data)); 2383 2384 /* Set up key and data DBT */ 2385 key.dlen = keydlen; 2386 key.ulen = keyulen; 2387 key.doff = keydoff; 2388 key.size = keysize; 2389 if (keyflags & DB_DBT_USERMEM) { 2390 if ((ret = __os_umalloc(env, key.ulen, &key.data)) != 0) 2391 goto err; 2392 if (keydata != 0) 2393 memcpy(key.data, keydata, 2394 (key.size < key.ulen) ? key.size : key.ulen); 2395 key.flags = DB_DBT_USERMEM; 2396 } else { 2397 key.data = keydata; 2398 key.flags = DB_DBT_MALLOC; 2399 } 2400 if (keyflags & DB_DBT_PARTIAL) 2401 key.flags |= DB_DBT_PARTIAL; 2402 2403 data.dlen = datadlen; 2404 data.ulen = dataulen; 2405 data.doff = datadoff; 2406 data.size = datasize; 2407 if (flags & (DB_MULTIPLE | DB_MULTIPLE_KEY) || 2408 dataflags & DB_DBT_USERMEM) { 2409 if ((ret = __os_umalloc(env, data.ulen, &data.data)) != 0) 2410 goto err; 2411 if (datadata != 0) 2412 memcpy(data.data, datadata, 2413 (data.size < data.ulen) ? data.size : data.ulen); 2414 data.flags = DB_DBT_USERMEM; 2415 } else { 2416 data.data = datadata; 2417 data.flags = DB_DBT_MALLOC; 2418 } 2419 if (dataflags & DB_DBT_PARTIAL) 2420 data.flags |= DB_DBT_PARTIAL; 2421 2422 /* Got all our stuff, now do the get */ 2423 ret = dbc->get(dbc, &key, &data, flags); 2424 2425 /* 2426 * Otherwise just status. 2427 */ 2428 if (ret == 0) { 2429 /* 2430 * XXX 2431 * We need to xdr_free whatever we are returning, next time. 2432 * However, DB does not allocate a new key if one was given 2433 * and we'd be free'ing up space allocated in the request. 2434 * So, allocate a new key/data pointer if it is the same one 2435 * as in the request. 2436 */ 2437 *freep = 1; 2438 /* 2439 * Key 2440 */ 2441 if (key.data == keydata) { 2442 ret = __os_umalloc(env, key.size, 2443 &replyp->keydata.keydata_val); 2444 if (ret != 0) 2445 goto err; 2446 memcpy(replyp->keydata.keydata_val, key.data, key.size); 2447 } else 2448 replyp->keydata.keydata_val = key.data; 2449 2450 replyp->keydata.keydata_len = key.size; 2451 2452 /* 2453 * Data 2454 */ 2455 if (data.data == datadata) { 2456 ret = __os_umalloc(env, data.size, 2457 &replyp->datadata.datadata_val); 2458 if (ret != 0) 2459 goto err; 2460 memcpy(replyp->datadata.datadata_val, data.data, 2461 data.size); 2462 } else 2463 replyp->datadata.datadata_val = data.data; 2464 replyp->datadata.datadata_len = data.size; 2465 } else { 2466err: FREE_IF_CHANGED(env, key.data, keydata); 2467 FREE_IF_CHANGED(env, data.data, datadata); 2468 FREE_IF_CHANGED(env, replyp->keydata.keydata_val, key.data); 2469 FREE_IF_CHANGED(env, replyp->datadata.datadata_val, data.data); 2470 replyp->keydata.keydata_val = NULL; 2471 replyp->keydata.keydata_len = 0; 2472 replyp->datadata.datadata_val = NULL; 2473 replyp->datadata.datadata_len = 0; 2474 *freep = 0; 2475 } 2476 replyp->status = ret; 2477 return; 2478} 2479 2480/* 2481 * PUBLIC: void __dbc_pget_proc __P((u_int, u_int32_t, u_int32_t, u_int32_t, 2482 * PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, 2483 * PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, 2484 * PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, __dbc_pget_reply *, 2485 * PUBLIC: int *)); 2486 */ 2487void 2488__dbc_pget_proc(dbccl_id, skeydlen, skeydoff, skeyulen, skeyflags, 2489 skeydata, skeysize, pkeydlen, pkeydoff, pkeyulen, pkeyflags, pkeydata, 2490 pkeysize, datadlen, datadoff, dataulen, dataflags, datadata, datasize, 2491 flags, replyp, freep) 2492 u_int dbccl_id; 2493 u_int32_t skeydlen; 2494 u_int32_t skeydoff; 2495 u_int32_t skeyulen; 2496 u_int32_t skeyflags; 2497 void *skeydata; 2498 u_int32_t skeysize; 2499 u_int32_t pkeydlen; 2500 u_int32_t pkeydoff; 2501 u_int32_t pkeyulen; 2502 u_int32_t pkeyflags; 2503 void *pkeydata; 2504 u_int32_t pkeysize; 2505 u_int32_t datadlen; 2506 u_int32_t datadoff; 2507 u_int32_t dataulen; 2508 u_int32_t dataflags; 2509 void *datadata; 2510 u_int32_t datasize; 2511 u_int32_t flags; 2512 __dbc_pget_reply *replyp; 2513 int * freep; 2514{ 2515 DBC *dbc; 2516 DBT skey, pkey, data; 2517 ENV *env; 2518 ct_entry *dbc_ctp; 2519 int ret; 2520 2521 ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); 2522 dbc = (DBC *)dbc_ctp->ct_anyp; 2523 env = dbc->env; 2524 2525 replyp->skeydata.skeydata_val = NULL; 2526 replyp->pkeydata.pkeydata_val = NULL; 2527 replyp->datadata.datadata_val = NULL; 2528 *freep = 0; 2529 memset(&skey, 0, sizeof(skey)); 2530 memset(&pkey, 0, sizeof(pkey)); 2531 memset(&data, 0, sizeof(data)); 2532 2533 /* 2534 * Ignore memory related flags on server. 2535 */ 2536 /* Set up key and data DBT */ 2537 skey.flags = DB_DBT_MALLOC; 2538 skey.dlen = skeydlen; 2539 skey.ulen = skeyulen; 2540 skey.doff = skeydoff; 2541 if (skeyflags & DB_DBT_PARTIAL) 2542 skey.flags |= DB_DBT_PARTIAL; 2543 skey.size = skeysize; 2544 skey.data = skeydata; 2545 2546 pkey.flags = DB_DBT_MALLOC; 2547 pkey.dlen = pkeydlen; 2548 pkey.ulen = pkeyulen; 2549 pkey.doff = pkeydoff; 2550 if (pkeyflags & DB_DBT_PARTIAL) 2551 pkey.flags |= DB_DBT_PARTIAL; 2552 pkey.size = pkeysize; 2553 pkey.data = pkeydata; 2554 2555 data.flags = DB_DBT_MALLOC; 2556 data.dlen = datadlen; 2557 data.ulen = dataulen; 2558 data.doff = datadoff; 2559 if (dataflags & DB_DBT_PARTIAL) 2560 data.flags |= DB_DBT_PARTIAL; 2561 data.size = datasize; 2562 data.data = datadata; 2563 2564 /* Got all our stuff, now do the get */ 2565 ret = dbc->pget(dbc, &skey, &pkey, &data, flags); 2566 /* 2567 * Otherwise just status. 2568 */ 2569 if (ret == 0) { 2570 /* 2571 * XXX 2572 * We need to xdr_free whatever we are returning, next time. 2573 * However, DB does not allocate a new key if one was given 2574 * and we'd be free'ing up space allocated in the request. 2575 * So, allocate a new key/data pointer if it is the same one 2576 * as in the request. 2577 */ 2578 *freep = 1; 2579 /* 2580 * Key 2581 */ 2582 if (skey.data == skeydata) { 2583 ret = __os_umalloc(env, 2584 skey.size, &replyp->skeydata.skeydata_val); 2585 if (ret != 0) 2586 goto err; 2587 memcpy(replyp->skeydata.skeydata_val, skey.data, 2588 skey.size); 2589 } else 2590 replyp->skeydata.skeydata_val = skey.data; 2591 replyp->skeydata.skeydata_len = skey.size; 2592 2593 /* 2594 * Primary key 2595 */ 2596 if (pkey.data == pkeydata) { 2597 ret = __os_umalloc(env, 2598 pkey.size, &replyp->pkeydata.pkeydata_val); 2599 if (ret != 0) 2600 goto err; 2601 /* 2602 * We can set it to 2, because they cannot send the 2603 * pkey over without sending the skey over too. 2604 * So if they did send a pkey, they must have sent 2605 * the skey as well. 2606 */ 2607 memcpy(replyp->pkeydata.pkeydata_val, pkey.data, 2608 pkey.size); 2609 } else 2610 replyp->pkeydata.pkeydata_val = pkey.data; 2611 replyp->pkeydata.pkeydata_len = pkey.size; 2612 2613 /* 2614 * Data 2615 */ 2616 if (data.data == datadata) { 2617 ret = __os_umalloc(env, 2618 data.size, &replyp->datadata.datadata_val); 2619 if (ret != 0) 2620 goto err; 2621 memcpy(replyp->datadata.datadata_val, data.data, 2622 data.size); 2623 } else 2624 replyp->datadata.datadata_val = data.data; 2625 replyp->datadata.datadata_len = data.size; 2626 } else { 2627err: FREE_IF_CHANGED(env, skey.data, skeydata); 2628 FREE_IF_CHANGED(env, pkey.data, pkeydata); 2629 FREE_IF_CHANGED(env, data.data, datadata); 2630 FREE_IF_CHANGED(env, replyp->skeydata.skeydata_val, skey.data); 2631 FREE_IF_CHANGED(env, replyp->pkeydata.pkeydata_val, pkey.data); 2632 FREE_IF_CHANGED(env, replyp->datadata.datadata_val, data.data); 2633 replyp->skeydata.skeydata_val = NULL; 2634 replyp->skeydata.skeydata_len = 0; 2635 replyp->pkeydata.pkeydata_val = NULL; 2636 replyp->pkeydata.pkeydata_len = 0; 2637 replyp->datadata.datadata_val = NULL; 2638 replyp->datadata.datadata_len = 0; 2639 *freep = 0; 2640 } 2641 replyp->status = ret; 2642 return; 2643} 2644 2645/* 2646 * PUBLIC: void __dbc_put_proc __P((u_int, u_int32_t, u_int32_t, u_int32_t, 2647 * PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, 2648 * PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, __dbc_put_reply *, 2649 * PUBLIC: int *)); 2650 */ 2651void 2652__dbc_put_proc(dbccl_id, keydlen, keydoff, keyulen, keyflags, keydata, 2653 keysize, datadlen, datadoff, dataulen, dataflags, datadata, datasize, 2654 flags, replyp, freep) 2655 u_int dbccl_id; 2656 u_int32_t keydlen; 2657 u_int32_t keydoff; 2658 u_int32_t keyulen; 2659 u_int32_t keyflags; 2660 void *keydata; 2661 u_int32_t keysize; 2662 u_int32_t datadlen; 2663 u_int32_t datadoff; 2664 u_int32_t dataulen; 2665 u_int32_t dataflags; 2666 void *datadata; 2667 u_int32_t datasize; 2668 u_int32_t flags; 2669 __dbc_put_reply *replyp; 2670 int * freep; 2671{ 2672 DB *dbp; 2673 DBC *dbc; 2674 DBT key, data; 2675 ct_entry *dbc_ctp; 2676 int ret; 2677 2678 ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); 2679 dbc = (DBC *)dbc_ctp->ct_anyp; 2680 dbp = (DB *)dbc_ctp->ct_parent->ct_anyp; 2681 2682 memset(&key, 0, sizeof(key)); 2683 memset(&data, 0, sizeof(data)); 2684 2685 /* Set up key and data DBT */ 2686 key.dlen = keydlen; 2687 key.ulen = keyulen; 2688 key.doff = keydoff; 2689 /* 2690 * Ignore memory related flags on server. 2691 */ 2692 key.flags = 0; 2693 if (keyflags & DB_DBT_PARTIAL) 2694 key.flags |= DB_DBT_PARTIAL; 2695 key.size = keysize; 2696 key.data = keydata; 2697 2698 data.dlen = datadlen; 2699 data.ulen = dataulen; 2700 data.doff = datadoff; 2701 data.flags = dataflags; 2702 data.size = datasize; 2703 data.data = datadata; 2704 2705 /* Got all our stuff, now do the put */ 2706 ret = dbc->put(dbc, &key, &data, flags); 2707 2708 *freep = 0; 2709 if (ret == 0 && (flags == DB_AFTER || flags == DB_BEFORE) && 2710 dbp->type == DB_RECNO) { 2711 /* 2712 * We need to xdr_free whatever we are returning, next time. 2713 */ 2714 replyp->keydata.keydata_val = key.data; 2715 replyp->keydata.keydata_len = key.size; 2716 } else { 2717 replyp->keydata.keydata_val = NULL; 2718 replyp->keydata.keydata_len = 0; 2719 } 2720 replyp->status = ret; 2721 return; 2722} 2723 2724/* 2725 * PUBLIC: void 2726 * PUBLIC: __dbc_get_priority_proc __P((u_int, __dbc_get_priority_reply *)); 2727 */ 2728void 2729__dbc_get_priority_proc(dbccl_id, replyp) 2730 u_int dbccl_id; 2731 __dbc_get_priority_reply *replyp; 2732{ 2733 DBC *dbc; 2734 ct_entry *dbc_ctp; 2735 2736 ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); 2737 dbc = (DBC *)dbc_ctp->ct_anyp; 2738 2739 replyp->status = 2740 dbc->get_priority(dbc, (DB_CACHE_PRIORITY *)&replyp->priority); 2741} 2742 2743/* 2744 * PUBLIC: void __dbc_set_priority_proc __P((u_int, u_int32_t, 2745 * PUBLIC: __dbc_set_priority_reply *)); 2746 */ 2747void 2748__dbc_set_priority_proc(dbccl_id, priority, replyp) 2749 u_int dbccl_id; 2750 u_int32_t priority; 2751 __dbc_set_priority_reply *replyp; 2752{ 2753 DBC *dbc; 2754 ct_entry *dbc_ctp; 2755 int ret; 2756 2757 ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); 2758 dbc = (DBC *)dbc_ctp->ct_anyp; 2759 2760 ret = dbc->set_priority(dbc, (DB_CACHE_PRIORITY)priority); 2761 2762 replyp->status = ret; 2763 return; 2764} 2765