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 #if TIME_WITH_SYS_TIME
00021 #include <sys/time.h>
00022 #include <time.h>
00023 #else
00024 #if HAVE_SYS_TIME_H
00025 #include <sys/time.h>
00026 #else
00027 #include <time.h>
00028 #endif
00029 #endif
00030
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <unistd.h>
00034 #endif
00035
00036 #include "db_int.h"
00037
00038 int db_recover_main __P((int, char *[]));
00039 int db_recover_read_timestamp __P((char *, time_t *));
00040 int db_recover_usage __P((void));
00041 int db_recover_version_check __P((void));
00042
00043 const char *progname;
00044
00045 int
00046 db_recover(args)
00047 char *args;
00048 {
00049 int argc;
00050 char **argv;
00051
00052 __db_util_arg("db_recover", args, &argc, &argv);
00053 return (db_recover_main(argc, argv) ? EXIT_FAILURE : EXIT_SUCCESS);
00054 }
00055
00056 #include <stdio.h>
00057 #define ERROR_RETURN ERROR
00058
00059 int
00060 db_recover_main(argc, argv)
00061 int argc;
00062 char *argv[];
00063 {
00064 extern char *optarg;
00065 extern int optind, __db_getopt_reset;
00066 DB_ENV *dbenv;
00067 time_t timestamp;
00068 u_int32_t flags;
00069 int ch, exitval, fatal_recover, ret, retain_env, verbose;
00070 char *home, *passwd;
00071
00072 if ((progname = strrchr(argv[0], '/')) == NULL)
00073 progname = argv[0];
00074 else
00075 ++progname;
00076
00077 if ((ret = db_recover_version_check()) != 0)
00078 return (ret);
00079
00080 home = passwd = NULL;
00081 timestamp = 0;
00082 exitval = fatal_recover = retain_env = verbose = 0;
00083 __db_getopt_reset = 1;
00084 while ((ch = getopt(argc, argv, "ceh:P:t:Vv")) != EOF)
00085 switch (ch) {
00086 case 'c':
00087 fatal_recover = 1;
00088 break;
00089 case 'e':
00090 retain_env = 1;
00091 break;
00092 case 'h':
00093 home = optarg;
00094 break;
00095 case 'P':
00096 passwd = strdup(optarg);
00097 memset(optarg, 0, strlen(optarg));
00098 if (passwd == NULL) {
00099 fprintf(stderr, "%s: strdup: %s\n",
00100 progname, strerror(errno));
00101 return (EXIT_FAILURE);
00102 }
00103 break;
00104 case 't':
00105 if ((ret = db_recover_read_timestamp(optarg, ×tamp)) != 0)
00106 return (ret);
00107 break;
00108 case 'V':
00109 printf("%s\n", db_version(NULL, NULL, NULL));
00110 return (EXIT_SUCCESS);
00111 case 'v':
00112 verbose = 1;
00113 break;
00114 case '?':
00115 default:
00116 return (db_recover_usage());
00117 }
00118 argc -= optind;
00119 argv += optind;
00120
00121 if (argc != 0)
00122 return (db_recover_usage());
00123
00124
00125 __db_util_siginit();
00126
00127
00128
00129
00130
00131 if ((ret = db_env_create(&dbenv, 0)) != 0) {
00132 fprintf(stderr,
00133 "%s: db_env_create: %s\n", progname, db_strerror(ret));
00134 return (EXIT_FAILURE);
00135 }
00136 dbenv->set_errfile(dbenv, stderr);
00137 dbenv->set_errpfx(dbenv, progname);
00138 if (verbose)
00139 (void)dbenv->set_verbose(dbenv, DB_VERB_RECOVERY, 1);
00140 if (timestamp &&
00141 (ret = dbenv->set_tx_timestamp(dbenv, ×tamp)) != 0) {
00142 dbenv->err(dbenv, ret, "DB_ENV->set_timestamp");
00143 goto shutdown;
00144 }
00145
00146 if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv,
00147 passwd, DB_ENCRYPT_AES)) != 0) {
00148 dbenv->err(dbenv, ret, "set_passwd");
00149 goto shutdown;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 flags = 0;
00165 LF_SET(DB_CREATE | DB_INIT_LOG |
00166 DB_INIT_MPOOL | DB_INIT_TXN | DB_USE_ENVIRON);
00167 LF_SET(fatal_recover ? DB_RECOVER_FATAL : DB_RECOVER);
00168 LF_SET(retain_env ? DB_INIT_LOCK : DB_PRIVATE);
00169 if ((ret = dbenv->open(dbenv, home, flags, 0)) != 0) {
00170 dbenv->err(dbenv, ret, "DB_ENV->open");
00171 goto shutdown;
00172 }
00173
00174 if (0) {
00175 shutdown: exitval = 1;
00176 }
00177
00178
00179 if ((ret = dbenv->close(dbenv, 0)) != 0) {
00180 exitval = 1;
00181 fprintf(stderr,
00182 "%s: dbenv->close: %s\n", progname, db_strerror(ret));
00183 }
00184 if (passwd != NULL)
00185 free(passwd);
00186
00187
00188 __db_util_sigresend();
00189
00190 return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
00191 }
00192
00193 #define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2;
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 int
00227 db_recover_read_timestamp(arg, timep)
00228 char *arg;
00229 time_t *timep;
00230 {
00231 struct tm *t;
00232 time_t now;
00233 int yearset;
00234 char *p;
00235
00236 (void)time(&now);
00237 if ((t = localtime(&now)) == NULL) {
00238 fprintf(stderr,
00239 "%s: localtime: %s\n", progname, strerror(errno));
00240 return (EXIT_FAILURE);
00241 }
00242
00243 if ((p = strchr(arg, '.')) == NULL)
00244 t->tm_sec = 0;
00245 else {
00246 if (strlen(p + 1) != 2)
00247 goto terr;
00248 *p++ = '\0';
00249 t->tm_sec = ATOI2(p);
00250 }
00251
00252 yearset = 0;
00253 switch (strlen(arg)) {
00254 case 12:
00255 t->tm_year = ATOI2(arg);
00256 t->tm_year *= 100;
00257 yearset = 1;
00258
00259 case 10:
00260 if (yearset) {
00261 yearset = ATOI2(arg);
00262 t->tm_year += yearset;
00263 } else {
00264 yearset = ATOI2(arg);
00265 if (yearset < 69)
00266 t->tm_year = yearset + 2000;
00267 else
00268 t->tm_year = yearset + 1900;
00269 }
00270 t->tm_year -= 1900;
00271
00272 case 8:
00273 t->tm_mon = ATOI2(arg);
00274 --t->tm_mon;
00275 t->tm_mday = ATOI2(arg);
00276 t->tm_hour = ATOI2(arg);
00277 t->tm_min = ATOI2(arg);
00278 break;
00279 default:
00280 goto terr;
00281 }
00282
00283 t->tm_isdst = -1;
00284
00285 *timep = mktime(t);
00286 if (*timep == -1) {
00287 terr: fprintf(stderr,
00288 "%s: out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]",
00289 progname);
00290 return (EXIT_FAILURE);
00291 }
00292 return (0);
00293 }
00294
00295 int
00296 db_recover_usage()
00297 {
00298 (void)fprintf(stderr, "usage: %s %s\n", progname,
00299 "[-ceVv] [-h home] [-P password] [-t [[CC]YY]MMDDhhmm[.SS]]");
00300 return (EXIT_FAILURE);
00301 }
00302
00303 int
00304 db_recover_version_check()
00305 {
00306 int v_major, v_minor, v_patch;
00307
00308
00309 (void)db_version(&v_major, &v_minor, &v_patch);
00310 if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
00311 fprintf(stderr,
00312 "%s: version %d.%d doesn't match library version %d.%d\n",
00313 progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
00314 v_major, v_minor);
00315 return (EXIT_FAILURE);
00316 }
00317 return (0);
00318 }