]> git.pld-linux.org Git - packages/rpm.git/blob - rpmdb_reset.c
make perl's heredoc matching more generic to get rid of bogus reqs; rel 6
[packages/rpm.git] / rpmdb_reset.c
1 #include <sys/types.h>
2 #include <stddef.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <errno.h>
8 #include <db.h>
9
10 typedef struct {                        /* XXX: Globals. */
11         const char *progname;           /* Program name. */
12         char    *hdrbuf;                /* Input file header. */
13         u_long  lineno;                 /* Input file line number. */
14         u_long  origline;               /* Original file line number. */
15         int     endodata;               /* Reached the end of a database. */
16         int     endofile;               /* Reached the end of the input. */
17         int     version;                /* Input version. */
18         char    *home;                  /* Env home. */
19         char    *passwd;                /* Env passwd. */
20         int     private;                /* Private env. */
21         u_int32_t cache;                /* Env cache size. */
22 } LDG;
23
24 int     db_init __P((DB_ENV *, char *, u_int32_t, int *));
25 int     env_create __P((DB_ENV **, LDG *));
26 int     main __P((int, char *[]));
27 int     usage __P((void));
28 int     version_check __P((void));
29
30 const char *progname = "rpmdb_reset";
31
32 int
33 main(argc, argv)
34         int argc;
35         char *argv[];
36 {
37         enum { NOTSET, FILEID_RESET, LSN_RESET, STANDARD_LOAD } mode;
38         extern char *optarg;
39         extern int optind;
40         DBTYPE dbtype;
41         DB_ENV  *dbenv;
42         LDG ldg;
43         u_int ldf;
44         int ch, exitval, ret;
45
46         if ((exitval = version_check()) != 0)
47                 goto done;
48
49         ldg.progname = progname;
50         ldg.lineno = 0;
51         ldg.endodata = ldg.endofile = 0;
52         ldg.version = 1;
53         ldg.cache = (1024 * 1024);
54         ldg.hdrbuf = NULL;
55         ldg.home = NULL;
56         ldg.passwd = NULL;
57
58         mode = NOTSET;
59         ldf = 0;
60         exitval = 0;
61         dbtype = DB_UNKNOWN;
62
63         /*
64          * There are two modes for db_load: -r and everything else.  The -r
65          * option zeroes out the database LSN's or resets the file ID, it
66          * doesn't really "load" a new database.  The functionality is in
67          * db_load because we don't have a better place to put it, and we
68          * don't want to create a new utility for just that functionality.
69          */
70         while ((ch = getopt(argc, argv, "h:r:V")) != EOF)
71                 switch (ch) {
72                 case 'h':
73                         ldg.home = optarg;
74                         break;
75                 case 'r':
76                         if (strcmp(optarg, "lsn") == 0)
77                                 mode = LSN_RESET;
78                         else if (strcmp(optarg, "fileid") == 0)
79                                 mode = FILEID_RESET;
80                         else {
81                                 exitval = usage();
82                                 goto done;
83                         }
84                         break;
85                 case 'V':
86                         printf("%s\n", db_version(NULL, NULL, NULL));
87                         return (EXIT_SUCCESS);
88                 case '?':
89                 default:
90                         exitval = usage();
91                         goto done;
92                 }
93         argc -= optind;
94         argv += optind;
95
96         if (argc != 1 || mode == NOTSET) {
97                 exitval = usage();
98                 goto done;
99         }
100
101         /*
102          * Create an environment object initialized for error reporting, and
103          * then open it.
104          */
105         if (env_create(&dbenv, &ldg) != 0)
106                 goto err;
107
108         /* If we're resetting the LSNs, that's an entirely separate path. */
109         switch (mode) {
110         case FILEID_RESET:
111                 exitval = dbenv->fileid_reset(dbenv, argv[0], 0);
112                 break;
113         case LSN_RESET:
114                 exitval = dbenv->lsn_reset(dbenv, argv[0], 0);
115                 break;
116         case NOTSET:
117                 break;
118         }
119
120         if (0) {
121 err:            exitval = 1;
122         }
123         if ((ret = dbenv->close(dbenv, 0)) != 0) {
124                 exitval = 1;
125                 fprintf(stderr,
126                     "%s: dbenv->close: %s\n", ldg.progname, db_strerror(ret));
127         }
128
129         if (ldg.passwd != NULL)
130                 free(ldg.passwd);
131
132 done:
133         return (exitval);
134 }
135
136 /*
137  * env_create --
138  *      Create the environment and initialize it for error reporting.
139  */
140 int
141 env_create(dbenvp, ldg)
142         DB_ENV **dbenvp;
143         LDG *ldg;
144 {
145         DB_ENV *dbenv;
146         int ret;
147
148         if ((ret = db_env_create(dbenvp, 0)) != 0) {
149                 fprintf(stderr, "%s: db_env_create: %s\n",
150                     ldg->progname, db_strerror(ret));
151                 return (ret);
152         }
153         dbenv = *dbenvp;
154         dbenv->set_errfile(dbenv, stderr);
155         dbenv->set_errpfx(dbenv, ldg->progname);
156         if (ldg->passwd != NULL && (ret = dbenv->set_encrypt(dbenv,
157             ldg->passwd, DB_ENCRYPT_AES)) != 0) {
158                 dbenv->err(dbenv, ret, "set_passwd");
159                 return (ret);
160         }
161         if ((ret = db_init(dbenv, ldg->home, ldg->cache, &ldg->private)) != 0)
162                 return (ret);
163         dbenv->app_private = ldg;
164
165         return (0);
166 }
167
168 /*
169  * db_init --
170  *      Initialize the environment.
171  */
172 int
173 db_init(dbenv, home, cache, is_private)
174         DB_ENV *dbenv;
175         char *home;
176         u_int32_t cache;
177         int *is_private;
178 {
179         u_int32_t flags;
180         int ret;
181
182         *is_private = 0;
183         /* We may be loading into a live environment.  Try and join. */
184         flags = DB_USE_ENVIRON |
185             DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN;
186         if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0)
187                 return (0);
188         if (ret == DB_VERSION_MISMATCH)
189                 goto err;
190
191         /*
192          * We're trying to load a database.
193          *
194          * An environment is required because we may be trying to look at
195          * databases in directories other than the current one.  We could
196          * avoid using an environment iff the -h option wasn't specified,
197          * but that seems like more work than it's worth.
198          *
199          * No environment exists (or, at least no environment that includes
200          * an mpool region exists).  Create one, but make it private so that
201          * no files are actually created.
202          */
203 #define LF_SET(f)       ((flags) |= (f))
204 #define LF_CLR(f)       ((flags) &= ~(f))
205         LF_CLR(DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN);
206         LF_SET(DB_CREATE | DB_PRIVATE);
207         *is_private = 1;
208         if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) {
209                 dbenv->err(dbenv, ret, "set_cachesize");
210                 return (1);
211         }
212         if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0)
213                 return (0);
214
215         /* An environment is required. */
216 err:    dbenv->err(dbenv, ret, "DB_ENV->open");
217         return (1);
218 }
219
220 /*
221  * usage --
222  *      Display the usage message.
223  */
224 int
225 usage()
226 {
227         (void)fprintf(stderr, "usage: %s %s\n\t%s %s\n",
228             progname, "[-V]",
229             progname, "-r lsn | fileid [-h home] db_file");
230         return (EXIT_FAILURE);
231 }
232
233 int
234 version_check()
235 {
236         int v_major, v_minor, v_patch;
237
238         /* Make sure we're loaded with the right version of the DB library. */
239         (void)db_version(&v_major, &v_minor, &v_patch);
240         if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) {
241                 fprintf(stderr,
242                     "%s: version %d.%d doesn't match library version %d.%d\n",
243                     progname, DB_VERSION_MAJOR,
244                     DB_VERSION_MINOR, v_major, v_minor);
245                 return (EXIT_FAILURE);
246         }
247         return (0);
248 }
This page took 0.041635 seconds and 3 git commands to generate.