Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

db_recover.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1996-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: db_recover.c,v 12.5 2005/06/16 20:21:29 bostic Exp $
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, &timestamp)) != 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         /* Handle possible interruptions. */
00125         __db_util_siginit();
00126 
00127         /*
00128          * Create an environment object and initialize it for error
00129          * reporting.
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, &timestamp)) != 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          * Initialize the environment -- we don't actually do anything
00154          * else, that all that's needed to run recovery.
00155          *
00156          * Note that unless the caller specified the -e option, we use a
00157          * private environment, as we're about to create a region, and we
00158          * don't want to to leave it around.  If we leave the region around,
00159          * the application that should create it will simply join it instead,
00160          * and will then be running with incorrectly sized (and probably
00161          * terribly small) caches.  Applications that use -e should almost
00162          * certainly use DB_CONFIG files in the directory.
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         /* Clean up the environment. */
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         /* Resend any caught signal. */
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  * read_timestamp --
00197  *      Convert a time argument to Epoch seconds.
00198  *
00199  * Copyright (c) 1993
00200  *      The Regents of the University of California.  All rights reserved.
00201  *
00202  * Redistribution and use in source and binary forms, with or without
00203  * modification, are permitted provided that the following conditions
00204  * are met:
00205  * 1. Redistributions of source code must retain the above copyright
00206  *    notice, this list of conditions and the following disclaimer.
00207  * 2. Redistributions in binary form must reproduce the above copyright
00208  *    notice, this list of conditions and the following disclaimer in the
00209  *    documentation and/or other materials provided with the distribution.
00210  * 3. Neither the name of the University nor the names of its contributors
00211  *    may be used to endorse or promote products derived from this software
00212  *    without specific prior written permission.
00213  *
00214  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00215  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00216  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00217  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00218  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00219  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00220  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00221  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00222  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00223  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00224  * SUCH DAMAGE.
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                                         /* Start with the current time. */
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                                         /* [[CC]YY]MMDDhhmm[.SS] */
00243         if ((p = strchr(arg, '.')) == NULL)
00244                 t->tm_sec = 0;          /* Seconds defaults to 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:                        /* CCYYMMDDhhmm */
00255                 t->tm_year = ATOI2(arg);
00256                 t->tm_year *= 100;
00257                 yearset = 1;
00258                 /* FALLTHROUGH */
00259         case 10:                        /* YYMMDDhhmm */
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;     /* Convert to UNIX time. */
00271                 /* FALLTHROUGH */
00272         case 8:                         /* MMDDhhmm */
00273                 t->tm_mon = ATOI2(arg);
00274                 --t->tm_mon;            /* Convert from 01-12 to 00-11 */
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;               /* Figure out DST. */
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         /* Make sure we're loaded with the right version of the DB library. */
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 }

Generated on Sun Dec 25 12:14:17 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2