~ubuntu-branches/ubuntu/edgy/rpm/edgy

« back to all changes in this revision

Viewing changes to db/rpc_server/db_server_proc.c

  • Committer: Bazaar Package Importer
  • Author(s): Joey Hess
  • Date: 2002-01-22 20:56:57 UTC
  • Revision ID: james.westby@ubuntu.com-20020122205657-l74j50mr9z8ofcl5
Tags: upstream-4.0.3
ImportĀ upstreamĀ versionĀ 4.0.3

Show diffs side-by-side

added added

removed removed

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