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 <ctype.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/btree.h"
00030 #include "dbinc/fop.h"
00031 #include "dbinc/hash.h"
00032 #include "dbinc/log.h"
00033 #include "dbinc/qam.h"
00034 #include "dbinc/txn.h"
00035
00036 int lsn_arg __P((char *, DB_LSN *));
00037 int main __P((int, char *[]));
00038 int open_rep_db __P((DB_ENV *, DB **, DBC **));
00039 int print_app_record __P((DB_ENV *, DBT *, DB_LSN *, db_recops));
00040 int usage __P((void));
00041 int version_check __P((void));
00042
00043 const char *progname;
00044
00045 int
00046 main(argc, argv)
00047 int argc;
00048 char *argv[];
00049 {
00050 extern char *optarg;
00051 extern int optind;
00052 DB *dbp;
00053 DBC *dbc;
00054 DBT data, keydbt;
00055 DB_ENV *dbenv;
00056 DB_LOGC *logc;
00057 DB_LSN key, start, stop;
00058 size_t dtabsize;
00059 u_int32_t logcflag;
00060 int ch, cmp, exitval, nflag, rflag, ret, repflag;
00061 int (**dtab) __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));
00062 char *home, *passwd;
00063
00064 if ((progname = strrchr(argv[0], '/')) == NULL)
00065 progname = argv[0];
00066 else
00067 ++progname;
00068
00069 if ((ret = version_check()) != 0)
00070 return (ret);
00071
00072 dbp = NULL;
00073 dbc = NULL;
00074 dbenv = NULL;
00075 logc = NULL;
00076 ZERO_LSN(start);
00077 ZERO_LSN(stop);
00078 dtabsize = 0;
00079 exitval = nflag = rflag = repflag = 0;
00080 dtab = NULL;
00081 home = passwd = NULL;
00082
00083 while ((ch = getopt(argc, argv, "b:e:h:NP:rRV")) != EOF)
00084 switch (ch) {
00085 case 'b':
00086 if (lsn_arg(optarg, &start))
00087 return (usage());
00088 break;
00089 case 'e':
00090 if (lsn_arg(optarg, &stop))
00091 return (usage());
00092 break;
00093 case 'h':
00094 home = optarg;
00095 break;
00096 case 'N':
00097 nflag = 1;
00098 break;
00099 case 'P':
00100 passwd = strdup(optarg);
00101 memset(optarg, 0, strlen(optarg));
00102 if (passwd == NULL) {
00103 fprintf(stderr, "%s: strdup: %s\n",
00104 progname, strerror(errno));
00105 return (EXIT_FAILURE);
00106 }
00107 break;
00108 case 'r':
00109 rflag = 1;
00110 break;
00111 case 'R':
00112 repflag = 1;
00113 break;
00114 case 'V':
00115 printf("%s\n", db_version(NULL, NULL, NULL));
00116 return (EXIT_SUCCESS);
00117 case '?':
00118 default:
00119 return (usage());
00120 }
00121 argc -= optind;
00122 argv += optind;
00123
00124 if (argc > 0)
00125 return (usage());
00126
00127
00128 __db_util_siginit();
00129
00130
00131
00132
00133
00134 if ((ret = db_env_create(&dbenv, 0)) != 0) {
00135 fprintf(stderr,
00136 "%s: db_env_create: %s\n", progname, db_strerror(ret));
00137 goto shutdown;
00138 }
00139
00140 dbenv->set_errfile(dbenv, stderr);
00141 dbenv->set_errpfx(dbenv, progname);
00142
00143 if (nflag) {
00144 if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) {
00145 dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING");
00146 goto shutdown;
00147 }
00148 if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) {
00149 dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC");
00150 goto shutdown;
00151 }
00152 }
00153
00154 if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv,
00155 passwd, DB_ENCRYPT_AES)) != 0) {
00156 dbenv->err(dbenv, ret, "set_passwd");
00157 goto shutdown;
00158 }
00159
00160
00161
00162
00163
00164 if ((ret = dbenv->set_app_dispatch(dbenv, print_app_record)) != 0) {
00165 dbenv->err(dbenv, ret, "app_dispatch");
00166 goto shutdown;
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176 if (repflag) {
00177 if ((ret = dbenv->open(dbenv, home,
00178 DB_INIT_MPOOL | DB_USE_ENVIRON, 0)) != 0 &&
00179 (ret == DB_VERSION_MISMATCH ||
00180 (ret = dbenv->open(dbenv, home,
00181 DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0))
00182 != 0)) {
00183 dbenv->err(dbenv, ret, "DB_ENV->open");
00184 goto shutdown;
00185 }
00186 } else if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0 &&
00187 (ret == DB_VERSION_MISMATCH ||
00188 (ret = dbenv->open(dbenv, home,
00189 DB_CREATE | DB_INIT_LOG | DB_PRIVATE | DB_USE_ENVIRON, 0)) != 0)) {
00190 dbenv->err(dbenv, ret, "DB_ENV->open");
00191 goto shutdown;
00192 }
00193
00194
00195 if ((ret = __bam_init_print(dbenv, &dtab, &dtabsize)) != 0 ||
00196 (ret = __crdel_init_print(dbenv, &dtab, &dtabsize)) != 0 ||
00197 (ret = __db_init_print(dbenv, &dtab, &dtabsize)) != 0 ||
00198 (ret = __dbreg_init_print(dbenv, &dtab, &dtabsize)) != 0 ||
00199 (ret = __fop_init_print(dbenv, &dtab, &dtabsize)) != 0 ||
00200 #ifdef HAVE_HASH
00201 (ret = __ham_init_print(dbenv, &dtab, &dtabsize)) != 0 ||
00202 #endif
00203 #ifdef HAVE_QUEUE
00204 (ret = __qam_init_print(dbenv, &dtab, &dtabsize)) != 0 ||
00205 #endif
00206 (ret = __txn_init_print(dbenv, &dtab, &dtabsize)) != 0) {
00207 dbenv->err(dbenv, ret, "callback: initialization");
00208 goto shutdown;
00209 }
00210
00211
00212 if (repflag) {
00213 if ((ret = open_rep_db(dbenv, &dbp, &dbc)) != 0)
00214 goto shutdown;
00215 } else if ((ret = dbenv->log_cursor(dbenv, &logc, 0)) != 0) {
00216 dbenv->err(dbenv, ret, "DB_ENV->log_cursor");
00217 goto shutdown;
00218 }
00219
00220 if (IS_ZERO_LSN(start)) {
00221 memset(&keydbt, 0, sizeof(keydbt));
00222 logcflag = rflag ? DB_PREV : DB_NEXT;
00223 } else {
00224 key = start;
00225 logcflag = DB_SET;
00226 }
00227 memset(&data, 0, sizeof(data));
00228
00229 for (; !__db_util_interrupted(); logcflag = rflag ? DB_PREV : DB_NEXT) {
00230 if (repflag) {
00231 ret = dbc->c_get(dbc, &keydbt, &data, logcflag);
00232 if (ret == 0)
00233 key = ((REP_CONTROL *)keydbt.data)->lsn;
00234 } else
00235 ret = logc->get(logc, &key, &data, logcflag);
00236 if (ret != 0) {
00237 if (ret == DB_NOTFOUND)
00238 break;
00239 dbenv->err(dbenv,
00240 ret, repflag ? "DB_LOGC->get" : "DBC->get");
00241 goto shutdown;
00242 }
00243
00244
00245
00246
00247 if (!IS_ZERO_LSN(stop)) {
00248 cmp = log_compare(&key, &stop);
00249 if ((rflag && cmp < 0) || (!rflag && cmp > 0))
00250 break;
00251 }
00252
00253 ret = __db_dispatch(dbenv,
00254 dtab, dtabsize, &data, &key, DB_TXN_PRINT, NULL);
00255
00256
00257
00258
00259
00260 (void)fflush(stdout);
00261
00262 if (ret != 0) {
00263 dbenv->err(dbenv, ret, "tx: dispatch");
00264 goto shutdown;
00265 }
00266 }
00267
00268 if (0) {
00269 shutdown: exitval = 1;
00270 }
00271 if (logc != NULL && (ret = logc->close(logc, 0)) != 0)
00272 exitval = 1;
00273
00274 if (dbc != NULL && (ret = dbc->c_close(dbc)) != 0)
00275 exitval = 1;
00276
00277 if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0)
00278 exitval = 1;
00279
00280
00281
00282
00283
00284
00285 if (dtab != NULL)
00286 __os_free(dbenv, dtab);
00287 if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) {
00288 exitval = 1;
00289 fprintf(stderr,
00290 "%s: dbenv->close: %s\n", progname, db_strerror(ret));
00291 }
00292
00293 if (passwd != NULL)
00294 free(passwd);
00295
00296
00297 __db_util_sigresend();
00298
00299 return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
00300 }
00301
00302 int
00303 usage()
00304 {
00305 fprintf(stderr, "usage: %s %s\n", progname,
00306 "[-NrV] [-b file/offset] [-e file/offset] [-h home] [-P password]");
00307 return (EXIT_FAILURE);
00308 }
00309
00310 int
00311 version_check()
00312 {
00313 int v_major, v_minor, v_patch;
00314
00315
00316 (void)db_version(&v_major, &v_minor, &v_patch);
00317 if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
00318 fprintf(stderr,
00319 "%s: version %d.%d doesn't match library version %d.%d\n",
00320 progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
00321 v_major, v_minor);
00322 return (EXIT_FAILURE);
00323 }
00324 return (0);
00325 }
00326
00327
00328 int
00329 print_app_record(dbenv, dbt, lsnp, op)
00330 DB_ENV *dbenv;
00331 DBT *dbt;
00332 DB_LSN *lsnp;
00333 db_recops op;
00334 {
00335 int ch;
00336 u_int32_t i, rectype;
00337
00338 DB_ASSERT(op == DB_TXN_PRINT);
00339
00340 COMPQUIET(dbenv, NULL);
00341 COMPQUIET(op, DB_TXN_PRINT);
00342
00343
00344
00345
00346
00347 memcpy(&rectype, dbt->data, sizeof(rectype));
00348
00349
00350
00351
00352
00353
00354 printf("[%lu][%lu]application specific record: rec: %lu\n",
00355 (u_long)lsnp->file, (u_long)lsnp->offset, (u_long)rectype);
00356 printf("\tdata: ");
00357 for (i = 0; i < dbt->size; i++) {
00358 ch = ((u_int8_t *)dbt->data)[i];
00359 printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch);
00360 }
00361 printf("\n\n");
00362
00363 return (0);
00364 }
00365
00366 int
00367 open_rep_db(dbenv, dbpp, dbcp)
00368 DB_ENV *dbenv;
00369 DB **dbpp;
00370 DBC **dbcp;
00371 {
00372 int ret;
00373
00374 DB *dbp;
00375 *dbpp = NULL;
00376 *dbcp = NULL;
00377
00378 if ((ret = db_create(dbpp, dbenv, 0)) != 0) {
00379 dbenv->err(dbenv, ret, "db_create");
00380 return (ret);
00381 }
00382
00383 dbp = *dbpp;
00384 if ((ret =
00385 dbp->open(dbp, NULL, "__db.rep.db", NULL, DB_BTREE, 0, 0)) != 0) {
00386 dbenv->err(dbenv, ret, "DB->open");
00387 goto err;
00388 }
00389
00390 if ((ret = dbp->cursor(dbp, NULL, dbcp, 0)) != 0) {
00391 dbenv->err(dbenv, ret, "DB->cursor");
00392 goto err;
00393 }
00394
00395 return (0);
00396
00397 err: if (*dbpp != NULL)
00398 (void)(*dbpp)->close(*dbpp, 0);
00399 return (ret);
00400 }
00401
00402
00403
00404
00405
00406 int
00407 lsn_arg(arg, lsnp)
00408 char *arg;
00409 DB_LSN *lsnp;
00410 {
00411 char *p;
00412 u_long uval;
00413
00414
00415
00416
00417
00418
00419 if ((p = strchr(arg, '/')) == NULL)
00420 return (1);
00421 *p = '\0';
00422
00423 if (__db_getulong(NULL, progname, arg, 0, 0, &uval))
00424 return (1);
00425 if (uval > UINT32_MAX)
00426 return (1);
00427 lsnp->file = uval;
00428 if (__db_getulong(NULL, progname, p + 1, 0, 0, &uval))
00429 return (1);
00430 if (uval > UINT32_MAX)
00431 return (1);
00432 lsnp->offset = uval;
00433 return (0);
00434 }