276da39af9
Approved by: roberto, delphij Security: VuXML: 0d0f3050-1f69-11e5-9ba9-d050996490d0 Security: http://bugs.ntp.org/show_bug.cgi?id=2853 Security: https://www.kb.cert.org/vuls/id/668167 Security: http://support.ntp.org/bin/view/Main/SecurityNotice#June_2015_NTP_Security_Vulnerabi
180 lines
5.1 KiB
C
180 lines
5.1 KiB
C
|
|
/**
|
|
* \file numeric.c
|
|
*
|
|
* Handle options with numeric (integer) arguments.
|
|
*
|
|
* @addtogroup autoopts
|
|
* @{
|
|
*/
|
|
/*
|
|
* This file is part of AutoOpts, a companion to AutoGen.
|
|
* AutoOpts is free software.
|
|
* AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
|
|
*
|
|
* AutoOpts is available under any one of two licenses. The license
|
|
* in use must be one of these two and the choice is under the control
|
|
* of the user of the license.
|
|
*
|
|
* The GNU Lesser General Public License, version 3 or later
|
|
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
|
*
|
|
* The Modified Berkeley Software Distribution License
|
|
* See the file "COPYING.mbsd"
|
|
*
|
|
* These files have the following sha256 sums:
|
|
*
|
|
* 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
|
|
* 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
|
|
* 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
|
|
*/
|
|
|
|
/*=export_func optionShowRange
|
|
* private:
|
|
*
|
|
* what: Show info about range constraints
|
|
* arg: + tOptions * + pOpts + program options descriptor +
|
|
* arg: + tOptDesc * + pOptDesc + the descriptor for this arg +
|
|
* arg: + void * + rng_table + the value range tables +
|
|
* arg: + int + rng_count + the number of entries +
|
|
*
|
|
* doc:
|
|
* Show information about a numeric option with range constraints.
|
|
=*/
|
|
void
|
|
optionShowRange(tOptions * pOpts, tOptDesc * pOD, void * rng_table, int rng_ct)
|
|
{
|
|
const struct {long const rmin, rmax;} * rng = rng_table;
|
|
|
|
char const * pz_indent = zTabHyp + tab_skip_ct;
|
|
|
|
/*
|
|
* The range is shown only for full usage requests and an error
|
|
* in this particular option.
|
|
*/
|
|
if (pOpts != OPTPROC_EMIT_USAGE) {
|
|
if (pOpts <= OPTPROC_EMIT_LIMIT)
|
|
return;
|
|
pz_indent = ONE_TAB_STR;
|
|
|
|
fprintf(option_usage_fp, zRangeErr, pOpts->pzProgName,
|
|
pOD->pz_Name, pOD->optArg.argInt);
|
|
pz_indent = "";
|
|
}
|
|
|
|
if (pOD->fOptState & OPTST_SCALED_NUM)
|
|
fprintf(option_usage_fp, zRangeScaled, pz_indent);
|
|
|
|
fprintf(option_usage_fp, (rng_ct > 1) ? zRangeLie : zRangeOnly, pz_indent);
|
|
pz_indent = (pOpts != OPTPROC_EMIT_USAGE)
|
|
? ONE_TAB_STR
|
|
: (zTabSpace + tab_skip_ct);
|
|
|
|
for (;;) {
|
|
if (rng->rmax == LONG_MIN)
|
|
fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin);
|
|
else if (rng->rmin == LONG_MIN)
|
|
fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax);
|
|
else if (rng->rmax == LONG_MAX)
|
|
fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin);
|
|
else
|
|
fprintf(option_usage_fp, zRange, pz_indent, rng->rmin,
|
|
rng->rmax);
|
|
|
|
if (--rng_ct <= 0) {
|
|
fputc(NL, option_usage_fp);
|
|
break;
|
|
}
|
|
fputs(zRangeOr, option_usage_fp);
|
|
rng++;
|
|
}
|
|
|
|
if (pOpts > OPTPROC_EMIT_LIMIT)
|
|
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
|
|
}
|
|
|
|
/*=export_func optionNumericVal
|
|
* private:
|
|
*
|
|
* what: process an option with a numeric value.
|
|
* arg: + tOptions * + opts + program options descriptor +
|
|
* arg: + tOptDesc * + od + the descriptor for this arg +
|
|
*
|
|
* doc:
|
|
* Decipher a numeric value.
|
|
=*/
|
|
void
|
|
optionNumericVal(tOptions * opts, tOptDesc * od)
|
|
{
|
|
char * pz;
|
|
long val;
|
|
|
|
/*
|
|
* Guard against all the different ways this procedure might get invoked
|
|
* when there is no string argument provided.
|
|
*/
|
|
if (INQUERY_CALL(opts, od) || (od->optArg.argString == NULL))
|
|
return;
|
|
|
|
/*
|
|
* Numeric options may have a range associated with it.
|
|
* If it does, the usage procedure requests that it be
|
|
* emitted by passing a NULL od pointer. Also bail out
|
|
* if there is no option argument or if we are being reset.
|
|
*/
|
|
if ( (od == NULL)
|
|
|| (od->optArg.argString == NULL)
|
|
|| ((od->fOptState & OPTST_RESET) != 0))
|
|
return;
|
|
|
|
errno = 0;
|
|
val = strtol(od->optArg.argString, &pz, 0);
|
|
if ((pz == od->optArg.argString) || (errno != 0))
|
|
goto bad_number;
|
|
|
|
if ((od->fOptState & OPTST_SCALED_NUM) != 0)
|
|
switch (*(pz++)) {
|
|
case NUL: pz--; break;
|
|
case 't': val *= 1000;
|
|
case 'g': val *= 1000;
|
|
case 'm': val *= 1000;
|
|
case 'k': val *= 1000; break;
|
|
|
|
case 'T': val *= 1024;
|
|
case 'G': val *= 1024;
|
|
case 'M': val *= 1024;
|
|
case 'K': val *= 1024; break;
|
|
|
|
default: goto bad_number;
|
|
}
|
|
|
|
if (*pz != NUL)
|
|
goto bad_number;
|
|
|
|
if (od->fOptState & OPTST_ALLOC_ARG) {
|
|
AGFREE(od->optArg.argString);
|
|
od->fOptState &= ~OPTST_ALLOC_ARG;
|
|
}
|
|
|
|
od->optArg.argInt = val;
|
|
return;
|
|
|
|
bad_number:
|
|
|
|
fprintf( stderr, zNotNumber, opts->pzProgName, od->optArg.argString );
|
|
if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
|
|
(*(opts->pUsageProc))(opts, EXIT_FAILURE);
|
|
|
|
errno = EINVAL;
|
|
od->optArg.argInt = ~0;
|
|
}
|
|
|
|
/** @}
|
|
*
|
|
* Local Variables:
|
|
* mode: C
|
|
* c-file-style: "stroustrup"
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
* end of autoopts/numeric.c */
|