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