summaryrefslogtreecommitdiffstats
path: root/sbin/sysctl
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2014-09-26 05:05:34 +0000
committerdelphij <delphij@FreeBSD.org>2014-09-26 05:05:34 +0000
commit478dd486cc0b118d74aa8e9a8d7d2747520c38d4 (patch)
tree9e89799dc4ddaeacc9f0530ef11f0591f4116bcc /sbin/sysctl
parentf0e5f3d683f5f84b8732becc468828e23f59d837 (diff)
downloadFreeBSD-src-478dd486cc0b118d74aa8e9a8d7d2747520c38d4.zip
FreeBSD-src-478dd486cc0b118d74aa8e9a8d7d2747520c38d4.tar.gz
Refactor the code a little bit to reduce duplicated code.
Reviewed by: mjg MFC after: 2 weeks
Diffstat (limited to 'sbin/sysctl')
-rw-r--r--sbin/sysctl/sysctl.c189
1 files changed, 87 insertions, 102 deletions
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 5ebec28..a6ea9f9 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -57,6 +57,7 @@ static const char rcsid[] =
#include <machine/pc/bios.h>
#endif
+#include <assert.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
@@ -80,7 +81,31 @@ static int show_var(int *, int);
static int sysctl_all(int *oid, int len);
static int name2oid(const char *, int *);
-static int set_IK(const char *, int *);
+static int strIKtoi(const char *, char **);
+
+static int ctl_sign[CTLTYPE+1] = {
+ [CTLTYPE_INT] = 1,
+ [CTLTYPE_LONG] = 1,
+ [CTLTYPE_S64] = 1,
+};
+
+static int ctl_size[CTLTYPE+1] = {
+ [CTLTYPE_INT] = sizeof(int),
+ [CTLTYPE_UINT] = sizeof(u_int),
+ [CTLTYPE_LONG] = sizeof(long),
+ [CTLTYPE_ULONG] = sizeof(u_long),
+ [CTLTYPE_S64] = sizeof(int64_t),
+ [CTLTYPE_U64] = sizeof(uint64_t),
+};
+
+static const char *ctl_typename[CTLTYPE+1] = {
+ [CTLTYPE_INT] = "integer",
+ [CTLTYPE_UINT] = "unsigned integer",
+ [CTLTYPE_LONG] = "long integer",
+ [CTLTYPE_ULONG] = "unsigned long",
+ [CTLTYPE_S64] = "int64_t",
+ [CTLTYPE_U64] = "uint64_t",
+};
static void
usage(void)
@@ -191,7 +216,8 @@ static int
parse(const char *string, int lineno)
{
int len, i, j;
- void *newval = 0;
+ const void *newval;
+ const char *newvalstr = NULL;
int intval;
unsigned int uintval;
long longval;
@@ -200,7 +226,7 @@ parse(const char *string, int lineno)
int64_t i64val;
uint64_t u64val;
int mib[CTL_MAXNAME];
- char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ], line[BUFSIZ];
+ char *cp, *bufp, buf[BUFSIZ], *endptr = NULL, fmt[BUFSIZ], line[BUFSIZ];
u_int kind;
if (lineno)
@@ -230,7 +256,7 @@ parse(const char *string, int lineno)
cp[strlen(cp) - 1] = '\0';
cp++;
}
- newval = cp;
+ newvalstr = cp;
newsize = strlen(cp);
}
len = name2oid(bufp, mib);
@@ -254,7 +280,7 @@ parse(const char *string, int lineno)
exit(1);
}
- if (newval == NULL || dflag) {
+ if (newvalstr == NULL || dflag) {
if ((kind & CTLTYPE) == CTLTYPE_NODE) {
if (dflag) {
i = show_var(mib, len);
@@ -282,105 +308,77 @@ parse(const char *string, int lineno)
return (1);
}
- if ((kind & CTLTYPE) == CTLTYPE_INT ||
- (kind & CTLTYPE) == CTLTYPE_UINT ||
- (kind & CTLTYPE) == CTLTYPE_LONG ||
- (kind & CTLTYPE) == CTLTYPE_ULONG ||
- (kind & CTLTYPE) == CTLTYPE_S64 ||
- (kind & CTLTYPE) == CTLTYPE_U64) {
- if (strlen(newval) == 0) {
+ switch (kind & CTLTYPE) {
+ case CTLTYPE_INT:
+ case CTLTYPE_UINT:
+ case CTLTYPE_LONG:
+ case CTLTYPE_ULONG:
+ case CTLTYPE_S64:
+ case CTLTYPE_U64:
+ if (strlen(newvalstr) == 0) {
warnx("empty numeric value");
return (1);
}
+ /* FALLTHROUGH */
+ case CTLTYPE_STRING:
+ break;
+ default:
+ warnx("oid '%s' is type %d,"
+ " cannot set that%s", bufp,
+ kind & CTLTYPE, line);
+ return (1);
}
errno = 0;
switch (kind & CTLTYPE) {
case CTLTYPE_INT:
- if (strcmp(fmt, "IK") == 0) {
- if (!set_IK(newval, &intval)) {
- warnx("invalid value '%s'%s",
- (char *)newval, line);
- return (1);
- }
- } else {
- intval = (int)strtol(newval, &endptr,
+ if (strcmp(fmt, "IK") == 0)
+ intval = strIKtoi(newvalstr, &endptr);
+ else
+ intval = (int)strtol(newvalstr, &endptr,
0);
- if (errno != 0 || endptr == newval ||
- *endptr != '\0') {
- warnx("invalid integer '%s'%s",
- (char *)newval, line);
- return (1);
- }
- }
newval = &intval;
newsize = sizeof(intval);
break;
case CTLTYPE_UINT:
- uintval = (int) strtoul(newval, &endptr, 0);
- if (errno != 0 || endptr == newval ||
- *endptr != '\0') {
- warnx("invalid unsigned integer '%s'%s",
- (char *)newval, line);
- return (1);
- }
+ uintval = (int) strtoul(newvalstr, &endptr, 0);
newval = &uintval;
newsize = sizeof(uintval);
break;
case CTLTYPE_LONG:
- longval = strtol(newval, &endptr, 0);
- if (errno != 0 || endptr == newval ||
- *endptr != '\0') {
- warnx("invalid long integer '%s'%s",
- (char *)newval, line);
- return (1);
- }
+ longval = strtol(newvalstr, &endptr, 0);
newval = &longval;
newsize = sizeof(longval);
break;
case CTLTYPE_ULONG:
- ulongval = strtoul(newval, &endptr, 0);
- if (errno != 0 || endptr == newval ||
- *endptr != '\0') {
- warnx("invalid unsigned long integer"
- " '%s'%s", (char *)newval, line);
- return (1);
- }
+ ulongval = strtoul(newvalstr, &endptr, 0);
newval = &ulongval;
newsize = sizeof(ulongval);
break;
case CTLTYPE_STRING:
+ newval = newvalstr;
break;
case CTLTYPE_S64:
- i64val = strtoimax(newval, &endptr, 0);
- if (errno != 0 || endptr == newval ||
- *endptr != '\0') {
- warnx("invalid int64_t '%s'%s",
- (char *)newval, line);
- return (1);
- }
+ i64val = strtoimax(newvalstr, &endptr, 0);
newval = &i64val;
newsize = sizeof(i64val);
break;
case CTLTYPE_U64:
- u64val = strtoumax(newval, &endptr, 0);
- if (errno != 0 || endptr == newval ||
- *endptr != '\0') {
- warnx("invalid uint64_t '%s'%s",
- (char *)newval, line);
- return (1);
- }
+ u64val = strtoumax(newvalstr, &endptr, 0);
newval = &u64val;
newsize = sizeof(u64val);
break;
- case CTLTYPE_OPAQUE:
- /* FALLTHROUGH */
default:
- warnx("oid '%s' is type %d,"
- " cannot set that%s", bufp,
- kind & CTLTYPE, line);
- return (1);
+ /* NOTREACHED */
+ abort();
+ }
+
+ if (errno != 0 || endptr == newvalstr ||
+ (endptr != NULL && *endptr != '\0')) {
+ warnx("invalid %s '%s'%s", ctl_typename[kind & CTLTYPE],
+ newvalstr, line);
+ return (1);
}
i = show_var(mib, len);
@@ -665,33 +663,35 @@ S_bios_smap_xattr(size_t l2, void *p)
#endif
static int
-set_IK(const char *str, int *val)
+strIKtoi(const char *str, char **endptrp)
{
+ int kelv;
float temp;
- int len, kelv;
+ size_t len;
const char *p;
- char *endptr;
- if ((len = strlen(str)) == 0)
- return (0);
+ assert(errno == 0);
+
+ len = strlen(str);
+ /* caller already checked this */
+ assert(len > 0);
+
p = &str[len - 1];
- errno = 0;
if (*p == 'C' || *p == 'F') {
- temp = strtof(str, &endptr);
- if (errno != 0 || endptr == str ||
- endptr != p)
- return (0);
- if (*p == 'F')
- temp = (temp - 32) * 5 / 9;
- kelv = temp * 10 + 2732;
+ temp = strtof(str, endptrp);
+ if (*endptrp != str && *endptrp == p && errno != 0) {
+ if (*p == 'F')
+ temp = (temp - 32) * 5 / 9;
+ return (temp * 10 + 2732);
+ }
} else {
- kelv = (int)strtol(str, &endptr, 10);
- if (errno != 0 || endptr == str ||
- *endptr != '\0')
- return (0);
+ kelv = (int)strtol(str, endptrp, 10);
+ if (*endptrp != str && *endptrp == p && errno != 0)
+ return (kelv);
}
- *val = kelv;
- return (1);
+
+ errno = ERANGE;
+ return (0);
}
/*
@@ -746,21 +746,6 @@ oidfmt(int *oid, int len, char *fmt, u_int *kind)
return (0);
}
-static int ctl_sign[CTLTYPE+1] = {
- [CTLTYPE_INT] = 1,
- [CTLTYPE_LONG] = 1,
- [CTLTYPE_S64] = 1,
-};
-
-static int ctl_size[CTLTYPE+1] = {
- [CTLTYPE_INT] = sizeof(int),
- [CTLTYPE_UINT] = sizeof(u_int),
- [CTLTYPE_LONG] = sizeof(long),
- [CTLTYPE_ULONG] = sizeof(u_long),
- [CTLTYPE_S64] = sizeof(int64_t),
- [CTLTYPE_U64] = sizeof(int64_t),
-};
-
/*
* This formats and outputs the value of one variable
*
OpenPOWER on IntegriCloud