db_server_proc.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:32k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 2000
  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.48 2001/01/06 16:08:01 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 "db_server.h"
  18. #include "db_int.h"
  19. #include "db_server_int.h"
  20. #include "rpc_server_ext.h"
  21. static int __db_stats_list __P((DB_ENV *,
  22.       __db_stat_statsreplist **, u_int32_t *, int));
  23. /* BEGIN __env_cachesize_1_proc */
  24. void
  25. __env_cachesize_1_proc(dbenvcl_id, gbytes, bytes,
  26. ncache, replyp)
  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_1_proc */
  33. {
  34. int ret;
  35. DB_ENV * dbenv;
  36. ct_entry *dbenv_ctp;
  37. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  38. dbenv = (DB_ENV *)dbenv_ctp->ct_anyp;
  39. ret = dbenv->set_cachesize(dbenv, gbytes, bytes, ncache);
  40. replyp->status = ret;
  41. return;
  42. }
  43. /* BEGIN __env_close_1_proc */
  44. void
  45. __env_close_1_proc(dbenvcl_id, flags, replyp)
  46. long dbenvcl_id;
  47. u_int32_t flags;
  48. __env_close_reply *replyp;
  49. /* END __env_close_1_proc */
  50. {
  51. replyp->status = __dbenv_close_int(dbenvcl_id, flags);
  52. return;
  53. }
  54. /* BEGIN __env_create_1_proc */
  55. void
  56. __env_create_1_proc(timeout, replyp)
  57. u_int32_t timeout;
  58. __env_create_reply *replyp;
  59. /* END __env_create_1_proc */
  60. {
  61. int ret;
  62. DB_ENV *dbenv;
  63. ct_entry *ctp;
  64. ctp = new_ct_ent(&replyp->status);
  65. if (ctp == NULL)
  66. return;
  67. if ((ret = db_env_create(&dbenv, 0)) == 0) {
  68. ctp->ct_envp = dbenv;
  69. ctp->ct_type = CT_ENV;
  70. ctp->ct_parent = NULL;
  71. ctp->ct_envparent = ctp;
  72. __dbsrv_settimeout(ctp, timeout);
  73. __dbsrv_active(ctp);
  74. replyp->envcl_id = ctp->ct_id;
  75. } else
  76. __dbclear_ctp(ctp);
  77. replyp->status = ret;
  78. return;
  79. }
  80. /* BEGIN __env_flags_1_proc */
  81. void
  82. __env_flags_1_proc(dbenvcl_id, flags, onoff, replyp)
  83. long dbenvcl_id;
  84. u_int32_t flags;
  85. u_int32_t onoff;
  86. __env_flags_reply *replyp;
  87. /* END __env_flags_1_proc */
  88. {
  89. int ret;
  90. DB_ENV * dbenv;
  91. ct_entry *dbenv_ctp;
  92. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  93. dbenv = (DB_ENV *)dbenv_ctp->ct_anyp;
  94. ret = dbenv->set_flags(dbenv, flags, onoff);
  95. replyp->status = ret;
  96. return;
  97. }
  98. /* BEGIN __env_open_1_proc */
  99. void
  100. __env_open_1_proc(dbenvcl_id, home, flags,
  101. mode, replyp)
  102. long dbenvcl_id;
  103. char *home;
  104. u_int32_t flags;
  105. u_int32_t mode;
  106. __env_open_reply *replyp;
  107. /* END __env_open_1_proc */
  108. {
  109. int ret;
  110. DB_ENV * dbenv;
  111. ct_entry *dbenv_ctp;
  112. char *fullhome;
  113. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  114. dbenv = (DB_ENV *)dbenv_ctp->ct_anyp;
  115. fullhome = get_home(home);
  116. if (fullhome == NULL) {
  117. replyp->status = DB_NOSERVER_HOME;
  118. return;
  119. }
  120. ret = dbenv->open(dbenv, fullhome, flags, mode);
  121. replyp->status = ret;
  122. return;
  123. }
  124. /* BEGIN __env_remove_1_proc */
  125. void
  126. __env_remove_1_proc(dbenvcl_id, home, flags, replyp)
  127. long dbenvcl_id;
  128. char *home;
  129. u_int32_t flags;
  130. __env_remove_reply *replyp;
  131. /* END __env_remove_1_proc */
  132. {
  133. int ret;
  134. DB_ENV * dbenv;
  135. ct_entry *dbenv_ctp;
  136. char *fullhome;
  137. ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
  138. dbenv = (DB_ENV *)dbenv_ctp->ct_anyp;
  139. fullhome = get_home(home);
  140. if (fullhome == NULL) {
  141. replyp->status = DB_NOSERVER_HOME;
  142. return;
  143. }
  144. ret = dbenv->remove(dbenv, fullhome, flags);
  145. __dbdel_ctp(dbenv_ctp);
  146. replyp->status = ret;
  147. return;
  148. }
  149. /* BEGIN __txn_abort_1_proc */
  150. void
  151. __txn_abort_1_proc(txnpcl_id, replyp)
  152. long txnpcl_id;
  153. __txn_abort_reply *replyp;
  154. /* END __txn_abort_1_proc */
  155. {
  156. DB_TXN * txnp;
  157. ct_entry *txnp_ctp;
  158. int ret;
  159. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  160. txnp = (DB_TXN *)txnp_ctp->ct_anyp;
  161. ret =  txn_abort(txnp);
  162. __dbdel_ctp(txnp_ctp);
  163. replyp->status = ret;
  164. return;
  165. }
  166. /* BEGIN __txn_begin_1_proc */
  167. void
  168. __txn_begin_1_proc(envpcl_id, parentcl_id,
  169. flags, replyp)
  170. long envpcl_id;
  171. long parentcl_id;
  172. u_int32_t flags;
  173. __txn_begin_reply *replyp;
  174. /* END __txn_begin_1_proc */
  175. {
  176. int ret;
  177. DB_ENV * envp;
  178. ct_entry *envp_ctp;
  179. DB_TXN * parent;
  180. ct_entry *parent_ctp;
  181. DB_TXN *txnp;
  182. ct_entry *ctp;
  183. ACTIVATE_CTP(envp_ctp, envpcl_id, CT_ENV);
  184. envp = (DB_ENV *)envp_ctp->ct_anyp;
  185. parent_ctp = NULL;
  186. ctp = new_ct_ent(&replyp->status);
  187. if (ctp == NULL)
  188. return;
  189. if (parentcl_id != 0) {
  190. ACTIVATE_CTP(parent_ctp, parentcl_id, CT_TXN);
  191. parent = (DB_TXN *)parent_ctp->ct_anyp;
  192. ctp->ct_activep = parent_ctp->ct_activep;
  193. } else
  194. parent = NULL;
  195. ret = txn_begin(envp, parent, &txnp, flags);
  196. if (ret == 0) {
  197. ctp->ct_txnp = txnp;
  198. ctp->ct_type = CT_TXN;
  199. ctp->ct_parent = parent_ctp;
  200. ctp->ct_envparent = envp_ctp;
  201. replyp->txnidcl_id = ctp->ct_id;
  202. __dbsrv_settimeout(ctp, envp_ctp->ct_timeout);
  203. __dbsrv_active(ctp);
  204. } else
  205. __dbclear_ctp(ctp);
  206. replyp->status = ret;
  207. return;
  208. }
  209. /* BEGIN __txn_commit_1_proc */
  210. void
  211. __txn_commit_1_proc(txnpcl_id, flags, replyp)
  212. long txnpcl_id;
  213. u_int32_t flags;
  214. __txn_commit_reply *replyp;
  215. /* END __txn_commit_1_proc */
  216. {
  217. int ret;
  218. DB_TXN * txnp;
  219. ct_entry *txnp_ctp;
  220. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  221. txnp = (DB_TXN *)txnp_ctp->ct_anyp;
  222. ret = txn_commit(txnp, flags);
  223. __dbdel_ctp(txnp_ctp);
  224. replyp->status = ret;
  225. return;
  226. }
  227. /* BEGIN __db_bt_maxkey_1_proc */
  228. void
  229. __db_bt_maxkey_1_proc(dbpcl_id, maxkey, replyp)
  230. long dbpcl_id;
  231. u_int32_t maxkey;
  232. __db_bt_maxkey_reply *replyp;
  233. /* END __db_bt_maxkey_1_proc */
  234. {
  235. int ret;
  236. DB * dbp;
  237. ct_entry *dbp_ctp;
  238. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  239. dbp = (DB *)dbp_ctp->ct_anyp;
  240. ret = dbp->set_bt_maxkey(dbp, maxkey);
  241. replyp->status = ret;
  242. return;
  243. }
  244. /* BEGIN __db_bt_minkey_1_proc */
  245. void
  246. __db_bt_minkey_1_proc(dbpcl_id, minkey, replyp)
  247. long dbpcl_id;
  248. u_int32_t minkey;
  249. __db_bt_minkey_reply *replyp;
  250. /* END __db_bt_minkey_1_proc */
  251. {
  252. int ret;
  253. DB * dbp;
  254. ct_entry *dbp_ctp;
  255. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  256. dbp = (DB *)dbp_ctp->ct_anyp;
  257. ret = dbp->set_bt_minkey(dbp, minkey);
  258. replyp->status = ret;
  259. return;
  260. }
  261. /* BEGIN __db_close_1_proc */
  262. void
  263. __db_close_1_proc(dbpcl_id, flags, replyp)
  264. long dbpcl_id;
  265. u_int32_t flags;
  266. __db_close_reply *replyp;
  267. /* END __db_close_1_proc */
  268. {
  269. int ret;
  270. DB * dbp;
  271. ct_entry *dbp_ctp;
  272. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  273. dbp = (DB *)dbp_ctp->ct_anyp;
  274. ret = dbp->close(dbp, flags);
  275. __dbdel_ctp(dbp_ctp);
  276. replyp-> status= ret;
  277. return;
  278. }
  279. /* BEGIN __db_create_1_proc */
  280. void
  281. __db_create_1_proc(flags, envpcl_id, replyp)
  282. u_int32_t flags;
  283. long envpcl_id;
  284. __db_create_reply *replyp;
  285. /* END __db_create_1_proc */
  286. {
  287. int ret;
  288. DB_ENV * envp;
  289. DB *dbp;
  290. ct_entry *envp_ctp, *dbp_ctp;
  291. ACTIVATE_CTP(envp_ctp, envpcl_id, CT_ENV);
  292. envp = (DB_ENV *)envp_ctp->ct_anyp;
  293. dbp_ctp = new_ct_ent(&replyp->status);
  294. if (dbp_ctp == NULL)
  295. return ;
  296. /*
  297.  * We actually require env's for databases.  The client should
  298.  * have caught it, but just in case.
  299.  */
  300. DB_ASSERT(envp != NULL);
  301. if ((ret = db_create(&dbp, envp, flags)) == 0) {
  302. dbp_ctp->ct_dbp = dbp;
  303. dbp_ctp->ct_type = CT_DB;
  304. dbp_ctp->ct_parent = envp_ctp;
  305. dbp_ctp->ct_envparent = envp_ctp;
  306. replyp->dbpcl_id = dbp_ctp->ct_id;
  307. } else
  308. __dbclear_ctp(dbp_ctp);
  309. replyp->status = ret;
  310. return;
  311. }
  312. /* BEGIN __db_del_1_proc */
  313. void
  314. __db_del_1_proc(dbpcl_id, txnpcl_id, keydlen,
  315. keydoff, keyflags, keydata, keysize,
  316. flags, replyp)
  317. long dbpcl_id;
  318. long txnpcl_id;
  319. u_int32_t keydlen;
  320. u_int32_t keydoff;
  321. u_int32_t keyflags;
  322. void *keydata;
  323. u_int32_t keysize;
  324. u_int32_t flags;
  325. __db_del_reply *replyp;
  326. /* END __db_del_1_proc */
  327. {
  328. int ret;
  329. DB * dbp;
  330. ct_entry *dbp_ctp;
  331. DB_TXN * txnp;
  332. ct_entry *txnp_ctp;
  333. DBT key;
  334. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  335. dbp = (DB *)dbp_ctp->ct_anyp;
  336. if (txnpcl_id != 0) {
  337. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  338. txnp = (DB_TXN *)txnp_ctp->ct_anyp;
  339. } else
  340. txnp = NULL;
  341. memset(&key, 0, sizeof(key));
  342. /* Set up key DBT */
  343. key.dlen = keydlen;
  344. key.doff = keydoff;
  345. key.flags = keyflags;
  346. key.size = keysize;
  347. key.data = keydata;
  348. ret = dbp->del(dbp, txnp, &key, flags);
  349. replyp->status = ret;
  350. return;
  351. }
  352. /* BEGIN __db_extentsize_1_proc */
  353. void
  354. __db_extentsize_1_proc(dbpcl_id, extentsize, replyp)
  355. long dbpcl_id;
  356. u_int32_t extentsize;
  357. __db_extentsize_reply *replyp;
  358. /* END __db_extentsize_1_proc */
  359. {
  360. int ret;
  361. DB * dbp;
  362. ct_entry *dbp_ctp;
  363. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  364. dbp = (DB *)dbp_ctp->ct_anyp;
  365. ret = dbp->set_q_extentsize(dbp, extentsize);
  366. replyp->status = ret;
  367. return;
  368. }
  369. /* BEGIN __db_flags_1_proc */
  370. void
  371. __db_flags_1_proc(dbpcl_id, flags, replyp)
  372. long dbpcl_id;
  373. u_int32_t flags;
  374. __db_flags_reply *replyp;
  375. /* END __db_flags_1_proc */
  376. {
  377. int ret;
  378. DB * dbp;
  379. ct_entry *dbp_ctp;
  380. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  381. dbp = (DB *)dbp_ctp->ct_anyp;
  382. ret = dbp->set_flags(dbp, flags);
  383. replyp->status = ret;
  384. return;
  385. }
  386. /* BEGIN __db_get_1_proc */
  387. void
  388. __db_get_1_proc(dbpcl_id, txnpcl_id, keydlen,
  389. keydoff, keyflags, keydata, keysize,
  390. datadlen, datadoff, dataflags, datadata,
  391. datasize, flags, replyp, freep)
  392. long dbpcl_id;
  393. long txnpcl_id;
  394. u_int32_t keydlen;
  395. u_int32_t keydoff;
  396. u_int32_t keyflags;
  397. void *keydata;
  398. u_int32_t keysize;
  399. u_int32_t datadlen;
  400. u_int32_t datadoff;
  401. u_int32_t dataflags;
  402. void *datadata;
  403. u_int32_t datasize;
  404. u_int32_t flags;
  405. __db_get_reply *replyp;
  406. int * freep;
  407. /* END __db_get_1_proc */
  408. {
  409. int key_alloc, ret;
  410. DB * dbp;
  411. ct_entry *dbp_ctp;
  412. DB_TXN * txnp;
  413. ct_entry *txnp_ctp;
  414. DBT key, data;
  415. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  416. dbp = (DB *)dbp_ctp->ct_anyp;
  417. if (txnpcl_id != 0) {
  418. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  419. txnp = (DB_TXN *)txnp_ctp->ct_anyp;
  420. } else
  421. txnp = NULL;
  422. *freep = 0;
  423. memset(&key, 0, sizeof(key));
  424. memset(&data, 0, sizeof(data));
  425. /* Set up key and data DBT */
  426. key.dlen = keydlen;
  427. key.doff = keydoff;
  428. /*
  429.  * Ignore memory related flags on server.
  430.  */
  431. key.flags = DB_DBT_MALLOC;
  432. if (keyflags & DB_DBT_PARTIAL)
  433. key.flags |= DB_DBT_PARTIAL;
  434. key.size = keysize;
  435. key.data = keydata;
  436. data.dlen = datadlen;
  437. data.doff = datadoff;
  438. /*
  439.  * Ignore memory related flags on server.
  440.  */
  441. data.flags = DB_DBT_MALLOC;
  442. if (dataflags & DB_DBT_PARTIAL)
  443. data.flags |= DB_DBT_PARTIAL;
  444. data.size = datasize;
  445. data.data = datadata;
  446. /* Got all our stuff, now do the get */
  447. ret = dbp->get(dbp, txnp, &key, &data, flags);
  448. /*
  449.  * Otherwise just status.
  450.  */
  451. if (ret == 0) {
  452. /*
  453.  * XXX
  454.  * We need to xdr_free whatever we are returning, next time.
  455.  * However, DB does not allocate a new key if one was given
  456.  * and we'd be free'ing up space allocated in the request.
  457.  * So, allocate a new key/data pointer if it is the same one
  458.  * as in the request.
  459.  */
  460. *freep = 1;
  461. /*
  462.  * Key
  463.  */
  464. key_alloc = 0;
  465. if (key.data == keydata) {
  466. ret = __os_malloc(dbp->dbenv,
  467.     key.size, NULL, &replyp->keydata.keydata_val);
  468. if (ret != 0) {
  469. __os_free(key.data, key.size);
  470. __os_free(data.data, data.size);
  471. goto err;
  472. }
  473. key_alloc = 1;
  474. memcpy(replyp->keydata.keydata_val, key.data, key.size);
  475. } else
  476. replyp->keydata.keydata_val = key.data;
  477. replyp->keydata.keydata_len = key.size;
  478. /*
  479.  * Data
  480.  */
  481. if (data.data == datadata) {
  482. ret = __os_malloc(dbp->dbenv,
  483.      data.size, NULL, &replyp->datadata.datadata_val);
  484. if (ret != 0) {
  485. __os_free(key.data, key.size);
  486. __os_free(data.data, data.size);
  487. if (key_alloc)
  488. __os_free(replyp->keydata.keydata_val,
  489.     key.size);
  490. goto err;
  491. }
  492. memcpy(replyp->datadata.datadata_val, data.data,
  493.     data.size);
  494. } else
  495. replyp->datadata.datadata_val = data.data;
  496. replyp->datadata.datadata_len = data.size;
  497. } else {
  498. err: replyp->keydata.keydata_val = NULL;
  499. replyp->keydata.keydata_len = 0;
  500. replyp->datadata.datadata_val = NULL;
  501. replyp->datadata.datadata_len = 0;
  502. *freep = 0;
  503. }
  504. replyp->status = ret;
  505. return;
  506. }
  507. /* BEGIN __db_h_ffactor_1_proc */
  508. void
  509. __db_h_ffactor_1_proc(dbpcl_id, ffactor, replyp)
  510. long dbpcl_id;
  511. u_int32_t ffactor;
  512. __db_h_ffactor_reply *replyp;
  513. /* END __db_h_ffactor_1_proc */
  514. {
  515. int ret;
  516. DB * dbp;
  517. ct_entry *dbp_ctp;
  518. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  519. dbp = (DB *)dbp_ctp->ct_anyp;
  520. ret = dbp->set_h_ffactor(dbp, ffactor);
  521. replyp->status = ret;
  522. return;
  523. }
  524. /* BEGIN __db_h_nelem_1_proc */
  525. void
  526. __db_h_nelem_1_proc(dbpcl_id, nelem, replyp)
  527. long dbpcl_id;
  528. u_int32_t nelem;
  529. __db_h_nelem_reply *replyp;
  530. /* END __db_h_nelem_1_proc */
  531. {
  532. int ret;
  533. DB * dbp;
  534. ct_entry *dbp_ctp;
  535. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  536. dbp = (DB *)dbp_ctp->ct_anyp;
  537. ret = dbp->set_h_nelem(dbp, nelem);
  538. replyp->status = ret;
  539. return;
  540. }
  541. /* BEGIN __db_key_range_1_proc */
  542. void
  543. __db_key_range_1_proc(dbpcl_id, txnpcl_id, keydlen,
  544. keydoff, keyflags, keydata, keysize,
  545. flags, replyp)
  546. long dbpcl_id;
  547. long txnpcl_id;
  548. u_int32_t keydlen;
  549. u_int32_t keydoff;
  550. u_int32_t keyflags;
  551. void *keydata;
  552. u_int32_t keysize;
  553. u_int32_t flags;
  554. __db_key_range_reply *replyp;
  555. /* END __db_key_range_1_proc */
  556. {
  557. int ret;
  558. DB * dbp;
  559. ct_entry *dbp_ctp;
  560. DB_TXN * txnp;
  561. ct_entry *txnp_ctp;
  562. DBT key;
  563. DB_KEY_RANGE range;
  564. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  565. dbp = (DB *)dbp_ctp->ct_anyp;
  566. if (txnpcl_id != 0) {
  567. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  568. txnp = (DB_TXN *)txnp_ctp->ct_anyp;
  569. } else
  570. txnp = NULL;
  571. memset(&key, 0, sizeof(key));
  572. /* Set up key and data DBT */
  573. key.dlen = keydlen;
  574. key.doff = keydoff;
  575. key.size = keysize;
  576. key.data = keydata;
  577. key.flags = keyflags;
  578. ret = dbp->key_range(dbp, txnp, &key, &range, flags);
  579. replyp->status = ret;
  580. replyp->less = range.less;
  581. replyp->equal = range.equal;
  582. replyp->greater = range.greater;
  583. return;
  584. }
  585. /* BEGIN __db_lorder_1_proc */
  586. void
  587. __db_lorder_1_proc(dbpcl_id, lorder, replyp)
  588. long dbpcl_id;
  589. u_int32_t lorder;
  590. __db_lorder_reply *replyp;
  591. /* END __db_lorder_1_proc */
  592. {
  593. int ret;
  594. DB * dbp;
  595. ct_entry *dbp_ctp;
  596. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  597. dbp = (DB *)dbp_ctp->ct_anyp;
  598. ret = dbp->set_lorder(dbp, lorder);
  599. replyp->status = ret;
  600. return;
  601. }
  602. /* BEGIN __dbopen_1_proc */
  603. void
  604. __db_open_1_proc(dbpcl_id, name, subdb,
  605. type, flags, mode, replyp)
  606. long dbpcl_id;
  607. char *name;
  608. char *subdb;
  609. u_int32_t type;
  610. u_int32_t flags;
  611. u_int32_t mode;
  612. __db_open_reply *replyp;
  613. /* END __db_open_1_proc */
  614. {
  615. int ret;
  616. DB * dbp;
  617. ct_entry *dbp_ctp;
  618. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  619. dbp = (DB *)dbp_ctp->ct_anyp;
  620. ret = dbp->open(dbp, name, subdb, (DBTYPE)type, flags, mode);
  621. if (ret == 0) {
  622. replyp->type = (int) dbp->get_type(dbp);
  623. /* XXX
  624.  * Tcl needs to peek at dbp->flags for DB_AM_DUP.  Send
  625.  * this dbp's flags back.
  626.  */
  627. replyp->dbflags = (int) dbp->flags;
  628. }
  629. replyp->status = ret;
  630. return;
  631. }
  632. /* BEGIN __db_pagesize_1_proc */
  633. void
  634. __db_pagesize_1_proc(dbpcl_id, pagesize, replyp)
  635. long dbpcl_id;
  636. u_int32_t pagesize;
  637. __db_pagesize_reply *replyp;
  638. /* END __db_pagesize_1_proc */
  639. {
  640. int ret;
  641. DB * dbp;
  642. ct_entry *dbp_ctp;
  643. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  644. dbp = (DB *)dbp_ctp->ct_anyp;
  645. ret = dbp->set_pagesize(dbp, pagesize);
  646. replyp->status = ret;
  647. return;
  648. }
  649. /* BEGIN __db_put_1_proc */
  650. void
  651. __db_put_1_proc(dbpcl_id, txnpcl_id, keydlen,
  652. keydoff, keyflags, keydata, keysize,
  653. datadlen, datadoff, dataflags, datadata,
  654. datasize, flags, replyp, freep)
  655. long dbpcl_id;
  656. long txnpcl_id;
  657. u_int32_t keydlen;
  658. u_int32_t keydoff;
  659. u_int32_t keyflags;
  660. void *keydata;
  661. u_int32_t keysize;
  662. u_int32_t datadlen;
  663. u_int32_t datadoff;
  664. u_int32_t dataflags;
  665. void *datadata;
  666. u_int32_t datasize;
  667. u_int32_t flags;
  668. __db_put_reply *replyp;
  669. int * freep;
  670. /* END __db_put_1_proc */
  671. {
  672. int ret;
  673. DB * dbp;
  674. ct_entry *dbp_ctp;
  675. DB_TXN * txnp;
  676. ct_entry *txnp_ctp;
  677. DBT key, data;
  678. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  679. dbp = (DB *)dbp_ctp->ct_anyp;
  680. if (txnpcl_id != 0) {
  681. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  682. txnp = (DB_TXN *)txnp_ctp->ct_anyp;
  683. } else
  684. txnp = NULL;
  685. *freep = 0;
  686. memset(&key, 0, sizeof(key));
  687. memset(&data, 0, sizeof(data));
  688. /* Set up key and data DBT */
  689. key.dlen = keydlen;
  690. key.doff = keydoff;
  691. /*
  692.  * Ignore memory related flags on server.
  693.  */
  694. key.flags = DB_DBT_MALLOC;
  695. if (keyflags & DB_DBT_PARTIAL)
  696. key.flags |= DB_DBT_PARTIAL;
  697. key.size = keysize;
  698. key.data = keydata;
  699. data.dlen = datadlen;
  700. data.doff = datadoff;
  701. data.flags = dataflags;
  702. data.size = datasize;
  703. data.data = datadata;
  704. /* Got all our stuff, now do the put */
  705. ret = dbp->put(dbp, txnp, &key, &data, flags);
  706. /*
  707.  * If the client did a DB_APPEND, set up key in reply.
  708.  * Otherwise just status.
  709.  */
  710. if (ret == 0 && (flags == DB_APPEND)) {
  711. /*
  712.  * XXX
  713.  * We need to xdr_free whatever we are returning, next time.
  714.  * However, DB does not allocate a new key if one was given
  715.  * and we'd be free'ing up space allocated in the request.
  716.  * So, allocate a new key/data pointer if it is the same one
  717.  * as in the request.
  718.  */
  719. *freep = 1;
  720. /*
  721.  * Key
  722.  */
  723. if (key.data == keydata) {
  724. ret = __os_malloc(dbp->dbenv,
  725.     key.size, NULL, &replyp->keydata.keydata_val);
  726. if (ret != 0) {
  727. __os_free(key.data, key.size);
  728. goto err;
  729. }
  730. memcpy(replyp->keydata.keydata_val, key.data, key.size);
  731. } else
  732. replyp->keydata.keydata_val = key.data;
  733. replyp->keydata.keydata_len = key.size;
  734. } else {
  735. err: replyp->keydata.keydata_val = NULL;
  736. replyp->keydata.keydata_len = 0;
  737. *freep = 0;
  738. }
  739. replyp->status = ret;
  740. return;
  741. }
  742. /* BEGIN __db_re_delim_1_proc */
  743. void
  744. __db_re_delim_1_proc(dbpcl_id, delim, replyp)
  745. long dbpcl_id;
  746. u_int32_t delim;
  747. __db_re_delim_reply *replyp;
  748. /* END __db_re_delim_1_proc */
  749. {
  750. int ret;
  751. DB * dbp;
  752. ct_entry *dbp_ctp;
  753. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  754. dbp = (DB *)dbp_ctp->ct_anyp;
  755. ret = dbp->set_re_delim(dbp, delim);
  756. replyp->status = ret;
  757. return;
  758. }
  759. /* BEGIN __db_re_len_1_proc */
  760. void
  761. __db_re_len_1_proc(dbpcl_id, len, replyp)
  762. long dbpcl_id;
  763. u_int32_t len;
  764. __db_re_len_reply *replyp;
  765. /* END __db_re_len_1_proc */
  766. {
  767. int ret;
  768. DB * dbp;
  769. ct_entry *dbp_ctp;
  770. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  771. dbp = (DB *)dbp_ctp->ct_anyp;
  772. ret = dbp->set_re_len(dbp, len);
  773. replyp->status = ret;
  774. return;
  775. }
  776. /* BEGIN __db_re_pad_1_proc */
  777. void
  778. __db_re_pad_1_proc(dbpcl_id, pad, replyp)
  779. long dbpcl_id;
  780. u_int32_t pad;
  781. __db_re_pad_reply *replyp;
  782. /* END __db_re_pad_1_proc */
  783. {
  784. int ret;
  785. DB * dbp;
  786. ct_entry *dbp_ctp;
  787. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  788. dbp = (DB *)dbp_ctp->ct_anyp;
  789. ret = dbp->set_re_pad(dbp, pad);
  790. replyp->status = ret;
  791. return;
  792. }
  793. /* BEGIN __db_remove_1_proc */
  794. void
  795. __db_remove_1_proc(dbpcl_id, name, subdb,
  796. flags, replyp)
  797. long dbpcl_id;
  798. char *name;
  799. char *subdb;
  800. u_int32_t flags;
  801. __db_remove_reply *replyp;
  802. /* END __db_remove_1_proc */
  803. {
  804. int ret;
  805. DB * dbp;
  806. ct_entry *dbp_ctp;
  807. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  808. dbp = (DB *)dbp_ctp->ct_anyp;
  809. ret = dbp->remove(dbp, name, subdb, flags);
  810. __dbdel_ctp(dbp_ctp);
  811. replyp->status = ret;
  812. return;
  813. }
  814. /* BEGIN __db_rename_1_proc */
  815. void
  816. __db_rename_1_proc(dbpcl_id, name, subdb,
  817. newname, flags, replyp)
  818. long dbpcl_id;
  819. char *name;
  820. char *subdb;
  821. char *newname;
  822. u_int32_t flags;
  823. __db_rename_reply *replyp;
  824. /* END __db_rename_1_proc */
  825. {
  826. int ret;
  827. DB * dbp;
  828. ct_entry *dbp_ctp;
  829. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  830. dbp = (DB *)dbp_ctp->ct_anyp;
  831. ret = dbp->rename(dbp, name, subdb, newname, flags);
  832. __dbdel_ctp(dbp_ctp);
  833. replyp->status = ret;
  834. return;
  835. }
  836. /* BEGIN __db_stat_1_proc */
  837. void
  838. __db_stat_1_proc(dbpcl_id,
  839. flags, replyp, freep)
  840. long dbpcl_id;
  841. u_int32_t flags;
  842. __db_stat_reply *replyp;
  843. int * freep;
  844. /* END __db_stat_1_proc */
  845. {
  846. int ret;
  847. DB * dbp;
  848. ct_entry *dbp_ctp;
  849. DBTYPE type;
  850. void *sp;
  851. int len;
  852. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  853. dbp = (DB *)dbp_ctp->ct_anyp;
  854. ret = dbp->stat(dbp, &sp, NULL, flags);
  855. replyp->status = ret;
  856. if (ret != 0)
  857. return;
  858. /*
  859.  * We get here, we have success.  Allocate an array so that
  860.  * we can use the list generator.  Generate the reply, free
  861.  * up the space.
  862.  */
  863. /*
  864.  * XXX This assumes that all elements of all stat structures
  865.  * are u_int32_t fields.  They are, currently.
  866.  */
  867. type = dbp->get_type(dbp);
  868. if (type == DB_HASH)
  869. len = sizeof(DB_HASH_STAT) / sizeof(u_int32_t);
  870. else if (type == DB_QUEUE)
  871. len = sizeof(DB_QUEUE_STAT) / sizeof(u_int32_t);
  872. else            /* BTREE or RECNO are same stats */
  873. len = sizeof(DB_BTREE_STAT) / sizeof(u_int32_t);
  874. /*
  875.  * Set up our list of stats.
  876.  */
  877. ret = __db_stats_list(dbp->dbenv,
  878.     &replyp->statslist, (u_int32_t*)sp, len);
  879. __os_free(sp, 0);
  880. if (ret == 0)
  881. *freep = 1;
  882. replyp->status = ret;
  883. return;
  884. }
  885. int
  886. __db_stats_list(dbenv, locp, pp, len)
  887. DB_ENV *dbenv;
  888. __db_stat_statsreplist **locp;
  889. u_int32_t *pp;
  890. int len;
  891. {
  892. u_int32_t *p, *q;
  893. int i, ret;
  894. __db_stat_statsreplist *nl, **nlp;
  895. nlp = locp;
  896. for (i = 0; i < len; i++) {
  897. p = pp+i;
  898. if ((ret = __os_malloc(dbenv, sizeof(*nl), NULL, nlp)) != 0)
  899. goto out;
  900. nl = *nlp;
  901. nl->next = NULL;
  902. if ((ret = __os_malloc(dbenv,
  903.     sizeof(u_int32_t), NULL, &nl->ent.ent_val)) != 0)
  904. goto out;
  905. q = (u_int32_t *)nl->ent.ent_val;
  906. *q = *p;
  907. nl->ent.ent_len = sizeof(u_int32_t);
  908. nlp = &nl->next;
  909. }
  910. return (0);
  911. out:
  912. __db_stats_freelist(locp);
  913. return (ret);
  914. }
  915. /*
  916.  * PUBLIC: void __db_stats_freelist __P((__db_stat_statsreplist **));
  917.  */
  918. void
  919. __db_stats_freelist(locp)
  920. __db_stat_statsreplist **locp;
  921. {
  922. __db_stat_statsreplist *nl, *nl1;
  923. for (nl = *locp; nl != NULL; nl = nl1) {
  924. nl1 = nl->next;
  925. if (nl->ent.ent_val)
  926. __os_free(nl->ent.ent_val, nl->ent.ent_len);
  927. __os_free(nl, sizeof(*nl));
  928. }
  929. *locp = NULL;
  930. }
  931. /* BEGIN __db_swapped_1_proc */
  932. void
  933. __db_swapped_1_proc(dbpcl_id, replyp)
  934. long dbpcl_id;
  935. __db_swapped_reply *replyp;
  936. /* END __db_swapped_1_proc */
  937. {
  938. int ret;
  939. DB * dbp;
  940. ct_entry *dbp_ctp;
  941. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  942. dbp = (DB *)dbp_ctp->ct_anyp;
  943. ret = dbp->get_byteswapped(dbp);
  944. replyp->status = ret;
  945. return;
  946. }
  947. /* BEGIN __db_sync_1_proc */
  948. void
  949. __db_sync_1_proc(dbpcl_id, flags, replyp)
  950. long dbpcl_id;
  951. u_int32_t flags;
  952. __db_sync_reply *replyp;
  953. /* END __db_sync_1_proc */
  954. {
  955. int ret;
  956. DB * dbp;
  957. ct_entry *dbp_ctp;
  958. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  959. dbp = (DB *)dbp_ctp->ct_anyp;
  960. ret = dbp->sync(dbp, flags);
  961. replyp->status = ret;
  962. return;
  963. }
  964. /* BEGIN __db_cursor_1_proc */
  965. void
  966. __db_cursor_1_proc(dbpcl_id, txnpcl_id,
  967. flags, replyp)
  968. long dbpcl_id;
  969. long txnpcl_id;
  970. u_int32_t flags;
  971. __db_cursor_reply *replyp;
  972. /* END __db_cursor_1_proc */
  973. {
  974. int ret;
  975. DB * dbp;
  976. ct_entry *dbp_ctp;
  977. DB_TXN * txnp;
  978. ct_entry *txnp_ctp;
  979. DBC *dbc;
  980. ct_entry *dbc_ctp, *env_ctp;
  981. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  982. dbp = (DB *)dbp_ctp->ct_anyp;
  983. dbc_ctp = new_ct_ent(&replyp->status);
  984. if (dbc_ctp == NULL)
  985. return;
  986. if (txnpcl_id != 0) {
  987. ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
  988. txnp = (DB_TXN *)txnp_ctp->ct_anyp;
  989. dbc_ctp->ct_activep = txnp_ctp->ct_activep;
  990. } else
  991. txnp = NULL;
  992. if ((ret = dbp->cursor(dbp, txnp, &dbc, flags)) == 0) {
  993. dbc_ctp->ct_dbc = dbc;
  994. dbc_ctp->ct_type = CT_CURSOR;
  995. dbc_ctp->ct_parent = dbp_ctp;
  996. env_ctp = dbp_ctp->ct_envparent;
  997. dbc_ctp->ct_envparent = env_ctp;
  998. __dbsrv_settimeout(dbc_ctp, env_ctp->ct_timeout);
  999. __dbsrv_active(dbc_ctp);
  1000. replyp->dbcidcl_id = dbc_ctp->ct_id;
  1001. } else
  1002. __dbclear_ctp(dbc_ctp);
  1003. replyp->status = ret;
  1004. return;
  1005. }
  1006. /* BEGIN __db_join_1_proc */
  1007. void
  1008. __db_join_1_proc(dbpcl_id, curslist,
  1009. flags, replyp)
  1010. long dbpcl_id;
  1011. u_int32_t * curslist;
  1012. u_int32_t flags;
  1013. __db_join_reply *replyp;
  1014. /* END __db_join_1_proc */
  1015. {
  1016. DB * dbp;
  1017. ct_entry *dbp_ctp;
  1018. DBC *dbc;
  1019. DBC **jcurs, **c;
  1020. ct_entry *dbc_ctp, *ctp;
  1021. size_t size;
  1022. int ret;
  1023. u_int32_t *cl;
  1024. ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
  1025. dbp = (DB *)dbp_ctp->ct_anyp;
  1026. dbc_ctp = new_ct_ent(&replyp->status);
  1027. if (dbc_ctp == NULL)
  1028. return;
  1029. for (size = sizeof(DBC *), cl = curslist; *cl != 0; size += sizeof(DBC *), cl++)
  1030. ;
  1031. if ((ret = __os_malloc(dbp->dbenv, size, NULL, &jcurs)) != 0) {
  1032. replyp->status = ret;
  1033. __dbclear_ctp(dbc_ctp);
  1034. return;
  1035. }
  1036. /*
  1037.  * If our curslist has a parent txn, we need to use it too
  1038.  * for the activity timeout.  All cursors must be part of
  1039.  * the same transaction, so just check the first.
  1040.  */
  1041. ctp = get_tableent(*curslist);
  1042. DB_ASSERT(ctp->ct_type == CT_CURSOR);
  1043. /*
  1044.  * If we are using a transaction, set the join activity timer
  1045.  * to point to the parent transaction.
  1046.  */
  1047. if (ctp->ct_activep != &ctp->ct_active)
  1048. dbc_ctp->ct_activep = ctp->ct_activep;
  1049. for (cl = curslist, c = jcurs; *cl != 0; cl++, c++) {
  1050. ctp = get_tableent(*cl);
  1051. if (ctp == NULL) {
  1052. replyp->status = DB_NOSERVER_ID;
  1053. goto out;
  1054. }
  1055. /*
  1056.  * If we are using a txn, the join cursor points to the
  1057.  * transaction timeout.  If we are not using a transaction,
  1058.  * then all the curslist cursors must point to the join
  1059.  * cursor's timeout so that we do not timeout any of the
  1060.  * curlist cursors while the join cursor is active.
  1061.  * Change the type of the curslist ctps to CT_JOIN so that
  1062.  * we know they are part of a join list and we can distinguish
  1063.  * them and later restore them when the join cursor is closed.
  1064.  */
  1065. DB_ASSERT(ctp->ct_type == CT_CURSOR);
  1066. ctp->ct_type |= CT_JOIN;
  1067. ctp->ct_origp = ctp->ct_activep;
  1068. /*
  1069.  * Setting this to the ct_active field of the dbc_ctp is
  1070.  * really just a way to distinguish which join dbc this
  1071.  * cursor is part of.  The ct_activep of this cursor is
  1072.  * not used at all during its lifetime as part of a join
  1073.  * cursor.
  1074.  */
  1075. ctp->ct_activep = &dbc_ctp->ct_active;
  1076. *c = ctp->ct_dbc;
  1077. }
  1078. *c = NULL;
  1079. if ((ret = dbp->join(dbp, jcurs, &dbc, flags)) == 0) {
  1080. dbc_ctp->ct_dbc = dbc;
  1081. dbc_ctp->ct_type = (CT_JOINCUR | CT_CURSOR);
  1082. dbc_ctp->ct_parent = dbp_ctp;
  1083. dbc_ctp->ct_envparent = dbp_ctp->ct_envparent;
  1084. __dbsrv_settimeout(dbc_ctp, dbp_ctp->ct_envparent->ct_timeout);
  1085. __dbsrv_active(dbc_ctp);
  1086. replyp->dbcidcl_id = dbc_ctp->ct_id;
  1087. } else {
  1088. __dbclear_ctp(dbc_ctp);
  1089. /*
  1090.  * If we get an error, undo what we did above to any cursors.
  1091.  */
  1092. for (cl = curslist; *cl != 0; cl++) {
  1093. ctp = get_tableent(*cl);
  1094. ctp->ct_type = CT_CURSOR;
  1095. ctp->ct_activep = ctp->ct_origp;
  1096. }
  1097. }
  1098. replyp->status = ret;
  1099. out:
  1100. __os_free(jcurs, size);
  1101. return;
  1102. }
  1103. /* BEGIN __dbc_close_1_proc */
  1104. void
  1105. __dbc_close_1_proc(dbccl_id, replyp)
  1106. long dbccl_id;
  1107. __dbc_close_reply *replyp;
  1108. /* END __dbc_close_1_proc */
  1109. {
  1110. ct_entry *dbc_ctp;
  1111. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1112. replyp->status = __dbc_close_int(dbc_ctp);
  1113. return;
  1114. }
  1115. /* BEGIN __dbc_count_1_proc */
  1116. void
  1117. __dbc_count_1_proc(dbccl_id, flags, replyp)
  1118. long dbccl_id;
  1119. u_int32_t flags;
  1120. __dbc_count_reply *replyp;
  1121. /* END __dbc_count_1_proc */
  1122. {
  1123. int ret;
  1124. DBC * dbc;
  1125. ct_entry *dbc_ctp;
  1126. db_recno_t num;
  1127. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1128. dbc = (DBC *)dbc_ctp->ct_anyp;
  1129. ret = dbc->c_count(dbc, &num, flags);
  1130. replyp->status = ret;
  1131. if (ret == 0)
  1132. replyp->dupcount = num;
  1133. return;
  1134. }
  1135. /* BEGIN __dbc_del_1_proc */
  1136. void
  1137. __dbc_del_1_proc(dbccl_id, flags, replyp)
  1138. long dbccl_id;
  1139. u_int32_t flags;
  1140. __dbc_del_reply *replyp;
  1141. /* END __dbc_del_1_proc */
  1142. {
  1143. int ret;
  1144. DBC * dbc;
  1145. ct_entry *dbc_ctp;
  1146. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1147. dbc = (DBC *)dbc_ctp->ct_anyp;
  1148. ret = dbc->c_del(dbc, flags);
  1149. replyp->status = ret;
  1150. return;
  1151. }
  1152. /* BEGIN __dbc_dup_1_proc */
  1153. void
  1154. __dbc_dup_1_proc(dbccl_id, flags, replyp)
  1155. long dbccl_id;
  1156. u_int32_t flags;
  1157. __dbc_dup_reply *replyp;
  1158. /* END __dbc_dup_1_proc */
  1159. {
  1160. int ret;
  1161. DBC * dbc;
  1162. ct_entry *dbc_ctp;
  1163. DBC *newdbc;
  1164. ct_entry *new_ctp;
  1165. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1166. dbc = (DBC *)dbc_ctp->ct_anyp;
  1167. new_ctp = new_ct_ent(&replyp->status);
  1168. if (new_ctp == NULL)
  1169. return;
  1170. if ((ret = dbc->c_dup(dbc, &newdbc, flags)) == 0) {
  1171. new_ctp->ct_dbc = newdbc;
  1172. new_ctp->ct_type = CT_CURSOR;
  1173. new_ctp->ct_parent = dbc_ctp->ct_parent;
  1174. new_ctp->ct_envparent = dbc_ctp->ct_envparent;
  1175. /*
  1176.  * If our cursor has a parent txn, we need to use it too.
  1177.  */
  1178. if (dbc_ctp->ct_activep != &dbc_ctp->ct_active)
  1179. new_ctp->ct_activep = dbc_ctp->ct_activep;
  1180. __dbsrv_settimeout(new_ctp, dbc_ctp->ct_timeout);
  1181. __dbsrv_active(new_ctp);
  1182. replyp->dbcidcl_id = new_ctp->ct_id;
  1183. } else
  1184. __dbclear_ctp(new_ctp);
  1185. replyp->status = ret;
  1186. return;
  1187. }
  1188. /* BEGIN __dbc_get_1_proc */
  1189. void
  1190. __dbc_get_1_proc(dbccl_id, keydlen, keydoff,
  1191. keyflags, keydata, keysize, datadlen,
  1192. datadoff, dataflags, datadata, datasize,
  1193. flags, replyp, freep)
  1194. long dbccl_id;
  1195. u_int32_t keydlen;
  1196. u_int32_t keydoff;
  1197. u_int32_t keyflags;
  1198. void *keydata;
  1199. u_int32_t keysize;
  1200. u_int32_t datadlen;
  1201. u_int32_t datadoff;
  1202. u_int32_t dataflags;
  1203. void *datadata;
  1204. u_int32_t datasize;
  1205. u_int32_t flags;
  1206. __dbc_get_reply *replyp;
  1207. int * freep;
  1208. /* END __dbc_get_1_proc */
  1209. {
  1210. DB_ENV *dbenv;
  1211. DBC *dbc;
  1212. DBT key, data;
  1213. ct_entry *dbc_ctp;
  1214. int key_alloc, ret;
  1215. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1216. dbc = (DBC *)dbc_ctp->ct_anyp;
  1217. dbenv = dbc->dbp->dbenv;
  1218. *freep = 0;
  1219. memset(&key, 0, sizeof(key));
  1220. memset(&data, 0, sizeof(data));
  1221. /* Set up key and data DBT */
  1222. key.dlen = keydlen;
  1223. key.doff = keydoff;
  1224. /*
  1225.  * Ignore memory related flags on server.
  1226.  */
  1227. key.flags = DB_DBT_MALLOC;
  1228. if (keyflags & DB_DBT_PARTIAL)
  1229. key.flags |= DB_DBT_PARTIAL;
  1230. key.size = keysize;
  1231. key.data = keydata;
  1232. data.dlen = datadlen;
  1233. data.doff = datadoff;
  1234. data.flags = DB_DBT_MALLOC;
  1235. if (dataflags & DB_DBT_PARTIAL)
  1236. data.flags |= DB_DBT_PARTIAL;
  1237. data.size = datasize;
  1238. data.data = datadata;
  1239. /* Got all our stuff, now do the get */
  1240. ret = dbc->c_get(dbc, &key, &data, flags);
  1241. /*
  1242.  * Otherwise just status.
  1243.  */
  1244. if (ret == 0) {
  1245. /*
  1246.  * XXX
  1247.  * We need to xdr_free whatever we are returning, next time.
  1248.  * However, DB does not allocate a new key if one was given
  1249.  * and we'd be free'ing up space allocated in the request.
  1250.  * So, allocate a new key/data pointer if it is the same one
  1251.  * as in the request.
  1252.  */
  1253. *freep = 1;
  1254. /*
  1255.  * Key
  1256.  */
  1257. key_alloc = 0;
  1258. if (key.data == keydata) {
  1259. ret = __os_malloc(dbenv, key.size, NULL,
  1260.     &replyp->keydata.keydata_val);
  1261. if (ret != 0) {
  1262. __os_free(key.data, key.size);
  1263. __os_free(data.data, data.size);
  1264. goto err;
  1265. }
  1266. key_alloc = 1;
  1267. memcpy(replyp->keydata.keydata_val, key.data, key.size);
  1268. } else
  1269. replyp->keydata.keydata_val = key.data;
  1270. replyp->keydata.keydata_len = key.size;
  1271. /*
  1272.  * Data
  1273.  */
  1274. if (data.data == datadata) {
  1275. ret = __os_malloc(dbenv, data.size, NULL,
  1276.     &replyp->datadata.datadata_val);
  1277. if (ret != 0) {
  1278. __os_free(key.data, key.size);
  1279. __os_free(data.data, data.size);
  1280. if (key_alloc)
  1281. __os_free(replyp->keydata.keydata_val,
  1282.     key.size);
  1283. goto err;
  1284. }
  1285. memcpy(replyp->datadata.datadata_val, data.data,
  1286.     data.size);
  1287. } else
  1288. replyp->datadata.datadata_val = data.data;
  1289. replyp->datadata.datadata_len = data.size;
  1290. } else {
  1291. err: replyp->keydata.keydata_val = NULL;
  1292. replyp->keydata.keydata_len = 0;
  1293. replyp->datadata.datadata_val = NULL;
  1294. replyp->datadata.datadata_len = 0;
  1295. *freep = 0;
  1296. }
  1297. replyp->status = ret;
  1298. return;
  1299. }
  1300. /* BEGIN __dbc_put_1_proc */
  1301. void
  1302. __dbc_put_1_proc(dbccl_id, keydlen, keydoff,
  1303. keyflags, keydata, keysize, datadlen,
  1304. datadoff, dataflags, datadata, datasize,
  1305. flags, replyp, freep)
  1306. long dbccl_id;
  1307. u_int32_t keydlen;
  1308. u_int32_t keydoff;
  1309. u_int32_t keyflags;
  1310. void *keydata;
  1311. u_int32_t keysize;
  1312. u_int32_t datadlen;
  1313. u_int32_t datadoff;
  1314. u_int32_t dataflags;
  1315. void *datadata;
  1316. u_int32_t datasize;
  1317. u_int32_t flags;
  1318. __dbc_put_reply *replyp;
  1319. int * freep;
  1320. /* END __dbc_put_1_proc */
  1321. {
  1322. int ret;
  1323. DBC * dbc;
  1324. DB *dbp;
  1325. ct_entry *dbc_ctp;
  1326. DBT key, data;
  1327. ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
  1328. dbc = (DBC *)dbc_ctp->ct_anyp;
  1329. dbp = (DB *)dbc_ctp->ct_parent->ct_anyp;
  1330. memset(&key, 0, sizeof(key));
  1331. memset(&data, 0, sizeof(data));
  1332. /* Set up key and data DBT */
  1333. key.dlen = keydlen;
  1334. key.doff = keydoff;
  1335. /*
  1336.  * Ignore memory related flags on server.
  1337.  */
  1338. key.flags = 0;
  1339. if (keyflags & DB_DBT_PARTIAL)
  1340. key.flags |= DB_DBT_PARTIAL;
  1341. key.size = keysize;
  1342. key.data = keydata;
  1343. data.dlen = datadlen;
  1344. data.doff = datadoff;
  1345. data.flags = dataflags;
  1346. data.size = datasize;
  1347. data.data = datadata;
  1348. /* Got all our stuff, now do the put */
  1349. ret = dbc->c_put(dbc, &key, &data, flags);
  1350. *freep = 0;
  1351. if (ret == 0 && (flags == DB_AFTER || flags == DB_BEFORE) &&
  1352.     dbp->type == DB_RECNO) {
  1353. /*
  1354.  * We need to xdr_free whatever we are returning, next time.
  1355.  */
  1356. replyp->keydata.keydata_val = key.data;
  1357. replyp->keydata.keydata_len = key.size;
  1358. } else {
  1359. replyp->keydata.keydata_val = NULL;
  1360. replyp->keydata.keydata_len = 0;
  1361. }
  1362. replyp->status = ret;
  1363. return;
  1364. }
  1365. #endif /* HAVE_RPC */