/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ int poptGetNextOpt(poptContext con) { const struct poptOption * opt = NULL; int done = 0; if (con == NULL) return -1; while (!done) { const char * origOptString = NULL; poptCallbackType cb = NULL; const void * cbData = NULL; const char * longArg = NULL; int canstrip = 0; int shorty = 0; while (!con->os->nextCharArg && con->os->next == con->os->argc && con->os > con->optionStack) { cleanOSE(con->os--); } if (!con->os->nextCharArg && con->os->next == con->os->argc) { /*@-internalglobs@*/ invokeCallbacksPOST(con, con->options); /*@=internalglobs@*/ if (con->doExec) return execCommand(con); return -1; } /* Process next long option */ if (!con->os->nextCharArg) { char * localOptString, * optString; int thisopt; /*@-sizeoftype@*/ if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) { con->os->next++; continue; } /*@=sizeoftype@*/ thisopt = con->os->next; if (con->os->argv != NULL) /* XXX can't happen */ origOptString = con->os->argv[con->os->next++]; if (origOptString == NULL) /* XXX can't happen */ return POPT_ERROR_BADOPT; if (con->restLeftover || *origOptString != '-') { if (con->flags & POPT_CONTEXT_POSIXMEHARDER) con->restLeftover = 1; if (con->flags & POPT_CONTEXT_ARG_OPTS) { con->os->nextArg = xstrdup(origOptString); return 0; } if (con->leftovers != NULL) /* XXX can't happen */ con->leftovers[con->numLeftovers++] = origOptString; continue; } /* Make a copy we can hack at */ localOptString = optString = strcpy((char *)alloca(strlen(origOptString) + 1), origOptString); if (optString[0] == '\0') return POPT_ERROR_BADOPT; if (optString[1] == '-' && !optString[2]) { con->restLeftover = 1; continue; } else { char *oe; int singleDash; optString++; if (*optString == '-') singleDash = 0, optString++; else singleDash = 1; /* XXX aliases with arg substitution need "--alias=arg" */ if (handleAlias(con, optString, '\0', NULL)) continue; if (handleExec(con, optString, '\0')) continue; /* Check for "--long=arg" option. */ for (oe = optString; *oe && *oe != '='; oe++) {}; if (*oe == '=') { *oe++ = '\0'; /* XXX longArg is mapped back to persistent storage. */ longArg = origOptString + (oe - localOptString); } opt = findOption(con->options, optString, '\0', &cb, &cbData, singleDash); if (!opt && !singleDash) return POPT_ERROR_BADOPT; } if (!opt) { con->os->nextCharArg = origOptString + 1; } else { if (con->os == con->optionStack && opt->argInfo & POPT_ARGFLAG_STRIP) { canstrip = 1; poptStripArg(con, thisopt); } shorty = 0; } } /* Process next short option */ /*@-branchstate@*/ /* FIX: W2DO? */ if (con->os->nextCharArg) { origOptString = con->os->nextCharArg; con->os->nextCharArg = NULL; if (handleAlias(con, NULL, *origOptString, origOptString + 1)) continue; if (handleExec(con, NULL, *origOptString)) { /* Restore rest of short options for further processing */ origOptString++; if (*origOptString != '\0') con->os->nextCharArg = origOptString; continue; } opt = findOption(con->options, NULL, *origOptString, &cb, &cbData, 0); if (!opt) return POPT_ERROR_BADOPT; shorty = 1; origOptString++; if (*origOptString != '\0') con->os->nextCharArg = origOptString; } /*@=branchstate@*/ if (opt == NULL) return POPT_ERROR_BADOPT; /* XXX can't happen */ if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) { if (poptSaveInt((int *)opt->arg, opt->argInfo, 1L)) return POPT_ERROR_BADOPERATION; } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) { if (opt->arg) { if (poptSaveInt((int *)opt->arg, opt->argInfo, (long)opt->val)) return POPT_ERROR_BADOPERATION; } } else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { con->os->nextArg = (const char *)_free(con->os->nextArg); /*@-usedef@*/ /* FIX: W2DO? */ if (longArg) { /*@=usedef@*/ longArg = expandNextArg(con, longArg); con->os->nextArg = longArg; } else if (con->os->nextCharArg) { longArg = expandNextArg(con, con->os->nextCharArg); con->os->nextArg = longArg; con->os->nextCharArg = NULL; } else { while (con->os->next == con->os->argc && con->os > con->optionStack) { cleanOSE(con->os--); } if (con->os->next == con->os->argc) { if (!(opt->argInfo & POPT_ARGFLAG_OPTIONAL)) /*@-compdef@*/ /* FIX: con->os->argv not defined */ return POPT_ERROR_NOARG; /*@=compdef@*/ con->os->nextArg = NULL; } else { /* * Make sure this isn't part of a short arg or the * result of an alias expansion. */ if (con->os == con->optionStack && (opt->argInfo & POPT_ARGFLAG_STRIP) && canstrip) { poptStripArg(con, con->os->next); } if (con->os->argv != NULL) { /* XXX can't happen */ /* XXX watchout: subtle side-effects live here. */ longArg = con->os->argv[con->os->next++]; longArg = expandNextArg(con, longArg); con->os->nextArg = longArg; } } } longArg = NULL; if (opt->arg) { switch (opt->argInfo & POPT_ARG_MASK) { case POPT_ARG_STRING: /* XXX memory leak, hard to plug */ *((const char **) opt->arg) = (con->os->nextArg) ? xstrdup(con->os->nextArg) : NULL; /*@switchbreak@*/ break; case POPT_ARG_INT: case POPT_ARG_LONG: { long aLong = 0; char *end; if (con->os->nextArg) { aLong = strtol(con->os->nextArg, &end, 0); if (!(end && *end == '\0')) return POPT_ERROR_BADNUMBER; } if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) { if (aLong == LONG_MIN || aLong == LONG_MAX) return POPT_ERROR_OVERFLOW; if (poptSaveLong((long *)opt->arg, opt->argInfo, aLong)) return POPT_ERROR_BADOPERATION; } else { if (aLong > INT_MAX || aLong < INT_MIN) return POPT_ERROR_OVERFLOW; if (poptSaveInt((int *)opt->arg, opt->argInfo, aLong)) return POPT_ERROR_BADOPERATION; } } /*@switchbreak@*/ break; case POPT_ARG_FLOAT: case POPT_ARG_DOUBLE: { double aDouble = 0.0; char *end; if (con->os->nextArg) { /*@-mods@*/ int saveerrno = errno; errno = 0; aDouble = strtod(con->os->nextArg, &end); if (errno == ERANGE) return POPT_ERROR_OVERFLOW; errno = saveerrno; /*@=mods@*/ if (*end != '\0') return POPT_ERROR_BADNUMBER; } if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_DOUBLE) { *((double *) opt->arg) = aDouble; } else { #ifndef _ABS #define _ABS(a) ((((a) - 0.0) < 0xff) ? -(a) : (a)) #endif } } /*@switchbreak@*/ break; default: fprintf(stdout, POPT_("option type (%d) not implemented in popt\n"), (opt->argInfo & POPT_ARG_MASK)); exit(EXIT_FAILURE); /*@notreached@*/ /*@switchbreak@*/ break; } } } if (cb) { /*@-internalglobs@*/ invokeCallbacksOPTION(con, con->options, opt, cbData, shorty); /*@=internalglobs@*/ } else if (opt->val && ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)) done = 1; if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) { con->finalArgvAlloced += 10; con->finalArgv = (const char **)realloc(con->finalArgv, sizeof(*con->finalArgv) * con->finalArgvAlloced); } if (con->finalArgv != NULL) { char *s = (char *)malloc( (opt->longName ? strlen(opt->longName) : 0) + 3); if (s != NULL) { /* XXX can't happen */ if (opt->longName) sprintf(s, "%s%s", ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"), opt->longName); else sprintf(s, "-%c", opt->shortName); con->finalArgv[con->finalArgvCount++] = s; } else con->finalArgv[con->finalArgvCount++] = NULL; } if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) /*@-ifempty@*/ ; /*@=ifempty@*/ else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) /*@-ifempty@*/ ; /*@=ifempty@*/ else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { if (con->finalArgv != NULL && con->os->nextArg) con->finalArgv[con->finalArgvCount++] = /*@-nullpass@*/ /* LCL: con->os->nextArg != NULL */ xstrdup(con->os->nextArg); /*@=nullpass@*/ } } return (opt ? opt->val : -1); /* XXX can't happen */ }
static void dbConfigure(rpmDbiTagVal rpmtag, struct dbConfig_s *cfg, struct dbiConfig_s *dbicfg) { char *dbOpts; dbOpts = rpmExpand("%{_dbi_config_", rpmTagGetName(rpmtag), "}", NULL); if (!(dbOpts && *dbOpts && *dbOpts != '%')) { dbOpts = _free(dbOpts); dbOpts = rpmExpand("%{_dbi_config}", NULL); if (!(dbOpts && *dbOpts && *dbOpts != '%')) { dbOpts = _free(dbOpts); } } /* Parse the options for the database element(s). */ if (dbOpts && *dbOpts && *dbOpts != '%') { char *o, *oe; char *p, *pe; memset(&staticdbicfg, 0, sizeof(staticdbicfg)); /*=========*/ for (o = dbOpts; o && *o; o = oe) { const struct poptOption *opt; const char * tok; unsigned int argInfo; /* Skip leading white space. */ while (*o && risspace(*o)) o++; /* Find and terminate next key=value pair. Save next start point. */ for (oe = o; oe && *oe; oe++) { if (risspace(*oe)) break; if (oe[0] == ':' && !(oe[1] == '/' && oe[2] == '/')) break; } if (oe && *oe) *oe++ = '\0'; if (*o == '\0') continue; /* Separate key from value, save value start (if any). */ for (pe = o; pe && *pe && *pe != '='; pe++) {}; p = (pe ? *pe++ = '\0', pe : NULL); /* Skip over negation at start of token. */ for (tok = o; *tok == '!'; tok++) {}; /* Find key in option table. */ for (opt = rdbOptions; opt->longName != NULL; opt++) { if (!rstreq(tok, opt->longName)) continue; break; } if (opt->longName == NULL) { rpmlog(RPMLOG_ERR, _("unrecognized db option: \"%s\" ignored.\n"), o); continue; } /* Toggle the flags for negated tokens, if necessary. */ argInfo = opt->argInfo; if (argInfo == POPT_BIT_SET && *o == '!' && ((tok - o) % 2)) argInfo = POPT_BIT_CLR; /* Save value in template as appropriate. */ switch (argInfo & POPT_ARG_MASK) { case POPT_ARG_NONE: (void) poptSaveInt((int *)opt->arg, argInfo, 1L); break; case POPT_ARG_VAL: (void) poptSaveInt((int *)opt->arg, argInfo, (long)opt->val); break; case POPT_ARG_STRING: { char ** t = opt->arg; if (t) { /* FIX: opt->arg annotation in popt.h */ *t = _free(*t); *t = xstrdup( (p ? p : "") ); } } break; case POPT_ARG_INT: case POPT_ARG_LONG: { long aLong = strtol(p, &pe, 0); if (pe) { if (!rstrncasecmp(pe, "Mb", 2)) aLong *= 1024 * 1024; else if (!rstrncasecmp(pe, "Kb", 2)) aLong *= 1024; else if (*pe != '\0') { rpmlog(RPMLOG_ERR, _("%s has invalid numeric value, skipped\n"), opt->longName); continue; } } if ((argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) { if (aLong == LONG_MIN || aLong == LONG_MAX) { rpmlog(RPMLOG_ERR, _("%s has too large or too small long value, skipped\n"), opt->longName); continue; } (void) poptSaveLong((long *)opt->arg, argInfo, aLong); break; } else { if (aLong > INT_MAX || aLong < INT_MIN) { rpmlog(RPMLOG_ERR, _("%s has too large or too small integer value, skipped\n"), opt->longName); continue; } (void) poptSaveInt((int *)opt->arg, argInfo, aLong); } } break; default: break; } } /*=========*/ } dbOpts = _free(dbOpts); if (cfg) { *cfg = staticcfg; /* structure assignment */ /* Throw in some defaults if configuration didn't set any */ if (!cfg->db_mmapsize) cfg->db_mmapsize = 16 * 1024 * 1024; if (!cfg->db_cachesize) cfg->db_cachesize = 8 * 1024 * 1024; } if (dbicfg) { *dbicfg = staticdbicfg; } }