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