9 #include <rpm/rpmtypes.h>
10 #include <rpm/rpmmacro.h>
11 #include <rpm/rpmstring.h>
12 #include <rpm/rpmlog.h>
14 #include "lib/rpmdb_internal.h"
17 static struct dbiIndex_s staticdbi;
18 static struct dbConfig_s staticcfg;
23 static const struct poptOption rdbOptions[] = {
24 /* Environment options */
26 { "cdb", 0,POPT_BIT_SET, &db_eflags, DB_INIT_CDB,
28 { "lock", 0,POPT_BIT_SET, &db_eflags, DB_INIT_LOCK,
30 { "log", 0,POPT_BIT_SET, &db_eflags, DB_INIT_LOG,
32 { "txn", 0,POPT_BIT_SET, &db_eflags, DB_INIT_TXN,
34 { "recover", 0,POPT_BIT_SET, &db_eflags, DB_RECOVER,
36 { "recover_fatal", 0,POPT_BIT_SET, &db_eflags, DB_RECOVER_FATAL,
38 { "lockdown", 0,POPT_BIT_SET, &db_eflags, DB_LOCKDOWN,
40 { "private", 0,POPT_BIT_SET, &db_eflags, DB_PRIVATE,
43 { "deadlock", 0,POPT_BIT_SET, &staticcfg.db_verbose, DB_VERB_DEADLOCK,
45 { "recovery", 0,POPT_BIT_SET, &staticcfg.db_verbose, DB_VERB_RECOVERY,
47 { "waitsfor", 0,POPT_BIT_SET, &staticcfg.db_verbose, DB_VERB_WAITSFOR,
49 { "verbose", 0,POPT_ARG_VAL, &staticcfg.db_verbose, -1,
52 { "cachesize", 0,POPT_ARG_INT, &staticcfg.db_cachesize, 0,
54 { "mmapsize", 0,POPT_ARG_INT, &staticcfg.db_mmapsize, 0,
56 { "mp_mmapsize", 0,POPT_ARG_INT, &staticcfg.db_mmapsize, 0,
58 { "mp_size", 0,POPT_ARG_INT, &staticcfg.db_cachesize, 0,
62 { "nofsync", 0,POPT_ARG_NONE, &staticcfg.db_no_fsync, 0,
67 { "nommap", 0,POPT_BIT_SET, &staticdbi.dbi_oflags, DB_NOMMAP,
70 { "nodbsync", 0,POPT_ARG_NONE, &staticdbi.dbi_no_dbsync, 0,
72 { "lockdbfd", 0,POPT_ARG_NONE, &staticdbi.dbi_lockdbfd, 0,
74 { "nofsync", 0,POPT_BIT_SET, &staticdbi.dbi_oflags, DB_NOFSYNC,
80 dbiIndex dbiFree(dbiIndex dbi)
88 dbiIndex dbiNew(rpmdb rdb, rpmDbiTagVal rpmtag)
90 dbiIndex dbi = xcalloc(1, sizeof(*dbi));
93 dbOpts = rpmExpand("%{_dbi_config_", rpmTagGetName(rpmtag), "}", NULL);
95 if (!(dbOpts && *dbOpts && *dbOpts != '%')) {
96 dbOpts = _free(dbOpts);
97 dbOpts = rpmExpand("%{_dbi_config}", NULL);
98 if (!(dbOpts && *dbOpts && *dbOpts != '%')) {
99 dbOpts = _free(dbOpts);
103 /* Parse the options for the database element(s). */
104 if (dbOpts && *dbOpts && *dbOpts != '%') {
108 memset(&staticdbi, 0, sizeof(staticdbi));
110 for (o = dbOpts; o && *o; o = oe) {
111 const struct poptOption *opt;
113 unsigned int argInfo;
115 /* Skip leading white space. */
116 while (*o && risspace(*o))
119 /* Find and terminate next key=value pair. Save next start point. */
120 for (oe = o; oe && *oe; oe++) {
123 if (oe[0] == ':' && !(oe[1] == '/' && oe[2] == '/'))
131 /* Separate key from value, save value start (if any). */
132 for (pe = o; pe && *pe && *pe != '='; pe++)
134 p = (pe ? *pe++ = '\0', pe : NULL);
136 /* Skip over negation at start of token. */
137 for (tok = o; *tok == '!'; tok++)
140 /* Find key in option table. */
141 for (opt = rdbOptions; opt->longName != NULL; opt++) {
142 if (!rstreq(tok, opt->longName))
146 if (opt->longName == NULL) {
148 _("unrecognized db option: \"%s\" ignored.\n"), o);
152 /* Toggle the flags for negated tokens, if necessary. */
153 argInfo = opt->argInfo;
154 if (argInfo == POPT_BIT_SET && *o == '!' && ((tok - o) % 2))
155 argInfo = POPT_BIT_CLR;
157 /* Save value in template as appropriate. */
158 switch (argInfo & POPT_ARG_MASK) {
161 (void) poptSaveInt((int *)opt->arg, argInfo, 1L);
164 (void) poptSaveInt((int *)opt->arg, argInfo, (long)opt->val);
166 case POPT_ARG_STRING:
167 { char ** t = opt->arg;
169 /* FIX: opt->arg annotation in popt.h */
171 *t = xstrdup( (p ? p : "") );
177 { long aLong = strtol(p, &pe, 0);
179 if (!rstrncasecmp(pe, "Mb", 2))
180 aLong *= 1024 * 1024;
181 else if (!rstrncasecmp(pe, "Kb", 2))
183 else if (*pe != '\0') {
185 _("%s has invalid numeric value, skipped\n"),
191 if ((argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) {
192 if (aLong == LONG_MIN || aLong == LONG_MAX) {
194 _("%s has too large or too small long value, skipped\n"),
198 (void) poptSaveLong((long *)opt->arg, argInfo, aLong);
201 if (aLong > INT_MAX || aLong < INT_MIN) {
203 _("%s has too large or too small integer value, skipped\n"),
207 (void) poptSaveInt((int *)opt->arg, argInfo, aLong);
217 dbOpts = _free(dbOpts);
219 *dbi = staticdbi; /* structure assignment */
220 memset(&staticdbi, 0, sizeof(staticdbi));
222 /* FIX: figger lib/dbi refcounts */
223 dbi->dbi_rpmdb = rdb;
224 dbi->dbi_file = rpmTagGetName(rpmtag);
225 dbi->dbi_type = (rpmtag == RPMDBI_PACKAGES) ? DBI_PRIMARY : DBI_SECONDARY;
226 dbi->dbi_byteswapped = -1; /* -1 unknown, 0 native order, 1 alien order */
228 /* XXX FIXME: Get environment configuration out of here! */
229 if (rdb->db_dbenv == NULL) {
230 struct dbConfig_s * cfg = &rdb->cfg;
231 *cfg = staticcfg; /* structure assignment */
232 /* Throw in some defaults if configuration didn't set any */
233 if (!cfg->db_mmapsize) cfg->db_mmapsize = 16 * 1024 * 1024;
234 if (!cfg->db_cachesize) cfg->db_cachesize = 8 * 1024 * 1024;
237 /* FIX: *(rdbOptions->arg) reachable */
241 char * prDbiOpenFlags(int dbflags, int print_dbenv_flags)
244 const struct poptOption *opt;
247 for (opt = rdbOptions; opt->longName != NULL; opt++) {
248 if (opt->argInfo != POPT_BIT_SET)
250 if (print_dbenv_flags) {
251 if (!(opt->arg == &db_eflags))
254 if (!(opt->arg == &staticdbi.dbi_oflags))
257 if ((dbflags & opt->val) != opt->val)
259 argvAdd(&flags, opt->longName);
260 dbflags &= ~opt->val;
264 rasprintf(&df, "0x%x", (unsigned)dbflags);
268 buf = argvJoin(flags, ":");
271 return buf ? buf : xstrdup("(none)");