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