db_server_cxxproc.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:48k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 2001-2002
  5.  *      Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifdef HAVE_RPC
  9. #ifndef lint
  10. static const char revid[] = "$Id: db_server_cxxproc.cpp,v 1.12 2002/08/09 01:56:08 bostic Exp $";
  11. #endif /* not lint */
  12. #ifndef NO_SYSTEM_INCLUDES
  13. #include <sys/types.h>
  14. #include <rpc/rpc.h>
  15. #include <string.h>
  16. #endif
  17. #include "dbinc_auto/db_server.h"
  18. #include "db_int.h"
  19. #include "db_cxx.h"
  20. extern "C" {
  21. #include "dbinc/db_server_int.h"
  22. #include "dbinc_auto/rpc_server_ext.h"
  23. }
  24. /* BEGIN __env_cachesize_proc */
  25. extern "C" void
  26. __env_cachesize_proc(
  27. long dbenvcl_id,
  28. u_int32_t gbytes,
  29. u_int32_t bytes,
  30. u_int32_t ncache,
  31. __env_cachesize_reply *replyp)
  32. /* END __env_cachesize_proc */
  33. {
  34. DbEnv *dbenv;
  35. ct_entry *dbenv_ctp;
  36. int ret;
  37. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  38. dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
  39. ret = dbenv->set_cachesize(gbytes, bytes, ncache);
  40. replyp->status = ret;
  41. return;
  42. }
  43. /* BEGIN __env_close_proc */
  44. extern "C" void
  45. __env_close_proc(
  46. long dbenvcl_id,
  47. u_int32_t flags,
  48. __env_close_reply *replyp)
  49. /* END __env_close_proc */
  50. {
  51. ct_entry *dbenv_ctp;
  52. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  53. replyp->status = __dbenv_close_int(dbenvcl_id, flags, 0);
  54. return;
  55. }
  56. /* BEGIN __env_create_proc */
  57. extern "C" void
  58. __env_create_proc(
  59. u_int32_t timeout,
  60. __env_create_reply *replyp)
  61. /* END __env_create_proc */
  62. {
  63. DbEnv *dbenv;
  64. ct_entry *ctp;
  65. ctp = new_ct_ent(&replyp->status);
  66. if (ctp == NULL)
  67. return;
  68. dbenv = new DbEnv(DB_CXX_NO_EXCEPTIONS);
  69. ctp->ct_envp = dbenv;
  70. ctp->ct_type = CT_ENV;
  71. ctp->ct_parent = NULL;
  72. ctp->ct_envparent = ctp;
  73. __dbsrv_settimeout(ctp, timeout);
  74. __dbsrv_active(ctp);
  75. replyp->envcl_id = ctp->ct_id;
  76. replyp->status = 0;
  77. return;
  78. }
  79. /* BEGIN __env_dbremove_proc */
  80. extern "C" void
  81. __env_dbremove_proc(
  82. long dbenvcl_id,
  83. long txnpcl_id,
  84. char *name,
  85. char *subdb,
  86. u_int32_t flags,
  87. __env_dbremove_reply *replyp)
  88. /* END __env_dbremove_proc */
  89. {
  90. int ret;
  91. DbEnv *dbenv;
  92. DbTxn *txnp;
  93. ct_entry *dbenv_ctp, *txnp_ctp;
  94. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  95. dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
  96. if (txnpcl_id != 0) {
  97. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  98. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  99. } else
  100. txnp = NULL;
  101. ret = dbenv->dbremove(txnp, name, subdb, flags);
  102. replyp->status = ret;
  103. return;
  104. }
  105. /* BEGIN __env_dbrename_proc */
  106. void
  107. __env_dbrename_proc(
  108. long dbenvcl_id,
  109. long txnpcl_id,
  110. char *name,
  111. char *subdb,
  112. char *newname,
  113. u_int32_t flags,
  114. __env_dbrename_reply *replyp)
  115. /* END __env_dbrename_proc */
  116. {
  117. int ret;
  118. DbEnv *dbenv;
  119. DbTxn *txnp;
  120. ct_entry *dbenv_ctp, *txnp_ctp;
  121. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  122. dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
  123. if (txnpcl_id != 0) {
  124. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  125. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  126. } else
  127. txnp = NULL;
  128. ret = dbenv->dbrename(txnp, name, subdb, newname, flags);
  129. replyp->status = ret;
  130. return;
  131. }
  132. /* BEGIN __env_encrypt_proc */
  133. extern "C" void
  134. __env_encrypt_proc(
  135. long dbenvcl_id,
  136. char *passwd,
  137. u_int32_t flags,
  138. __env_encrypt_reply *replyp)
  139. /* END __env_encrypt_proc */
  140. {
  141. DbEnv *dbenv;
  142. ct_entry *dbenv_ctp;
  143. int ret;
  144. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  145. dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
  146. ret = dbenv->set_encrypt(passwd, flags);
  147. replyp->status = ret;
  148. return;
  149. }
  150. /* BEGIN __env_flags_proc */
  151. extern "C" void
  152. __env_flags_proc(
  153. long dbenvcl_id,
  154. u_int32_t flags,
  155. u_int32_t onoff,
  156. __env_flags_reply *replyp)
  157. /* END __env_flags_proc */
  158. {
  159. DbEnv *dbenv;
  160. ct_entry *dbenv_ctp;
  161. int ret;
  162. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  163. dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
  164. ret = dbenv->set_flags(flags, onoff);
  165. if (onoff)
  166. dbenv_ctp->ct_envdp.onflags = flags;
  167. else
  168. dbenv_ctp->ct_envdp.offflags = flags;
  169. replyp->status = ret;
  170. return;
  171. }
  172. /* BEGIN __env_open_proc */
  173. extern "C" void
  174. __env_open_proc(
  175. long dbenvcl_id,
  176. char *home,
  177. u_int32_t flags,
  178. u_int32_t mode,
  179. __env_open_reply *replyp)
  180. /* END __env_open_proc */
  181. {
  182. DbEnv *dbenv;
  183. ct_entry *dbenv_ctp, *new_ctp;
  184. u_int32_t newflags, shareflags;
  185. int ret;
  186. home_entry *fullhome;
  187. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  188. dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
  189. fullhome = get_home(home);
  190. if (fullhome == NULL) {
  191. ret = DB_NOSERVER_HOME;
  192. goto out;
  193. }
  194. /*
  195.  * If they are using locking do deadlock detection for them,
  196.  * internally.
  197.  */
  198. if ((flags & DB_INIT_LOCK) &&
  199.     (ret = dbenv->set_lk_detect(DB_LOCK_DEFAULT)) != 0)
  200. goto out;
  201. if (__dbsrv_verbose) {
  202. dbenv->set_errfile(stderr);
  203. dbenv->set_errpfx(fullhome->home);
  204. }
  205. /*
  206.  * Mask off flags we ignore
  207.  */
  208. newflags = (flags & ~DB_SERVER_FLAGMASK);
  209. shareflags = (newflags & DB_SERVER_ENVFLAGS);
  210. /*
  211.  * Check now whether we can share a handle for this env.
  212.  */
  213. replyp->envcl_id = dbenvcl_id;
  214. if ((new_ctp = __dbsrv_shareenv(dbenv_ctp, fullhome, shareflags))
  215.     != NULL) {
  216. /*
  217.  * We can share, clean up old  ID, set new one.
  218.  */
  219. if (__dbsrv_verbose)
  220. printf("Sharing env ID %ldn", new_ctp->ct_id);
  221. replyp->envcl_id = new_ctp->ct_id;
  222. ret = __dbenv_close_int(dbenvcl_id, 0, 0);
  223. } else {
  224. ret = dbenv->open(fullhome->home, newflags, mode);
  225. dbenv_ctp->ct_envdp.home = fullhome;
  226. dbenv_ctp->ct_envdp.envflags = shareflags;
  227. }
  228. out: replyp->status = ret;
  229. return;
  230. }
  231. /* BEGIN __env_remove_proc */
  232. extern "C" void
  233. __env_remove_proc(
  234. long dbenvcl_id,
  235. char *home,
  236. u_int32_t flags,
  237. __env_remove_reply *replyp)
  238. /* END __env_remove_proc */
  239. {
  240. DbEnv *dbenv;
  241. ct_entry *dbenv_ctp;
  242. int ret;
  243. home_entry *fullhome;
  244. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  245. dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
  246. fullhome = get_home(home);
  247. if (fullhome == NULL) {
  248. replyp->status = DB_NOSERVER_HOME;
  249. return;
  250. }
  251. ret = dbenv->remove(fullhome->home, flags);
  252. __dbdel_ctp(dbenv_ctp);
  253. replyp->status = ret;
  254. return;
  255. }
  256. /* BEGIN __txn_abort_proc */
  257. extern "C" void
  258. __txn_abort_proc(
  259. long txnpcl_id,
  260. __txn_abort_reply *replyp)
  261. /* END __txn_abort_proc */
  262. {
  263. DbTxn *txnp;
  264. ct_entry *txnp_ctp;
  265. int ret;
  266. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  267. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  268. ret = txnp->abort();
  269. __dbdel_ctp(txnp_ctp);
  270. replyp->status = ret;
  271. return;
  272. }
  273. /* BEGIN __txn_begin_proc */
  274. extern "C" void
  275. __txn_begin_proc(
  276. long dbenvcl_id,
  277. long parentcl_id,
  278. u_int32_t flags,
  279. __txn_begin_reply *replyp)
  280. /* END __txn_begin_proc */
  281. {
  282. DbEnv *dbenv;
  283. DbTxn *parent, *txnp;
  284. ct_entry *ctp, *dbenv_ctp, *parent_ctp;
  285. int ret;
  286. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  287. dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
  288. parent_ctp = NULL;
  289. ctp = new_ct_ent(&replyp->status);
  290. if (ctp == NULL)
  291. return;
  292. if (parentcl_id != 0) {
  293. ACTIVATE_CTP(parent_ctp, parentcl_id, CT_TXN);
  294. parent = (DbTxn *)parent_ctp->ct_anyp;
  295. ctp->ct_activep = parent_ctp->ct_activep;
  296. } else
  297. parent = NULL;
  298. ret = dbenv->txn_begin(parent, &txnp, flags);
  299. if (ret == 0) {
  300. ctp->ct_txnp = txnp;
  301. ctp->ct_type = CT_TXN;
  302. ctp->ct_parent = parent_ctp;
  303. ctp->ct_envparent = dbenv_ctp;
  304. replyp->txnidcl_id = ctp->ct_id;
  305. __dbsrv_settimeout(ctp, dbenv_ctp->ct_timeout);
  306. __dbsrv_active(ctp);
  307. } else
  308. __dbclear_ctp(ctp);
  309. replyp->status = ret;
  310. return;
  311. }
  312. /* BEGIN __txn_commit_proc */
  313. extern "C" void
  314. __txn_commit_proc(
  315. long txnpcl_id,
  316. u_int32_t flags,
  317. __txn_commit_reply *replyp)
  318. /* END __txn_commit_proc */
  319. {
  320. DbTxn *txnp;
  321. ct_entry *txnp_ctp;
  322. int ret;
  323. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  324. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  325. ret = txnp->commit(flags);
  326. __dbdel_ctp(txnp_ctp);
  327. replyp->status = ret;
  328. return;
  329. }
  330. /* BEGIN __txn_discard_proc */
  331. extern "C" void
  332. __txn_discard_proc(
  333. long txnpcl_id,
  334. u_int32_t flags,
  335. __txn_discard_reply *replyp)
  336. /* END __txn_discard_proc */
  337. {
  338. DbTxn *txnp;
  339. ct_entry *txnp_ctp;
  340. int ret;
  341. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  342. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  343. ret = txnp->discard(flags);
  344. __dbdel_ctp(txnp_ctp);
  345. replyp->status = ret;
  346. return;
  347. }
  348. /* BEGIN __txn_prepare_proc */
  349. extern "C" void
  350. __txn_prepare_proc(
  351. long txnpcl_id,
  352. u_int8_t *gid,
  353. __txn_prepare_reply *replyp)
  354. /* END __txn_prepare_proc */
  355. {
  356. DbTxn *txnp;
  357. ct_entry *txnp_ctp;
  358. int ret;
  359. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  360. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  361. ret = txnp->prepare(gid);
  362. replyp->status = ret;
  363. return;
  364. }
  365. /* BEGIN __txn_recover_proc */
  366. extern "C" void
  367. __txn_recover_proc(
  368. long dbenvcl_id,
  369. u_int32_t count,
  370. u_int32_t flags,
  371. __txn_recover_reply *replyp,
  372. int * freep)
  373. /* END __txn_recover_proc */
  374. {
  375. DbEnv *dbenv;
  376. DbPreplist *dbprep, *p;
  377. ct_entry *dbenv_ctp, *ctp;
  378. long erri, i, retcount;
  379. u_int32_t *txnidp;
  380. int ret;
  381. char *gid;
  382. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  383. dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
  384. *freep = 0;
  385. if ((ret =
  386.     __os_malloc(dbenv->get_DB_ENV(), count * sizeof(DbPreplist), &dbprep)) != 0)
  387. goto out;
  388. if ((ret =
  389.     dbenv->txn_recover(dbprep, count, &retcount, flags)) != 0)
  390. goto out;
  391. /*
  392.  * If there is nothing, success, but it's easy.
  393.  */
  394. replyp->retcount = retcount; // TODO: fix C++ txn_recover
  395. if (retcount == 0) {
  396. replyp->txn.txn_val = NULL;
  397. replyp->txn.txn_len = 0;
  398. replyp->gid.gid_val = NULL;
  399. replyp->gid.gid_len = 0;
  400. }
  401. /*
  402.  * We have our txn list.  Now we need to allocate the space for
  403.  * the txn ID array and the GID array and set them up.
  404.  */
  405. if ((ret = __os_calloc(dbenv->get_DB_ENV(), retcount, sizeof(u_int32_t),
  406.     &replyp->txn.txn_val)) != 0)
  407. goto out;
  408. replyp->txn.txn_len = retcount * sizeof(u_int32_t);
  409. if ((ret = __os_calloc(dbenv->get_DB_ENV(), retcount, DB_XIDDATASIZE,
  410.     &replyp->gid.gid_val)) != 0) {
  411. __os_free(dbenv->get_DB_ENV(), replyp->txn.txn_val);
  412. goto out;
  413. }
  414. replyp->gid.gid_len = retcount * DB_XIDDATASIZE;
  415. /*
  416.  * Now walk through our results, creating parallel arrays
  417.  * to send back.  For each entry we need to create a new
  418.  * txn ctp and then fill in the array info.
  419.  */
  420. i = 0;
  421. p = dbprep;
  422. gid = replyp->gid.gid_val;
  423. txnidp = replyp->txn.txn_val;
  424. while (i++ < retcount) {
  425. ctp = new_ct_ent(&ret);
  426. if (ret != 0) {
  427. i--;
  428. goto out2;
  429. }
  430. ctp->ct_txnp = p->txn;
  431. ctp->ct_type = CT_TXN;
  432. ctp->ct_parent = NULL;
  433. ctp->ct_envparent = dbenv_ctp;
  434. __dbsrv_settimeout(ctp, dbenv_ctp->ct_timeout);
  435. __dbsrv_active(ctp);
  436. *txnidp = ctp->ct_id;
  437. memcpy(gid, p->gid, DB_XIDDATASIZE);
  438. p++;
  439. txnidp++;
  440. gid += DB_XIDDATASIZE;
  441. }
  442. /*
  443.  * If we get here, we have success and we have to set freep
  444.  * so it'll get properly freed next time.
  445.  */
  446. *freep = 1;
  447. out:
  448. if (dbprep != NULL)
  449. __os_free(dbenv->get_DB_ENV(), dbprep);
  450. replyp->status = ret;
  451. return;
  452. out2:
  453. /*
  454.  * We had an error in the middle of creating our new txn
  455.  * ct entries.  We have to unwind all that we have done.  Ugh.
  456.  */
  457. for (txnidp = replyp->txn.txn_val, erri = 0;
  458.     erri < i; erri++, txnidp++) {
  459. ctp = get_tableent(*txnidp);
  460. __dbclear_ctp(ctp);
  461. }
  462. __os_free(dbenv->get_DB_ENV(), replyp->txn.txn_val);
  463. __os_free(dbenv->get_DB_ENV(), replyp->gid.gid_val);
  464. __os_free(dbenv->get_DB_ENV(), dbprep);
  465. replyp->status = ret;
  466. return;
  467. }
  468. /* BEGIN __db_bt_maxkey_proc */
  469. extern "C" void
  470. __db_bt_maxkey_proc(
  471. long dbpcl_id,
  472. u_int32_t maxkey,
  473. __db_bt_maxkey_reply *replyp)
  474. /* END __db_bt_maxkey_proc */
  475. {
  476. Db *dbp;
  477. ct_entry *dbp_ctp;
  478. int ret;
  479. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  480. dbp = (Db *)dbp_ctp->ct_anyp;
  481. ret = dbp->set_bt_maxkey(maxkey);
  482. replyp->status = ret;
  483. return;
  484. }
  485. /* BEGIN __db_associate_proc */
  486. extern "C" void
  487. __db_associate_proc(
  488. long dbpcl_id,
  489. long txnpcl_id,
  490. long sdbpcl_id,
  491. u_int32_t flags,
  492. __db_associate_reply *replyp)
  493. /* END __db_associate_proc */
  494. {
  495. Db *dbp, *sdbp;
  496. DbTxn *txnp;
  497. ct_entry *dbp_ctp, *sdbp_ctp, *txnp_ctp;
  498. int ret;
  499. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  500. dbp = (Db *)dbp_ctp->ct_anyp;
  501. ACTIVATE_CTP(sdbp_ctp, sdbpcl_id, CT_DB);
  502. sdbp = (Db *)sdbp_ctp->ct_anyp;
  503. if (txnpcl_id != 0) {
  504. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  505. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  506. } else
  507. txnp = NULL;
  508. /*
  509.  * We do not support DB_CREATE for associate.   Users
  510.  * can only access secondary indices on a read-only basis,
  511.  * so whatever they are looking for needs to be there already.
  512.  */
  513. if (flags != 0)
  514. ret = EINVAL;
  515. else
  516. ret = dbp->associate(txnp, sdbp, NULL, flags);
  517. replyp->status = ret;
  518. return;
  519. }
  520. /* BEGIN __db_bt_minkey_proc */
  521. extern "C" void
  522. __db_bt_minkey_proc(
  523. long dbpcl_id,
  524. u_int32_t minkey,
  525. __db_bt_minkey_reply *replyp)
  526. /* END __db_bt_minkey_proc */
  527. {
  528. Db *dbp;
  529. ct_entry *dbp_ctp;
  530. int ret;
  531. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  532. dbp = (Db *)dbp_ctp->ct_anyp;
  533. ret = dbp->set_bt_minkey(minkey);
  534. replyp->status = ret;
  535. return;
  536. }
  537. /* BEGIN __db_close_proc */
  538. extern "C" void
  539. __db_close_proc(
  540. long dbpcl_id,
  541. u_int32_t flags,
  542. __db_close_reply *replyp)
  543. /* END __db_close_proc */
  544. {
  545. ct_entry *dbp_ctp;
  546. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  547. replyp->status = __db_close_int(dbpcl_id, flags);
  548. return;
  549. }
  550. /* BEGIN __db_create_proc */
  551. extern "C" void
  552. __db_create_proc(
  553. long dbenvcl_id,
  554. u_int32_t flags,
  555. __db_create_reply *replyp)
  556. /* END __db_create_proc */
  557. {
  558. Db *dbp;
  559. DbEnv *dbenv;
  560. ct_entry *dbenv_ctp, *dbp_ctp;
  561. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  562. dbenv = (DbEnv *)dbenv_ctp->ct_anyp;
  563. dbp_ctp = new_ct_ent(&replyp->status);
  564. if (dbp_ctp == NULL)
  565. return ;
  566. /*
  567.  * We actually require env's for databases.  The client should
  568.  * have caught it, but just in case.
  569.  */
  570. DB_ASSERT(dbenv != NULL);
  571. dbp = new Db(dbenv, flags);
  572. dbp_ctp->ct_dbp = dbp;
  573. dbp_ctp->ct_type = CT_DB;
  574. dbp_ctp->ct_parent = dbenv_ctp;
  575. dbp_ctp->ct_envparent = dbenv_ctp;
  576. replyp->dbcl_id = dbp_ctp->ct_id;
  577. replyp->status = 0;
  578. return;
  579. }
  580. /* BEGIN __db_del_proc */
  581. extern "C" void
  582. __db_del_proc(
  583. long dbpcl_id,
  584. long txnpcl_id,
  585. u_int32_t keydlen,
  586. u_int32_t keydoff,
  587. u_int32_t keyulen,
  588. u_int32_t keyflags,
  589. void *keydata,
  590. u_int32_t keysize,
  591. u_int32_t flags,
  592. __db_del_reply *replyp)
  593. /* END __db_del_proc */
  594. {
  595. Db *dbp;
  596. DbTxn *txnp;
  597. ct_entry *dbp_ctp, *txnp_ctp;
  598. int ret;
  599. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  600. dbp = (Db *)dbp_ctp->ct_anyp;
  601. if (txnpcl_id != 0) {
  602. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  603. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  604. } else
  605. txnp = NULL;
  606. /* Set up key */
  607. Dbt key(keydata, keysize);
  608. key.set_dlen(keydlen);
  609. key.set_ulen(keyulen);
  610. key.set_doff(keydoff);
  611. key.set_flags(keyflags);
  612. ret = dbp->del(txnp, &key, flags);
  613. replyp->status = ret;
  614. return;
  615. }
  616. /* BEGIN __db_encrypt_proc */
  617. extern "C" void
  618. __db_encrypt_proc(
  619. long dbpcl_id,
  620. char *passwd,
  621. u_int32_t flags,
  622. __db_encrypt_reply *replyp)
  623. /* END __db_encrypt_proc */
  624. {
  625. Db *dbp;
  626. ct_entry *dbp_ctp;
  627. int ret;
  628. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  629. dbp = (Db *)dbp_ctp->ct_anyp;
  630. ret = dbp->set_encrypt(passwd, flags);
  631. replyp->status = ret;
  632. return;
  633. }
  634. /* BEGIN __db_extentsize_proc */
  635. extern "C" void
  636. __db_extentsize_proc(
  637. long dbpcl_id,
  638. u_int32_t extentsize,
  639. __db_extentsize_reply *replyp)
  640. /* END __db_extentsize_proc */
  641. {
  642. Db *dbp;
  643. ct_entry *dbp_ctp;
  644. int ret;
  645. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  646. dbp = (Db *)dbp_ctp->ct_anyp;
  647. ret = dbp->set_q_extentsize(extentsize);
  648. replyp->status = ret;
  649. return;
  650. }
  651. /* BEGIN __db_flags_proc */
  652. extern "C" void
  653. __db_flags_proc(
  654. long dbpcl_id,
  655. u_int32_t flags,
  656. __db_flags_reply *replyp)
  657. /* END __db_flags_proc */
  658. {
  659. Db *dbp;
  660. ct_entry *dbp_ctp;
  661. int ret;
  662. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  663. dbp = (Db *)dbp_ctp->ct_anyp;
  664. ret = dbp->set_flags(flags);
  665. dbp_ctp->ct_dbdp.setflags = flags;
  666. replyp->status = ret;
  667. return;
  668. }
  669. /* BEGIN __db_get_proc */
  670. extern "C" void
  671. __db_get_proc(
  672. long dbpcl_id,
  673. long txnpcl_id,
  674. u_int32_t keydlen,
  675. u_int32_t keydoff,
  676. u_int32_t keyulen,
  677. u_int32_t keyflags,
  678. void *keydata,
  679. u_int32_t keysize,
  680. u_int32_t datadlen,
  681. u_int32_t datadoff,
  682. u_int32_t dataulen,
  683. u_int32_t dataflags,
  684. void *datadata,
  685. u_int32_t datasize,
  686. u_int32_t flags,
  687. __db_get_reply *replyp,
  688. int * freep)
  689. /* END __db_get_proc */
  690. {
  691. Db *dbp;
  692. DbTxn *txnp;
  693. ct_entry *dbp_ctp, *txnp_ctp;
  694. int key_alloc, bulk_alloc, ret;
  695. void *tmpdata;
  696. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  697. dbp = (Db *)dbp_ctp->ct_anyp;
  698. if (txnpcl_id != 0) {
  699. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  700. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  701. } else
  702. txnp = NULL;
  703. *freep = 0;
  704. bulk_alloc = 0;
  705. /* Set up key and data */
  706. Dbt key(keydata, keysize);
  707. key.set_dlen(keydlen);
  708. key.set_ulen(keyulen);
  709. key.set_doff(keydoff);
  710. /*
  711.  * Ignore memory related flags on server.
  712.  */
  713. key.set_flags(DB_DBT_MALLOC | (keyflags & DB_DBT_PARTIAL));
  714. Dbt data(datadata, datasize);
  715. data.set_dlen(datadlen);
  716. data.set_ulen(dataulen);
  717. data.set_doff(datadoff);
  718. /*
  719.  * Ignore memory related flags on server.
  720.  */
  721. dataflags &= DB_DBT_PARTIAL;
  722. if (flags & DB_MULTIPLE) {
  723. if (data.get_data() == 0) {
  724. ret = __os_umalloc(dbp->get_DB()->dbenv,
  725.     dataulen, &tmpdata);
  726. if (ret != 0)
  727. goto err;
  728. data.set_data(tmpdata);
  729. bulk_alloc = 1;
  730. }
  731. dataflags |= DB_DBT_USERMEM;
  732. } else
  733. dataflags |= DB_DBT_MALLOC;
  734. data.set_flags(dataflags);
  735. /* Got all our stuff, now do the get */
  736. ret = dbp->get(txnp, &key, &data, flags);
  737. /*
  738.  * Otherwise just status.
  739.  */
  740. if (ret == 0) {
  741. /*
  742.  * XXX
  743.  * We need to xdr_free whatever we are returning, next time.
  744.  * However, DB does not allocate a new key if one was given
  745.  * and we'd be free'ing up space allocated in the request.
  746.  * So, allocate a new key/data pointer if it is the same one
  747.  * as in the request.
  748.  */
  749. *freep = 1;
  750. /*
  751.  * Key
  752.  */
  753. key_alloc = 0;
  754. if (key.get_data() == keydata) {
  755. ret = __os_umalloc(dbp->get_DB()->dbenv,
  756.     key.get_size(), &replyp->keydata.keydata_val);
  757. if (ret != 0) {
  758. __os_ufree(dbp->get_DB()->dbenv, key.get_data());
  759. __os_ufree(dbp->get_DB()->dbenv, data.get_data());
  760. goto err;
  761. }
  762. key_alloc = 1;
  763. memcpy(replyp->keydata.keydata_val, key.get_data(), key.get_size());
  764. } else
  765. replyp->keydata.keydata_val = (char *)key.get_data();
  766. replyp->keydata.keydata_len = key.get_size();
  767. /*
  768.  * Data
  769.  */
  770. if (data.get_data() == datadata) {
  771. ret = __os_umalloc(dbp->get_DB()->dbenv,
  772.      data.get_size(), &replyp->datadata.datadata_val);
  773. if (ret != 0) {
  774. __os_ufree(dbp->get_DB()->dbenv, key.get_data());
  775. __os_ufree(dbp->get_DB()->dbenv, data.get_data());
  776. if (key_alloc)
  777. __os_ufree(dbp->get_DB()->dbenv,
  778.     replyp->keydata.keydata_val);
  779. goto err;
  780. }
  781. memcpy(replyp->datadata.datadata_val, data.get_data(),
  782.     data.get_size());
  783. } else
  784. replyp->datadata.datadata_val = (char *)data.get_data();
  785. replyp->datadata.datadata_len = data.get_size();
  786. } else {
  787. err: replyp->keydata.keydata_val = NULL;
  788. replyp->keydata.keydata_len = 0;
  789. replyp->datadata.datadata_val = NULL;
  790. replyp->datadata.datadata_len = 0;
  791. *freep = 0;
  792. if (bulk_alloc)
  793. __os_ufree(dbp->get_DB()->dbenv, data.get_data());
  794. }
  795. replyp->status = ret;
  796. return;
  797. }
  798. /* BEGIN __db_h_ffactor_proc */
  799. extern "C" void
  800. __db_h_ffactor_proc(
  801. long dbpcl_id,
  802. u_int32_t ffactor,
  803. __db_h_ffactor_reply *replyp)
  804. /* END __db_h_ffactor_proc */
  805. {
  806. Db *dbp;
  807. ct_entry *dbp_ctp;
  808. int ret;
  809. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  810. dbp = (Db *)dbp_ctp->ct_anyp;
  811. ret = dbp->set_h_ffactor(ffactor);
  812. replyp->status = ret;
  813. return;
  814. }
  815. /* BEGIN __db_h_nelem_proc */
  816. extern "C" void
  817. __db_h_nelem_proc(
  818. long dbpcl_id,
  819. u_int32_t nelem,
  820. __db_h_nelem_reply *replyp)
  821. /* END __db_h_nelem_proc */
  822. {
  823. Db *dbp;
  824. ct_entry *dbp_ctp;
  825. int ret;
  826. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  827. dbp = (Db *)dbp_ctp->ct_anyp;
  828. ret = dbp->set_h_nelem(nelem);
  829. replyp->status = ret;
  830. return;
  831. }
  832. /* BEGIN __db_key_range_proc */
  833. extern "C" void
  834. __db_key_range_proc(
  835. long dbpcl_id,
  836. long txnpcl_id,
  837. u_int32_t keydlen,
  838. u_int32_t keydoff,
  839. u_int32_t keyulen,
  840. u_int32_t keyflags,
  841. void *keydata,
  842. u_int32_t keysize,
  843. u_int32_t flags,
  844. __db_key_range_reply *replyp)
  845. /* END __db_key_range_proc */
  846. {
  847. Db *dbp;
  848. DB_KEY_RANGE range;
  849. DbTxn *txnp;
  850. ct_entry *dbp_ctp, *txnp_ctp;
  851. int ret;
  852. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  853. dbp = (Db *)dbp_ctp->ct_anyp;
  854. if (txnpcl_id != 0) {
  855. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  856. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  857. } else
  858. txnp = NULL;
  859. /* Set up key */
  860. Dbt key(keydata, keysize);
  861. key.set_dlen(keydlen);
  862. key.set_ulen(keyulen);
  863. key.set_doff(keydoff);
  864. key.set_flags(keyflags);
  865. ret = dbp->key_range(txnp, &key, &range, flags);
  866. replyp->status = ret;
  867. replyp->less = range.less;
  868. replyp->equal = range.equal;
  869. replyp->greater = range.greater;
  870. return;
  871. }
  872. /* BEGIN __db_lorder_proc */
  873. extern "C" void
  874. __db_lorder_proc(
  875. long dbpcl_id,
  876. u_int32_t lorder,
  877. __db_lorder_reply *replyp)
  878. /* END __db_lorder_proc */
  879. {
  880. Db *dbp;
  881. ct_entry *dbp_ctp;
  882. int ret;
  883. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  884. dbp = (Db *)dbp_ctp->ct_anyp;
  885. ret = dbp->set_lorder(lorder);
  886. replyp->status = ret;
  887. return;
  888. }
  889. /* BEGIN __db_open_proc */
  890. extern "C" void
  891. __db_open_proc(
  892. long dbpcl_id,
  893. long txnpcl_id,
  894. char *name,
  895. char *subdb,
  896. u_int32_t type,
  897. u_int32_t flags,
  898. u_int32_t mode,
  899. __db_open_reply *replyp)
  900. /* END __db_open_proc */
  901. {
  902. Db *dbp;
  903. DbTxn *txnp;
  904. DBTYPE dbtype;
  905. ct_entry *dbp_ctp, *new_ctp, *txnp_ctp;
  906. int isswapped, ret;
  907. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  908. dbp = (Db *)dbp_ctp->ct_anyp;
  909. if (txnpcl_id != 0) {
  910. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  911. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  912. } else
  913. txnp = NULL;
  914. replyp->dbcl_id = dbpcl_id;
  915. if ((new_ctp = __dbsrv_sharedb(dbp_ctp, name, subdb, (DBTYPE)type, flags))
  916.     != NULL) {
  917. /*
  918.  * We can share, clean up old ID, set new one.
  919.  */
  920. if (__dbsrv_verbose)
  921. printf("Sharing db ID %ldn", new_ctp->ct_id);
  922. replyp->dbcl_id = new_ctp->ct_id;
  923. ret = __db_close_int(dbpcl_id, 0);
  924. goto out;
  925. }
  926. ret = dbp->open(txnp, name, subdb, (DBTYPE)type, flags, mode);
  927. if (ret == 0) {
  928. (void)dbp->get_type(&dbtype);
  929. replyp->type = dbtype;
  930. /* XXX
  931.  * Tcl needs to peek at dbp->flags for DB_AM_DUP.  Send
  932.  * this dbp's flags back.
  933.  */
  934. replyp->dbflags = (int) dbp->get_DB()->flags;
  935. /*
  936.  * We need to determine the byte order of the database
  937.  * and send it back to the client.  Determine it by
  938.  * the server's native order and the swapped value of
  939.  * the DB itself.
  940.  */
  941. (void)dbp->get_byteswapped(&isswapped);
  942. if (__db_byteorder(NULL, 1234) == 0) {
  943. if (isswapped == 0)
  944. replyp->lorder = 1234;
  945. else
  946. replyp->lorder = 4321;
  947. } else {
  948. if (isswapped == 0)
  949. replyp->lorder = 4321;
  950. else
  951. replyp->lorder = 1234;
  952. }
  953. dbp_ctp->ct_dbdp.type = dbtype;
  954. dbp_ctp->ct_dbdp.dbflags = LF_ISSET(DB_SERVER_DBFLAGS);
  955. if (name == NULL)
  956. dbp_ctp->ct_dbdp.db = NULL;
  957. else if ((ret = __os_strdup(dbp->get_DB()->dbenv, name,
  958.     &dbp_ctp->ct_dbdp.db)) != 0)
  959. goto out;
  960. if (subdb == NULL)
  961. dbp_ctp->ct_dbdp.subdb = NULL;
  962. else if ((ret = __os_strdup(dbp->get_DB()->dbenv, subdb,
  963.     &dbp_ctp->ct_dbdp.subdb)) != 0)
  964. goto out;
  965. }
  966. out:
  967. replyp->status = ret;
  968. return;
  969. }
  970. /* BEGIN __db_pagesize_proc */
  971. extern "C" void
  972. __db_pagesize_proc(
  973. long dbpcl_id,
  974. u_int32_t pagesize,
  975. __db_pagesize_reply *replyp)
  976. /* END __db_pagesize_proc */
  977. {
  978. Db *dbp;
  979. ct_entry *dbp_ctp;
  980. int ret;
  981. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  982. dbp = (Db *)dbp_ctp->ct_anyp;
  983. ret = dbp->set_pagesize(pagesize);
  984. replyp->status = ret;
  985. return;
  986. }
  987. /* BEGIN __db_pget_proc */
  988. extern "C" void
  989. __db_pget_proc(
  990. long dbpcl_id,
  991. long txnpcl_id,
  992. u_int32_t skeydlen,
  993. u_int32_t skeydoff,
  994. u_int32_t skeyulen,
  995. u_int32_t skeyflags,
  996. void *skeydata,
  997. u_int32_t skeysize,
  998. u_int32_t pkeydlen,
  999. u_int32_t pkeydoff,
  1000. u_int32_t pkeyulen,
  1001. u_int32_t pkeyflags,
  1002. void *pkeydata,
  1003. u_int32_t pkeysize,
  1004. u_int32_t datadlen,
  1005. u_int32_t datadoff,
  1006. u_int32_t dataulen,
  1007. u_int32_t dataflags,
  1008. void *datadata,
  1009. u_int32_t datasize,
  1010. u_int32_t flags,
  1011. __db_pget_reply *replyp,
  1012. int * freep)
  1013. /* END __db_pget_proc */
  1014. {
  1015. Db *dbp;
  1016. DbTxn *txnp;
  1017. ct_entry *dbp_ctp, *txnp_ctp;
  1018. int key_alloc, ret;
  1019. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1020. dbp = (Db *)dbp_ctp->ct_anyp;
  1021. if (txnpcl_id != 0) {
  1022. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  1023. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  1024. } else
  1025. txnp = NULL;
  1026. *freep = 0;
  1027. /*
  1028.  * Ignore memory related flags on server.
  1029.  */
  1030. /* Set up key and data */
  1031. Dbt skey(skeydata, skeysize);
  1032. skey.set_dlen(skeydlen);
  1033. skey.set_ulen(skeyulen);
  1034. skey.set_doff(skeydoff);
  1035. skey.set_flags(DB_DBT_MALLOC | (skeyflags & DB_DBT_PARTIAL));
  1036. Dbt pkey(pkeydata, pkeysize);
  1037. pkey.set_dlen(pkeydlen);
  1038. pkey.set_ulen(pkeyulen);
  1039. pkey.set_doff(pkeydoff);
  1040. pkey.set_flags(DB_DBT_MALLOC | (pkeyflags & DB_DBT_PARTIAL));
  1041. Dbt data(datadata, datasize);
  1042. data.set_dlen(datadlen);
  1043. data.set_ulen(dataulen);
  1044. data.set_doff(datadoff);
  1045. data.set_flags(DB_DBT_MALLOC | (dataflags & DB_DBT_PARTIAL));
  1046. /* Got all our stuff, now do the get */
  1047. ret = dbp->pget(txnp, &skey, &pkey, &data, flags);
  1048. /*
  1049.  * Otherwise just status.
  1050.  */
  1051. if (ret == 0) {
  1052. /*
  1053.  * XXX
  1054.  * We need to xdr_free whatever we are returning, next time.
  1055.  * However, DB does not allocate a new key if one was given
  1056.  * and we'd be free'ing up space allocated in the request.
  1057.  * So, allocate a new key/data pointer if it is the same one
  1058.  * as in the request.
  1059.  */
  1060. *freep = 1;
  1061. /*
  1062.  * Key
  1063.  */
  1064. key_alloc = 0;
  1065. if (skey.get_data() == skeydata) {
  1066. ret = __os_umalloc(dbp->get_DB()->dbenv,
  1067.     skey.get_size(), &replyp->skeydata.skeydata_val);
  1068. if (ret != 0) {
  1069. __os_ufree(dbp->get_DB()->dbenv, skey.get_data());
  1070. __os_ufree(dbp->get_DB()->dbenv, pkey.get_data());
  1071. __os_ufree(dbp->get_DB()->dbenv, data.get_data());
  1072. goto err;
  1073. }
  1074. key_alloc = 1;
  1075. memcpy(replyp->skeydata.skeydata_val, skey.get_data(),
  1076.     skey.get_size());
  1077. } else
  1078. replyp->skeydata.skeydata_val = (char *)skey.get_data();
  1079. replyp->skeydata.skeydata_len = skey.get_size();
  1080. /*
  1081.  * Primary key
  1082.  */
  1083. if (pkey.get_data() == pkeydata) {
  1084. ret = __os_umalloc(dbp->get_DB()->dbenv,
  1085.      pkey.get_size(), &replyp->pkeydata.pkeydata_val);
  1086. if (ret != 0) {
  1087. __os_ufree(dbp->get_DB()->dbenv, skey.get_data());
  1088. __os_ufree(dbp->get_DB()->dbenv, pkey.get_data());
  1089. __os_ufree(dbp->get_DB()->dbenv, data.get_data());
  1090. if (key_alloc)
  1091. __os_ufree(dbp->get_DB()->dbenv,
  1092.     replyp->skeydata.skeydata_val);
  1093. goto err;
  1094. }
  1095. /*
  1096.  * We can set it to 2, because they cannot send the
  1097.  * pkey over without sending the skey over too.
  1098.  * So if they did send a pkey, they must have sent
  1099.  * the skey as well.
  1100.  */
  1101. key_alloc = 2;
  1102. memcpy(replyp->pkeydata.pkeydata_val, pkey.get_data(),
  1103.     pkey.get_size());
  1104. } else
  1105. replyp->pkeydata.pkeydata_val = (char *)pkey.get_data();
  1106. replyp->pkeydata.pkeydata_len = pkey.get_size();
  1107. /*
  1108.  * Data
  1109.  */
  1110. if (data.get_data() == datadata) {
  1111. ret = __os_umalloc(dbp->get_DB()->dbenv,
  1112.      data.get_size(), &replyp->datadata.datadata_val);
  1113. if (ret != 0) {
  1114. __os_ufree(dbp->get_DB()->dbenv, skey.get_data());
  1115. __os_ufree(dbp->get_DB()->dbenv, pkey.get_data());
  1116. __os_ufree(dbp->get_DB()->dbenv, data.get_data());
  1117. /*
  1118.  * If key_alloc is 1, just skey needs to be
  1119.  * freed, if key_alloc is 2, both skey and pkey
  1120.  * need to be freed.
  1121.  */
  1122. if (key_alloc--)
  1123. __os_ufree(dbp->get_DB()->dbenv,
  1124.     replyp->skeydata.skeydata_val);
  1125. if (key_alloc)
  1126. __os_ufree(dbp->get_DB()->dbenv,
  1127.     replyp->pkeydata.pkeydata_val);
  1128. goto err;
  1129. }
  1130. memcpy(replyp->datadata.datadata_val, data.get_data(),
  1131.     data.get_size());
  1132. } else
  1133. replyp->datadata.datadata_val = (char *)data.get_data();
  1134. replyp->datadata.datadata_len = data.get_size();
  1135. } else {
  1136. err: replyp->skeydata.skeydata_val = NULL;
  1137. replyp->skeydata.skeydata_len = 0;
  1138. replyp->pkeydata.pkeydata_val = NULL;
  1139. replyp->pkeydata.pkeydata_len = 0;
  1140. replyp->datadata.datadata_val = NULL;
  1141. replyp->datadata.datadata_len = 0;
  1142. *freep = 0;
  1143. }
  1144. replyp->status = ret;
  1145. return;
  1146. }
  1147. /* BEGIN __db_put_proc */
  1148. extern "C" void
  1149. __db_put_proc(
  1150. long dbpcl_id,
  1151. long txnpcl_id,
  1152. u_int32_t keydlen,
  1153. u_int32_t keydoff,
  1154. u_int32_t keyulen,
  1155. u_int32_t keyflags,
  1156. void *keydata,
  1157. u_int32_t keysize,
  1158. u_int32_t datadlen,
  1159. u_int32_t datadoff,
  1160. u_int32_t dataulen,
  1161. u_int32_t dataflags,
  1162. void *datadata,
  1163. u_int32_t datasize,
  1164. u_int32_t flags,
  1165. __db_put_reply *replyp,
  1166. int * freep)
  1167. /* END __db_put_proc */
  1168. {
  1169. Db *dbp;
  1170. DbTxn *txnp;
  1171. ct_entry *dbp_ctp, *txnp_ctp;
  1172. int ret;
  1173. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1174. dbp = (Db *)dbp_ctp->ct_anyp;
  1175. if (txnpcl_id != 0) {
  1176. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  1177. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  1178. } else
  1179. txnp = NULL;
  1180. *freep = 0;
  1181. /* Set up key and data */
  1182. Dbt key(keydata, keysize);
  1183. key.set_dlen(keydlen);
  1184. key.set_ulen(keyulen);
  1185. key.set_doff(keydoff);
  1186. key.set_flags(DB_DBT_MALLOC | (keyflags & DB_DBT_PARTIAL));
  1187. Dbt data(datadata, datasize);
  1188. data.set_dlen(datadlen);
  1189. data.set_ulen(dataulen);
  1190. data.set_doff(datadoff);
  1191. data.set_flags(dataflags);
  1192. /* Got all our stuff, now do the put */
  1193. ret = dbp->put(txnp, &key, &data, flags);
  1194. /*
  1195.  * If the client did a DB_APPEND, set up key in reply.
  1196.  * Otherwise just status.
  1197.  */
  1198. if (ret == 0 && (flags == DB_APPEND)) {
  1199. /*
  1200.  * XXX
  1201.  * We need to xdr_free whatever we are returning, next time.
  1202.  * However, DB does not allocate a new key if one was given
  1203.  * and we'd be free'ing up space allocated in the request.
  1204.  * So, allocate a new key/data pointer if it is the same one
  1205.  * as in the request.
  1206.  */
  1207. *freep = 1;
  1208. /*
  1209.  * Key
  1210.  */
  1211. if (key.get_data() == keydata) {
  1212. ret = __os_umalloc(dbp->get_DB()->dbenv,
  1213.     key.get_size(), &replyp->keydata.keydata_val);
  1214. if (ret != 0) {
  1215. __os_ufree(dbp->get_DB()->dbenv, key.get_data());
  1216. goto err;
  1217. }
  1218. memcpy(replyp->keydata.keydata_val, key.get_data(), key.get_size());
  1219. } else
  1220. replyp->keydata.keydata_val = (char *)key.get_data();
  1221. replyp->keydata.keydata_len = key.get_size();
  1222. } else {
  1223. err: replyp->keydata.keydata_val = NULL;
  1224. replyp->keydata.keydata_len = 0;
  1225. *freep = 0;
  1226. }
  1227. replyp->status = ret;
  1228. return;
  1229. }
  1230. /* BEGIN __db_re_delim_proc */
  1231. extern "C" void
  1232. __db_re_delim_proc(
  1233. long dbpcl_id,
  1234. u_int32_t delim,
  1235. __db_re_delim_reply *replyp)
  1236. /* END __db_re_delim_proc */
  1237. {
  1238. Db *dbp;
  1239. ct_entry *dbp_ctp;
  1240. int ret;
  1241. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1242. dbp = (Db *)dbp_ctp->ct_anyp;
  1243. ret = dbp->set_re_delim(delim);
  1244. replyp->status = ret;
  1245. return;
  1246. }
  1247. /* BEGIN __db_re_len_proc */
  1248. extern "C" void
  1249. __db_re_len_proc(
  1250. long dbpcl_id,
  1251. u_int32_t len,
  1252. __db_re_len_reply *replyp)
  1253. /* END __db_re_len_proc */
  1254. {
  1255. Db *dbp;
  1256. ct_entry *dbp_ctp;
  1257. int ret;
  1258. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1259. dbp = (Db *)dbp_ctp->ct_anyp;
  1260. ret = dbp->set_re_len(len);
  1261. replyp->status = ret;
  1262. return;
  1263. }
  1264. /* BEGIN __db_re_pad_proc */
  1265. extern "C" void
  1266. __db_re_pad_proc(
  1267. long dbpcl_id,
  1268. u_int32_t pad,
  1269. __db_re_pad_reply *replyp)
  1270. /* END __db_re_pad_proc */
  1271. {
  1272. Db *dbp;
  1273. ct_entry *dbp_ctp;
  1274. int ret;
  1275. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1276. dbp = (Db *)dbp_ctp->ct_anyp;
  1277. ret = dbp->set_re_pad(pad);
  1278. replyp->status = ret;
  1279. return;
  1280. }
  1281. /* BEGIN __db_remove_proc */
  1282. extern "C" void
  1283. __db_remove_proc(
  1284. long dbpcl_id,
  1285. char *name,
  1286. char *subdb,
  1287. u_int32_t flags,
  1288. __db_remove_reply *replyp)
  1289. /* END __db_remove_proc */
  1290. {
  1291. Db *dbp;
  1292. ct_entry *dbp_ctp;
  1293. int ret;
  1294. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1295. dbp = (Db *)dbp_ctp->ct_anyp;
  1296. ret = dbp->remove(name, subdb, flags);
  1297. __dbdel_ctp(dbp_ctp);
  1298. replyp->status = ret;
  1299. return;
  1300. }
  1301. /* BEGIN __db_rename_proc */
  1302. extern "C" void
  1303. __db_rename_proc(
  1304. long dbpcl_id,
  1305. char *name,
  1306. char *subdb,
  1307. char *newname,
  1308. u_int32_t flags,
  1309. __db_rename_reply *replyp)
  1310. /* END __db_rename_proc */
  1311. {
  1312. Db *dbp;
  1313. ct_entry *dbp_ctp;
  1314. int ret;
  1315. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1316. dbp = (Db *)dbp_ctp->ct_anyp;
  1317. ret = dbp->rename(name, subdb, newname, flags);
  1318. __dbdel_ctp(dbp_ctp);
  1319. replyp->status = ret;
  1320. return;
  1321. }
  1322. /* BEGIN __db_stat_proc */
  1323. extern "C" void
  1324. __db_stat_proc(
  1325. long dbpcl_id,
  1326. u_int32_t flags,
  1327. __db_stat_reply *replyp,
  1328. int * freep)
  1329. /* END __db_stat_proc */
  1330. {
  1331. Db *dbp;
  1332. DBTYPE type;
  1333. ct_entry *dbp_ctp;
  1334. u_int32_t *q, *p, *retsp;
  1335. int i, len, ret;
  1336. void *sp;
  1337. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1338. dbp = (Db *)dbp_ctp->ct_anyp;
  1339. ret = dbp->stat(&sp, flags);
  1340. replyp->status = ret;
  1341. if (ret != 0)
  1342. return;
  1343. /*
  1344.  * We get here, we have success.  Allocate an array so that
  1345.  * we can use the list generator.  Generate the reply, free
  1346.  * up the space.
  1347.  */
  1348. /*
  1349.  * XXX This assumes that all elements of all stat structures
  1350.  * are u_int32_t fields.  They are, currently.
  1351.  */
  1352. (void)dbp->get_type(&type);
  1353. if (type == DB_HASH)
  1354. len = sizeof(DB_HASH_STAT);
  1355. else if (type == DB_QUEUE)
  1356. len = sizeof(DB_QUEUE_STAT);
  1357. else            /* BTREE or RECNO are same stats */
  1358. len = sizeof(DB_BTREE_STAT);
  1359. replyp->stats.stats_len = len / sizeof(u_int32_t);
  1360. if ((ret = __os_umalloc(dbp->get_DB()->dbenv,
  1361.     len * replyp->stats.stats_len, &retsp)) != 0)
  1362. goto out;
  1363. for (i = 0, q = retsp, p = (u_int32_t *)sp; i < len;
  1364.     i++, q++, p++)
  1365. *q = *p;
  1366. replyp->stats.stats_val = retsp;
  1367. __os_ufree(dbp->get_DB()->dbenv, sp);
  1368. if (ret == 0)
  1369. *freep = 1;
  1370. out:
  1371. replyp->status = ret;
  1372. return;
  1373. }
  1374. /* BEGIN __db_sync_proc */
  1375. extern "C" void
  1376. __db_sync_proc(
  1377. long dbpcl_id,
  1378. u_int32_t flags,
  1379. __db_sync_reply *replyp)
  1380. /* END __db_sync_proc */
  1381. {
  1382. Db *dbp;
  1383. ct_entry *dbp_ctp;
  1384. int ret;
  1385. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1386. dbp = (Db *)dbp_ctp->ct_anyp;
  1387. ret = dbp->sync(flags);
  1388. replyp->status = ret;
  1389. return;
  1390. }
  1391. /* BEGIN __db_truncate_proc */
  1392. extern "C" void
  1393. __db_truncate_proc(
  1394. long dbpcl_id,
  1395. long txnpcl_id,
  1396. u_int32_t flags,
  1397. __db_truncate_reply *replyp)
  1398. /* END __db_truncate_proc */
  1399. {
  1400. Db *dbp;
  1401. DbTxn *txnp;
  1402. ct_entry *dbp_ctp, *txnp_ctp;
  1403. u_int32_t count;
  1404. int ret;
  1405. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1406. dbp = (Db *)dbp_ctp->ct_anyp;
  1407. if (txnpcl_id != 0) {
  1408. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  1409. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  1410. } else
  1411. txnp = NULL;
  1412. ret = dbp->truncate(txnp, &count, flags);
  1413. replyp->status = ret;
  1414. if (ret == 0)
  1415. replyp->count = count;
  1416. return;
  1417. }
  1418. /* BEGIN __db_cursor_proc */
  1419. extern "C" void
  1420. __db_cursor_proc(
  1421. long dbpcl_id,
  1422. long txnpcl_id,
  1423. u_int32_t flags,
  1424. __db_cursor_reply *replyp)
  1425. /* END __db_cursor_proc */
  1426. {
  1427. Db *dbp;
  1428. Dbc *dbc;
  1429. DbTxn *txnp;
  1430. ct_entry *dbc_ctp, *env_ctp, *dbp_ctp, *txnp_ctp;
  1431. int ret;
  1432. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1433. dbp = (Db *)dbp_ctp->ct_anyp;
  1434. dbc_ctp = new_ct_ent(&replyp->status);
  1435. if (dbc_ctp == NULL)
  1436. return;
  1437. if (txnpcl_id != 0) {
  1438. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  1439. txnp = (DbTxn *)txnp_ctp->ct_anyp;
  1440. dbc_ctp->ct_activep = txnp_ctp->ct_activep;
  1441. } else
  1442. txnp = NULL;
  1443. if ((ret = dbp->cursor(txnp, &dbc, flags)) == 0) {
  1444. dbc_ctp->ct_dbc = dbc;
  1445. dbc_ctp->ct_type = CT_CURSOR;
  1446. dbc_ctp->ct_parent = dbp_ctp;
  1447. env_ctp = dbp_ctp->ct_envparent;
  1448. dbc_ctp->ct_envparent = env_ctp;
  1449. __dbsrv_settimeout(dbc_ctp, env_ctp->ct_timeout);
  1450. __dbsrv_active(dbc_ctp);
  1451. replyp->dbcidcl_id = dbc_ctp->ct_id;
  1452. } else
  1453. __dbclear_ctp(dbc_ctp);
  1454. replyp->status = ret;
  1455. return;
  1456. }
  1457. /* BEGIN __db_join_proc */
  1458. extern "C" void
  1459. __db_join_proc(
  1460. long dbpcl_id,
  1461. u_int32_t *curs,
  1462. u_int32_t curslen,
  1463. u_int32_t flags,
  1464. __db_join_reply *replyp)
  1465. /* END __db_join_proc */
  1466. {
  1467. Db *dbp;
  1468. Dbc **jcurs, **c;
  1469. Dbc *dbc;
  1470. ct_entry *dbc_ctp, *ctp, *dbp_ctp;
  1471. size_t size;
  1472. u_int32_t *cl, i;
  1473. int ret;
  1474. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1475. dbp = (Db *)dbp_ctp->ct_anyp;
  1476. dbc_ctp = new_ct_ent(&replyp->status);
  1477. if (dbc_ctp == NULL)
  1478. return;
  1479. size = (curslen + 1) * sizeof(Dbc *);
  1480. if ((ret = __os_calloc(dbp->get_DB()->dbenv,
  1481.     curslen + 1, sizeof(Dbc *), &jcurs)) != 0) {
  1482. replyp->status = ret;
  1483. __dbclear_ctp(dbc_ctp);
  1484. return;
  1485. }
  1486. /*
  1487.  * If our curslist has a parent txn, we need to use it too
  1488.  * for the activity timeout.  All cursors must be part of
  1489.  * the same transaction, so just check the first.
  1490.  */
  1491. ctp = get_tableent(*curs);
  1492. DB_ASSERT(ctp->ct_type == CT_CURSOR);
  1493. /*
  1494.  * If we are using a transaction, set the join activity timer
  1495.  * to point to the parent transaction.
  1496.  */
  1497. if (ctp->ct_activep != &ctp->ct_active)
  1498. dbc_ctp->ct_activep = ctp->ct_activep;
  1499. for (i = 0, cl = curs, c = jcurs; i < curslen; i++, cl++, c++) {
  1500. ctp = get_tableent(*cl);
  1501. if (ctp == NULL) {
  1502. replyp->status = DB_NOSERVER_ID;
  1503. goto out;
  1504. }
  1505. /*
  1506.  * If we are using a txn, the join cursor points to the
  1507.  * transaction timeout.  If we are not using a transaction,
  1508.  * then all the curslist cursors must point to the join
  1509.  * cursor's timeout so that we do not timeout any of the
  1510.  * curlist cursors while the join cursor is active.
  1511.  * Change the type of the curslist ctps to CT_JOIN so that
  1512.  * we know they are part of a join list and we can distinguish
  1513.  * them and later restore them when the join cursor is closed.
  1514.  */
  1515. DB_ASSERT(ctp->ct_type == CT_CURSOR);
  1516. ctp->ct_type |= CT_JOIN;
  1517. ctp->ct_origp = ctp->ct_activep;
  1518. /*
  1519.  * Setting this to the ct_active field of the dbc_ctp is
  1520.  * really just a way to distinguish which join dbc this
  1521.  * cursor is part of.  The ct_activep of this cursor is
  1522.  * not used at all during its lifetime as part of a join
  1523.  * cursor.
  1524.  */
  1525. ctp->ct_activep = &dbc_ctp->ct_active;
  1526. *c = ctp->ct_dbc;
  1527. }
  1528. *c = NULL;
  1529. if ((ret = dbp->join(jcurs, &dbc, flags)) == 0) {
  1530. dbc_ctp->ct_dbc = dbc;
  1531. dbc_ctp->ct_type = (CT_JOINCUR | CT_CURSOR);
  1532. dbc_ctp->ct_parent = dbp_ctp;
  1533. dbc_ctp->ct_envparent = dbp_ctp->ct_envparent;
  1534. __dbsrv_settimeout(dbc_ctp, dbp_ctp->ct_envparent->ct_timeout);
  1535. __dbsrv_active(dbc_ctp);
  1536. replyp->dbcidcl_id = dbc_ctp->ct_id;
  1537. } else {
  1538. __dbclear_ctp(dbc_ctp);
  1539. /*
  1540.  * If we get an error, undo what we did above to any cursors.
  1541.  */
  1542. for (cl = curs; *cl != 0; cl++) {
  1543. ctp = get_tableent(*cl);
  1544. ctp->ct_type = CT_CURSOR;
  1545. ctp->ct_activep = ctp->ct_origp;
  1546. }
  1547. }
  1548. replyp->status = ret;
  1549. out:
  1550. __os_free(dbp->get_DB()->dbenv, jcurs);
  1551. return;
  1552. }
  1553. /* BEGIN __dbc_close_proc */
  1554. extern "C" void
  1555. __dbc_close_proc(
  1556. long dbccl_id,
  1557. __dbc_close_reply *replyp)
  1558. /* END __dbc_close_proc */
  1559. {
  1560. ct_entry *dbc_ctp;
  1561. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1562. replyp->status = __dbc_close_int(dbc_ctp);
  1563. return;
  1564. }
  1565. /* BEGIN __dbc_count_proc */
  1566. extern "C" void
  1567. __dbc_count_proc(
  1568. long dbccl_id,
  1569. u_int32_t flags,
  1570. __dbc_count_reply *replyp)
  1571. /* END __dbc_count_proc */
  1572. {
  1573. Dbc *dbc;
  1574. ct_entry *dbc_ctp;
  1575. db_recno_t num;
  1576. int ret;
  1577. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1578. dbc = (Dbc *)dbc_ctp->ct_anyp;
  1579. ret = dbc->count(&num, flags);
  1580. replyp->status = ret;
  1581. if (ret == 0)
  1582. replyp->dupcount = num;
  1583. return;
  1584. }
  1585. /* BEGIN __dbc_del_proc */
  1586. extern "C" void
  1587. __dbc_del_proc(
  1588. long dbccl_id,
  1589. u_int32_t flags,
  1590. __dbc_del_reply *replyp)
  1591. /* END __dbc_del_proc */
  1592. {
  1593. Dbc *dbc;
  1594. ct_entry *dbc_ctp;
  1595. int ret;
  1596. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1597. dbc = (Dbc *)dbc_ctp->ct_anyp;
  1598. ret = dbc->del(flags);
  1599. replyp->status = ret;
  1600. return;
  1601. }
  1602. /* BEGIN __dbc_dup_proc */
  1603. extern "C" void
  1604. __dbc_dup_proc(
  1605. long dbccl_id,
  1606. u_int32_t flags,
  1607. __dbc_dup_reply *replyp)
  1608. /* END __dbc_dup_proc */
  1609. {
  1610. Dbc *dbc, *newdbc;
  1611. ct_entry *dbc_ctp, *new_ctp;
  1612. int ret;
  1613. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1614. dbc = (Dbc *)dbc_ctp->ct_anyp;
  1615. new_ctp = new_ct_ent(&replyp->status);
  1616. if (new_ctp == NULL)
  1617. return;
  1618. if ((ret = dbc->dup(&newdbc, flags)) == 0) {
  1619. new_ctp->ct_dbc = newdbc;
  1620. new_ctp->ct_type = CT_CURSOR;
  1621. new_ctp->ct_parent = dbc_ctp->ct_parent;
  1622. new_ctp->ct_envparent = dbc_ctp->ct_envparent;
  1623. /*
  1624.  * If our cursor has a parent txn, we need to use it too.
  1625.  */
  1626. if (dbc_ctp->ct_activep != &dbc_ctp->ct_active)
  1627. new_ctp->ct_activep = dbc_ctp->ct_activep;
  1628. __dbsrv_settimeout(new_ctp, dbc_ctp->ct_timeout);
  1629. __dbsrv_active(new_ctp);
  1630. replyp->dbcidcl_id = new_ctp->ct_id;
  1631. } else
  1632. __dbclear_ctp(new_ctp);
  1633. replyp->status = ret;
  1634. return;
  1635. }
  1636. /* BEGIN __dbc_get_proc */
  1637. extern "C" void
  1638. __dbc_get_proc(
  1639. long dbccl_id,
  1640. u_int32_t keydlen,
  1641. u_int32_t keydoff,
  1642. u_int32_t keyulen,
  1643. u_int32_t keyflags,
  1644. void *keydata,
  1645. u_int32_t keysize,
  1646. u_int32_t datadlen,
  1647. u_int32_t datadoff,
  1648. u_int32_t dataulen,
  1649. u_int32_t dataflags,
  1650. void *datadata,
  1651. u_int32_t datasize,
  1652. u_int32_t flags,
  1653. __dbc_get_reply *replyp,
  1654. int * freep)
  1655. /* END __dbc_get_proc */
  1656. {
  1657. Dbc *dbc;
  1658. DbEnv *dbenv;
  1659. ct_entry *dbc_ctp;
  1660. int key_alloc, bulk_alloc, ret;
  1661. void *tmpdata;
  1662. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1663. dbc = (Dbc *)dbc_ctp->ct_anyp;
  1664. dbenv = DbEnv::get_DbEnv(((DBC *)dbc)->dbp->dbenv);
  1665. *freep = 0;
  1666. bulk_alloc = 0;
  1667. /* Set up key and data */
  1668. Dbt key(keydata, keysize);
  1669. key.set_dlen(keydlen);
  1670. key.set_ulen(keyulen);
  1671. key.set_doff(keydoff);
  1672. key.set_flags(DB_DBT_MALLOC | (keyflags & DB_DBT_PARTIAL));
  1673. Dbt data(datadata, datasize);
  1674. data.set_dlen(datadlen);
  1675. data.set_ulen(dataulen);
  1676. data.set_doff(datadoff);
  1677. dataflags &= DB_DBT_PARTIAL;
  1678. if (flags & DB_MULTIPLE || flags & DB_MULTIPLE_KEY) {
  1679. if (data.get_data() == NULL) {
  1680. ret = __os_umalloc(dbenv->get_DB_ENV(),
  1681.     data.get_ulen(), &tmpdata);
  1682. if (ret != 0)
  1683. goto err;
  1684. data.set_data(tmpdata);
  1685. bulk_alloc = 1;
  1686. }
  1687. dataflags |= DB_DBT_USERMEM;
  1688. } else
  1689. dataflags |= DB_DBT_MALLOC;
  1690. data.set_flags(dataflags);
  1691. /* Got all our stuff, now do the get */
  1692. ret = dbc->get(&key, &data, flags);
  1693. /*
  1694.  * Otherwise just status.
  1695.  */
  1696. if (ret == 0) {
  1697. /*
  1698.  * XXX
  1699.  * We need to xdr_free whatever we are returning, next time.
  1700.  * However, DB does not allocate a new key if one was given
  1701.  * and we'd be free'ing up space allocated in the request.
  1702.  * So, allocate a new key/data pointer if it is the same one
  1703.  * as in the request.
  1704.  */
  1705. *freep = 1;
  1706. /*
  1707.  * Key
  1708.  */
  1709. key_alloc = 0;
  1710. if (key.get_data() == keydata) {
  1711. ret = __os_umalloc(dbenv->get_DB_ENV(), key.get_size(),
  1712.     &replyp->keydata.keydata_val);
  1713. if (ret != 0) {
  1714. __os_ufree(dbenv->get_DB_ENV(), key.get_data());
  1715. __os_ufree(dbenv->get_DB_ENV(), data.get_data());
  1716. goto err;
  1717. }
  1718. key_alloc = 1;
  1719. memcpy(replyp->keydata.keydata_val, key.get_data(), key.get_size());
  1720. } else
  1721. replyp->keydata.keydata_val = (char *)key.get_data();
  1722. replyp->keydata.keydata_len = key.get_size();
  1723. /*
  1724.  * Data
  1725.  */
  1726. if (data.get_data() == datadata) {
  1727. ret = __os_umalloc(dbenv->get_DB_ENV(), data.get_size(),
  1728.     &replyp->datadata.datadata_val);
  1729. if (ret != 0) {
  1730. __os_ufree(dbenv->get_DB_ENV(), key.get_data());
  1731. __os_ufree(dbenv->get_DB_ENV(), data.get_data());
  1732. if (key_alloc)
  1733. __os_ufree(dbenv->get_DB_ENV(),
  1734.     replyp->keydata.keydata_val);
  1735. goto err;
  1736. }
  1737. memcpy(replyp->datadata.datadata_val, data.get_data(),
  1738.     data.get_size());
  1739. } else
  1740. replyp->datadata.datadata_val = (char *)data.get_data();
  1741. replyp->datadata.datadata_len = data.get_size();
  1742. } else {
  1743. err: replyp->keydata.keydata_val = NULL;
  1744. replyp->keydata.keydata_len = 0;
  1745. replyp->datadata.datadata_val = NULL;
  1746. replyp->datadata.datadata_len = 0;
  1747. *freep = 0;
  1748. if (bulk_alloc)
  1749. __os_ufree(dbenv->get_DB_ENV(), data.get_data());
  1750. }
  1751. replyp->status = ret;
  1752. return;
  1753. }
  1754. /* BEGIN __dbc_pget_proc */
  1755. extern "C" void
  1756. __dbc_pget_proc(
  1757. long dbccl_id,
  1758. u_int32_t skeydlen,
  1759. u_int32_t skeydoff,
  1760. u_int32_t skeyulen,
  1761. u_int32_t skeyflags,
  1762. void *skeydata,
  1763. u_int32_t skeysize,
  1764. u_int32_t pkeydlen,
  1765. u_int32_t pkeydoff,
  1766. u_int32_t pkeyulen,
  1767. u_int32_t pkeyflags,
  1768. void *pkeydata,
  1769. u_int32_t pkeysize,
  1770. u_int32_t datadlen,
  1771. u_int32_t datadoff,
  1772. u_int32_t dataulen,
  1773. u_int32_t dataflags,
  1774. void *datadata,
  1775. u_int32_t datasize,
  1776. u_int32_t flags,
  1777. __dbc_pget_reply *replyp,
  1778. int * freep)
  1779. /* END __dbc_pget_proc */
  1780. {
  1781. Dbc *dbc;
  1782. DbEnv *dbenv;
  1783. ct_entry *dbc_ctp;
  1784. int key_alloc, ret;
  1785. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1786. dbc = (Dbc *)dbc_ctp->ct_anyp;
  1787. dbenv = DbEnv::get_DbEnv(((DBC *)dbc)->dbp->dbenv);
  1788. *freep = 0;
  1789. /*
  1790.  * Ignore memory related flags on server.
  1791.  */
  1792. /* Set up key and data */
  1793. Dbt skey(skeydata, skeysize);
  1794. skey.set_dlen(skeydlen);
  1795. skey.set_ulen(skeyulen);
  1796. skey.set_doff(skeydoff);
  1797. skey.set_flags(DB_DBT_MALLOC | (skeyflags & DB_DBT_PARTIAL));
  1798. Dbt pkey(pkeydata, pkeysize);
  1799. pkey.set_dlen(pkeydlen);
  1800. pkey.set_ulen(pkeyulen);
  1801. pkey.set_doff(pkeydoff);
  1802. pkey.set_flags(DB_DBT_MALLOC | (pkeyflags & DB_DBT_PARTIAL));
  1803. Dbt data(datadata, datasize);
  1804. data.set_dlen(datadlen);
  1805. data.set_ulen(dataulen);
  1806. data.set_doff(datadoff);
  1807. data.set_flags(DB_DBT_MALLOC | (dataflags & DB_DBT_PARTIAL));
  1808. /* Got all our stuff, now do the get */
  1809. ret = dbc->pget(&skey, &pkey, &data, flags);
  1810. /*
  1811.  * Otherwise just status.
  1812.  */
  1813. if (ret == 0) {
  1814. /*
  1815.  * XXX
  1816.  * We need to xdr_free whatever we are returning, next time.
  1817.  * However, DB does not allocate a new key if one was given
  1818.  * and we'd be free'ing up space allocated in the request.
  1819.  * So, allocate a new key/data pointer if it is the same one
  1820.  * as in the request.
  1821.  */
  1822. *freep = 1;
  1823. /*
  1824.  * Key
  1825.  */
  1826. key_alloc = 0;
  1827. if (skey.get_data() == skeydata) {
  1828. ret = __os_umalloc(dbenv->get_DB_ENV(),
  1829.     skey.get_size(), &replyp->skeydata.skeydata_val);
  1830. if (ret != 0) {
  1831. __os_ufree(dbenv->get_DB_ENV(), skey.get_data());
  1832. __os_ufree(dbenv->get_DB_ENV(), pkey.get_data());
  1833. __os_ufree(dbenv->get_DB_ENV(), data.get_data());
  1834. goto err;
  1835. }
  1836. key_alloc = 1;
  1837. memcpy(replyp->skeydata.skeydata_val, skey.get_data(),
  1838.     skey.get_size());
  1839. } else
  1840. replyp->skeydata.skeydata_val = (char *)skey.get_data();
  1841. replyp->skeydata.skeydata_len = skey.get_size();
  1842. /*
  1843.  * Primary key
  1844.  */
  1845. if (pkey.get_data() == pkeydata) {
  1846. ret = __os_umalloc(dbenv->get_DB_ENV(),
  1847.      pkey.get_size(), &replyp->pkeydata.pkeydata_val);
  1848. if (ret != 0) {
  1849. __os_ufree(dbenv->get_DB_ENV(), skey.get_data());
  1850. __os_ufree(dbenv->get_DB_ENV(), pkey.get_data());
  1851. __os_ufree(dbenv->get_DB_ENV(), data.get_data());
  1852. if (key_alloc)
  1853. __os_ufree(dbenv->get_DB_ENV(),
  1854.     replyp->skeydata.skeydata_val);
  1855. goto err;
  1856. }
  1857. /*
  1858.  * We can set it to 2, because they cannot send the
  1859.  * pkey over without sending the skey over too.
  1860.  * So if they did send a pkey, they must have sent
  1861.  * the skey as well.
  1862.  */
  1863. key_alloc = 2;
  1864. memcpy(replyp->pkeydata.pkeydata_val, pkey.get_data(),
  1865.     pkey.get_size());
  1866. } else
  1867. replyp->pkeydata.pkeydata_val = (char *)pkey.get_data();
  1868. replyp->pkeydata.pkeydata_len = pkey.get_size();
  1869. /*
  1870.  * Data
  1871.  */
  1872. if (data.get_data() == datadata) {
  1873. ret = __os_umalloc(dbenv->get_DB_ENV(),
  1874.      data.get_size(), &replyp->datadata.datadata_val);
  1875. if (ret != 0) {
  1876. __os_ufree(dbenv->get_DB_ENV(), skey.get_data());
  1877. __os_ufree(dbenv->get_DB_ENV(), pkey.get_data());
  1878. __os_ufree(dbenv->get_DB_ENV(), data.get_data());
  1879. /*
  1880.  * If key_alloc is 1, just skey needs to be
  1881.  * freed, if key_alloc is 2, both skey and pkey
  1882.  * need to be freed.
  1883.  */
  1884. if (key_alloc--)
  1885. __os_ufree(dbenv->get_DB_ENV(),
  1886.     replyp->skeydata.skeydata_val);
  1887. if (key_alloc)
  1888. __os_ufree(dbenv->get_DB_ENV(),
  1889.     replyp->pkeydata.pkeydata_val);
  1890. goto err;
  1891. }
  1892. memcpy(replyp->datadata.datadata_val, data.get_data(),
  1893.     data.get_size());
  1894. } else
  1895. replyp->datadata.datadata_val = (char *)data.get_data();
  1896. replyp->datadata.datadata_len = data.get_size();
  1897. } else {
  1898. err: replyp->skeydata.skeydata_val = NULL;
  1899. replyp->skeydata.skeydata_len = 0;
  1900. replyp->pkeydata.pkeydata_val = NULL;
  1901. replyp->pkeydata.pkeydata_len = 0;
  1902. replyp->datadata.datadata_val = NULL;
  1903. replyp->datadata.datadata_len = 0;
  1904. *freep = 0;
  1905. }
  1906. replyp->status = ret;
  1907. return;
  1908. }
  1909. /* BEGIN __dbc_put_proc */
  1910. extern "C" void
  1911. __dbc_put_proc(
  1912. long dbccl_id,
  1913. u_int32_t keydlen,
  1914. u_int32_t keydoff,
  1915. u_int32_t keyulen,
  1916. u_int32_t keyflags,
  1917. void *keydata,
  1918. u_int32_t keysize,
  1919. u_int32_t datadlen,
  1920. u_int32_t datadoff,
  1921. u_int32_t dataulen,
  1922. u_int32_t dataflags,
  1923. void *datadata,
  1924. u_int32_t datasize,
  1925. u_int32_t flags,
  1926. __dbc_put_reply *replyp,
  1927. int * freep)
  1928. /* END __dbc_put_proc */
  1929. {
  1930. Db *dbp;
  1931. Dbc *dbc;
  1932. ct_entry *dbc_ctp;
  1933. int ret;
  1934. DBTYPE dbtype;
  1935. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1936. dbc = (Dbc *)dbc_ctp->ct_anyp;
  1937. dbp = (Db *)dbc_ctp->ct_parent->ct_anyp;
  1938. /* Set up key and data */
  1939. Dbt key(keydata, keysize);
  1940. key.set_dlen(keydlen);
  1941. key.set_ulen(keyulen);
  1942. key.set_doff(keydoff);
  1943. /*
  1944.  * Ignore memory related flags on server.
  1945.  */
  1946. key.set_flags(DB_DBT_MALLOC | (keyflags & DB_DBT_PARTIAL));
  1947. Dbt data(datadata, datasize);
  1948. data.set_dlen(datadlen);
  1949. data.set_ulen(dataulen);
  1950. data.set_doff(datadoff);
  1951. data.set_flags(dataflags);
  1952. /* Got all our stuff, now do the put */
  1953. ret = dbc->put(&key, &data, flags);
  1954. *freep = 0;
  1955. replyp->keydata.keydata_val = NULL;
  1956. replyp->keydata.keydata_len = 0;
  1957. if (ret == 0 && (flags == DB_AFTER || flags == DB_BEFORE)) {
  1958. ret = dbp->get_type(&dbtype);
  1959. if (ret == 0 && dbtype == DB_RECNO) {
  1960. /*
  1961.  * We need to xdr_free whatever we are returning, next time.
  1962.  */
  1963. replyp->keydata.keydata_val = (char *)key.get_data();
  1964. replyp->keydata.keydata_len = key.get_size();
  1965. }
  1966. }
  1967. replyp->status = ret;
  1968. return;
  1969. }
  1970. #endif /* HAVE_RPC */