~ubuntu-branches/ubuntu/maverick/evolution-data-server/maverick-proposed

« back to all changes in this revision

Viewing changes to libdb/db_load/db_load.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

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) 1996-2002
5
 
 *      Sleepycat Software.  All rights reserved.
6
 
 */
7
 
 
8
 
#include "db_config.h"
9
 
 
10
 
#ifndef lint
11
 
static const char copyright[] =
12
 
    "Copyright (c) 1996-2002\nSleepycat Software Inc.  All rights reserved.\n";
13
 
static const char revid[] =
14
 
    "$Id$";
15
 
#endif
16
 
 
17
 
#ifndef NO_SYSTEM_INCLUDES
18
 
#include <sys/types.h>
19
 
 
20
 
#include <limits.h>
21
 
#include <stdio.h>
22
 
#include <stdlib.h>
23
 
#include <string.h>
24
 
#include <unistd.h>
25
 
#endif
26
 
 
27
 
#include "db_int.h"
28
 
#include "dbinc/db_page.h"
29
 
#include "dbinc/db_am.h"
30
 
 
31
 
typedef struct {                        /* XXX: Globals. */
32
 
        const char *progname;           /* Program name. */
33
 
        char    *hdrbuf;                /* Input file header. */
34
 
        u_long  lineno;                 /* Input file line number. */
35
 
        u_long  origline;               /* Original file line number. */
36
 
        int     endodata;               /* Reached the end of a database. */
37
 
        int     endofile;               /* Reached the end of the input. */
38
 
        int     version;                /* Input version. */
39
 
        char    *home;                  /* Env home. */
40
 
        char    *passwd;                /* Env passwd. */
41
 
        int     private;                /* Private env. */
42
 
        u_int32_t cache;                /* Env cache size. */
43
 
} LDG;
44
 
 
45
 
void    badend __P((DB_ENV *));
46
 
void    badnum __P((DB_ENV *));
47
 
int     configure __P((DB_ENV *, DB *, char **, char **, int *));
48
 
int     convprintable __P((DB_ENV *, char *, char **));
49
 
int     db_init __P((DB_ENV *, char *, u_int32_t, int *));
50
 
int     dbt_rdump __P((DB_ENV *, DBT *));
51
 
int     dbt_rprint __P((DB_ENV *, DBT *));
52
 
int     dbt_rrecno __P((DB_ENV *, DBT *, int));
53
 
int     digitize __P((DB_ENV *, int, int *));
54
 
int     env_create __P((DB_ENV **, LDG *));
55
 
int     load __P((DB_ENV *, char *, DBTYPE, char **, u_int, LDG *, int *));
56
 
int     main __P((int, char *[]));
57
 
int     rheader __P((DB_ENV *, DB *, DBTYPE *, char **, int *, int *));
58
 
int     usage __P((void));
59
 
int     version_check __P((const char *));
60
 
 
61
 
#define G(f)    ((LDG *)dbenv->app_private)->f
62
 
 
63
 
                                        /* Flags to the load function. */
64
 
#define LDF_NOHEADER    0x01            /* No dump header. */
65
 
#define LDF_NOOVERWRITE 0x02            /* Don't overwrite existing rows. */
66
 
#define LDF_PASSWORD    0x04            /* Encrypt created databases. */
67
 
 
68
 
int
69
 
main(argc, argv)
70
 
        int argc;
71
 
        char *argv[];
72
 
{
73
 
        extern char *optarg;
74
 
        extern int optind;
75
 
        DBTYPE dbtype;
76
 
        DB_ENV  *dbenv;
77
 
        LDG ldg;
78
 
        u_int32_t ldf;
79
 
        int ch, existed, exitval, ret;
80
 
        char **clist, **clp;
81
 
 
82
 
        ldg.progname = "db_load";
83
 
        ldg.lineno = 0;
84
 
        ldg.endodata = ldg.endofile = 0;
85
 
        ldg.version = 1;
86
 
        ldg.cache = MEGABYTE;
87
 
        ldg.hdrbuf = NULL;
88
 
        ldg.home = NULL;
89
 
        ldg.passwd = NULL;
90
 
 
91
 
        if ((ret = version_check(ldg.progname)) != 0)
92
 
                return (ret);
93
 
 
94
 
        ldf = 0;
95
 
        exitval = 0;
96
 
        dbtype = DB_UNKNOWN;
97
 
 
98
 
        /* Allocate enough room for configuration arguments. */
99
 
        if ((clp = clist = (char **)calloc(argc + 1, sizeof(char *))) == NULL) {
100
 
                fprintf(stderr, "%s: %s\n", ldg.progname, strerror(ENOMEM));
101
 
                return (EXIT_FAILURE);
102
 
        }
103
 
 
104
 
        while ((ch = getopt(argc, argv, "c:f:h:nP:Tt:V")) != EOF)
105
 
                switch (ch) {
106
 
                case 'c':
107
 
                        *clp++ = optarg;
108
 
                        break;
109
 
                case 'f':
110
 
                        if (freopen(optarg, "r", stdin) == NULL) {
111
 
                                fprintf(stderr, "%s: %s: reopen: %s\n",
112
 
                                    ldg.progname, optarg, strerror(errno));
113
 
                                return (EXIT_FAILURE);
114
 
                        }
115
 
                        break;
116
 
                case 'h':
117
 
                        ldg.home = optarg;
118
 
                        break;
119
 
                case 'n':
120
 
                        ldf |= LDF_NOOVERWRITE;
121
 
                        break;
122
 
                case 'P':
123
 
                        ldg.passwd = strdup(optarg);
124
 
                        memset(optarg, 0, strlen(optarg));
125
 
                        if (ldg.passwd == NULL) {
126
 
                                fprintf(stderr, "%s: strdup: %s\n",
127
 
                                    ldg.progname, strerror(errno));
128
 
                                return (EXIT_FAILURE);
129
 
                        }
130
 
                        ldf |= LDF_PASSWORD;
131
 
                        break;
132
 
                case 'T':
133
 
                        ldf |= LDF_NOHEADER;
134
 
                        break;
135
 
                case 't':
136
 
                        if (strcmp(optarg, "btree") == 0) {
137
 
                                dbtype = DB_BTREE;
138
 
                                break;
139
 
                        }
140
 
                        if (strcmp(optarg, "hash") == 0) {
141
 
                                dbtype = DB_HASH;
142
 
                                break;
143
 
                        }
144
 
                        if (strcmp(optarg, "recno") == 0) {
145
 
                                dbtype = DB_RECNO;
146
 
                                break;
147
 
                        }
148
 
                        if (strcmp(optarg, "queue") == 0) {
149
 
                                dbtype = DB_QUEUE;
150
 
                                break;
151
 
                        }
152
 
                        return (usage());
153
 
                case 'V':
154
 
                        printf("%s\n", db_version(NULL, NULL, NULL));
155
 
                        return (EXIT_SUCCESS);
156
 
                case '?':
157
 
                default:
158
 
                        return (usage());
159
 
                }
160
 
        argc -= optind;
161
 
        argv += optind;
162
 
 
163
 
        if (argc != 1)
164
 
                return (usage());
165
 
 
166
 
        /* Handle possible interruptions. */
167
 
        __db_util_siginit();
168
 
 
169
 
        /*
170
 
         * Create an environment object initialized for error reporting, and
171
 
         * then open it.
172
 
         */
173
 
        if (env_create(&dbenv, &ldg) != 0)
174
 
                goto shutdown;
175
 
 
176
 
        while (!ldg.endofile)
177
 
                if (load(dbenv, argv[0], dbtype, clist, ldf,
178
 
                    &ldg, &existed) != 0)
179
 
                        goto shutdown;
180
 
 
181
 
        if (0) {
182
 
shutdown:       exitval = 1;
183
 
        }
184
 
        if ((ret = dbenv->close(dbenv, 0)) != 0) {
185
 
                exitval = 1;
186
 
                fprintf(stderr,
187
 
                    "%s: dbenv->close: %s\n", ldg.progname, db_strerror(ret));
188
 
        }
189
 
 
190
 
        /* Resend any caught signal. */
191
 
        __db_util_sigresend();
192
 
        free(clist);
193
 
 
194
 
        /*
195
 
         * Return 0 on success, 1 if keys existed already, and 2 on failure.
196
 
         *
197
 
         * Technically, this is wrong, because exit of anything other than
198
 
         * 0 is implementation-defined by the ANSI C standard.  I don't see
199
 
         * any good solutions that don't involve API changes.
200
 
         */
201
 
        return (exitval == 0 ? (existed == 0 ? 0 : 1) : 2);
202
 
}
203
 
 
204
 
/*
205
 
 * load --
206
 
 *      Load a database.
207
 
 */
208
 
int
209
 
load(dbenv, name, argtype, clist, flags, ldg, existedp)
210
 
        DB_ENV *dbenv;
211
 
        char *name, **clist;
212
 
        DBTYPE argtype;
213
 
        u_int flags;
214
 
        LDG *ldg;
215
 
        int *existedp;
216
 
{
217
 
        DB *dbp;
218
 
        DBT key, rkey, data, *readp, *writep;
219
 
        DBTYPE dbtype;
220
 
        DB_TXN *ctxn, *txn;
221
 
        db_recno_t recno, datarecno;
222
 
        u_int32_t put_flags;
223
 
        int ascii_recno, checkprint, hexkeys, keyflag, keys, resize, ret, rval;
224
 
        char *subdb;
225
 
 
226
 
        *existedp = 0;
227
 
 
228
 
        put_flags = LF_ISSET(LDF_NOOVERWRITE) ? DB_NOOVERWRITE : 0;
229
 
        G(endodata) = 0;
230
 
 
231
 
        subdb = NULL;
232
 
        ctxn = txn = NULL;
233
 
        memset(&key, 0, sizeof(DBT));
234
 
        memset(&data, 0, sizeof(DBT));
235
 
        memset(&rkey, 0, sizeof(DBT));
236
 
 
237
 
retry_db:
238
 
        /* Create the DB object. */
239
 
        if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
240
 
                dbenv->err(dbenv, ret, "db_create");
241
 
                goto err;
242
 
        }
243
 
 
244
 
        dbtype = DB_UNKNOWN;
245
 
        keys = -1;
246
 
        hexkeys = -1;
247
 
        keyflag = -1;
248
 
        /* Read the header -- if there's no header, we expect flat text. */
249
 
        if (LF_ISSET(LDF_NOHEADER)) {
250
 
                checkprint = 1;
251
 
                dbtype = argtype;
252
 
        } else {
253
 
                if (rheader(dbenv,
254
 
                    dbp, &dbtype, &subdb, &checkprint, &keys) != 0)
255
 
                        goto err;
256
 
                if (G(endofile))
257
 
                        goto done;
258
 
        }
259
 
 
260
 
        /*
261
 
         * Apply command-line configuration changes.  (We apply command-line
262
 
         * configuration changes to all databases that are loaded, e.g., all
263
 
         * subdatabases.)
264
 
         */
265
 
        if (configure(dbenv, dbp, clist, &subdb, &keyflag))
266
 
                goto err;
267
 
 
268
 
        if (keys != 1) {
269
 
                if (keyflag == 1) {
270
 
                        dbp->err(dbp, EINVAL, "No keys specified in file");
271
 
                        goto err;
272
 
                }
273
 
        }
274
 
        else if (keyflag == 0) {
275
 
                dbp->err(dbp, EINVAL, "Keys specified in file");
276
 
                goto err;
277
 
        }
278
 
        else
279
 
                keyflag = 1;
280
 
 
281
 
        if (dbtype == DB_BTREE || dbtype == DB_HASH) {
282
 
                if (keyflag == 0)
283
 
                        dbp->err(dbp,
284
 
                            EINVAL, "Btree and Hash must specify keys");
285
 
                else
286
 
                        keyflag = 1;
287
 
        }
288
 
 
289
 
        if (argtype != DB_UNKNOWN) {
290
 
 
291
 
                if (dbtype == DB_RECNO || dbtype == DB_QUEUE)
292
 
                        if (keyflag != 1 && argtype != DB_RECNO &&
293
 
                            argtype != DB_QUEUE) {
294
 
                                dbenv->errx(dbenv,
295
 
                           "improper database type conversion specified");
296
 
                                goto err;
297
 
                        }
298
 
                dbtype = argtype;
299
 
        }
300
 
 
301
 
        if (dbtype == DB_UNKNOWN) {
302
 
                dbenv->errx(dbenv, "no database type specified");
303
 
                goto err;
304
 
        }
305
 
 
306
 
        if (keyflag == -1)
307
 
                keyflag = 0;
308
 
 
309
 
        /*
310
 
         * Recno keys have only been printed in hexadecimal starting
311
 
         * with db_dump format version 3 (DB 3.2).
312
 
         *
313
 
         * !!!
314
 
         * Note that version is set in rheader(), which must be called before
315
 
         * this assignment.
316
 
         */
317
 
        hexkeys = (G(version) >= 3 && keyflag == 1 && checkprint == 0);
318
 
 
319
 
        if (keyflag == 1 && (dbtype == DB_RECNO || dbtype == DB_QUEUE))
320
 
                ascii_recno = 1;
321
 
        else
322
 
                ascii_recno = 0;
323
 
 
324
 
        /* If configured with a password, encrypt databases we create. */
325
 
        if (LF_ISSET(LDF_PASSWORD) &&
326
 
            (ret = dbp->set_flags(dbp, DB_ENCRYPT)) != 0) {
327
 
                dbp->err(dbp, ret, "DB->set_flags: DB_ENCRYPT");
328
 
                goto err;
329
 
        }
330
 
 
331
 
        /* Open the DB file. */
332
 
        if ((ret = dbp->open(dbp, NULL, name, subdb, dbtype,
333
 
            DB_CREATE | (TXN_ON(dbenv) ? DB_AUTO_COMMIT : 0),
334
 
            __db_omode("rwrwrw"))) != 0) {
335
 
                dbp->err(dbp, ret, "DB->open: %s", name);
336
 
                goto err;
337
 
        }
338
 
        if (ldg->private != 0) {
339
 
                if ((ret =
340
 
                    __db_util_cache(dbenv, dbp, &ldg->cache, &resize)) != 0)
341
 
                        goto err;
342
 
                if (resize) {
343
 
                        dbp->close(dbp, 0);
344
 
                        dbp = NULL;
345
 
                        dbenv->close(dbenv, 0);
346
 
                        if ((ret = env_create(&dbenv, ldg)) != 0)
347
 
                                goto err;
348
 
                        goto retry_db;
349
 
                }
350
 
        }
351
 
 
352
 
        /* Initialize the key/data pair. */
353
 
        readp = &key;
354
 
        writep = &key;
355
 
        if (dbtype == DB_RECNO || dbtype == DB_QUEUE) {
356
 
                key.size = sizeof(recno);
357
 
                if (keyflag) {
358
 
                        key.data = &datarecno;
359
 
                        if (checkprint) {
360
 
                                readp = &rkey;
361
 
                                goto key_data;
362
 
                        }
363
 
                }
364
 
                else
365
 
                        key.data = &recno;
366
 
        } else
367
 
key_data:       if ((readp->data =
368
 
                    (void *)malloc(readp->ulen = 1024)) == NULL) {
369
 
                        dbenv->err(dbenv, ENOMEM, NULL);
370
 
                        goto err;
371
 
                }
372
 
        if ((data.data = (void *)malloc(data.ulen = 1024)) == NULL) {
373
 
                dbenv->err(dbenv, ENOMEM, NULL);
374
 
                goto err;
375
 
        }
376
 
 
377
 
        if (TXN_ON(dbenv) &&
378
 
            (ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0)
379
 
                goto err;
380
 
 
381
 
        /* Get each key/data pair and add them to the database. */
382
 
        for (recno = 1; !__db_util_interrupted(); ++recno) {
383
 
                if (!keyflag)
384
 
                        if (checkprint) {
385
 
                                if (dbt_rprint(dbenv, &data))
386
 
                                        goto err;
387
 
                        } else {
388
 
                                if (dbt_rdump(dbenv, &data))
389
 
                                        goto err;
390
 
                        }
391
 
                else
392
 
                        if (checkprint) {
393
 
                                if (dbt_rprint(dbenv, readp))
394
 
                                        goto err;
395
 
                                if (!G(endodata) && dbt_rprint(dbenv, &data))
396
 
                                        goto fmt;
397
 
                        } else {
398
 
                                if (ascii_recno) {
399
 
                                        if (dbt_rrecno(dbenv, readp, hexkeys))
400
 
                                                goto err;
401
 
                                } else
402
 
                                        if (dbt_rdump(dbenv, readp))
403
 
                                                goto err;
404
 
                                if (!G(endodata) && dbt_rdump(dbenv, &data)) {
405
 
fmt:                                    dbenv->errx(dbenv,
406
 
                                            "odd number of key/data pairs");
407
 
                                        goto err;
408
 
                                }
409
 
                        }
410
 
                if (G(endodata))
411
 
                        break;
412
 
                if (readp != writep) {
413
 
                        if (sscanf(readp->data, "%ud", &datarecno) != 1)
414
 
                                dbenv->errx(dbenv,
415
 
                                    "%s: non-integer key at line: %d",
416
 
                                    name, !keyflag ? recno : recno * 2 - 1);
417
 
                        if (datarecno == 0)
418
 
                                dbenv->errx(dbenv, "%s: zero key at line: %d",
419
 
                                    name,
420
 
                                    !keyflag ? recno : recno * 2 - 1);
421
 
                }
422
 
retry:          if (txn != NULL)
423
 
                        if ((ret = dbenv->txn_begin(dbenv, txn, &ctxn, 0)) != 0)
424
 
                                goto err;
425
 
                switch (ret = dbp->put(dbp, ctxn, writep, &data, put_flags)) {
426
 
                case 0:
427
 
                        if (ctxn != NULL) {
428
 
                                if ((ret =
429
 
                                    ctxn->commit(ctxn, DB_TXN_NOSYNC)) != 0)
430
 
                                        goto err;
431
 
                                ctxn = NULL;
432
 
                        }
433
 
                        break;
434
 
                case DB_KEYEXIST:
435
 
                        *existedp = 1;
436
 
                        dbenv->errx(dbenv,
437
 
                            "%s: line %d: key already exists, not loaded:",
438
 
                            name,
439
 
                            !keyflag ? recno : recno * 2 - 1);
440
 
 
441
 
                        (void)__db_prdbt(&key, checkprint, 0, stderr,
442
 
                            __db_verify_callback, 0, NULL);
443
 
                        break;
444
 
                case DB_LOCK_DEADLOCK:
445
 
                        /* If we have a child txn, retry--else it's fatal. */
446
 
                        if (ctxn != NULL) {
447
 
                                if ((ret = ctxn->abort(ctxn)) != 0)
448
 
                                        goto err;
449
 
                                ctxn = NULL;
450
 
                                goto retry;
451
 
                        }
452
 
                        /* FALLTHROUGH */
453
 
                default:
454
 
                        dbenv->err(dbenv, ret, NULL);
455
 
                        if (ctxn != NULL) {
456
 
                                (void)ctxn->abort(ctxn);
457
 
                                ctxn = NULL;
458
 
                        }
459
 
                        goto err;
460
 
                }
461
 
                if (ctxn != NULL) {
462
 
                        if ((ret = ctxn->abort(ctxn)) != 0)
463
 
                                goto err;
464
 
                        ctxn = NULL;
465
 
                }
466
 
        }
467
 
done:   rval = 0;
468
 
        DB_ASSERT(ctxn == NULL);
469
 
        if (txn != NULL && (ret = txn->commit(txn, 0)) != 0) {
470
 
                txn = NULL;
471
 
                goto err;
472
 
        }
473
 
 
474
 
        if (0) {
475
 
err:            rval = 1;
476
 
                DB_ASSERT(ctxn == NULL);
477
 
                if (txn != NULL)
478
 
                        (void)txn->abort(txn);
479
 
        }
480
 
 
481
 
        /* Close the database. */
482
 
        if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) {
483
 
                dbenv->err(dbenv, ret, "DB->close");
484
 
                rval = 1;
485
 
        }
486
 
 
487
 
        if (G(hdrbuf) != NULL)
488
 
                free(G(hdrbuf));
489
 
        G(hdrbuf) = NULL;
490
 
        /* Free allocated memory. */
491
 
        if (subdb != NULL)
492
 
                free(subdb);
493
 
        if (dbtype != DB_RECNO && dbtype != DB_QUEUE)
494
 
                free(key.data);
495
 
        if (rkey.data != NULL)
496
 
                free(rkey.data);
497
 
        free(data.data);
498
 
 
499
 
        return (rval);
500
 
}
501
 
 
502
 
/*
503
 
 * db_init --
504
 
 *      Initialize the environment.
505
 
 */
506
 
int
507
 
db_init(dbenv, home, cache, is_private)
508
 
        DB_ENV *dbenv;
509
 
        char *home;
510
 
        u_int32_t cache;
511
 
        int *is_private;
512
 
{
513
 
        u_int32_t flags;
514
 
        int ret;
515
 
 
516
 
        *is_private = 0;
517
 
        /* We may be loading into a live environment.  Try and join. */
518
 
        flags = DB_USE_ENVIRON |
519
 
            DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN;
520
 
        if (dbenv->open(dbenv, home, flags, 0) == 0)
521
 
                return (0);
522
 
 
523
 
        /*
524
 
         * We're trying to load a database.
525
 
         *
526
 
         * An environment is required because we may be trying to look at
527
 
         * databases in directories other than the current one.  We could
528
 
         * avoid using an environment iff the -h option wasn't specified,
529
 
         * but that seems like more work than it's worth.
530
 
         *
531
 
         * No environment exists (or, at least no environment that includes
532
 
         * an mpool region exists).  Create one, but make it private so that
533
 
         * no files are actually created.
534
 
         */
535
 
        LF_CLR(DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN);
536
 
        LF_SET(DB_CREATE | DB_PRIVATE);
537
 
        *is_private = 1;
538
 
        if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) {
539
 
                dbenv->err(dbenv, ret, "set_cachesize");
540
 
                return (1);
541
 
        }
542
 
        if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0)
543
 
                return (0);
544
 
 
545
 
        /* An environment is required. */
546
 
        dbenv->err(dbenv, ret, "DB_ENV->open");
547
 
        return (1);
548
 
}
549
 
 
550
 
#define FLAG(name, value, keyword, flag)                                \
551
 
        if (strcmp(name, keyword) == 0) {                               \
552
 
                switch (*value) {                                       \
553
 
                case '1':                                               \
554
 
                        if ((ret = dbp->set_flags(dbp, flag)) != 0) {   \
555
 
                                dbp->err(dbp, ret, "%s: set_flags: %s", \
556
 
                                    G(progname), name);                 \
557
 
                                return (1);                             \
558
 
                        }                                               \
559
 
                        break;                                          \
560
 
                case '0':                                               \
561
 
                        break;                                          \
562
 
                default:                                                \
563
 
                        badnum(dbenv);                                  \
564
 
                        return (1);                                     \
565
 
                }                                                       \
566
 
                continue;                                               \
567
 
        }
568
 
#define NUMBER(name, value, keyword, func)                              \
569
 
        if (strcmp(name, keyword) == 0) {                               \
570
 
                if (__db_getlong(dbp,                                   \
571
 
                    NULL, value, 1, LONG_MAX, &val) != 0)               \
572
 
                        return (1);                                     \
573
 
                if ((ret = dbp->func(dbp, val)) != 0)                   \
574
 
                        goto nameerr;                                   \
575
 
                continue;                                               \
576
 
        }
577
 
#define STRING(name, value, keyword, func)                              \
578
 
        if (strcmp(name, keyword) == 0) {                               \
579
 
                if ((ret = dbp->func(dbp, value[0])) != 0)              \
580
 
                        goto nameerr;                                   \
581
 
                continue;                                               \
582
 
        }
583
 
 
584
 
/*
585
 
 * configure --
586
 
 *      Handle command-line configuration options.
587
 
 */
588
 
int
589
 
configure(dbenv, dbp, clp, subdbp, keysp)
590
 
        DB_ENV *dbenv;
591
 
        DB *dbp;
592
 
        char **clp, **subdbp;
593
 
        int *keysp;
594
 
{
595
 
        long val;
596
 
        int ret, savech;
597
 
        char *name, *value;
598
 
 
599
 
        for (; (name = *clp) != NULL; *--value = savech, ++clp) {
600
 
                if ((value = strchr(name, '=')) == NULL) {
601
 
                        dbp->errx(dbp,
602
 
                    "command-line configuration uses name=value format");
603
 
                        return (1);
604
 
                }
605
 
                savech = *value;
606
 
                *value++ = '\0';
607
 
 
608
 
                if (strcmp(name, "database") == 0 ||
609
 
                    strcmp(name, "subdatabase") == 0) {
610
 
                        if (*subdbp != NULL)
611
 
                                free(*subdbp);
612
 
                        if ((*subdbp = strdup(value)) == NULL) {
613
 
                                dbp->err(dbp, ENOMEM, NULL);
614
 
                                return (1);
615
 
                        }
616
 
                        continue;
617
 
                }
618
 
                if (strcmp(name, "keys") == 0) {
619
 
                        if (strcmp(value, "1") == 0)
620
 
                                *keysp = 1;
621
 
                        else if (strcmp(value, "0") == 0)
622
 
                                *keysp = 0;
623
 
                        else {
624
 
                                badnum(dbenv);
625
 
                                return (1);
626
 
                        }
627
 
                        continue;
628
 
                }
629
 
 
630
 
#ifdef notyet
631
 
                NUMBER(name, value, "bt_maxkey", set_bt_maxkey);
632
 
#endif
633
 
                NUMBER(name, value, "bt_minkey", set_bt_minkey);
634
 
                NUMBER(name, value, "db_lorder", set_lorder);
635
 
                NUMBER(name, value, "db_pagesize", set_pagesize);
636
 
                FLAG(name, value, "chksum", DB_CHKSUM_SHA1);
637
 
                FLAG(name, value, "duplicates", DB_DUP);
638
 
                FLAG(name, value, "dupsort", DB_DUPSORT);
639
 
                NUMBER(name, value, "h_ffactor", set_h_ffactor);
640
 
                NUMBER(name, value, "h_nelem", set_h_nelem);
641
 
                NUMBER(name, value, "re_len", set_re_len);
642
 
                STRING(name, value, "re_pad", set_re_pad);
643
 
                FLAG(name, value, "recnum", DB_RECNUM);
644
 
                FLAG(name, value, "renumber", DB_RENUMBER);
645
 
 
646
 
                dbp->errx(dbp,
647
 
                    "unknown command-line configuration keyword \"%s\"", name);
648
 
                return (1);
649
 
        }
650
 
        return (0);
651
 
 
652
 
nameerr:
653
 
        dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value);
654
 
        return (1);
655
 
}
656
 
 
657
 
/*
658
 
 * rheader --
659
 
 *      Read the header message.
660
 
 */
661
 
int
662
 
rheader(dbenv, dbp, dbtypep, subdbp, checkprintp, keysp)
663
 
        DB_ENV *dbenv;
664
 
        DB *dbp;
665
 
        DBTYPE *dbtypep;
666
 
        char **subdbp;
667
 
        int *checkprintp, *keysp;
668
 
{
669
 
        long val;
670
 
        int ch, first, hdr, linelen, buflen, ret, start;
671
 
        char *buf, *name, *p, *value;
672
 
 
673
 
        *dbtypep = DB_UNKNOWN;
674
 
        *checkprintp = 0;
675
 
        name = p = NULL;
676
 
 
677
 
        /*
678
 
         * We start with a smallish buffer;  most headers are small.
679
 
         * We may need to realloc it for a large subdatabase name.
680
 
         */
681
 
        buflen = 4096;
682
 
        if (G(hdrbuf) == NULL) {
683
 
                hdr = 0;
684
 
                if ((buf = (char *)malloc(buflen)) == NULL) {
685
 
memerr:                 dbp->errx(dbp, "could not allocate buffer %d", buflen);
686
 
                        return (1);
687
 
                }
688
 
                G(hdrbuf) = buf;
689
 
                G(origline) = G(lineno);
690
 
        } else {
691
 
                hdr = 1;
692
 
                buf = G(hdrbuf);
693
 
                G(lineno) = G(origline);
694
 
        }
695
 
 
696
 
        start = 0;
697
 
        for (first = 1;; first = 0) {
698
 
                ++G(lineno);
699
 
 
700
 
                /* Read a line, which may be of arbitrary length, into buf. */
701
 
                linelen = 0;
702
 
                buf = &G(hdrbuf)[start];
703
 
                if (hdr == 0) {
704
 
                        for (;;) {
705
 
                                if ((ch = getchar()) == EOF) {
706
 
                                        if (!first || ferror(stdin))
707
 
                                                goto badfmt;
708
 
                                        G(endofile) = 1;
709
 
                                        break;
710
 
                                }
711
 
 
712
 
                                if (ch == '\n')
713
 
                                        break;
714
 
 
715
 
                                buf[linelen++] = ch;
716
 
 
717
 
                                /* If the buffer is too small, double it. */
718
 
                                if (linelen + start == buflen) {
719
 
                                        G(hdrbuf) = (char *)realloc(G(hdrbuf),
720
 
                                            buflen *= 2);
721
 
                                        if (G(hdrbuf) == NULL)
722
 
                                                goto memerr;
723
 
                                        buf = &G(hdrbuf)[start];
724
 
                                }
725
 
                        }
726
 
                        if (G(endofile) == 1)
727
 
                                break;
728
 
                        buf[linelen++] = '\0';
729
 
                } else
730
 
                        linelen = strlen(buf) + 1;
731
 
                start += linelen;
732
 
 
733
 
                if (name != NULL) {
734
 
                        *p = '=';
735
 
                        free(name);
736
 
                        name = NULL;
737
 
                }
738
 
                /* If we don't see the expected information, it's an error. */
739
 
                if ((name = strdup(buf)) == NULL)
740
 
                        goto memerr;
741
 
                if ((p = strchr(name, '=')) == NULL)
742
 
                        goto badfmt;
743
 
                *p++ = '\0';
744
 
 
745
 
                value = p--;
746
 
 
747
 
                if (name[0] == '\0' || value[0] == '\0')
748
 
                        goto badfmt;
749
 
 
750
 
                if (strcmp(name, "HEADER") == 0)
751
 
                        break;
752
 
                if (strcmp(name, "VERSION") == 0) {
753
 
                        /*
754
 
                         * Version 1 didn't have a "VERSION" header line.  We
755
 
                         * only support versions 1, 2, and 3 of the dump format.
756
 
                         */
757
 
                        G(version) = atoi(value);
758
 
 
759
 
                        if (G(version) > 3) {
760
 
                                dbp->errx(dbp,
761
 
                                    "line %lu: VERSION %d is unsupported",
762
 
                                    G(lineno), G(version));
763
 
                                goto err;
764
 
                        }
765
 
                        continue;
766
 
                }
767
 
                if (strcmp(name, "format") == 0) {
768
 
                        if (strcmp(value, "bytevalue") == 0) {
769
 
                                *checkprintp = 0;
770
 
                                continue;
771
 
                        }
772
 
                        if (strcmp(value, "print") == 0) {
773
 
                                *checkprintp = 1;
774
 
                                continue;
775
 
                        }
776
 
                        goto badfmt;
777
 
                }
778
 
                if (strcmp(name, "type") == 0) {
779
 
                        if (strcmp(value, "btree") == 0) {
780
 
                                *dbtypep = DB_BTREE;
781
 
                                continue;
782
 
                        }
783
 
                        if (strcmp(value, "hash") == 0) {
784
 
                                *dbtypep = DB_HASH;
785
 
                                continue;
786
 
                        }
787
 
                        if (strcmp(value, "recno") == 0) {
788
 
                                *dbtypep = DB_RECNO;
789
 
                                continue;
790
 
                        }
791
 
                        if (strcmp(value, "queue") == 0) {
792
 
                                *dbtypep = DB_QUEUE;
793
 
                                continue;
794
 
                        }
795
 
                        dbp->errx(dbp, "line %lu: unknown type", G(lineno));
796
 
                        goto err;
797
 
                }
798
 
                if (strcmp(name, "database") == 0 ||
799
 
                    strcmp(name, "subdatabase") == 0) {
800
 
                        if ((ret = convprintable(dbenv, value, subdbp)) != 0) {
801
 
                                dbp->err(dbp, ret, "error reading db name");
802
 
                                goto err;
803
 
                        }
804
 
                        continue;
805
 
                }
806
 
                if (strcmp(name, "keys") == 0) {
807
 
                        if (strcmp(value, "1") == 0)
808
 
                                *keysp = 1;
809
 
                        else if (strcmp(value, "0") == 0)
810
 
                                *keysp = 0;
811
 
                        else {
812
 
                                badnum(dbenv);
813
 
                                goto err;
814
 
                        }
815
 
                        continue;
816
 
                }
817
 
 
818
 
#ifdef notyet
819
 
                NUMBER(name, value, "bt_maxkey", set_bt_maxkey);
820
 
#endif
821
 
                NUMBER(name, value, "bt_minkey", set_bt_minkey);
822
 
                NUMBER(name, value, "db_lorder", set_lorder);
823
 
                NUMBER(name, value, "db_pagesize", set_pagesize);
824
 
                NUMBER(name, value, "extentsize", set_q_extentsize);
825
 
                FLAG(name, value, "chksum", DB_CHKSUM_SHA1);
826
 
                FLAG(name, value, "duplicates", DB_DUP);
827
 
                FLAG(name, value, "dupsort", DB_DUPSORT);
828
 
                NUMBER(name, value, "h_ffactor", set_h_ffactor);
829
 
                NUMBER(name, value, "h_nelem", set_h_nelem);
830
 
                NUMBER(name, value, "re_len", set_re_len);
831
 
                STRING(name, value, "re_pad", set_re_pad);
832
 
                FLAG(name, value, "recnum", DB_RECNUM);
833
 
                FLAG(name, value, "renumber", DB_RENUMBER);
834
 
 
835
 
                dbp->errx(dbp,
836
 
                    "unknown input-file header configuration keyword \"%s\"",
837
 
                    name);
838
 
                goto err;
839
 
        }
840
 
        ret = 0;
841
 
        if (0) {
842
 
nameerr:
843
 
                dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value);
844
 
                ret = 1;
845
 
        }
846
 
        if (0)
847
 
err:            ret = 1;
848
 
        if (0) {
849
 
badfmt:
850
 
                dbp->errx(dbp, "line %lu: unexpected format", G(lineno));
851
 
                ret = 1;
852
 
        }
853
 
        if (name != NULL) {
854
 
                *p = '=';
855
 
                free(name);
856
 
        }
857
 
        return (ret);
858
 
}
859
 
 
860
 
/*
861
 
 * convprintable --
862
 
 *      Convert a printable-encoded string into a newly allocated string.
863
 
 *
864
 
 * In an ideal world, this would probably share code with dbt_rprint, but
865
 
 * that's set up to read character-by-character (to avoid large memory
866
 
 * allocations that aren't likely to be a problem here), and this has fewer
867
 
 * special cases to deal with.
868
 
 *
869
 
 * Note that despite the printable encoding, the char * interface to this
870
 
 * function (which is, not coincidentally, also used for database naming)
871
 
 * means that outstr cannot contain any nuls.
872
 
 */
873
 
int
874
 
convprintable(dbenv, instr, outstrp)
875
 
        DB_ENV *dbenv;
876
 
        char *instr, **outstrp;
877
 
{
878
 
        char c, *outstr;
879
 
        int e1, e2;
880
 
 
881
 
        /*
882
 
         * Just malloc a string big enough for the whole input string;
883
 
         * the output string will be smaller (or of equal length).
884
 
         */
885
 
        if ((outstr = (char *)malloc(strlen(instr))) == NULL)
886
 
                return (ENOMEM);
887
 
 
888
 
        *outstrp = outstr;
889
 
 
890
 
        e1 = e2 = 0;
891
 
        for ( ; *instr != '\0'; instr++)
892
 
                if (*instr == '\\') {
893
 
                        if (*++instr == '\\') {
894
 
                                *outstr++ = '\\';
895
 
                                continue;
896
 
                        }
897
 
                        c = digitize(dbenv, *instr, &e1) << 4;
898
 
                        c |= digitize(dbenv, *++instr, &e2);
899
 
                        if (e1 || e2) {
900
 
                                badend(dbenv);
901
 
                                return (EINVAL);
902
 
                        }
903
 
 
904
 
                        *outstr++ = c;
905
 
                } else
906
 
                        *outstr++ = *instr;
907
 
 
908
 
        *outstr = '\0';
909
 
 
910
 
        return (0);
911
 
}
912
 
 
913
 
/*
914
 
 * dbt_rprint --
915
 
 *      Read a printable line into a DBT structure.
916
 
 */
917
 
int
918
 
dbt_rprint(dbenv, dbtp)
919
 
        DB_ENV *dbenv;
920
 
        DBT *dbtp;
921
 
{
922
 
        u_int32_t len;
923
 
        u_int8_t *p;
924
 
        int c1, c2, e, escape, first;
925
 
        char buf[32];
926
 
 
927
 
        ++G(lineno);
928
 
 
929
 
        first = 1;
930
 
        e = escape = 0;
931
 
        for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {
932
 
                if (c1 == EOF) {
933
 
                        if (len == 0) {
934
 
                                G(endofile) = G(endodata) = 1;
935
 
                                return (0);
936
 
                        }
937
 
                        badend(dbenv);
938
 
                        return (1);
939
 
                }
940
 
                if (first) {
941
 
                        first = 0;
942
 
                        if (G(version) > 1) {
943
 
                                if (c1 != ' ') {
944
 
                                        buf[0] = c1;
945
 
                                        if (fgets(buf + 1,
946
 
                                            sizeof(buf) - 1, stdin) == NULL ||
947
 
                                            strcmp(buf, "DATA=END\n") != 0) {
948
 
                                                badend(dbenv);
949
 
                                                return (1);
950
 
                                        }
951
 
                                        G(endodata) = 1;
952
 
                                        return (0);
953
 
                                }
954
 
                                continue;
955
 
                        }
956
 
                }
957
 
                if (escape) {
958
 
                        if (c1 != '\\') {
959
 
                                if ((c2 = getchar()) == EOF) {
960
 
                                        badend(dbenv);
961
 
                                        return (1);
962
 
                                }
963
 
                                c1 = digitize(dbenv,
964
 
                                    c1, &e) << 4 | digitize(dbenv, c2, &e);
965
 
                                if (e)
966
 
                                        return (1);
967
 
                        }
968
 
                        escape = 0;
969
 
                } else
970
 
                        if (c1 == '\\') {
971
 
                                escape = 1;
972
 
                                continue;
973
 
                        }
974
 
                if (len >= dbtp->ulen - 10) {
975
 
                        dbtp->ulen *= 2;
976
 
                        if ((dbtp->data =
977
 
                            (void *)realloc(dbtp->data, dbtp->ulen)) == NULL) {
978
 
                                dbenv->err(dbenv, ENOMEM, NULL);
979
 
                                return (1);
980
 
                        }
981
 
                        p = (u_int8_t *)dbtp->data + len;
982
 
                }
983
 
                ++len;
984
 
                *p++ = c1;
985
 
        }
986
 
        dbtp->size = len;
987
 
 
988
 
        return (0);
989
 
}
990
 
 
991
 
/*
992
 
 * dbt_rdump --
993
 
 *      Read a byte dump line into a DBT structure.
994
 
 */
995
 
int
996
 
dbt_rdump(dbenv, dbtp)
997
 
        DB_ENV *dbenv;
998
 
        DBT *dbtp;
999
 
{
1000
 
        u_int32_t len;
1001
 
        u_int8_t *p;
1002
 
        int c1, c2, e, first;
1003
 
        char buf[32];
1004
 
 
1005
 
        ++G(lineno);
1006
 
 
1007
 
        first = 1;
1008
 
        e = 0;
1009
 
        for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {
1010
 
                if (c1 == EOF) {
1011
 
                        if (len == 0) {
1012
 
                                G(endofile) = G(endodata) = 1;
1013
 
                                return (0);
1014
 
                        }
1015
 
                        badend(dbenv);
1016
 
                        return (1);
1017
 
                }
1018
 
                if (first) {
1019
 
                        first = 0;
1020
 
                        if (G(version) > 1) {
1021
 
                                if (c1 != ' ') {
1022
 
                                        buf[0] = c1;
1023
 
                                        if (fgets(buf + 1,
1024
 
                                            sizeof(buf) - 1, stdin) == NULL ||
1025
 
                                            strcmp(buf, "DATA=END\n") != 0) {
1026
 
                                                badend(dbenv);
1027
 
                                                return (1);
1028
 
                                        }
1029
 
                                        G(endodata) = 1;
1030
 
                                        return (0);
1031
 
                                }
1032
 
                                continue;
1033
 
                        }
1034
 
                }
1035
 
                if ((c2 = getchar()) == EOF) {
1036
 
                        badend(dbenv);
1037
 
                        return (1);
1038
 
                }
1039
 
                if (len >= dbtp->ulen - 10) {
1040
 
                        dbtp->ulen *= 2;
1041
 
                        if ((dbtp->data =
1042
 
                            (void *)realloc(dbtp->data, dbtp->ulen)) == NULL) {
1043
 
                                dbenv->err(dbenv, ENOMEM, NULL);
1044
 
                                return (1);
1045
 
                        }
1046
 
                        p = (u_int8_t *)dbtp->data + len;
1047
 
                }
1048
 
                ++len;
1049
 
                *p++ = digitize(dbenv, c1, &e) << 4 | digitize(dbenv, c2, &e);
1050
 
                if (e)
1051
 
                        return (1);
1052
 
        }
1053
 
        dbtp->size = len;
1054
 
 
1055
 
        return (0);
1056
 
}
1057
 
 
1058
 
/*
1059
 
 * dbt_rrecno --
1060
 
 *      Read a record number dump line into a DBT structure.
1061
 
 */
1062
 
int
1063
 
dbt_rrecno(dbenv, dbtp, ishex)
1064
 
        DB_ENV *dbenv;
1065
 
        DBT *dbtp;
1066
 
        int ishex;
1067
 
{
1068
 
        char buf[32], *p, *q;
1069
 
 
1070
 
        ++G(lineno);
1071
 
 
1072
 
        if (fgets(buf, sizeof(buf), stdin) == NULL) {
1073
 
                G(endofile) = G(endodata) = 1;
1074
 
                return (0);
1075
 
        }
1076
 
 
1077
 
        if (strcmp(buf, "DATA=END\n") == 0) {
1078
 
                G(endodata) = 1;
1079
 
                return (0);
1080
 
        }
1081
 
 
1082
 
        if (buf[0] != ' ')
1083
 
                goto bad;
1084
 
 
1085
 
        /*
1086
 
         * If we're expecting a hex key, do an in-place conversion
1087
 
         * of hex to straight ASCII before calling __db_getulong().
1088
 
         */
1089
 
        if (ishex) {
1090
 
                for (p = q = buf + 1; *q != '\0' && *q != '\n';) {
1091
 
                        /*
1092
 
                         * 0-9 in hex are 0x30-0x39, so this is easy.
1093
 
                         * We should alternate between 3's and [0-9], and
1094
 
                         * if the [0-9] are something unexpected,
1095
 
                         * __db_getulong will fail, so we only need to catch
1096
 
                         * end-of-string conditions.
1097
 
                         */
1098
 
                        if (*q++ != '3')
1099
 
                                goto bad;
1100
 
                        if (*q == '\n' || *q == '\0')
1101
 
                                goto bad;
1102
 
                        *p++ = *q++;
1103
 
                }
1104
 
                *p = '\0';
1105
 
        }
1106
 
 
1107
 
        if (__db_getulong(NULL,
1108
 
            G(progname), buf + 1, 0, 0, (u_long *)dbtp->data)) {
1109
 
bad:            badend(dbenv);
1110
 
                return (1);
1111
 
        }
1112
 
 
1113
 
        dbtp->size = sizeof(db_recno_t);
1114
 
        return (0);
1115
 
}
1116
 
 
1117
 
/*
1118
 
 * digitize --
1119
 
 *      Convert a character to an integer.
1120
 
 */
1121
 
int
1122
 
digitize(dbenv, c, errorp)
1123
 
        DB_ENV *dbenv;
1124
 
        int c, *errorp;
1125
 
{
1126
 
        switch (c) {                    /* Don't depend on ASCII ordering. */
1127
 
        case '0': return (0);
1128
 
        case '1': return (1);
1129
 
        case '2': return (2);
1130
 
        case '3': return (3);
1131
 
        case '4': return (4);
1132
 
        case '5': return (5);
1133
 
        case '6': return (6);
1134
 
        case '7': return (7);
1135
 
        case '8': return (8);
1136
 
        case '9': return (9);
1137
 
        case 'a': return (10);
1138
 
        case 'b': return (11);
1139
 
        case 'c': return (12);
1140
 
        case 'd': return (13);
1141
 
        case 'e': return (14);
1142
 
        case 'f': return (15);
1143
 
        }
1144
 
 
1145
 
        dbenv->errx(dbenv, "unexpected hexadecimal value");
1146
 
        *errorp = 1;
1147
 
 
1148
 
        return (0);
1149
 
}
1150
 
 
1151
 
/*
1152
 
 * badnum --
1153
 
 *      Display the bad number message.
1154
 
 */
1155
 
void
1156
 
badnum(dbenv)
1157
 
        DB_ENV *dbenv;
1158
 
{
1159
 
        dbenv->errx(dbenv,
1160
 
            "boolean name=value pairs require a value of 0 or 1");
1161
 
}
1162
 
 
1163
 
/*
1164
 
 * badend --
1165
 
 *      Display the bad end to input message.
1166
 
 */
1167
 
void
1168
 
badend(dbenv)
1169
 
        DB_ENV *dbenv;
1170
 
{
1171
 
        dbenv->errx(dbenv, "unexpected end of input data or key/data pair");
1172
 
}
1173
 
 
1174
 
/*
1175
 
 * usage --
1176
 
 *      Display the usage message.
1177
 
 */
1178
 
int
1179
 
usage()
1180
 
{
1181
 
        (void)fprintf(stderr, "%s\n\t%s\n",
1182
 
            "usage: db_load [-nTV] [-c name=value] [-f file]",
1183
 
    "[-h home] [-P password] [-t btree | hash | recno | queue] db_file");
1184
 
        return (EXIT_FAILURE);
1185
 
}
1186
 
 
1187
 
int
1188
 
version_check(progname)
1189
 
        const char *progname;
1190
 
{
1191
 
        int v_major, v_minor, v_patch;
1192
 
 
1193
 
        /* Make sure we're loaded with the right version of the DB library. */
1194
 
        (void)db_version(&v_major, &v_minor, &v_patch);
1195
 
        if (v_major != DB_VERSION_MAJOR ||
1196
 
            v_minor != DB_VERSION_MINOR || v_patch != DB_VERSION_PATCH) {
1197
 
                fprintf(stderr,
1198
 
        "%s: version %d.%d.%d doesn't match library version %d.%d.%d\n",
1199
 
                    progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
1200
 
                    DB_VERSION_PATCH, v_major, v_minor, v_patch);
1201
 
                return (EXIT_FAILURE);
1202
 
        }
1203
 
        return (0);
1204
 
}
1205
 
 
1206
 
int
1207
 
env_create(dbenvp, ldg)
1208
 
        DB_ENV **dbenvp;
1209
 
        LDG *ldg;
1210
 
{
1211
 
        DB_ENV *dbenv;
1212
 
        int ret;
1213
 
 
1214
 
        if ((ret = db_env_create(dbenvp, 0)) != 0) {
1215
 
                fprintf(stderr,
1216
 
                    "%s: db_env_create: %s\n", ldg->progname, db_strerror(ret));
1217
 
                return (ret);
1218
 
        }
1219
 
        dbenv = *dbenvp;
1220
 
        dbenv->set_errfile(dbenv, stderr);
1221
 
        dbenv->set_errpfx(dbenv, ldg->progname);
1222
 
        if (ldg->passwd != NULL && (ret = dbenv->set_encrypt(dbenv,
1223
 
            ldg->passwd, DB_ENCRYPT_AES)) != 0) {
1224
 
                dbenv->err(dbenv, ret, "set_passwd");
1225
 
                return (ret);
1226
 
        }
1227
 
        if ((ret = db_init(dbenv, ldg->home, ldg->cache, &ldg->private)) != 0)
1228
 
                return (ret);
1229
 
        dbenv->app_private = ldg;
1230
 
 
1231
 
        return (0);
1232
 
}