2
* See the file LICENSE for redistribution information.
4
* Copyright (c) 2000-2001
5
* Sleepycat Software. All rights reserved.
12
static const char revid[] = "$Id: db_server_proc.c,v 1.74 2001/07/03 19:09:51 sue Exp $";
15
#ifndef NO_SYSTEM_INCLUDES
16
#include <sys/types.h>
22
#include "db_server.h"
25
#include "db_server_int.h"
26
#include "rpc_server_ext.h"
28
/* BEGIN __env_cachesize_proc */
30
* PUBLIC: void __env_cachesize_proc __P((long, u_int32_t, u_int32_t,
31
* PUBLIC: u_int32_t, __env_cachesize_reply *));
34
__env_cachesize_proc(dbenvcl_id, gbytes, bytes,
40
__env_cachesize_reply *replyp;
41
/* END __env_cachesize_proc */
47
ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
48
dbenv = (DB_ENV *)dbenv_ctp->ct_anyp;
50
ret = dbenv->set_cachesize(dbenv, gbytes, bytes, ncache);
56
/* BEGIN __env_close_proc */
58
* PUBLIC: void __env_close_proc __P((long, u_int32_t, __env_close_reply *));
61
__env_close_proc(dbenvcl_id, flags, replyp)
64
__env_close_reply *replyp;
65
/* END __env_close_proc */
67
replyp->status = __dbenv_close_int(dbenvcl_id, flags);
71
/* BEGIN __env_create_proc */
73
* PUBLIC: void __env_create_proc __P((u_int32_t, __env_create_reply *));
76
__env_create_proc(timeout, replyp)
78
__env_create_reply *replyp;
79
/* END __env_create_proc */
85
ctp = new_ct_ent(&replyp->status);
88
if ((ret = db_env_create(&dbenv, 0)) == 0) {
90
ctp->ct_type = CT_ENV;
91
ctp->ct_parent = NULL;
92
ctp->ct_envparent = ctp;
93
__dbsrv_settimeout(ctp, timeout);
95
replyp->envcl_id = ctp->ct_id;
103
/* BEGIN __env_flags_proc */
105
* PUBLIC: void __env_flags_proc __P((long, u_int32_t, u_int32_t,
106
* PUBLIC: __env_flags_reply *));
109
__env_flags_proc(dbenvcl_id, flags, onoff, replyp)
113
__env_flags_reply *replyp;
114
/* END __env_flags_proc */
120
ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
121
dbenv = (DB_ENV *)dbenv_ctp->ct_anyp;
123
ret = dbenv->set_flags(dbenv, flags, onoff);
125
replyp->status = ret;
128
/* BEGIN __env_open_proc */
130
* PUBLIC: void __env_open_proc __P((long, char *, u_int32_t, u_int32_t,
131
* PUBLIC: __env_open_reply *));
134
__env_open_proc(dbenvcl_id, home, flags,
140
__env_open_reply *replyp;
141
/* END __env_open_proc */
148
ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
149
dbenv = (DB_ENV *)dbenv_ctp->ct_anyp;
150
fullhome = get_home(home);
151
if (fullhome == NULL) {
152
ret = DB_NOSERVER_HOME;
157
* If they are using locking do deadlock detection for them,
160
if ((flags & DB_INIT_LOCK) &&
161
(ret = dbenv->set_lk_detect(dbenv, DB_LOCK_DEFAULT)) != 0)
165
* Mask off flags we ignore
167
newflags = (flags & ~DB_SERVER_FLAGMASK);
168
ret = dbenv->open(dbenv, fullhome, newflags, mode);
169
out: replyp->status = ret;
173
/* BEGIN __env_remove_proc */
175
* PUBLIC: void __env_remove_proc __P((long, char *, u_int32_t,
176
* PUBLIC: __env_remove_reply *));
179
__env_remove_proc(dbenvcl_id, home, flags, replyp)
183
__env_remove_reply *replyp;
184
/* END __env_remove_proc */
191
ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
192
dbenv = (DB_ENV *)dbenv_ctp->ct_anyp;
193
fullhome = get_home(home);
194
if (fullhome == NULL) {
195
replyp->status = DB_NOSERVER_HOME;
199
ret = dbenv->remove(dbenv, fullhome, flags);
200
__dbdel_ctp(dbenv_ctp);
201
replyp->status = ret;
205
/* BEGIN __txn_abort_proc */
207
* PUBLIC: void __txn_abort_proc __P((long, __txn_abort_reply *));
210
__txn_abort_proc(txnpcl_id, replyp)
212
__txn_abort_reply *replyp;
213
/* END __txn_abort_proc */
219
ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
220
txnp = (DB_TXN *)txnp_ctp->ct_anyp;
222
ret = txn_abort(txnp);
223
__dbdel_ctp(txnp_ctp);
224
replyp->status = ret;
228
/* BEGIN __txn_begin_proc */
230
* PUBLIC: void __txn_begin_proc __P((long, long, u_int32_t,
231
* PUBLIC: __txn_begin_reply *));
234
__txn_begin_proc(dbenvcl_id, parentcl_id,
239
__txn_begin_reply *replyp;
240
/* END __txn_begin_proc */
243
DB_TXN *parent, *txnp;
244
ct_entry *ctp, *dbenv_ctp, *parent_ctp;
247
ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
248
dbenv = (DB_ENV *)dbenv_ctp->ct_anyp;
251
ctp = new_ct_ent(&replyp->status);
255
if (parentcl_id != 0) {
256
ACTIVATE_CTP(parent_ctp, parentcl_id, CT_TXN);
257
parent = (DB_TXN *)parent_ctp->ct_anyp;
258
ctp->ct_activep = parent_ctp->ct_activep;
262
ret = txn_begin(dbenv, parent, &txnp, flags);
265
ctp->ct_type = CT_TXN;
266
ctp->ct_parent = parent_ctp;
267
ctp->ct_envparent = dbenv_ctp;
268
replyp->txnidcl_id = ctp->ct_id;
269
__dbsrv_settimeout(ctp, dbenv_ctp->ct_timeout);
274
replyp->status = ret;
278
/* BEGIN __txn_commit_proc */
280
* PUBLIC: void __txn_commit_proc __P((long, u_int32_t,
281
* PUBLIC: __txn_commit_reply *));
284
__txn_commit_proc(txnpcl_id, flags, replyp)
287
__txn_commit_reply *replyp;
288
/* END __txn_commit_proc */
294
ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
295
txnp = (DB_TXN *)txnp_ctp->ct_anyp;
297
ret = txn_commit(txnp, flags);
298
__dbdel_ctp(txnp_ctp);
300
replyp->status = ret;
304
/* BEGIN __txn_discard_proc */
306
* PUBLIC: void __txn_discard_proc __P((long, u_int32_t,
307
* PUBLIC: __txn_discard_reply *));
310
__txn_discard_proc(txnpcl_id, flags, replyp)
313
__txn_discard_reply *replyp;
314
/* END __txn_discard_proc */
320
ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
321
txnp = (DB_TXN *)txnp_ctp->ct_anyp;
323
ret = txn_discard(txnp, flags);
324
__dbdel_ctp(txnp_ctp);
326
replyp->status = ret;
330
/* BEGIN __txn_prepare_proc */
332
* PUBLIC: void __txn_prepare_proc __P((long, u_int8_t *,
333
* PUBLIC: __txn_prepare_reply *));
336
__txn_prepare_proc(txnpcl_id, gid, replyp)
339
__txn_prepare_reply *replyp;
340
/* END __txn_prepare_proc */
346
ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
347
txnp = (DB_TXN *)txnp_ctp->ct_anyp;
349
ret = txn_prepare(txnp, gid);
350
replyp->status = ret;
354
/* BEGIN __txn_recover_proc */
356
* PUBLIC: void __txn_recover_proc __P((long, u_int32_t, u_int32_t,
357
* PUBLIC: __txn_recover_reply *, int *));
360
__txn_recover_proc(dbenvcl_id, count,
361
flags, replyp, freep)
365
__txn_recover_reply *replyp;
367
/* END __txn_recover_proc */
370
DB_PREPLIST *dbprep, *p;
371
ct_entry *dbenv_ctp, *ctp;
372
long erri, i, retcount;
377
ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
378
dbenv = (DB_ENV *)dbenv_ctp->ct_anyp;
382
if ((ret = __os_malloc(dbenv, count * sizeof(DB_PREPLIST), &dbprep))
385
if ((ret = txn_recover(dbenv, dbprep, count, &retcount, flags))
389
* If there is nothing, success, but it's easy.
391
replyp->retcount = retcount;
393
replyp->txn.txn_val = NULL;
394
replyp->txn.txn_len = 0;
395
replyp->gid.gid_val = NULL;
396
replyp->gid.gid_len = 0;
400
* We have our txn list. Now we need to allocate the space for
401
* the txn ID array and the GID array and set them up.
403
if ((ret = __os_calloc(dbenv, retcount, sizeof(u_int32_t),
404
&replyp->txn.txn_val)) != 0)
406
replyp->txn.txn_len = retcount * sizeof(u_int32_t);
407
if ((ret = __os_calloc(dbenv, retcount, DB_XIDDATASIZE,
408
&replyp->gid.gid_val)) != 0) {
409
__os_free(dbenv, replyp->txn.txn_val,
410
retcount * sizeof(u_int32_t));
413
replyp->gid.gid_len = retcount * DB_XIDDATASIZE;
416
* Now walk through our results, creating parallel arrays
417
* to send back. For each entry we need to create a new
418
* txn ctp and then fill in the array info.
422
gid = replyp->gid.gid_val;
423
txnidp = replyp->txn.txn_val;
424
while (i++ < retcount) {
425
ctp = new_ct_ent(&ret);
430
ctp->ct_txnp = p->txn;
431
ctp->ct_type = CT_TXN;
432
ctp->ct_parent = NULL;
433
ctp->ct_envparent = dbenv_ctp;
434
__dbsrv_settimeout(ctp, dbenv_ctp->ct_timeout);
437
*txnidp = ctp->ct_id;
438
memcpy(gid, p->gid, DB_XIDDATASIZE);
442
gid += DB_XIDDATASIZE;
445
* If we get here, we have success and we have to set freep
446
* so it'll get properly freed next time.
451
__os_free(dbenv, dbprep, count * sizeof(DB_PREPLIST));
452
replyp->status = ret;
456
* We had an error in the middle of creating our new txn
457
* ct entries. We have to unwind all that we have done. Ugh.
459
for (txnidp = replyp->txn.txn_val, erri = 0;
460
erri < i; erri++, txnidp++) {
461
ctp = get_tableent(*txnidp);
464
__os_free(dbenv, replyp->txn.txn_val,
465
retcount * sizeof(u_int32_t));
466
__os_free(dbenv, replyp->gid.gid_val,
467
retcount * DB_XIDDATASIZE);
468
__os_free(dbenv, dbprep, count * sizeof(DB_PREPLIST));
469
replyp->status = ret;
473
/* BEGIN __db_bt_maxkey_proc */
475
* PUBLIC: void __db_bt_maxkey_proc __P((long, u_int32_t,
476
* PUBLIC: __db_bt_maxkey_reply *));
479
__db_bt_maxkey_proc(dbpcl_id, maxkey, replyp)
482
__db_bt_maxkey_reply *replyp;
483
/* END __db_bt_maxkey_proc */
489
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
490
dbp = (DB *)dbp_ctp->ct_anyp;
492
ret = dbp->set_bt_maxkey(dbp, maxkey);
494
replyp->status = ret;
498
/* BEGIN __db_associate_proc */
500
* PUBLIC: void __db_associate_proc __P((long, long, u_int32_t,
501
* PUBLIC: __db_associate_reply *));
504
__db_associate_proc(dbpcl_id, sdbpcl_id,
509
__db_associate_reply *replyp;
510
/* END __db_associate_proc */
513
ct_entry *dbp_ctp, *sdbp_ctp;
516
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
517
dbp = (DB *)dbp_ctp->ct_anyp;
518
ACTIVATE_CTP(sdbp_ctp, sdbpcl_id, CT_DB);
519
sdbp = (DB *)sdbp_ctp->ct_anyp;
522
* We do not support DB_CREATE for associate. Users
523
* can only access secondary indices on a read-only basis,
524
* so whatever they are looking for needs to be there already.
529
ret = dbp->associate(dbp, sdbp, NULL, flags);
531
replyp->status = ret;
535
/* BEGIN __db_bt_minkey_proc */
537
* PUBLIC: void __db_bt_minkey_proc __P((long, u_int32_t,
538
* PUBLIC: __db_bt_minkey_reply *));
541
__db_bt_minkey_proc(dbpcl_id, minkey, replyp)
544
__db_bt_minkey_reply *replyp;
545
/* END __db_bt_minkey_proc */
551
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
552
dbp = (DB *)dbp_ctp->ct_anyp;
554
ret = dbp->set_bt_minkey(dbp, minkey);
556
replyp->status = ret;
560
/* BEGIN __db_close_proc */
562
* PUBLIC: void __db_close_proc __P((long, u_int32_t, __db_close_reply *));
565
__db_close_proc(dbpcl_id, flags, replyp)
568
__db_close_reply *replyp;
569
/* END __db_close_proc */
575
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
576
dbp = (DB *)dbp_ctp->ct_anyp;
578
ret = dbp->close(dbp, flags);
579
__dbdel_ctp(dbp_ctp);
581
replyp-> status= ret;
585
/* BEGIN __db_create_proc */
587
* PUBLIC: void __db_create_proc __P((long, u_int32_t, __db_create_reply *));
590
__db_create_proc(dbenvcl_id, flags, replyp)
593
__db_create_reply *replyp;
594
/* END __db_create_proc */
598
ct_entry *dbenv_ctp, *dbp_ctp;
601
ACTIVATE_CTP(dbenv_ctp, dbenvcl_id, CT_ENV);
602
dbenv = (DB_ENV *)dbenv_ctp->ct_anyp;
604
dbp_ctp = new_ct_ent(&replyp->status);
608
* We actually require env's for databases. The client should
609
* have caught it, but just in case.
611
DB_ASSERT(dbenv != NULL);
612
if ((ret = db_create(&dbp, dbenv, flags)) == 0) {
613
dbp_ctp->ct_dbp = dbp;
614
dbp_ctp->ct_type = CT_DB;
615
dbp_ctp->ct_parent = dbenv_ctp;
616
dbp_ctp->ct_envparent = dbenv_ctp;
617
replyp->dbcl_id = dbp_ctp->ct_id;
619
__dbclear_ctp(dbp_ctp);
620
replyp->status = ret;
624
/* BEGIN __db_del_proc */
626
* PUBLIC: void __db_del_proc __P((long, long, u_int32_t, u_int32_t, u_int32_t,
627
* PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, __db_del_reply *));
630
__db_del_proc(dbpcl_id, txnpcl_id, keydlen,
631
keydoff, keyulen, keyflags, keydata,
632
keysize, flags, replyp)
642
__db_del_reply *replyp;
643
/* END __db_del_proc */
648
ct_entry *dbp_ctp, *txnp_ctp;
651
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
652
dbp = (DB *)dbp_ctp->ct_anyp;
653
if (txnpcl_id != 0) {
654
ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
655
txnp = (DB_TXN *)txnp_ctp->ct_anyp;
659
memset(&key, 0, sizeof(key));
665
key.flags = keyflags;
669
ret = dbp->del(dbp, txnp, &key, flags);
671
replyp->status = ret;
675
/* BEGIN __db_extentsize_proc */
677
* PUBLIC: void __db_extentsize_proc __P((long, u_int32_t,
678
* PUBLIC: __db_extentsize_reply *));
681
__db_extentsize_proc(dbpcl_id, extentsize, replyp)
683
u_int32_t extentsize;
684
__db_extentsize_reply *replyp;
685
/* END __db_extentsize_proc */
691
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
692
dbp = (DB *)dbp_ctp->ct_anyp;
694
ret = dbp->set_q_extentsize(dbp, extentsize);
696
replyp->status = ret;
700
/* BEGIN __db_flags_proc */
702
* PUBLIC: void __db_flags_proc __P((long, u_int32_t, __db_flags_reply *));
705
__db_flags_proc(dbpcl_id, flags, replyp)
708
__db_flags_reply *replyp;
709
/* END __db_flags_proc */
715
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
716
dbp = (DB *)dbp_ctp->ct_anyp;
718
ret = dbp->set_flags(dbp, flags);
720
replyp->status = ret;
724
/* BEGIN __db_get_proc */
726
* PUBLIC: void __db_get_proc __P((long, long, u_int32_t, u_int32_t, u_int32_t,
727
* PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *,
728
* PUBLIC: u_int32_t, u_int32_t, __db_get_reply *, int *));
731
__db_get_proc(dbpcl_id, txnpcl_id, keydlen,
732
keydoff, keyulen, keyflags, keydata,
733
keysize, datadlen, datadoff, dataulen,
734
dataflags, datadata, datasize, flags, replyp, freep)
750
__db_get_reply *replyp;
752
/* END __db_get_proc */
757
ct_entry *dbp_ctp, *txnp_ctp;
758
int key_alloc, bulk_alloc, ret;
760
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
761
dbp = (DB *)dbp_ctp->ct_anyp;
762
if (txnpcl_id != 0) {
763
ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
764
txnp = (DB_TXN *)txnp_ctp->ct_anyp;
770
memset(&key, 0, sizeof(key));
771
memset(&data, 0, sizeof(data));
773
/* Set up key and data DBT */
777
* Ignore memory related flags on server.
779
key.flags = DB_DBT_MALLOC;
780
if (keyflags & DB_DBT_PARTIAL)
781
key.flags |= DB_DBT_PARTIAL;
786
data.dlen = datadlen;
787
data.doff = datadoff;
788
data.ulen = dataulen;
790
* Ignore memory related flags on server.
792
data.size = datasize;
793
data.data = datadata;
794
if (flags & DB_MULTIPLE) {
795
if (data.data == 0) {
796
ret = __os_malloc(dbp->dbenv,
797
data.ulen, &data.data);
802
data.flags |= DB_DBT_USERMEM;
804
data.flags |= DB_DBT_MALLOC;
805
if (dataflags & DB_DBT_PARTIAL)
806
data.flags |= DB_DBT_PARTIAL;
808
/* Got all our stuff, now do the get */
809
ret = dbp->get(dbp, txnp, &key, &data, flags);
811
* Otherwise just status.
816
* We need to xdr_free whatever we are returning, next time.
817
* However, DB does not allocate a new key if one was given
818
* and we'd be free'ing up space allocated in the request.
819
* So, allocate a new key/data pointer if it is the same one
827
if (key.data == keydata) {
828
ret = __os_malloc(dbp->dbenv,
829
key.size, &replyp->keydata.keydata_val);
831
__os_free(dbp->dbenv, key.data, key.size);
832
__os_free(dbp->dbenv, data.data, data.size);
836
memcpy(replyp->keydata.keydata_val, key.data, key.size);
838
replyp->keydata.keydata_val = key.data;
840
replyp->keydata.keydata_len = key.size;
845
if (data.data == datadata) {
846
ret = __os_malloc(dbp->dbenv,
847
data.size, &replyp->datadata.datadata_val);
849
__os_free(dbp->dbenv, key.data, key.size);
850
__os_free(dbp->dbenv, data.data, data.size);
852
__os_free(dbp->dbenv,
853
replyp->keydata.keydata_val,
857
memcpy(replyp->datadata.datadata_val, data.data,
860
replyp->datadata.datadata_val = data.data;
861
replyp->datadata.datadata_len = data.size;
863
err: replyp->keydata.keydata_val = NULL;
864
replyp->keydata.keydata_len = 0;
865
replyp->datadata.datadata_val = NULL;
866
replyp->datadata.datadata_len = 0;
869
__os_free(dbp->dbenv, data.data, data.ulen);
871
replyp->status = ret;
875
/* BEGIN __db_h_ffactor_proc */
877
* PUBLIC: void __db_h_ffactor_proc __P((long, u_int32_t,
878
* PUBLIC: __db_h_ffactor_reply *));
881
__db_h_ffactor_proc(dbpcl_id, ffactor, replyp)
884
__db_h_ffactor_reply *replyp;
885
/* END __db_h_ffactor_proc */
891
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
892
dbp = (DB *)dbp_ctp->ct_anyp;
894
ret = dbp->set_h_ffactor(dbp, ffactor);
896
replyp->status = ret;
900
/* BEGIN __db_h_nelem_proc */
902
* PUBLIC: void __db_h_nelem_proc __P((long, u_int32_t,
903
* PUBLIC: __db_h_nelem_reply *));
906
__db_h_nelem_proc(dbpcl_id, nelem, replyp)
909
__db_h_nelem_reply *replyp;
910
/* END __db_h_nelem_proc */
916
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
917
dbp = (DB *)dbp_ctp->ct_anyp;
919
ret = dbp->set_h_nelem(dbp, nelem);
921
replyp->status = ret;
925
/* BEGIN __db_key_range_proc */
927
* PUBLIC: void __db_key_range_proc __P((long, long, u_int32_t, u_int32_t,
928
* PUBLIC: u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, __db_key_range_reply *));
931
__db_key_range_proc(dbpcl_id, txnpcl_id, keydlen,
932
keydoff, keyulen, keyflags, keydata,
933
keysize, flags, replyp)
943
__db_key_range_reply *replyp;
944
/* END __db_key_range_proc */
950
ct_entry *dbp_ctp, *txnp_ctp;
953
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
954
dbp = (DB *)dbp_ctp->ct_anyp;
955
if (txnpcl_id != 0) {
956
ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
957
txnp = (DB_TXN *)txnp_ctp->ct_anyp;
961
memset(&key, 0, sizeof(key));
962
/* Set up key and data DBT */
968
key.flags = keyflags;
970
ret = dbp->key_range(dbp, txnp, &key, &range, flags);
972
replyp->status = ret;
973
replyp->less = range.less;
974
replyp->equal = range.equal;
975
replyp->greater = range.greater;
979
/* BEGIN __db_lorder_proc */
981
* PUBLIC: void __db_lorder_proc __P((long, u_int32_t, __db_lorder_reply *));
984
__db_lorder_proc(dbpcl_id, lorder, replyp)
987
__db_lorder_reply *replyp;
988
/* END __db_lorder_proc */
994
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
995
dbp = (DB *)dbp_ctp->ct_anyp;
997
ret = dbp->set_lorder(dbp, lorder);
999
replyp->status = ret;
1003
/* BEGIN __db_open_proc */
1005
* PUBLIC: void __db_open_proc __P((long, char *, char *, u_int32_t, u_int32_t,
1006
* PUBLIC: u_int32_t, __db_open_reply *));
1009
__db_open_proc(dbpcl_id, name, subdb,
1010
type, flags, mode, replyp)
1017
__db_open_reply *replyp;
1018
/* END __db_open_proc */
1025
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1026
dbp = (DB *)dbp_ctp->ct_anyp;
1028
ret = dbp->open(dbp, name, subdb, (DBTYPE)type, flags, mode);
1030
(void)dbp->get_type(dbp, &dbtype);
1031
replyp->type = dbtype;
1033
* Tcl needs to peek at dbp->flags for DB_AM_DUP. Send
1034
* this dbp's flags back.
1036
replyp->dbflags = (int) dbp->flags;
1038
* We need to determine the byte order of the database
1039
* and send it back to the client. Determine it by
1040
* the server's native order and the swapped value of
1043
(void)dbp->get_byteswapped(dbp, &isswapped);
1044
if (__db_byteorder(NULL, 1234) == 0) {
1046
replyp->lorder = 1234;
1048
replyp->lorder = 4321;
1051
replyp->lorder = 4321;
1053
replyp->lorder = 1234;
1056
replyp->status = ret;
1060
/* BEGIN __db_pagesize_proc */
1062
* PUBLIC: void __db_pagesize_proc __P((long, u_int32_t,
1063
* PUBLIC: __db_pagesize_reply *));
1066
__db_pagesize_proc(dbpcl_id, pagesize, replyp)
1069
__db_pagesize_reply *replyp;
1070
/* END __db_pagesize_proc */
1076
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1077
dbp = (DB *)dbp_ctp->ct_anyp;
1079
ret = dbp->set_pagesize(dbp, pagesize);
1081
replyp->status = ret;
1085
/* BEGIN __db_pget_proc */
1087
* PUBLIC: void __db_pget_proc __P((long, long, u_int32_t, u_int32_t,
1088
* PUBLIC: u_int32_t, u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t,
1089
* PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *,
1090
* PUBLIC: u_int32_t, u_int32_t, __db_pget_reply *, int *));
1093
__db_pget_proc(dbpcl_id, txnpcl_id, skeydlen,
1094
skeydoff, skeyulen, skeyflags, skeydata,
1095
skeysize, pkeydlen, pkeydoff, pkeyulen,
1096
pkeyflags, pkeydata, pkeysize, datadlen,
1097
datadoff, dataulen, dataflags, datadata,
1098
datasize, flags, replyp, freep)
1104
u_int32_t skeyflags;
1110
u_int32_t pkeyflags;
1116
u_int32_t dataflags;
1120
__db_pget_reply *replyp;
1122
/* END __db_pget_proc */
1125
DBT skey, pkey, data;
1127
ct_entry *dbp_ctp, *txnp_ctp;
1130
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1131
dbp = (DB *)dbp_ctp->ct_anyp;
1132
if (txnpcl_id != 0) {
1133
ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
1134
txnp = (DB_TXN *)txnp_ctp->ct_anyp;
1139
memset(&skey, 0, sizeof(skey));
1140
memset(&pkey, 0, sizeof(pkey));
1141
memset(&data, 0, sizeof(data));
1144
* Ignore memory related flags on server.
1146
/* Set up key and data DBT */
1147
skey.flags = DB_DBT_MALLOC;
1148
skey.dlen = skeydlen;
1149
skey.ulen = skeyulen;
1150
skey.doff = skeydoff;
1151
if (skeyflags & DB_DBT_PARTIAL)
1152
skey.flags |= DB_DBT_PARTIAL;
1153
skey.size = skeysize;
1154
skey.data = skeydata;
1156
pkey.flags = DB_DBT_MALLOC;
1157
pkey.dlen = pkeydlen;
1158
pkey.ulen = pkeyulen;
1159
pkey.doff = pkeydoff;
1160
if (pkeyflags & DB_DBT_PARTIAL)
1161
pkey.flags |= DB_DBT_PARTIAL;
1162
pkey.size = pkeysize;
1163
pkey.data = pkeydata;
1165
data.flags = DB_DBT_MALLOC;
1166
data.dlen = datadlen;
1167
data.ulen = dataulen;
1168
data.doff = datadoff;
1169
if (dataflags & DB_DBT_PARTIAL)
1170
data.flags |= DB_DBT_PARTIAL;
1171
data.size = datasize;
1172
data.data = datadata;
1174
/* Got all our stuff, now do the get */
1175
ret = dbp->pget(dbp, txnp, &skey, &pkey, &data, flags);
1177
* Otherwise just status.
1182
* We need to xdr_free whatever we are returning, next time.
1183
* However, DB does not allocate a new key if one was given
1184
* and we'd be free'ing up space allocated in the request.
1185
* So, allocate a new key/data pointer if it is the same one
1186
* as in the request.
1193
if (skey.data == skeydata) {
1194
ret = __os_malloc(dbp->dbenv,
1195
skey.size, &replyp->skeydata.skeydata_val);
1197
__os_free(dbp->dbenv, skey.data, skey.size);
1198
__os_free(dbp->dbenv, pkey.data, pkey.size);
1199
__os_free(dbp->dbenv, data.data, data.size);
1203
memcpy(replyp->skeydata.skeydata_val, skey.data,
1206
replyp->skeydata.skeydata_val = skey.data;
1208
replyp->skeydata.skeydata_len = skey.size;
1213
if (pkey.data == pkeydata) {
1214
ret = __os_malloc(dbp->dbenv,
1215
pkey.size, &replyp->pkeydata.pkeydata_val);
1217
__os_free(dbp->dbenv, skey.data, skey.size);
1218
__os_free(dbp->dbenv, pkey.data, pkey.size);
1219
__os_free(dbp->dbenv, data.data, data.size);
1221
__os_free(dbp->dbenv,
1222
replyp->skeydata.skeydata_val,
1227
* We can set it to 2, because they cannot send the
1228
* pkey over without sending the skey over too.
1229
* So if they did send a pkey, they must have sent
1233
memcpy(replyp->pkeydata.pkeydata_val, pkey.data,
1236
replyp->pkeydata.pkeydata_val = pkey.data;
1237
replyp->pkeydata.pkeydata_len = pkey.size;
1242
if (data.data == datadata) {
1243
ret = __os_malloc(dbp->dbenv,
1244
data.size, &replyp->datadata.datadata_val);
1246
__os_free(dbp->dbenv, skey.data, skey.size);
1247
__os_free(dbp->dbenv, pkey.data, pkey.size);
1248
__os_free(dbp->dbenv, data.data, data.size);
1250
* If key_alloc is 1, just skey needs to be
1251
* freed, if key_alloc is 2, both skey and pkey
1255
__os_free(dbp->dbenv,
1256
replyp->skeydata.skeydata_val,
1259
__os_free(dbp->dbenv,
1260
replyp->pkeydata.pkeydata_val,
1264
memcpy(replyp->datadata.datadata_val, data.data,
1267
replyp->datadata.datadata_val = data.data;
1268
replyp->datadata.datadata_len = data.size;
1270
err: replyp->skeydata.skeydata_val = NULL;
1271
replyp->skeydata.skeydata_len = 0;
1272
replyp->pkeydata.pkeydata_val = NULL;
1273
replyp->pkeydata.pkeydata_len = 0;
1274
replyp->datadata.datadata_val = NULL;
1275
replyp->datadata.datadata_len = 0;
1278
replyp->status = ret;
1282
/* BEGIN __db_put_proc */
1284
* PUBLIC: void __db_put_proc __P((long, long, u_int32_t, u_int32_t, u_int32_t,
1285
* PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *,
1286
* PUBLIC: u_int32_t, u_int32_t, __db_put_reply *, int *));
1289
__db_put_proc(dbpcl_id, txnpcl_id, keydlen,
1290
keydoff, keyulen, keyflags, keydata,
1291
keysize, datadlen, datadoff, dataulen,
1292
dataflags, datadata, datasize, flags, replyp, freep)
1304
u_int32_t dataflags;
1308
__db_put_reply *replyp;
1310
/* END __db_put_proc */
1315
ct_entry *dbp_ctp, *txnp_ctp;
1318
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1319
dbp = (DB *)dbp_ctp->ct_anyp;
1320
if (txnpcl_id != 0) {
1321
ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
1322
txnp = (DB_TXN *)txnp_ctp->ct_anyp;
1327
memset(&key, 0, sizeof(key));
1328
memset(&data, 0, sizeof(data));
1330
/* Set up key and data DBT */
1335
* Ignore memory related flags on server.
1337
key.flags = DB_DBT_MALLOC;
1338
if (keyflags & DB_DBT_PARTIAL)
1339
key.flags |= DB_DBT_PARTIAL;
1343
data.dlen = datadlen;
1344
data.ulen = dataulen;
1345
data.doff = datadoff;
1346
data.flags = dataflags;
1347
data.size = datasize;
1348
data.data = datadata;
1350
/* Got all our stuff, now do the put */
1351
ret = dbp->put(dbp, txnp, &key, &data, flags);
1353
* If the client did a DB_APPEND, set up key in reply.
1354
* Otherwise just status.
1356
if (ret == 0 && (flags == DB_APPEND)) {
1359
* We need to xdr_free whatever we are returning, next time.
1360
* However, DB does not allocate a new key if one was given
1361
* and we'd be free'ing up space allocated in the request.
1362
* So, allocate a new key/data pointer if it is the same one
1363
* as in the request.
1369
if (key.data == keydata) {
1370
ret = __os_malloc(dbp->dbenv,
1371
key.size, &replyp->keydata.keydata_val);
1373
__os_free(dbp->dbenv, key.data, key.size);
1376
memcpy(replyp->keydata.keydata_val, key.data, key.size);
1378
replyp->keydata.keydata_val = key.data;
1380
replyp->keydata.keydata_len = key.size;
1382
err: replyp->keydata.keydata_val = NULL;
1383
replyp->keydata.keydata_len = 0;
1386
replyp->status = ret;
1390
/* BEGIN __db_re_delim_proc */
1392
* PUBLIC: void __db_re_delim_proc __P((long, u_int32_t,
1393
* PUBLIC: __db_re_delim_reply *));
1396
__db_re_delim_proc(dbpcl_id, delim, replyp)
1399
__db_re_delim_reply *replyp;
1400
/* END __db_re_delim_proc */
1406
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1407
dbp = (DB *)dbp_ctp->ct_anyp;
1409
ret = dbp->set_re_delim(dbp, delim);
1411
replyp->status = ret;
1415
/* BEGIN __db_re_len_proc */
1417
* PUBLIC: void __db_re_len_proc __P((long, u_int32_t, __db_re_len_reply *));
1420
__db_re_len_proc(dbpcl_id, len, replyp)
1423
__db_re_len_reply *replyp;
1424
/* END __db_re_len_proc */
1430
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1431
dbp = (DB *)dbp_ctp->ct_anyp;
1433
ret = dbp->set_re_len(dbp, len);
1435
replyp->status = ret;
1439
/* BEGIN __db_re_pad_proc */
1441
* PUBLIC: void __db_re_pad_proc __P((long, u_int32_t, __db_re_pad_reply *));
1444
__db_re_pad_proc(dbpcl_id, pad, replyp)
1447
__db_re_pad_reply *replyp;
1448
/* END __db_re_pad_proc */
1454
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1455
dbp = (DB *)dbp_ctp->ct_anyp;
1457
ret = dbp->set_re_pad(dbp, pad);
1459
replyp->status = ret;
1463
/* BEGIN __db_remove_proc */
1465
* PUBLIC: void __db_remove_proc __P((long, char *, char *, u_int32_t,
1466
* PUBLIC: __db_remove_reply *));
1469
__db_remove_proc(dbpcl_id, name, subdb,
1475
__db_remove_reply *replyp;
1476
/* END __db_remove_proc */
1482
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1483
dbp = (DB *)dbp_ctp->ct_anyp;
1485
ret = dbp->remove(dbp, name, subdb, flags);
1486
__dbdel_ctp(dbp_ctp);
1488
replyp->status = ret;
1492
/* BEGIN __db_rename_proc */
1494
* PUBLIC: void __db_rename_proc __P((long, char *, char *, char *, u_int32_t,
1495
* PUBLIC: __db_rename_reply *));
1498
__db_rename_proc(dbpcl_id, name, subdb,
1499
newname, flags, replyp)
1505
__db_rename_reply *replyp;
1506
/* END __db_rename_proc */
1512
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1513
dbp = (DB *)dbp_ctp->ct_anyp;
1515
ret = dbp->rename(dbp, name, subdb, newname, flags);
1516
__dbdel_ctp(dbp_ctp);
1518
replyp->status = ret;
1522
/* BEGIN __db_stat_proc */
1524
* PUBLIC: void __db_stat_proc __P((long, u_int32_t, __db_stat_reply *,
1528
__db_stat_proc(dbpcl_id, flags, replyp, freep)
1531
__db_stat_reply *replyp;
1533
/* END __db_stat_proc */
1538
u_int32_t *q, *p, *retsp;
1542
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1543
dbp = (DB *)dbp_ctp->ct_anyp;
1545
ret = dbp->stat(dbp, &sp, flags);
1546
replyp->status = ret;
1550
* We get here, we have success. Allocate an array so that
1551
* we can use the list generator. Generate the reply, free
1555
* XXX This assumes that all elements of all stat structures
1556
* are u_int32_t fields. They are, currently.
1558
(void)dbp->get_type(dbp, &type);
1559
if (type == DB_HASH)
1560
len = sizeof(DB_HASH_STAT);
1561
else if (type == DB_QUEUE)
1562
len = sizeof(DB_QUEUE_STAT);
1563
else /* BTREE or RECNO are same stats */
1564
len = sizeof(DB_BTREE_STAT);
1565
replyp->stats.stats_len = len / sizeof(u_int32_t);
1567
if ((ret = __os_calloc(dbp->dbenv, replyp->stats.stats_len,
1570
for (i = 0, q = retsp, p = sp; i < len;
1573
replyp->stats.stats_val = retsp;
1574
__os_free(dbp->dbenv, sp, 0);
1578
replyp->status = ret;
1582
/* BEGIN __db_sync_proc */
1584
* PUBLIC: void __db_sync_proc __P((long, u_int32_t, __db_sync_reply *));
1587
__db_sync_proc(dbpcl_id, flags, replyp)
1590
__db_sync_reply *replyp;
1591
/* END __db_sync_proc */
1597
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1598
dbp = (DB *)dbp_ctp->ct_anyp;
1600
ret = dbp->sync(dbp, flags);
1602
replyp->status = ret;
1606
/* BEGIN __db_truncate_proc */
1608
* PUBLIC: void __db_truncate_proc __P((long, long, u_int32_t,
1609
* PUBLIC: __db_truncate_reply *));
1612
__db_truncate_proc(dbpcl_id, txnpcl_id,
1617
__db_truncate_reply *replyp;
1618
/* END __db_truncate_proc */
1622
ct_entry *dbp_ctp, *txnp_ctp;
1626
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1627
dbp = (DB *)dbp_ctp->ct_anyp;
1628
if (txnpcl_id != 0) {
1629
ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
1630
txnp = (DB_TXN *)txnp_ctp->ct_anyp;
1635
ret = dbp->truncate(dbp, txnp, &count, flags);
1636
replyp->status = ret;
1638
replyp->count = count;
1642
/* BEGIN __db_cursor_proc */
1644
* PUBLIC: void __db_cursor_proc __P((long, long, u_int32_t,
1645
* PUBLIC: __db_cursor_reply *));
1648
__db_cursor_proc(dbpcl_id, txnpcl_id,
1653
__db_cursor_reply *replyp;
1654
/* END __db_cursor_proc */
1659
ct_entry *dbc_ctp, *env_ctp, *dbp_ctp, *txnp_ctp;
1662
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1663
dbp = (DB *)dbp_ctp->ct_anyp;
1664
dbc_ctp = new_ct_ent(&replyp->status);
1665
if (dbc_ctp == NULL)
1668
if (txnpcl_id != 0) {
1669
ACTIVATE_CTP(txnp_ctp, txnpcl_id, CT_TXN);
1670
txnp = (DB_TXN *)txnp_ctp->ct_anyp;
1671
dbc_ctp->ct_activep = txnp_ctp->ct_activep;
1675
if ((ret = dbp->cursor(dbp, txnp, &dbc, flags)) == 0) {
1676
dbc_ctp->ct_dbc = dbc;
1677
dbc_ctp->ct_type = CT_CURSOR;
1678
dbc_ctp->ct_parent = dbp_ctp;
1679
env_ctp = dbp_ctp->ct_envparent;
1680
dbc_ctp->ct_envparent = env_ctp;
1681
__dbsrv_settimeout(dbc_ctp, env_ctp->ct_timeout);
1682
__dbsrv_active(dbc_ctp);
1683
replyp->dbcidcl_id = dbc_ctp->ct_id;
1685
__dbclear_ctp(dbc_ctp);
1687
replyp->status = ret;
1691
/* BEGIN __db_join_proc */
1693
* PUBLIC: void __db_join_proc __P((long, u_int32_t *, u_int32_t, u_int32_t,
1694
* PUBLIC: __db_join_reply *));
1697
__db_join_proc(dbpcl_id, curs, curslen,
1703
__db_join_reply *replyp;
1704
/* END __db_join_proc */
1709
ct_entry *dbc_ctp, *ctp, *dbp_ctp;
1714
ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB);
1715
dbp = (DB *)dbp_ctp->ct_anyp;
1717
dbc_ctp = new_ct_ent(&replyp->status);
1718
if (dbc_ctp == NULL)
1721
size = (curslen + 1) * sizeof(DBC *);
1722
if ((ret = __os_calloc(dbp->dbenv,
1723
curslen + 1, sizeof(DBC *), &jcurs)) != 0) {
1724
replyp->status = ret;
1725
__dbclear_ctp(dbc_ctp);
1729
* If our curslist has a parent txn, we need to use it too
1730
* for the activity timeout. All cursors must be part of
1731
* the same transaction, so just check the first.
1733
ctp = get_tableent(*curs);
1734
DB_ASSERT(ctp->ct_type == CT_CURSOR);
1736
* If we are using a transaction, set the join activity timer
1737
* to point to the parent transaction.
1739
if (ctp->ct_activep != &ctp->ct_active)
1740
dbc_ctp->ct_activep = ctp->ct_activep;
1741
for (i = 0, cl = curs, c = jcurs; i < curslen; i++, cl++, c++) {
1742
ctp = get_tableent(*cl);
1744
replyp->status = DB_NOSERVER_ID;
1748
* If we are using a txn, the join cursor points to the
1749
* transaction timeout. If we are not using a transaction,
1750
* then all the curslist cursors must point to the join
1751
* cursor's timeout so that we do not timeout any of the
1752
* curlist cursors while the join cursor is active.
1753
* Change the type of the curslist ctps to CT_JOIN so that
1754
* we know they are part of a join list and we can distinguish
1755
* them and later restore them when the join cursor is closed.
1757
DB_ASSERT(ctp->ct_type == CT_CURSOR);
1758
ctp->ct_type |= CT_JOIN;
1759
ctp->ct_origp = ctp->ct_activep;
1761
* Setting this to the ct_active field of the dbc_ctp is
1762
* really just a way to distinguish which join dbc this
1763
* cursor is part of. The ct_activep of this cursor is
1764
* not used at all during its lifetime as part of a join
1767
ctp->ct_activep = &dbc_ctp->ct_active;
1771
if ((ret = dbp->join(dbp, jcurs, &dbc, flags)) == 0) {
1772
dbc_ctp->ct_dbc = dbc;
1773
dbc_ctp->ct_type = (CT_JOINCUR | CT_CURSOR);
1774
dbc_ctp->ct_parent = dbp_ctp;
1775
dbc_ctp->ct_envparent = dbp_ctp->ct_envparent;
1776
__dbsrv_settimeout(dbc_ctp, dbp_ctp->ct_envparent->ct_timeout);
1777
__dbsrv_active(dbc_ctp);
1778
replyp->dbcidcl_id = dbc_ctp->ct_id;
1780
__dbclear_ctp(dbc_ctp);
1782
* If we get an error, undo what we did above to any cursors.
1784
for (cl = curs; *cl != 0; cl++) {
1785
ctp = get_tableent(*cl);
1786
ctp->ct_type = CT_CURSOR;
1787
ctp->ct_activep = ctp->ct_origp;
1791
replyp->status = ret;
1793
__os_free(dbp->dbenv, jcurs, size);
1797
/* BEGIN __dbc_close_proc */
1799
* PUBLIC: void __dbc_close_proc __P((long, __dbc_close_reply *));
1802
__dbc_close_proc(dbccl_id, replyp)
1804
__dbc_close_reply *replyp;
1805
/* END __dbc_close_proc */
1809
ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
1810
replyp->status = __dbc_close_int(dbc_ctp);
1814
/* BEGIN __dbc_count_proc */
1816
* PUBLIC: void __dbc_count_proc __P((long, u_int32_t, __dbc_count_reply *));
1819
__dbc_count_proc(dbccl_id, flags, replyp)
1822
__dbc_count_reply *replyp;
1823
/* END __dbc_count_proc */
1830
ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
1831
dbc = (DBC *)dbc_ctp->ct_anyp;
1833
ret = dbc->c_count(dbc, &num, flags);
1834
replyp->status = ret;
1836
replyp->dupcount = num;
1840
/* BEGIN __dbc_del_proc */
1842
* PUBLIC: void __dbc_del_proc __P((long, u_int32_t, __dbc_del_reply *));
1845
__dbc_del_proc(dbccl_id, flags, replyp)
1848
__dbc_del_reply *replyp;
1849
/* END __dbc_del_proc */
1855
ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
1856
dbc = (DBC *)dbc_ctp->ct_anyp;
1858
ret = dbc->c_del(dbc, flags);
1860
replyp->status = ret;
1864
/* BEGIN __dbc_dup_proc */
1866
* PUBLIC: void __dbc_dup_proc __P((long, u_int32_t, __dbc_dup_reply *));
1869
__dbc_dup_proc(dbccl_id, flags, replyp)
1872
__dbc_dup_reply *replyp;
1873
/* END __dbc_dup_proc */
1876
ct_entry *dbc_ctp, *new_ctp;
1879
ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
1880
dbc = (DBC *)dbc_ctp->ct_anyp;
1882
new_ctp = new_ct_ent(&replyp->status);
1883
if (new_ctp == NULL)
1886
if ((ret = dbc->c_dup(dbc, &newdbc, flags)) == 0) {
1887
new_ctp->ct_dbc = newdbc;
1888
new_ctp->ct_type = CT_CURSOR;
1889
new_ctp->ct_parent = dbc_ctp->ct_parent;
1890
new_ctp->ct_envparent = dbc_ctp->ct_envparent;
1892
* If our cursor has a parent txn, we need to use it too.
1894
if (dbc_ctp->ct_activep != &dbc_ctp->ct_active)
1895
new_ctp->ct_activep = dbc_ctp->ct_activep;
1896
__dbsrv_settimeout(new_ctp, dbc_ctp->ct_timeout);
1897
__dbsrv_active(new_ctp);
1898
replyp->dbcidcl_id = new_ctp->ct_id;
1900
__dbclear_ctp(new_ctp);
1902
replyp->status = ret;
1906
/* BEGIN __dbc_get_proc */
1908
* PUBLIC: void __dbc_get_proc __P((long, u_int32_t, u_int32_t, u_int32_t,
1909
* PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *,
1910
* PUBLIC: u_int32_t, u_int32_t, __dbc_get_reply *, int *));
1913
__dbc_get_proc(dbccl_id, keydlen, keydoff,
1914
keyulen, keyflags, keydata, keysize,
1915
datadlen, datadoff, dataulen, dataflags,
1916
datadata, datasize, flags, replyp, freep)
1927
u_int32_t dataflags;
1931
__dbc_get_reply *replyp;
1933
/* END __dbc_get_proc */
1939
int key_alloc, bulk_alloc, ret;
1941
ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
1942
dbc = (DBC *)dbc_ctp->ct_anyp;
1943
dbenv = dbc->dbp->dbenv;
1947
memset(&key, 0, sizeof(key));
1948
memset(&data, 0, sizeof(data));
1950
/* Set up key and data DBT */
1955
* Ignore memory related flags on server.
1957
key.flags = DB_DBT_MALLOC;
1958
if (keyflags & DB_DBT_PARTIAL)
1959
key.flags |= DB_DBT_PARTIAL;
1963
data.dlen = datadlen;
1964
data.ulen = dataulen;
1965
data.doff = datadoff;
1966
data.size = datasize;
1967
data.data = datadata;
1968
if (flags & DB_MULTIPLE || flags & DB_MULTIPLE_KEY) {
1969
if (data.data == 0) {
1970
ret = __os_malloc(dbenv, data.ulen, &data.data);
1975
data.flags |= DB_DBT_USERMEM;
1977
data.flags |= DB_DBT_MALLOC;
1978
if (dataflags & DB_DBT_PARTIAL)
1979
data.flags |= DB_DBT_PARTIAL;
1982
/* Got all our stuff, now do the get */
1983
ret = dbc->c_get(dbc, &key, &data, flags);
1986
* Otherwise just status.
1991
* We need to xdr_free whatever we are returning, next time.
1992
* However, DB does not allocate a new key if one was given
1993
* and we'd be free'ing up space allocated in the request.
1994
* So, allocate a new key/data pointer if it is the same one
1995
* as in the request.
2002
if (key.data == keydata) {
2003
ret = __os_malloc(dbenv, key.size,
2004
&replyp->keydata.keydata_val);
2006
__os_free(dbenv, key.data, key.size);
2007
__os_free(dbenv, data.data, data.size);
2011
memcpy(replyp->keydata.keydata_val, key.data, key.size);
2013
replyp->keydata.keydata_val = key.data;
2015
replyp->keydata.keydata_len = key.size;
2020
if (data.data == datadata) {
2021
ret = __os_malloc(dbenv, data.size,
2022
&replyp->datadata.datadata_val);
2024
__os_free(dbenv, key.data, key.size);
2025
__os_free(dbenv, data.data, data.size);
2027
__os_free(dbenv, replyp->keydata.keydata_val,
2031
memcpy(replyp->datadata.datadata_val, data.data,
2034
replyp->datadata.datadata_val = data.data;
2035
replyp->datadata.datadata_len = data.size;
2037
err: replyp->keydata.keydata_val = NULL;
2038
replyp->keydata.keydata_len = 0;
2039
replyp->datadata.datadata_val = NULL;
2040
replyp->datadata.datadata_len = 0;
2043
__os_free(dbenv, data.data, data.ulen);
2045
replyp->status = ret;
2049
/* BEGIN __dbc_pget_proc */
2051
* PUBLIC: void __dbc_pget_proc __P((long, u_int32_t, u_int32_t, u_int32_t,
2052
* PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *,
2053
* PUBLIC: u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *, u_int32_t,
2054
* PUBLIC: u_int32_t, __dbc_pget_reply *, int *));
2057
__dbc_pget_proc(dbccl_id, skeydlen, skeydoff,
2058
skeyulen, skeyflags, skeydata, skeysize,
2059
pkeydlen, pkeydoff, pkeyulen, pkeyflags,
2060
pkeydata, pkeysize, datadlen, datadoff,
2061
dataulen, dataflags, datadata, datasize,
2062
flags, replyp, freep)
2067
u_int32_t skeyflags;
2073
u_int32_t pkeyflags;
2079
u_int32_t dataflags;
2083
__dbc_pget_reply *replyp;
2085
/* END __dbc_pget_proc */
2088
DBT skey, pkey, data;
2093
ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
2094
dbc = (DBC *)dbc_ctp->ct_anyp;
2095
dbenv = dbc->dbp->dbenv;
2098
memset(&skey, 0, sizeof(skey));
2099
memset(&pkey, 0, sizeof(pkey));
2100
memset(&data, 0, sizeof(data));
2103
* Ignore memory related flags on server.
2105
/* Set up key and data DBT */
2106
skey.flags = DB_DBT_MALLOC;
2107
skey.dlen = skeydlen;
2108
skey.ulen = skeyulen;
2109
skey.doff = skeydoff;
2110
if (skeyflags & DB_DBT_PARTIAL)
2111
skey.flags |= DB_DBT_PARTIAL;
2112
skey.size = skeysize;
2113
skey.data = skeydata;
2115
pkey.flags = DB_DBT_MALLOC;
2116
pkey.dlen = pkeydlen;
2117
pkey.ulen = pkeyulen;
2118
pkey.doff = pkeydoff;
2119
if (pkeyflags & DB_DBT_PARTIAL)
2120
pkey.flags |= DB_DBT_PARTIAL;
2121
pkey.size = pkeysize;
2122
pkey.data = pkeydata;
2124
data.flags = DB_DBT_MALLOC;
2125
data.dlen = datadlen;
2126
data.ulen = dataulen;
2127
data.doff = datadoff;
2128
if (dataflags & DB_DBT_PARTIAL)
2129
data.flags |= DB_DBT_PARTIAL;
2130
data.size = datasize;
2131
data.data = datadata;
2133
/* Got all our stuff, now do the get */
2134
ret = dbc->c_pget(dbc, &skey, &pkey, &data, flags);
2136
* Otherwise just status.
2141
* We need to xdr_free whatever we are returning, next time.
2142
* However, DB does not allocate a new key if one was given
2143
* and we'd be free'ing up space allocated in the request.
2144
* So, allocate a new key/data pointer if it is the same one
2145
* as in the request.
2152
if (skey.data == skeydata) {
2153
ret = __os_malloc(dbenv,
2154
skey.size, &replyp->skeydata.skeydata_val);
2156
__os_free(dbenv, skey.data, skey.size);
2157
__os_free(dbenv, pkey.data, pkey.size);
2158
__os_free(dbenv, data.data, data.size);
2162
memcpy(replyp->skeydata.skeydata_val, skey.data,
2165
replyp->skeydata.skeydata_val = skey.data;
2166
replyp->skeydata.skeydata_len = skey.size;
2171
if (pkey.data == pkeydata) {
2172
ret = __os_malloc(dbenv,
2173
pkey.size, &replyp->pkeydata.pkeydata_val);
2175
__os_free(dbenv, skey.data, skey.size);
2176
__os_free(dbenv, pkey.data, pkey.size);
2177
__os_free(dbenv, data.data, data.size);
2180
replyp->skeydata.skeydata_val,
2185
* We can set it to 2, because they cannot send the
2186
* pkey over without sending the skey over too.
2187
* So if they did send a pkey, they must have sent
2191
memcpy(replyp->pkeydata.pkeydata_val, pkey.data,
2194
replyp->pkeydata.pkeydata_val = pkey.data;
2195
replyp->pkeydata.pkeydata_len = pkey.size;
2200
if (data.data == datadata) {
2201
ret = __os_malloc(dbenv,
2202
data.size, &replyp->datadata.datadata_val);
2204
__os_free(dbenv, skey.data, skey.size);
2205
__os_free(dbenv, pkey.data, pkey.size);
2206
__os_free(dbenv, data.data, data.size);
2208
* If key_alloc is 1, just skey needs to be
2209
* freed, if key_alloc is 2, both skey and pkey
2214
replyp->skeydata.skeydata_val,
2218
replyp->pkeydata.pkeydata_val,
2222
memcpy(replyp->datadata.datadata_val, data.data,
2225
replyp->datadata.datadata_val = data.data;
2226
replyp->datadata.datadata_len = data.size;
2228
err: replyp->skeydata.skeydata_val = NULL;
2229
replyp->skeydata.skeydata_len = 0;
2230
replyp->pkeydata.pkeydata_val = NULL;
2231
replyp->pkeydata.pkeydata_len = 0;
2232
replyp->datadata.datadata_val = NULL;
2233
replyp->datadata.datadata_len = 0;
2236
replyp->status = ret;
2240
/* BEGIN __dbc_put_proc */
2242
* PUBLIC: void __dbc_put_proc __P((long, u_int32_t, u_int32_t, u_int32_t,
2243
* PUBLIC: u_int32_t, void *, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, void *,
2244
* PUBLIC: u_int32_t, u_int32_t, __dbc_put_reply *, int *));
2247
__dbc_put_proc(dbccl_id, keydlen, keydoff,
2248
keyulen, keyflags, keydata, keysize,
2249
datadlen, datadoff, dataulen, dataflags,
2250
datadata, datasize, flags, replyp, freep)
2261
u_int32_t dataflags;
2265
__dbc_put_reply *replyp;
2267
/* END __dbc_put_proc */
2275
ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR);
2276
dbc = (DBC *)dbc_ctp->ct_anyp;
2277
dbp = (DB *)dbc_ctp->ct_parent->ct_anyp;
2279
memset(&key, 0, sizeof(key));
2280
memset(&data, 0, sizeof(data));
2282
/* Set up key and data DBT */
2287
* Ignore memory related flags on server.
2290
if (keyflags & DB_DBT_PARTIAL)
2291
key.flags |= DB_DBT_PARTIAL;
2295
data.dlen = datadlen;
2296
data.ulen = dataulen;
2297
data.doff = datadoff;
2298
data.flags = dataflags;
2299
data.size = datasize;
2300
data.data = datadata;
2302
/* Got all our stuff, now do the put */
2303
ret = dbc->c_put(dbc, &key, &data, flags);
2306
if (ret == 0 && (flags == DB_AFTER || flags == DB_BEFORE) &&
2307
dbp->type == DB_RECNO) {
2309
* We need to xdr_free whatever we are returning, next time.
2311
replyp->keydata.keydata_val = key.data;
2312
replyp->keydata.keydata_len = key.size;
2314
replyp->keydata.keydata_val = NULL;
2315
replyp->keydata.keydata_len = 0;
2317
replyp->status = ret;
2320
#endif /* HAVE_RPC */