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

MySQL数据库

开发平台:

Visual C++

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