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 main __P((int, char *[]));
00039 int read_timestamp __P((char *, time_t *));
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_ENV  *dbenv;
00053         time_t timestamp;
00054         u_int32_t flags;
00055         int ch, exitval, fatal_recover, ret, retain_env, verbose;
00056         char *home, *passwd;
00057 
00058         if ((progname = strrchr(argv[0], '/')) == NULL)
00059                 progname = argv[0];
00060         else
00061                 ++progname;
00062 
00063         if ((ret = version_check()) != 0)
00064                 return (ret);
00065 
00066         home = passwd = NULL;
00067         timestamp = 0;
00068         exitval = fatal_recover = retain_env = verbose = 0;
00069         while ((ch = getopt(argc, argv, "ceh:P:t:Vv")) != EOF)
00070                 switch (ch) {
00071                 case 'c':
00072                         fatal_recover = 1;
00073                         break;
00074                 case 'e':
00075                         retain_env = 1;
00076                         break;
00077                 case 'h':
00078                         home = optarg;
00079                         break;
00080                 case 'P':
00081                         passwd = strdup(optarg);
00082                         memset(optarg, 0, strlen(optarg));
00083                         if (passwd == NULL) {
00084                                 fprintf(stderr, "%s: strdup: %s\n",
00085                                     progname, strerror(errno));
00086                                 return (EXIT_FAILURE);
00087                         }
00088                         break;
00089                 case 't':
00090                         if ((ret = read_timestamp(optarg, &timestamp)) != 0)
00091                                 return (ret);
00092                         break;
00093                 case 'V':
00094                         printf("%s\n", db_version(NULL, NULL, NULL));
00095                         return (EXIT_SUCCESS);
00096                 case 'v':
00097                         verbose = 1;
00098                         break;
00099                 case '?':
00100                 default:
00101                         return (usage());
00102                 }
00103         argc -= optind;
00104         argv += optind;
00105 
00106         if (argc != 0)
00107                 return (usage());
00108 
00109         /* Handle possible interruptions. */
00110         __db_util_siginit();
00111 
00112         /*
00113          * Create an environment object and initialize it for error
00114          * reporting.
00115          */
00116         if ((ret = db_env_create(&dbenv, 0)) != 0) {
00117                 fprintf(stderr,
00118                     "%s: db_env_create: %s\n", progname, db_strerror(ret));
00119                 return (EXIT_FAILURE);
00120         }
00121         dbenv->set_errfile(dbenv, stderr);
00122         dbenv->set_errpfx(dbenv, progname);
00123         if (verbose)
00124                 (void)dbenv->set_verbose(dbenv, DB_VERB_RECOVERY, 1);
00125         if (timestamp &&
00126             (ret = dbenv->set_tx_timestamp(dbenv, &timestamp)) != 0) {
00127                 dbenv->err(dbenv, ret, "DB_ENV->set_timestamp");
00128                 goto shutdown;
00129         }
00130 
00131         if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv,
00132             passwd, DB_ENCRYPT_AES)) != 0) {
00133                 dbenv->err(dbenv, ret, "set_passwd");
00134                 goto shutdown;
00135         }
00136 
00137         /*
00138          * Initialize the environment -- we don't actually do anything
00139          * else, that all that's needed to run recovery.
00140          *
00141          * Note that unless the caller specified the -e option, we use a
00142          * private environment, as we're about to create a region, and we
00143          * don't want to to leave it around.  If we leave the region around,
00144          * the application that should create it will simply join it instead,
00145          * and will then be running with incorrectly sized (and probably
00146          * terribly small) caches.  Applications that use -e should almost
00147          * certainly use DB_CONFIG files in the directory.
00148          */
00149         flags = 0;
00150         LF_SET(DB_CREATE | DB_INIT_LOG |
00151             DB_INIT_MPOOL | DB_INIT_TXN | DB_USE_ENVIRON);
00152         LF_SET(fatal_recover ? DB_RECOVER_FATAL : DB_RECOVER);
00153         LF_SET(retain_env ? DB_INIT_LOCK : DB_PRIVATE);
00154         if ((ret = dbenv->open(dbenv, home, flags, 0)) != 0) {
00155                 dbenv->err(dbenv, ret, "DB_ENV->open");
00156                 goto shutdown;
00157         }
00158 
00159         if (0) {
00160 shutdown:       exitval = 1;
00161         }
00162 
00163         /* Clean up the environment. */
00164         if ((ret = dbenv->close(dbenv, 0)) != 0) {
00165                 exitval = 1;
00166                 fprintf(stderr,
00167                     "%s: dbenv->close: %s\n", progname, db_strerror(ret));
00168         }
00169         if (passwd != NULL)
00170                 free(passwd);
00171 
00172         /* Resend any caught signal. */
00173         __db_util_sigresend();
00174 
00175         return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
00176 }
00177 
00178 #define ATOI2(ar)       ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2;
00179 
00180 /*
00181  * read_timestamp --
00182  *      Convert a time argument to Epoch seconds.
00183  *
00184  * Copyright (c) 1993
00185  *      The Regents of the University of California.  All rights reserved.
00186  *
00187  * Redistribution and use in source and binary forms, with or without
00188  * modification, are permitted provided that the following conditions
00189  * are met:
00190  * 1. Redistributions of source code must retain the above copyright
00191  *    notice, this list of conditions and the following disclaimer.
00192  * 2. Redistributions in binary form must reproduce the above copyright
00193  *    notice, this list of conditions and the following disclaimer in the
00194  *    documentation and/or other materials provided with the distribution.
00195  * 3. Neither the name of the University nor the names of its contributors
00196  *    may be used to endorse or promote products derived from this software
00197  *    without specific prior written permission.
00198  *
00199  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00200  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00201  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00202  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00203  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00204  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00205  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00206  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00207  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00208  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00209  * SUCH DAMAGE.
00210  */
00211 int
00212 read_timestamp(arg, timep)
00213         char *arg;
00214         time_t *timep;
00215 {
00216         struct tm *t;
00217         time_t now;
00218         int yearset;
00219         char *p;
00220                                         /* Start with the current time. */
00221         (void)time(&now);
00222         if ((t = localtime(&now)) == NULL) {
00223                 fprintf(stderr,
00224                     "%s: localtime: %s\n", progname, strerror(errno));
00225                 return (EXIT_FAILURE);
00226         }
00227                                         /* [[CC]YY]MMDDhhmm[.SS] */
00228         if ((p = strchr(arg, '.')) == NULL)
00229                 t->tm_sec = 0;          /* Seconds defaults to 0. */
00230         else {
00231                 if (strlen(p + 1) != 2)
00232                         goto terr;
00233                 *p++ = '\0';
00234                 t->tm_sec = ATOI2(p);
00235         }
00236 
00237         yearset = 0;
00238         switch (strlen(arg)) {
00239         case 12:                        /* CCYYMMDDhhmm */
00240                 t->tm_year = ATOI2(arg);
00241                 t->tm_year *= 100;
00242                 yearset = 1;
00243                 /* FALLTHROUGH */
00244         case 10:                        /* YYMMDDhhmm */
00245                 if (yearset) {
00246                         yearset = ATOI2(arg);
00247                         t->tm_year += yearset;
00248                 } else {
00249                         yearset = ATOI2(arg);
00250                         if (yearset < 69)
00251                                 t->tm_year = yearset + 2000;
00252                         else
00253                                 t->tm_year = yearset + 1900;
00254                 }
00255                 t->tm_year -= 1900;     /* Convert to UNIX time. */
00256                 /* FALLTHROUGH */
00257         case 8:                         /* MMDDhhmm */
00258                 t->tm_mon = ATOI2(arg);
00259                 --t->tm_mon;            /* Convert from 01-12 to 00-11 */
00260                 t->tm_mday = ATOI2(arg);
00261                 t->tm_hour = ATOI2(arg);
00262                 t->tm_min = ATOI2(arg);
00263                 break;
00264         default:
00265                 goto terr;
00266         }
00267 
00268         t->tm_isdst = -1;               /* Figure out DST. */
00269 
00270         *timep = mktime(t);
00271         if (*timep == -1) {
00272 terr:           fprintf(stderr,
00273         "%s: out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]",
00274                     progname);
00275                 return (EXIT_FAILURE);
00276         }
00277         return (0);
00278 }
00279 
00280 int
00281 usage()
00282 {
00283         (void)fprintf(stderr, "usage: %s %s\n", progname,
00284             "[-ceVv] [-h home] [-P password] [-t [[CC]YY]MMDDhhmm[.SS]]");
00285         return (EXIT_FAILURE);
00286 }
00287 
00288 int
00289 version_check()
00290 {
00291         int v_major, v_minor, v_patch;
00292 
00293         /* Make sure we're loaded with the right version of the DB library. */
00294         (void)db_version(&v_major, &v_minor, &v_patch);
00295         if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
00296                 fprintf(stderr,
00297         "%s: version %d.%d doesn't match library version %d.%d\n",
00298                     progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
00299                     v_major, v_minor);
00300                 return (EXIT_FAILURE);
00301         }
00302         return (0);
00303 }

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