Use strtonum-like functions for parsing numeric arguments

This commit is contained in:
Lucas 2020-06-14 15:15:29 +00:00
parent 55b0b396dc
commit 9a5f0f724e
4 changed files with 90 additions and 13 deletions

View File

@ -17,8 +17,8 @@
P = otpcli
V = 0.0
HDR = err.h otp.h
OBJ = cli.o err.o otp.o
HDR = err.h mystrtonum.h otp.h
OBJ = cli.o err.o mystrtonum.o otp.o
SRC = ${OBJ:.o=.c}
DIST_FILES = COPYING Makefile ${HDR} ${SRC}

16
cli.c
View File

@ -22,6 +22,7 @@
#include <unistd.h>
#include "err.h"
#include "mystrtonum.h"
#include "otp.h"
extern const char *__progname;
@ -36,8 +37,7 @@ usage(void)
int
main(int argc, char *argv[])
{
char *end;
uintmax_t n;
const char *errstr;
uint64_t counter;
int32_t r;
int ch, do_hotp;
@ -47,15 +47,9 @@ main(int argc, char *argv[])
while ((ch = getopt(argc, argv, "H:")) != -1) {
switch (ch) {
case 'H':
errno = 0;
n = strtoumax(optarg, &end, 0);
if (*optarg == '\0' || *end != '\0')
errx(1, "-H: not a number");
if (errno != 0)
err(1, "-H");
else if (n > UINT64_MAX)
errx(1, "-H: out of range");
counter = n;
counter = mystrtonum(optarg, 0, LLONG_MAX, &errstr);
if (errstr != NULL)
errx(1, "counter is %s: %s", errstr, optarg);
do_hotp = 1;
break;
default:

67
mystrtonum.c Normal file
View File

@ -0,0 +1,67 @@
/* This is OpenBSD's strtonum(3), renamed to mystrtonum */
/* $OpenBSD: strtonum.c,v 1.8 2015/09/13 08:31:48 guenther Exp $ */
/*
* Copyright (c) 2004 Ted Unangst and Todd Miller
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#define INVALID 1
#define TOOSMALL 2
#define TOOLARGE 3
long long
mystrtonum(const char *numstr, long long minval, long long maxval,
const char **errstrp)
{
long long ll = 0;
int error = 0;
char *ep;
struct errval {
const char *errstr;
int err;
} ev[4] = {
{ NULL, 0 },
{ "invalid", EINVAL },
{ "too small", ERANGE },
{ "too large", ERANGE },
};
ev[0].err = errno;
errno = 0;
if (minval > maxval) {
error = INVALID;
} else {
ll = strtoll(numstr, &ep, 10);
if (numstr == ep || *ep != '\0')
error = INVALID;
else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
error = TOOSMALL;
else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
error = TOOLARGE;
}
if (errstrp != NULL)
*errstrp = ev[error].errstr;
errno = ev[error].err;
if (error)
ll = 0;
return (ll);
}

16
mystrtonum.h Normal file
View File

@ -0,0 +1,16 @@
/*
* libutil - C utility functions
*
* Written in 2020 by Lucas
*
* To the extent possible under law, the author(s) have dedicated all
* copyright and related and neighboring rights to this software to the
* public domain worldwide. This software is distributed without any
* warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication
* along with this software. If not, see
* <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
long long mystrtonum(const char *, long long, long long, const char **);