1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1996,2008 Oracle. All rights reserved. 5 * 6 * $Id: db_upgrade.c,v 12.13 2008/01/08 20:58:16 bostic Exp $ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12 13#ifndef lint 14static const char copyright[] = 15 "Copyright (c) 1996,2008 Oracle. All rights reserved.\n"; 16#endif 17 18int main __P((int, char *[])); 19int usage __P((void)); 20int version_check __P((void)); 21 22const char *progname; 23 24int 25main(argc, argv) 26 int argc; 27 char *argv[]; 28{ 29 extern char *optarg; 30 extern int optind; 31 DB *dbp; 32 DB_ENV *dbenv; 33 u_int32_t flags; 34 int ch, exitval, nflag, ret, t_ret, verbose; 35 char *home, *passwd; 36 37 if ((progname = __db_rpath(argv[0])) == NULL) 38 progname = argv[0]; 39 else 40 ++progname; 41 42 if ((ret = version_check()) != 0) 43 return (ret); 44 45 dbenv = NULL; 46 flags = nflag = verbose = 0; 47 exitval = 0; 48 home = passwd = NULL; 49 while ((ch = getopt(argc, argv, "h:NP:sVv")) != EOF) 50 switch (ch) { 51 case 'h': 52 home = optarg; 53 break; 54 case 'N': 55 nflag = 1; 56 break; 57 case 'P': 58 passwd = strdup(optarg); 59 memset(optarg, 0, strlen(optarg)); 60 if (passwd == NULL) { 61 fprintf(stderr, "%s: strdup: %s\n", 62 progname, strerror(errno)); 63 return (EXIT_FAILURE); 64 } 65 break; 66 case 's': 67 LF_SET(DB_DUPSORT); 68 break; 69 case 'V': 70 printf("%s\n", db_version(NULL, NULL, NULL)); 71 return (EXIT_SUCCESS); 72 case 'v': 73 verbose = 1; 74 break; 75 case '?': 76 default: 77 return (usage()); 78 } 79 argc -= optind; 80 argv += optind; 81 82 if (argc <= 0) 83 return (usage()); 84 85 /* Handle possible interruptions. */ 86 __db_util_siginit(); 87 88 /* 89 * Create an environment object and initialize it for error 90 * reporting. 91 */ 92 if ((ret = db_env_create(&dbenv, 0)) != 0) { 93 fprintf(stderr, "%s: db_env_create: %s\n", 94 progname, db_strerror(ret)); 95 goto shutdown; 96 } 97 98 dbenv->set_errfile(dbenv, stderr); 99 dbenv->set_errpfx(dbenv, progname); 100 101 if (nflag) { 102 if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) { 103 dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING"); 104 goto shutdown; 105 } 106 if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) { 107 dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC"); 108 goto shutdown; 109 } 110 } 111 112 if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, 113 passwd, DB_ENCRYPT_AES)) != 0) { 114 dbenv->err(dbenv, ret, "set_passwd"); 115 goto shutdown; 116 } 117 118 /* 119 * If attaching to a pre-existing environment fails, create a 120 * private one and try again. 121 */ 122 if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0 && 123 (ret == DB_VERSION_MISMATCH || 124 (ret = dbenv->open(dbenv, home, 125 DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 126 0)) != 0)) { 127 dbenv->err(dbenv, ret, "DB_ENV->open"); 128 goto shutdown; 129 } 130 131 for (; !__db_util_interrupted() && argv[0] != NULL; ++argv) { 132 if ((ret = db_create(&dbp, dbenv, 0)) != 0) { 133 fprintf(stderr, 134 "%s: db_create: %s\n", progname, db_strerror(ret)); 135 goto shutdown; 136 } 137 dbp->set_errfile(dbp, stderr); 138 dbp->set_errpfx(dbp, progname); 139 if ((ret = dbp->upgrade(dbp, argv[0], flags)) != 0) 140 dbp->err(dbp, ret, "DB->upgrade: %s", argv[0]); 141 if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0) { 142 dbenv->err(dbenv, ret, "DB->close: %s", argv[0]); 143 ret = t_ret; 144 } 145 if (ret != 0) 146 goto shutdown; 147 /* 148 * People get concerned if they don't see a success message. 149 * If verbose is set, give them one. 150 */ 151 if (verbose) 152 printf("%s: %s upgraded successfully\n", 153 progname, argv[0]); 154 } 155 156 if (0) { 157shutdown: exitval = 1; 158 } 159 if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { 160 exitval = 1; 161 fprintf(stderr, 162 "%s: dbenv->close: %s\n", progname, db_strerror(ret)); 163 } 164 165 if (passwd != NULL) 166 free(passwd); 167 168 /* Resend any caught signal. */ 169 __db_util_sigresend(); 170 171 return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); 172} 173 174int 175usage() 176{ 177 fprintf(stderr, "usage: %s %s\n", progname, 178 "[-NsVv] [-h home] [-P password] db_file ..."); 179 return (EXIT_FAILURE); 180} 181 182int 183version_check() 184{ 185 int v_major, v_minor, v_patch; 186 187 /* Make sure we're loaded with the right version of the DB library. */ 188 (void)db_version(&v_major, &v_minor, &v_patch); 189 if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { 190 fprintf(stderr, 191 "%s: version %d.%d doesn't match library version %d.%d\n", 192 progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, 193 v_major, v_minor); 194 return (EXIT_FAILURE); 195 } 196 return (0); 197} 198