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 #ifndef WITH_EXTERNAL_DB
75 { "nofsync", 0,POPT_BIT_SET, &staticdbi.dbi_oflags, DB_NOFSYNC,
82 dbiIndex dbiFree(dbiIndex dbi)
90 dbiIndex dbiNew(rpmdb rdb, rpmDbiTagVal rpmtag)
92 dbiIndex dbi = xcalloc(1, sizeof(*dbi));
95 dbOpts = rpmExpand("%{_dbi_config_", rpmTagGetName(rpmtag), "}", NULL);
97 if (!(dbOpts && *dbOpts && *dbOpts != '%')) {
98 dbOpts = _free(dbOpts);
99 dbOpts = rpmExpand("%{_dbi_config}", NULL);
100 if (!(dbOpts && *dbOpts && *dbOpts != '%')) {
101 dbOpts = _free(dbOpts);
105 /* Parse the options for the database element(s). */
106 if (dbOpts && *dbOpts && *dbOpts != '%') {
110 memset(&staticdbi, 0, sizeof(staticdbi));
112 for (o = dbOpts; o && *o; o = oe) {
113 const struct poptOption *opt;
115 unsigned int argInfo;
117 /* Skip leading white space. */
118 while (*o && risspace(*o))
121 /* Find and terminate next key=value pair. Save next start point. */
122 for (oe = o; oe && *oe; oe++) {
125 if (oe[0] == ':' && !(oe[1] == '/' && oe[2] == '/'))
133 /* Separate key from value, save value start (if any). */
134 for (pe = o; pe && *pe && *pe != '='; pe++)
136 p = (pe ? *pe++ = '\0', pe : NULL);
138 /* Skip over negation at start of token. */
139 for (tok = o; *tok == '!'; tok++)
142 /* Find key in option table. */
143 for (opt = rdbOptions; opt->longName != NULL; opt++) {
144 if (!rstreq(tok, opt->longName))
148 if (opt->longName == NULL) {
150 _("unrecognized db option: \"%s\" ignored.\n"), o);
154 /* Toggle the flags for negated tokens, if necessary. */
155 argInfo = opt->argInfo;
156 if (argInfo == POPT_BIT_SET && *o == '!' && ((tok - o) % 2))
157 argInfo = POPT_BIT_CLR;
159 /* Save value in template as appropriate. */
160 switch (argInfo & POPT_ARG_MASK) {
163 (void) poptSaveInt((int *)opt->arg, argInfo, 1L);
166 (void) poptSaveInt((int *)opt->arg, argInfo, (long)opt->val);
168 case POPT_ARG_STRING:
169 { char ** t = opt->arg;
171 /* FIX: opt->arg annotation in popt.h */
173 *t = xstrdup( (p ? p : "") );
179 { long aLong = strtol(p, &pe, 0);
181 if (!rstrncasecmp(pe, "Mb", 2))
182 aLong *= 1024 * 1024;
183 else if (!rstrncasecmp(pe, "Kb", 2))
185 else if (*pe != '\0') {
187 _("%s has invalid numeric value, skipped\n"),
193 if ((argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) {
194 if (aLong == LONG_MIN || aLong == LONG_MAX) {
196 _("%s has too large or too small long value, skipped\n"),
200 (void) poptSaveLong((long *)opt->arg, argInfo, aLong);
203 if (aLong > INT_MAX || aLong < INT_MIN) {
205 _("%s has too large or too small integer value, skipped\n"),
209 (void) poptSaveInt((int *)opt->arg, argInfo, aLong);
219 dbOpts = _free(dbOpts);
221 *dbi = staticdbi; /* structure assignment */
222 memset(&staticdbi, 0, sizeof(staticdbi));
224 /* FIX: figger lib/dbi refcounts */
225 dbi->dbi_rpmdb = rdb;
226 dbi->dbi_file = rpmTagGetName(rpmtag);
227 dbi->dbi_type = (rpmtag == RPMDBI_PACKAGES) ? DBI_PRIMARY : DBI_SECONDARY;
228 dbi->dbi_byteswapped = -1; /* -1 unknown, 0 native order, 1 alien order */
230 /* XXX FIXME: Get environment configuration out of here! */
231 if (rdb->db_dbenv == NULL) {
232 struct dbConfig_s * cfg = &rdb->cfg;
233 *cfg = staticcfg; /* structure assignment */
234 /* Throw in some defaults if configuration didn't set any */
235 if (!cfg->db_mmapsize) cfg->db_mmapsize = 16 * 1024 * 1024;
236 if (!cfg->db_cachesize) cfg->db_cachesize = 8 * 1024 * 1024;
239 /* FIX: *(rdbOptions->arg) reachable */
243 char * prDbiOpenFlags(int dbflags, int print_dbenv_flags)
246 const struct poptOption *opt;
249 for (opt = rdbOptions; opt->longName != NULL; opt++) {
250 if (opt->argInfo != POPT_BIT_SET)
252 if (print_dbenv_flags) {
253 if (!(opt->arg == &db_eflags))
256 if (!(opt->arg == &staticdbi.dbi_oflags))
259 if ((dbflags & opt->val) != opt->val)
261 argvAdd(&flags, opt->longName);
262 dbflags &= ~opt->val;
266 rasprintf(&df, "0x%x", (unsigned)dbflags);
270 buf = argvJoin(flags, ":");
273 return buf ? buf : xstrdup("(none)");