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