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