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

db_verify.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_verify.c,v 12.3 2005/06/16 20:21:37 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 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include <unistd.h>
00024 #endif
00025 
00026 #include "db_int.h"
00027 
00028 int db_verify_main __P((int, char *[]));
00029 int db_verify_usage __P((void));
00030 int db_verify_version_check __P((void));
00031 
00032 const char *progname;
00033 
00034 int
00035 db_verify(args)
00036         char *args;
00037 {
00038         int argc;
00039         char **argv;
00040 
00041         __db_util_arg("db_verify", args, &argc, &argv);
00042         return (db_verify_main(argc, argv) ? EXIT_FAILURE : EXIT_SUCCESS);
00043 }
00044 
00045 #include <stdio.h>
00046 #define ERROR_RETURN    ERROR
00047 
00048 int
00049 db_verify_main(argc, argv)
00050         int argc;
00051         char *argv[];
00052 {
00053         extern char *optarg;
00054         extern int optind, __db_getopt_reset;
00055         DB *dbp, *dbp1;
00056         DB_ENV *dbenv;
00057         u_int32_t flags, cache;
00058         int ch, exitval, nflag, private;
00059         int quiet, resize, ret;
00060         char *home, *passwd;
00061 
00062         if ((progname = strrchr(argv[0], '/')) == NULL)
00063                 progname = argv[0];
00064         else
00065                 ++progname;
00066 
00067         if ((ret = db_verify_version_check()) != 0)
00068                 return (ret);
00069 
00070         dbenv = NULL;
00071         dbp = NULL;
00072         cache = MEGABYTE;
00073         exitval = nflag = quiet = 0;
00074         flags = 0;
00075         home = passwd = NULL;
00076         __db_getopt_reset = 1;
00077         while ((ch = getopt(argc, argv, "h:NoP:quV")) != EOF)
00078                 switch (ch) {
00079                 case 'h':
00080                         home = optarg;
00081                         break;
00082                 case 'N':
00083                         nflag = 1;
00084                         break;
00085                 case 'P':
00086                         passwd = strdup(optarg);
00087                         memset(optarg, 0, strlen(optarg));
00088                         if (passwd == NULL) {
00089                                 fprintf(stderr, "%s: strdup: %s\n",
00090                                     progname, strerror(errno));
00091                                 return (EXIT_FAILURE);
00092                         }
00093                         break;
00094                 case 'o':
00095                         LF_SET(DB_NOORDERCHK);
00096                         break;
00097                 case 'q':
00098                         quiet = 1;
00099                         break;
00100                 case 'u':                       /* Undocumented. */
00101                         LF_SET(DB_UNREF);
00102                         break;
00103                 case 'V':
00104                         printf("%s\n", db_version(NULL, NULL, NULL));
00105                         return (EXIT_SUCCESS);
00106                 case '?':
00107                 default:
00108                         return (db_verify_usage());
00109                 }
00110         argc -= optind;
00111         argv += optind;
00112 
00113         if (argc <= 0)
00114                 return (db_verify_usage());
00115 
00116         /* Handle possible interruptions. */
00117         __db_util_siginit();
00118 
00119         /*
00120          * Create an environment object and initialize it for error
00121          * reporting.
00122          */
00123 retry:  if ((ret = db_env_create(&dbenv, 0)) != 0) {
00124                 fprintf(stderr,
00125                     "%s: db_env_create: %s\n", progname, db_strerror(ret));
00126                 goto shutdown;
00127         }
00128 
00129         if (!quiet) {
00130                 dbenv->set_errfile(dbenv, stderr);
00131                 dbenv->set_errpfx(dbenv, progname);
00132         }
00133 
00134         if (nflag) {
00135                 if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) {
00136                         dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING");
00137                         goto shutdown;
00138                 }
00139                 if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) {
00140                         dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC");
00141                         goto shutdown;
00142                 }
00143         }
00144 
00145         if (passwd != NULL &&
00146             (ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES)) != 0) {
00147                 dbenv->err(dbenv, ret, "set_passwd");
00148                 goto shutdown;
00149         }
00150         /*
00151          * Attach to an mpool if it exists, but if that fails, attach to a
00152          * private region.  In the latter case, declare a reasonably large
00153          * cache so that we don't fail when verifying large databases.
00154          */
00155         private = 0;
00156         if ((ret =
00157             dbenv->open(dbenv, home, DB_INIT_MPOOL | DB_USE_ENVIRON, 0)) != 0) {
00158                 if (ret != DB_VERSION_MISMATCH) {
00159                         if ((ret =
00160                             dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) {
00161                                 dbenv->err(dbenv, ret, "set_cachesize");
00162                                 goto shutdown;
00163                         }
00164                         private = 1;
00165                         ret = dbenv->open(dbenv, home, DB_CREATE |
00166                             DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0);
00167                 }
00168                 if (ret != 0) {
00169                         dbenv->err(dbenv, ret, "DB_ENV->open");
00170                         goto shutdown;
00171                 }
00172         }
00173 
00174         for (; !__db_util_interrupted() && argv[0] != NULL; ++argv) {
00175                 if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
00176                         dbenv->err(dbenv, ret, "%s: db_create", progname);
00177                         goto shutdown;
00178                 }
00179 
00180                 /*
00181                  * We create a 2nd dbp to this database to get its pagesize
00182                  * because the dbp we're using for verify cannot be opened.
00183                  *
00184                  * If the database is corrupted, we may not be able to open
00185                  * it, of course.  In that case, just continue, using the
00186                  * cache size we have.
00187                  */
00188                 if (private) {
00189                         if ((ret = db_create(&dbp1, dbenv, 0)) != 0) {
00190                                 dbenv->err(
00191                                     dbenv, ret, "%s: db_create", progname);
00192                                 goto shutdown;
00193                         }
00194 
00195                         ret = dbp1->open(dbp1,
00196                             NULL, argv[0], NULL, DB_UNKNOWN, DB_RDONLY, 0);
00197 
00198                         /*
00199                          * If we get here, we can check the cache/page.
00200                          * !!!
00201                          * If we have to retry with an env with a larger
00202                          * cache, we jump out of this loop.  However, we
00203                          * will still be working on the same argv when we
00204                          * get back into the for-loop.
00205                          */
00206                         if (ret == 0) {
00207                                 if (__db_util_cache(
00208                                     dbp1, &cache, &resize) == 0 && resize) {
00209                                         (void)dbp1->close(dbp1, 0);
00210                                         (void)dbp->close(dbp, 0);
00211                                         dbp = NULL;
00212 
00213                                         (void)dbenv->close(dbenv, 0);
00214                                         dbenv = NULL;
00215                                         goto retry;
00216                                 }
00217                         }
00218                         (void)dbp1->close(dbp1, 0);
00219                 }
00220 
00221                 /* The verify method is a destructor. */
00222                 ret = dbp->verify(dbp, argv[0], NULL, NULL, flags);
00223                 dbp = NULL;
00224                 if (ret != 0)
00225                         goto shutdown;
00226         }
00227 
00228         if (0) {
00229 shutdown:       exitval = 1;
00230         }
00231 
00232         if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) {
00233                 exitval = 1;
00234                 dbenv->err(dbenv, ret, "close");
00235         }
00236         if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) {
00237                 exitval = 1;
00238                 fprintf(stderr,
00239                     "%s: dbenv->close: %s\n", progname, db_strerror(ret));
00240         }
00241 
00242         if (passwd != NULL)
00243                 free(passwd);
00244 
00245         /* Resend any caught signal. */
00246         __db_util_sigresend();
00247 
00248         return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
00249 }
00250 
00251 int
00252 db_verify_usage()
00253 {
00254         fprintf(stderr, "usage: %s %s\n", progname,
00255             "[-NoqV] [-h home] [-P password] db_file ...");
00256         return (EXIT_FAILURE);
00257 }
00258 
00259 int
00260 db_verify_version_check()
00261 {
00262         int v_major, v_minor, v_patch;
00263 
00264         /* Make sure we're loaded with the right version of the DB library. */
00265         (void)db_version(&v_major, &v_minor, &v_patch);
00266         if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
00267                 fprintf(stderr,
00268         "%s: version %d.%d doesn't match library version %d.%d\n",
00269                     progname, DB_VERSION_MAJOR, DB_VERSION_MINOR,
00270                     v_major, v_minor);
00271                 return (EXIT_FAILURE);
00272         }
00273         return (0);
00274 }

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