00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "db_config.h"
00011
00012 #ifndef lint
00013 static const char copyright[] =
00014 "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n";
00015 #endif
00016
00017 #ifndef NO_SYSTEM_INCLUDES
00018 #include <sys/types.h>
00019
00020 #include <limits.h>
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <unistd.h>
00025 #endif
00026
00027 #include "db_int.h"
00028 #include "dbinc/db_page.h"
00029 #include "dbinc/db_am.h"
00030
00031 typedef struct {
00032 const char *progname;
00033 char *hdrbuf;
00034 u_long lineno;
00035 u_long origline;
00036 int endodata;
00037 int endofile;
00038 int version;
00039 char *home;
00040 char *passwd;
00041 int private;
00042 u_int32_t cache;
00043 } LDG;
00044
00045 void db_load_badend __P((DB_ENV *));
00046 void db_load_badnum __P((DB_ENV *));
00047 int db_load_configure __P((DB_ENV *, DB *, char **, char **, int *));
00048 int db_load_convprintable __P((DB_ENV *, char *, char **));
00049 int db_load_db_init __P((DB_ENV *, char *, u_int32_t, int *));
00050 int db_load_dbt_rdump __P((DB_ENV *, DBT *));
00051 int db_load_dbt_rprint __P((DB_ENV *, DBT *));
00052 int db_load_dbt_rrecno __P((DB_ENV *, DBT *, int));
00053 int db_load_dbt_to_recno __P((DB_ENV *, DBT *, db_recno_t *));
00054 int db_load_digitize __P((DB_ENV *, int, int *));
00055 int db_load_env_create __P((DB_ENV **, LDG *));
00056 int db_load_load __P((DB_ENV *, char *, DBTYPE, char **, u_int, LDG *, int *));
00057 int db_load_main __P((int, char *[]));
00058 int db_load_rheader __P((DB_ENV *, DB *, DBTYPE *, char **, int *, int *));
00059 int db_load_usage __P((void));
00060 int db_load_version_check __P((void));
00061
00062 const char *progname;
00063
00064 #define G(f) ((LDG *)dbenv->app_private)->f
00065
00066
00067 #define LDF_NOHEADER 0x01
00068 #define LDF_NOOVERWRITE 0x02
00069 #define LDF_PASSWORD 0x04
00070
00071 int
00072 db_load(args)
00073 char *args;
00074 {
00075 int argc;
00076 char **argv;
00077
00078 __db_util_arg("db_load", args, &argc, &argv);
00079 return (db_load_main(argc, argv) ? EXIT_FAILURE : EXIT_SUCCESS);
00080 }
00081
00082 #include <stdio.h>
00083 #define ERROR_RETURN ERROR
00084
00085 int
00086 db_load_main(argc, argv)
00087 int argc;
00088 char *argv[];
00089 {
00090 enum { NOTSET, FILEID_RESET, LSN_RESET, STANDARD_LOAD } mode;
00091 extern char *optarg;
00092 extern int optind, __db_getopt_reset;
00093 DBTYPE dbtype;
00094 DB_ENV *dbenv;
00095 LDG ldg;
00096 u_int ldf;
00097 int ch, existed, exitval, ret;
00098 char **clist, **clp;
00099
00100 if ((progname = strrchr(argv[0], '/')) == NULL)
00101 progname = argv[0];
00102 else
00103 ++progname;
00104
00105 if ((ret = db_load_version_check()) != 0)
00106 return (ret);
00107
00108 ldg.progname = progname;
00109 ldg.lineno = 0;
00110 ldg.endodata = ldg.endofile = 0;
00111 ldg.version = 1;
00112 ldg.cache = MEGABYTE;
00113 ldg.hdrbuf = NULL;
00114 ldg.home = NULL;
00115 ldg.passwd = NULL;
00116
00117 mode = NOTSET;
00118 ldf = 0;
00119 exitval = existed = 0;
00120 dbtype = DB_UNKNOWN;
00121
00122
00123 if ((clp = clist =
00124 (char **)calloc((size_t)argc + 1, sizeof(char *))) == NULL) {
00125 fprintf(stderr, "%s: %s\n", ldg.progname, strerror(ENOMEM));
00126 return (EXIT_FAILURE);
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136 __db_getopt_reset = 1;
00137 while ((ch = getopt(argc, argv, "c:f:h:nP:r:Tt:V")) != EOF)
00138 switch (ch) {
00139 case 'c':
00140 if (mode != NOTSET && mode != STANDARD_LOAD)
00141 return (db_load_usage());
00142 mode = STANDARD_LOAD;
00143
00144 *clp++ = optarg;
00145 break;
00146 case 'f':
00147 if (mode != NOTSET && mode != STANDARD_LOAD)
00148 return (db_load_usage());
00149 mode = STANDARD_LOAD;
00150
00151 if (freopen(optarg, "r", stdin) == NULL) {
00152 fprintf(stderr, "%s: %s: reopen: %s\n",
00153 ldg.progname, optarg, strerror(errno));
00154 return (EXIT_FAILURE);
00155 }
00156 break;
00157 case 'h':
00158 ldg.home = optarg;
00159 break;
00160 case 'n':
00161 if (mode != NOTSET && mode != STANDARD_LOAD)
00162 return (db_load_usage());
00163 mode = STANDARD_LOAD;
00164
00165 ldf |= LDF_NOOVERWRITE;
00166 break;
00167 case 'P':
00168 ldg.passwd = strdup(optarg);
00169 memset(optarg, 0, strlen(optarg));
00170 if (ldg.passwd == NULL) {
00171 fprintf(stderr, "%s: strdup: %s\n",
00172 ldg.progname, strerror(errno));
00173 return (EXIT_FAILURE);
00174 }
00175 ldf |= LDF_PASSWORD;
00176 break;
00177 case 'r':
00178 if (mode == STANDARD_LOAD)
00179 return (db_load_usage());
00180 if (strcmp(optarg, "lsn") == 0)
00181 mode = LSN_RESET;
00182 else if (strcmp(optarg, "fileid") == 0)
00183 mode = FILEID_RESET;
00184 else
00185 return (db_load_usage());
00186 break;
00187 case 'T':
00188 if (mode != NOTSET && mode != STANDARD_LOAD)
00189 return (db_load_usage());
00190 mode = STANDARD_LOAD;
00191
00192 ldf |= LDF_NOHEADER;
00193 break;
00194 case 't':
00195 if (mode != NOTSET && mode != STANDARD_LOAD)
00196 return (db_load_usage());
00197 mode = STANDARD_LOAD;
00198
00199 if (strcmp(optarg, "btree") == 0) {
00200 dbtype = DB_BTREE;
00201 break;
00202 }
00203 if (strcmp(optarg, "hash") == 0) {
00204 dbtype = DB_HASH;
00205 break;
00206 }
00207 if (strcmp(optarg, "recno") == 0) {
00208 dbtype = DB_RECNO;
00209 break;
00210 }
00211 if (strcmp(optarg, "queue") == 0) {
00212 dbtype = DB_QUEUE;
00213 break;
00214 }
00215 return (db_load_usage());
00216 case 'V':
00217 printf("%s\n", db_version(NULL, NULL, NULL));
00218 return (EXIT_SUCCESS);
00219 case '?':
00220 default:
00221 return (db_load_usage());
00222 }
00223 argc -= optind;
00224 argv += optind;
00225
00226 if (argc != 1)
00227 return (db_load_usage());
00228
00229
00230 __db_util_siginit();
00231
00232
00233
00234
00235
00236 if (db_load_env_create(&dbenv, &ldg) != 0)
00237 goto shutdown;
00238
00239
00240 switch (mode) {
00241 case FILEID_RESET:
00242 exitval = dbenv->fileid_reset(
00243 dbenv, argv[0], ldf & LDF_PASSWORD ? DB_ENCRYPT : 0);
00244 break;
00245 case LSN_RESET:
00246 exitval = dbenv->lsn_reset(
00247 dbenv, argv[0], ldf & LDF_PASSWORD ? DB_ENCRYPT : 0);
00248 break;
00249 case NOTSET:
00250 case STANDARD_LOAD:
00251 while (!ldg.endofile)
00252 if (db_load_load(dbenv, argv[0], dbtype, clist, ldf,
00253 &ldg, &existed) != 0)
00254 goto shutdown;
00255 break;
00256 }
00257
00258 if (0) {
00259 shutdown: exitval = 1;
00260 }
00261 if ((ret = dbenv->close(dbenv, 0)) != 0) {
00262 exitval = 1;
00263 fprintf(stderr,
00264 "%s: dbenv->close: %s\n", ldg.progname, db_strerror(ret));
00265 }
00266
00267
00268 __db_util_sigresend();
00269 free(clist);
00270 if (ldg.passwd != NULL)
00271 free(ldg.passwd);
00272
00273
00274
00275
00276
00277
00278
00279
00280 return (exitval == 0 ? (existed == 0 ? 0 : 1) : 2);
00281 }
00282
00283
00284
00285
00286
00287 int
00288 db_load_load(dbenv, name, argtype, clist, flags, ldg, existedp)
00289 DB_ENV *dbenv;
00290 char *name, **clist;
00291 DBTYPE argtype;
00292 u_int flags;
00293 LDG *ldg;
00294 int *existedp;
00295 {
00296 DB *dbp;
00297 DBT key, rkey, data, *readp, *writep;
00298 DBTYPE dbtype;
00299 DB_TXN *ctxn, *txn;
00300 db_recno_t recno, datarecno;
00301 u_int32_t put_flags;
00302 int ascii_recno, checkprint, hexkeys, keyflag, keys, resize, ret, rval;
00303 char *subdb;
00304
00305 put_flags = LF_ISSET(LDF_NOOVERWRITE) ? DB_NOOVERWRITE : 0;
00306 G(endodata) = 0;
00307
00308 subdb = NULL;
00309 ctxn = txn = NULL;
00310 memset(&key, 0, sizeof(DBT));
00311 memset(&data, 0, sizeof(DBT));
00312 memset(&rkey, 0, sizeof(DBT));
00313
00314 retry_db:
00315 dbtype = DB_UNKNOWN;
00316 keys = -1;
00317 hexkeys = -1;
00318 keyflag = -1;
00319
00320
00321 if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
00322 dbenv->err(dbenv, ret, "db_create");
00323 goto err;
00324 }
00325
00326
00327 if (LF_ISSET(LDF_NOHEADER)) {
00328 checkprint = 1;
00329 dbtype = argtype;
00330 } else {
00331 if (db_load_rheader(dbenv,
00332 dbp, &dbtype, &subdb, &checkprint, &keys) != 0)
00333 goto err;
00334 if (G(endofile))
00335 goto done;
00336 }
00337
00338
00339
00340
00341
00342
00343 if (db_load_configure(dbenv, dbp, clist, &subdb, &keyflag))
00344 goto err;
00345
00346 if (keys != 1) {
00347 if (keyflag == 1) {
00348 dbp->err(dbp, EINVAL, "No keys specified in file");
00349 goto err;
00350 }
00351 }
00352 else if (keyflag == 0) {
00353 dbp->err(dbp, EINVAL, "Keys specified in file");
00354 goto err;
00355 }
00356 else
00357 keyflag = 1;
00358
00359 if (dbtype == DB_BTREE || dbtype == DB_HASH) {
00360 if (keyflag == 0)
00361 dbp->err(dbp,
00362 EINVAL, "Btree and Hash must specify keys");
00363 else
00364 keyflag = 1;
00365 }
00366
00367 if (argtype != DB_UNKNOWN) {
00368
00369 if (dbtype == DB_RECNO || dbtype == DB_QUEUE)
00370 if (keyflag != 1 && argtype != DB_RECNO &&
00371 argtype != DB_QUEUE) {
00372 dbenv->errx(dbenv,
00373 "improper database type conversion specified");
00374 goto err;
00375 }
00376 dbtype = argtype;
00377 }
00378
00379 if (dbtype == DB_UNKNOWN) {
00380 dbenv->errx(dbenv, "no database type specified");
00381 goto err;
00382 }
00383
00384 if (keyflag == -1)
00385 keyflag = 0;
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 hexkeys = (G(version) >= 3 && keyflag == 1 && checkprint == 0);
00396
00397 if (keyflag == 1 && (dbtype == DB_RECNO || dbtype == DB_QUEUE))
00398 ascii_recno = 1;
00399 else
00400 ascii_recno = 0;
00401
00402
00403 if (LF_ISSET(LDF_PASSWORD) &&
00404 (ret = dbp->set_flags(dbp, DB_ENCRYPT)) != 0) {
00405 dbp->err(dbp, ret, "DB->set_flags: DB_ENCRYPT");
00406 goto err;
00407 }
00408
00409 #if 0
00410 Set application-specific btree comparison or hash functions here.
00411 For example:
00412
00413 if ((ret = dbp->set_bt_compare(dbp, local_comparison_func)) != 0) {
00414 dbp->err(dbp, ret, "DB->set_bt_compare");
00415 goto err;
00416 }
00417 if ((ret = dbp->set_h_hash(dbp, local_hash_func)) != 0) {
00418 dbp->err(dbp, ret, "DB->set_h_hash");
00419 goto err;
00420 }
00421 #endif
00422
00423
00424 if ((ret = dbp->open(dbp, NULL, name, subdb, dbtype,
00425 DB_CREATE | (TXN_ON(dbenv) ? DB_AUTO_COMMIT : 0),
00426 __db_omode("rw-rw-rw-"))) != 0) {
00427 dbp->err(dbp, ret, "DB->open: %s", name);
00428 goto err;
00429 }
00430 if (ldg->private != 0) {
00431 if ((ret = __db_util_cache(dbp, &ldg->cache, &resize)) != 0)
00432 goto err;
00433 if (resize) {
00434 if ((ret = dbp->close(dbp, 0)) != 0)
00435 goto err;
00436 dbp = NULL;
00437 if ((ret = dbenv->close(dbenv, 0)) != 0)
00438 goto err;
00439 if ((ret = db_load_env_create(&dbenv, ldg)) != 0)
00440 goto err;
00441 goto retry_db;
00442 }
00443 }
00444
00445
00446 readp = writep = &key;
00447 if (dbtype == DB_RECNO || dbtype == DB_QUEUE) {
00448 key.size = sizeof(recno);
00449 if (keyflag) {
00450 key.data = &datarecno;
00451 if (checkprint) {
00452 readp = &rkey;
00453 goto key_data;
00454 }
00455 } else
00456 key.data = &recno;
00457 } else
00458 key_data: if ((readp->data = malloc(readp->ulen = 1024)) == NULL) {
00459 dbenv->err(dbenv, ENOMEM, NULL);
00460 goto err;
00461 }
00462 if ((data.data = malloc(data.ulen = 1024)) == NULL) {
00463 dbenv->err(dbenv, ENOMEM, NULL);
00464 goto err;
00465 }
00466
00467 if (TXN_ON(dbenv) &&
00468 (ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0)
00469 goto err;
00470
00471
00472 for (recno = 1; !__db_util_interrupted(); ++recno) {
00473 if (!keyflag) {
00474 if (checkprint) {
00475 if (db_load_dbt_rprint(dbenv, &data))
00476 goto err;
00477 } else {
00478 if (db_load_dbt_rdump(dbenv, &data))
00479 goto err;
00480 }
00481 } else {
00482 if (checkprint) {
00483 if (db_load_dbt_rprint(dbenv, readp))
00484 goto err;
00485 if (ascii_recno &&
00486 db_load_dbt_to_recno(dbenv, readp, &datarecno) != 0)
00487 goto err;
00488
00489 if (!G(endodata) && db_load_dbt_rprint(dbenv, &data))
00490 goto odd_count;
00491 } else {
00492 if (ascii_recno) {
00493 if (db_load_dbt_rrecno(dbenv, readp, hexkeys))
00494 goto err;
00495 } else
00496 if (db_load_dbt_rdump(dbenv, readp))
00497 goto err;
00498
00499 if (!G(endodata) && db_load_dbt_rdump(dbenv, &data)) {
00500 odd_count: dbenv->errx(dbenv,
00501 "odd number of key/data pairs");
00502 goto err;
00503 }
00504 }
00505 }
00506 if (G(endodata))
00507 break;
00508 retry: if (txn != NULL)
00509 if ((ret = dbenv->txn_begin(dbenv, txn, &ctxn, 0)) != 0)
00510 goto err;
00511 switch (ret = dbp->put(dbp, ctxn, writep, &data, put_flags)) {
00512 case 0:
00513 if (ctxn != NULL) {
00514 if ((ret =
00515 ctxn->commit(ctxn, DB_TXN_NOSYNC)) != 0)
00516 goto err;
00517 ctxn = NULL;
00518 }
00519 break;
00520 case DB_KEYEXIST:
00521 *existedp = 1;
00522 dbenv->errx(dbenv,
00523 "%s: line %d: key already exists, not loaded:",
00524 name,
00525 !keyflag ? recno : recno * 2 - 1);
00526
00527 (void)dbenv->prdbt(&key,
00528 checkprint, 0, stderr, __db_pr_callback, 0);
00529 break;
00530 case DB_LOCK_DEADLOCK:
00531
00532 if (ctxn != NULL) {
00533 if ((ret = ctxn->abort(ctxn)) != 0)
00534 goto err;
00535 ctxn = NULL;
00536 goto retry;
00537 }
00538
00539 default:
00540 dbenv->err(dbenv, ret, NULL);
00541 if (ctxn != NULL) {
00542 (void)ctxn->abort(ctxn);
00543 ctxn = NULL;
00544 }
00545 goto err;
00546 }
00547 if (ctxn != NULL) {
00548 if ((ret = ctxn->abort(ctxn)) != 0)
00549 goto err;
00550 ctxn = NULL;
00551 }
00552 }
00553 done: rval = 0;
00554 DB_ASSERT(ctxn == NULL);
00555 if (txn != NULL && (ret = txn->commit(txn, 0)) != 0) {
00556 txn = NULL;
00557 goto err;
00558 }
00559
00560 if (0) {
00561 err: rval = 1;
00562 DB_ASSERT(ctxn == NULL);
00563 if (txn != NULL)
00564 (void)txn->abort(txn);
00565 }
00566
00567
00568 if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) {
00569 dbenv->err(dbenv, ret, "DB->close");
00570 rval = 1;
00571 }
00572
00573 if (G(hdrbuf) != NULL)
00574 free(G(hdrbuf));
00575 G(hdrbuf) = NULL;
00576
00577 if (subdb != NULL)
00578 free(subdb);
00579 if (dbtype != DB_RECNO && dbtype != DB_QUEUE && key.data != NULL)
00580 free(key.data);
00581 if (rkey.data != NULL)
00582 free(rkey.data);
00583 free(data.data);
00584
00585 return (rval);
00586 }
00587
00588
00589
00590
00591
00592 int
00593 db_load_env_create(dbenvp, ldg)
00594 DB_ENV **dbenvp;
00595 LDG *ldg;
00596 {
00597 DB_ENV *dbenv;
00598 int ret;
00599
00600 if ((ret = db_env_create(dbenvp, 0)) != 0) {
00601 fprintf(stderr,
00602 "%s: db_env_create: %s\n", ldg->progname, db_strerror(ret));
00603 return (ret);
00604 }
00605 dbenv = *dbenvp;
00606 dbenv->set_errfile(dbenv, stderr);
00607 dbenv->set_errpfx(dbenv, ldg->progname);
00608 if (ldg->passwd != NULL && (ret = dbenv->set_encrypt(dbenv,
00609 ldg->passwd, DB_ENCRYPT_AES)) != 0) {
00610 dbenv->err(dbenv, ret, "set_passwd");
00611 return (ret);
00612 }
00613 if ((ret = db_load_db_init(dbenv, ldg->home, ldg->cache, &ldg->private)) != 0)
00614 return (ret);
00615 dbenv->app_private = ldg;
00616
00617 return (0);
00618 }
00619
00620
00621
00622
00623
00624 int
00625 db_load_db_init(dbenv, home, cache, is_private)
00626 DB_ENV *dbenv;
00627 char *home;
00628 u_int32_t cache;
00629 int *is_private;
00630 {
00631 u_int32_t flags;
00632 int ret;
00633
00634 *is_private = 0;
00635
00636 flags = DB_USE_ENVIRON |
00637 DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN;
00638 if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0)
00639 return (0);
00640 if (ret == DB_VERSION_MISMATCH)
00641 goto err;
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 LF_CLR(DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN);
00656 LF_SET(DB_CREATE | DB_PRIVATE);
00657 *is_private = 1;
00658 if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) {
00659 dbenv->err(dbenv, ret, "set_cachesize");
00660 return (1);
00661 }
00662 if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0)
00663 return (0);
00664
00665
00666 err: dbenv->err(dbenv, ret, "DB_ENV->open");
00667 return (1);
00668 }
00669
00670 #define FLAG(name, value, keyword, flag) \
00671 if (strcmp(name, keyword) == 0) { \
00672 switch (*value) { \
00673 case '1': \
00674 if ((ret = dbp->set_flags(dbp, flag)) != 0) { \
00675 dbp->err(dbp, ret, "%s: set_flags: %s", \
00676 G(progname), name); \
00677 goto err; \
00678 } \
00679 break; \
00680 case '0': \
00681 break; \
00682 default: \
00683 db_load_badnum(dbenv); \
00684 goto err; \
00685 } \
00686 continue; \
00687 }
00688 #define NUMBER(name, value, keyword, func, t) \
00689 if (strcmp(name, keyword) == 0) { \
00690 if ((ret = __db_getlong(dbenv, \
00691 NULL, value, 0, LONG_MAX, &val)) != 0 || \
00692 (ret = dbp->func(dbp, (t)val)) != 0) \
00693 goto nameerr; \
00694 continue; \
00695 }
00696 #define STRING(name, value, keyword, func) \
00697 if (strcmp(name, keyword) == 0) { \
00698 if ((ret = dbp->func(dbp, value[0])) != 0) \
00699 goto nameerr; \
00700 continue; \
00701 }
00702
00703
00704
00705
00706
00707 int
00708 db_load_configure(dbenv, dbp, clp, subdbp, keysp)
00709 DB_ENV *dbenv;
00710 DB *dbp;
00711 char **clp, **subdbp;
00712 int *keysp;
00713 {
00714 long val;
00715 int ret, savech;
00716 char *name, *value;
00717
00718 for (; (name = *clp) != NULL; *--value = savech, ++clp) {
00719 if ((value = strchr(name, '=')) == NULL) {
00720 dbp->errx(dbp,
00721 "command-line configuration uses name=value format");
00722 return (1);
00723 }
00724 savech = *value;
00725 *value++ = '\0';
00726
00727 if (strcmp(name, "database") == 0 ||
00728 strcmp(name, "subdatabase") == 0) {
00729 if (*subdbp != NULL)
00730 free(*subdbp);
00731 if ((*subdbp = strdup(value)) == NULL) {
00732 dbp->err(dbp, ENOMEM, NULL);
00733 return (1);
00734 }
00735 continue;
00736 }
00737 if (strcmp(name, "keys") == 0) {
00738 if (strcmp(value, "1") == 0)
00739 *keysp = 1;
00740 else if (strcmp(value, "0") == 0)
00741 *keysp = 0;
00742 else {
00743 db_load_badnum(dbenv);
00744 return (1);
00745 }
00746 continue;
00747 }
00748
00749 NUMBER(name, value, "bt_minkey", set_bt_minkey, u_int32_t);
00750 NUMBER(name, value, "db_lorder", set_lorder, int);
00751 NUMBER(name, value, "db_pagesize", set_pagesize, u_int32_t);
00752 FLAG(name, value, "chksum", DB_CHKSUM);
00753 FLAG(name, value, "duplicates", DB_DUP);
00754 FLAG(name, value, "dupsort", DB_DUPSORT);
00755 NUMBER(name, value, "h_ffactor", set_h_ffactor, u_int32_t);
00756 NUMBER(name, value, "h_nelem", set_h_nelem, u_int32_t);
00757 NUMBER(name, value, "re_len", set_re_len, u_int32_t);
00758 STRING(name, value, "re_pad", set_re_pad);
00759 FLAG(name, value, "recnum", DB_RECNUM);
00760 FLAG(name, value, "renumber", DB_RENUMBER);
00761
00762 dbp->errx(dbp,
00763 "unknown command-line configuration keyword \"%s\"", name);
00764 return (1);
00765 }
00766 return (0);
00767
00768 nameerr:
00769 dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value);
00770 err: return (1);
00771 }
00772
00773
00774
00775
00776
00777 int
00778 db_load_rheader(dbenv, dbp, dbtypep, subdbp, checkprintp, keysp)
00779 DB_ENV *dbenv;
00780 DB *dbp;
00781 DBTYPE *dbtypep;
00782 char **subdbp;
00783 int *checkprintp, *keysp;
00784 {
00785 size_t buflen, linelen, start;
00786 long val;
00787 int ch, first, hdr, ret;
00788 char *buf, *name, *p, *value;
00789
00790 *dbtypep = DB_UNKNOWN;
00791 *checkprintp = 0;
00792 name = NULL;
00793
00794
00795
00796
00797
00798 buflen = 4096;
00799 if (G(hdrbuf) == NULL) {
00800 hdr = 0;
00801 if ((buf = malloc(buflen)) == NULL)
00802 goto memerr;
00803 G(hdrbuf) = buf;
00804 G(origline) = G(lineno);
00805 } else {
00806 hdr = 1;
00807 buf = G(hdrbuf);
00808 G(lineno) = G(origline);
00809 }
00810
00811 start = 0;
00812 for (first = 1;; first = 0) {
00813 ++G(lineno);
00814
00815
00816 linelen = 0;
00817 buf = &G(hdrbuf)[start];
00818 if (hdr == 0) {
00819 for (;;) {
00820 if ((ch = getchar()) == EOF) {
00821 if (!first || ferror(stdin))
00822 goto badfmt;
00823 G(endofile) = 1;
00824 break;
00825 }
00826
00827
00828
00829
00830 if (linelen + start == buflen) {
00831 G(hdrbuf) =
00832 realloc(G(hdrbuf), buflen *= 2);
00833 if (G(hdrbuf) == NULL)
00834 goto memerr;
00835 buf = &G(hdrbuf)[start];
00836 }
00837
00838 if (ch == '\n')
00839 break;
00840
00841 buf[linelen++] = ch;
00842 }
00843 if (G(endofile) == 1)
00844 break;
00845 buf[linelen++] = '\0';
00846 } else
00847 linelen = strlen(buf) + 1;
00848 start += linelen;
00849
00850 if (name != NULL) {
00851 free(name);
00852 name = NULL;
00853 }
00854
00855 if ((name = strdup(buf)) == NULL)
00856 goto memerr;
00857 if ((p = strchr(name, '=')) == NULL)
00858 goto badfmt;
00859 *p++ = '\0';
00860
00861 value = p--;
00862
00863 if (name[0] == '\0' || value[0] == '\0')
00864 goto badfmt;
00865
00866 if (strcmp(name, "HEADER") == 0)
00867 break;
00868 if (strcmp(name, "VERSION") == 0) {
00869
00870
00871
00872
00873 G(version) = atoi(value);
00874
00875 if (G(version) > 3) {
00876 dbp->errx(dbp,
00877 "line %lu: VERSION %d is unsupported",
00878 G(lineno), G(version));
00879 goto err;
00880 }
00881 continue;
00882 }
00883 if (strcmp(name, "format") == 0) {
00884 if (strcmp(value, "bytevalue") == 0) {
00885 *checkprintp = 0;
00886 continue;
00887 }
00888 if (strcmp(value, "print") == 0) {
00889 *checkprintp = 1;
00890 continue;
00891 }
00892 goto badfmt;
00893 }
00894 if (strcmp(name, "type") == 0) {
00895 if (strcmp(value, "btree") == 0) {
00896 *dbtypep = DB_BTREE;
00897 continue;
00898 }
00899 if (strcmp(value, "hash") == 0) {
00900 *dbtypep = DB_HASH;
00901 continue;
00902 }
00903 if (strcmp(value, "recno") == 0) {
00904 *dbtypep = DB_RECNO;
00905 continue;
00906 }
00907 if (strcmp(value, "queue") == 0) {
00908 *dbtypep = DB_QUEUE;
00909 continue;
00910 }
00911 dbp->errx(dbp, "line %lu: unknown type", G(lineno));
00912 goto err;
00913 }
00914 if (strcmp(name, "database") == 0 ||
00915 strcmp(name, "subdatabase") == 0) {
00916 if ((ret = db_load_convprintable(dbenv, value, subdbp)) != 0) {
00917 dbp->err(dbp, ret, "error reading db name");
00918 goto err;
00919 }
00920 continue;
00921 }
00922 if (strcmp(name, "keys") == 0) {
00923 if (strcmp(value, "1") == 0)
00924 *keysp = 1;
00925 else if (strcmp(value, "0") == 0)
00926 *keysp = 0;
00927 else {
00928 db_load_badnum(dbenv);
00929 goto err;
00930 }
00931 continue;
00932 }
00933
00934 #ifdef notyet
00935 NUMBER(name, value, "bt_maxkey", set_bt_maxkey, u_int32_t);
00936 #endif
00937 NUMBER(name, value, "bt_minkey", set_bt_minkey, u_int32_t);
00938 NUMBER(name, value, "db_lorder", set_lorder, int);
00939 NUMBER(name, value, "db_pagesize", set_pagesize, u_int32_t);
00940 NUMBER(name, value, "extentsize", set_q_extentsize, u_int32_t);
00941 FLAG(name, value, "chksum", DB_CHKSUM);
00942 FLAG(name, value, "duplicates", DB_DUP);
00943 FLAG(name, value, "dupsort", DB_DUPSORT);
00944 NUMBER(name, value, "h_ffactor", set_h_ffactor, u_int32_t);
00945 NUMBER(name, value, "h_nelem", set_h_nelem, u_int32_t);
00946 NUMBER(name, value, "re_len", set_re_len, u_int32_t);
00947 STRING(name, value, "re_pad", set_re_pad);
00948 FLAG(name, value, "recnum", DB_RECNUM);
00949 FLAG(name, value, "renumber", DB_RENUMBER);
00950
00951 dbp->errx(dbp,
00952 "unknown input-file header configuration keyword \"%s\"",
00953 name);
00954 goto err;
00955 }
00956 ret = 0;
00957
00958 if (0) {
00959 nameerr: dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value);
00960 ret = 1;
00961 }
00962 if (0) {
00963 badfmt: dbp->errx(dbp, "line %lu: unexpected format", G(lineno));
00964 ret = 1;
00965 }
00966 if (0) {
00967 memerr: dbp->errx(dbp, "unable to allocate memory");
00968 err: ret = 1;
00969 }
00970 if (name != NULL)
00971 free(name);
00972 return (ret);
00973 }
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988 int
00989 db_load_convprintable(dbenv, instr, outstrp)
00990 DB_ENV *dbenv;
00991 char *instr, **outstrp;
00992 {
00993 char c, *outstr;
00994 int e1, e2;
00995
00996
00997
00998
00999
01000 if ((outstr = malloc(strlen(instr) + 1)) == NULL)
01001 return (ENOMEM);
01002
01003 *outstrp = outstr;
01004
01005 e1 = e2 = 0;
01006 for ( ; *instr != '\0'; instr++)
01007 if (*instr == '\\') {
01008 if (*++instr == '\\') {
01009 *outstr++ = '\\';
01010 continue;
01011 }
01012 c = db_load_digitize(dbenv, *instr, &e1) << 4;
01013 c |= db_load_digitize(dbenv, *++instr, &e2);
01014 if (e1 || e2) {
01015 db_load_badend(dbenv);
01016 return (EINVAL);
01017 }
01018
01019 *outstr++ = c;
01020 } else
01021 *outstr++ = *instr;
01022
01023 *outstr = '\0';
01024
01025 return (0);
01026 }
01027
01028
01029
01030
01031
01032 int
01033 db_load_dbt_rprint(dbenv, dbtp)
01034 DB_ENV *dbenv;
01035 DBT *dbtp;
01036 {
01037 u_int32_t len;
01038 u_int8_t *p;
01039 int c1, c2, e, escape, first;
01040 char buf[32];
01041
01042 ++G(lineno);
01043
01044 first = 1;
01045 e = escape = 0;
01046 for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {
01047 if (c1 == EOF) {
01048 if (len == 0) {
01049 G(endofile) = G(endodata) = 1;
01050 return (0);
01051 }
01052 db_load_badend(dbenv);
01053 return (1);
01054 }
01055 if (first) {
01056 first = 0;
01057 if (G(version) > 1) {
01058 if (c1 != ' ') {
01059 buf[0] = c1;
01060 if (fgets(buf + 1,
01061 sizeof(buf) - 1, stdin) == NULL ||
01062 strcmp(buf, "DATA=END\n") != 0) {
01063 db_load_badend(dbenv);
01064 return (1);
01065 }
01066 G(endodata) = 1;
01067 return (0);
01068 }
01069 continue;
01070 }
01071 }
01072 if (escape) {
01073 if (c1 != '\\') {
01074 if ((c2 = getchar()) == EOF) {
01075 db_load_badend(dbenv);
01076 return (1);
01077 }
01078 c1 = db_load_digitize(dbenv,
01079 c1, &e) << 4 | db_load_digitize(dbenv, c2, &e);
01080 if (e)
01081 return (1);
01082 }
01083 escape = 0;
01084 } else
01085 if (c1 == '\\') {
01086 escape = 1;
01087 continue;
01088 }
01089 if (len >= dbtp->ulen - 10) {
01090 dbtp->ulen *= 2;
01091 if ((dbtp->data =
01092 realloc(dbtp->data, dbtp->ulen)) == NULL) {
01093 dbenv->err(dbenv, ENOMEM, NULL);
01094 return (1);
01095 }
01096 p = (u_int8_t *)dbtp->data + len;
01097 }
01098 ++len;
01099 *p++ = c1;
01100 }
01101 dbtp->size = len;
01102
01103 return (0);
01104 }
01105
01106
01107
01108
01109
01110 int
01111 db_load_dbt_rdump(dbenv, dbtp)
01112 DB_ENV *dbenv;
01113 DBT *dbtp;
01114 {
01115 u_int32_t len;
01116 u_int8_t *p;
01117 int c1, c2, e, first;
01118 char buf[32];
01119
01120 ++G(lineno);
01121
01122 first = 1;
01123 e = 0;
01124 for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) {
01125 if (c1 == EOF) {
01126 if (len == 0) {
01127 G(endofile) = G(endodata) = 1;
01128 return (0);
01129 }
01130 db_load_badend(dbenv);
01131 return (1);
01132 }
01133 if (first) {
01134 first = 0;
01135 if (G(version) > 1) {
01136 if (c1 != ' ') {
01137 buf[0] = c1;
01138 if (fgets(buf + 1,
01139 sizeof(buf) - 1, stdin) == NULL ||
01140 strcmp(buf, "DATA=END\n") != 0) {
01141 db_load_badend(dbenv);
01142 return (1);
01143 }
01144 G(endodata) = 1;
01145 return (0);
01146 }
01147 continue;
01148 }
01149 }
01150 if ((c2 = getchar()) == EOF) {
01151 db_load_badend(dbenv);
01152 return (1);
01153 }
01154 if (len >= dbtp->ulen - 10) {
01155 dbtp->ulen *= 2;
01156 if ((dbtp->data =
01157 realloc(dbtp->data, dbtp->ulen)) == NULL) {
01158 dbenv->err(dbenv, ENOMEM, NULL);
01159 return (1);
01160 }
01161 p = (u_int8_t *)dbtp->data + len;
01162 }
01163 ++len;
01164 *p++ = db_load_digitize(dbenv, c1, &e) << 4 | db_load_digitize(dbenv, c2, &e);
01165 if (e)
01166 return (1);
01167 }
01168 dbtp->size = len;
01169
01170 return (0);
01171 }
01172
01173
01174
01175
01176
01177 int
01178 db_load_dbt_rrecno(dbenv, dbtp, ishex)
01179 DB_ENV *dbenv;
01180 DBT *dbtp;
01181 int ishex;
01182 {
01183 char buf[32], *p, *q;
01184 u_long recno;
01185
01186 ++G(lineno);
01187
01188 if (fgets(buf, sizeof(buf), stdin) == NULL) {
01189 G(endofile) = G(endodata) = 1;
01190 return (0);
01191 }
01192
01193 if (strcmp(buf, "DATA=END\n") == 0) {
01194 G(endodata) = 1;
01195 return (0);
01196 }
01197
01198 if (buf[0] != ' ')
01199 goto bad;
01200
01201
01202
01203
01204
01205 if (ishex) {
01206 for (p = q = buf + 1; *q != '\0' && *q != '\n';) {
01207
01208
01209
01210
01211
01212
01213
01214 if (*q++ != '3')
01215 goto bad;
01216 if (*q == '\n' || *q == '\0')
01217 goto bad;
01218 *p++ = *q++;
01219 }
01220 *p = '\0';
01221 }
01222
01223 if (__db_getulong(dbenv, G(progname), buf + 1, 0, 0, &recno)) {
01224 bad: db_load_badend(dbenv);
01225 return (1);
01226 }
01227
01228 *((db_recno_t *)dbtp->data) = recno;
01229 dbtp->size = sizeof(db_recno_t);
01230 return (0);
01231 }
01232
01233 int
01234 db_load_dbt_to_recno(dbenv, dbt, recnop)
01235 DB_ENV *dbenv;
01236 DBT *dbt;
01237 db_recno_t *recnop;
01238 {
01239 char buf[32];
01240
01241 memcpy(buf, dbt->data, dbt->size);
01242 buf[dbt->size] = '\0';
01243
01244 return (__db_getulong(dbenv, G(progname), buf, 0, 0, (u_long *)recnop));
01245 }
01246
01247
01248
01249
01250
01251 int
01252 db_load_digitize(dbenv, c, errorp)
01253 DB_ENV *dbenv;
01254 int c, *errorp;
01255 {
01256 switch (c) {
01257 case '0': return (0);
01258 case '1': return (1);
01259 case '2': return (2);
01260 case '3': return (3);
01261 case '4': return (4);
01262 case '5': return (5);
01263 case '6': return (6);
01264 case '7': return (7);
01265 case '8': return (8);
01266 case '9': return (9);
01267 case 'a': return (10);
01268 case 'b': return (11);
01269 case 'c': return (12);
01270 case 'd': return (13);
01271 case 'e': return (14);
01272 case 'f': return (15);
01273 default:
01274 break;
01275 }
01276
01277 dbenv->errx(dbenv, "unexpected hexadecimal value");
01278 *errorp = 1;
01279
01280 return (0);
01281 }
01282
01283
01284
01285
01286
01287 void
01288 db_load_badnum(dbenv)
01289 DB_ENV *dbenv;
01290 {
01291 dbenv->errx(dbenv,
01292 "boolean name=value pairs require a value of 0 or 1");
01293 }
01294
01295
01296
01297
01298
01299 void
01300 db_load_badend(dbenv)
01301 DB_ENV *dbenv;
01302 {
01303 dbenv->errx(dbenv, "unexpected end of input data or key/data pair");
01304 }
01305
01306
01307
01308
01309
01310 int
01311 db_load_usage()
01312 {
01313 (void)fprintf(stderr, "usage: %s %s\n\t%s\n", progname,
01314 "[-nTV] [-c name=value] [-f file]",
01315 "[-h home] [-P password] [-t btree | hash | recno | queue] db_file");
01316 (void)fprintf(stderr, "usage: %s %s\n",
01317 progname, "-r lsn | fileid [-h home] [-P password] db_file");
01318 return (EXIT_FAILURE);
01319 }
01320
01321 int
01322 db_load_version_check()
01323 {
01324 int v_major, v_minor, v_patch;
01325
01326
01327 (void)db_version(&v_major, &v_minor, &v_patch);
01328 if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
01329 fprintf(stderr,
01330 "%s: version %d.%d doesn't match library version %d.%d\n",
01331 progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
01332 v_major, v_minor);
01333 return (EXIT_FAILURE);
01334 }
01335 return (0);
01336 }