aboutsummaryrefslogtreecommitdiff
path: root/sbin/sysctl
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2018-03-09 23:37:19 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2018-03-09 23:37:19 +0000
commit2365fe5616cfcd3cfde5fd640ef0153979205a8a (patch)
treece582b4ef4f0181991ea9a1b2b8e5b6093beb555 /sbin/sysctl
parentd3953c1f478f7933f905cfb85ef8ea7a08133e19 (diff)
Notes
Diffstat (limited to 'sbin/sysctl')
-rw-r--r--sbin/sysctl/sysctl.84
-rw-r--r--sbin/sysctl/sysctl.c224
2 files changed, 135 insertions, 93 deletions
diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8
index efebfebf054b..1f3041b1f6c7 100644
--- a/sbin/sysctl/sysctl.8
+++ b/sbin/sysctl/sysctl.8
@@ -28,7 +28,7 @@
.\" From: @(#)sysctl.8 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
-.Dd December 10, 2015
+.Dd March 9, 2018
.Dt SYSCTL 8
.Os
.Sh NAME
@@ -39,7 +39,7 @@
.Op Fl bdehiNnoRTtqx
.Op Fl B Ar bufsize
.Op Fl f Ar filename
-.Ar name Ns Op = Ns Ar value
+.Ar name Ns Op = Ns Ar value Ns Op , Ns Ar value
.Ar ...
.Nm
.Op Fl bdehNnoRTtqx
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index de7fd67f2580..ef52235e8377 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -65,6 +65,7 @@ static const char rcsid[] =
#include <errno.h>
#include <inttypes.h>
#include <locale.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -234,16 +235,17 @@ main(int argc, char **argv)
}
/*
- * Parse a name into a MIB entry.
- * Lookup and print out the MIB entry if it exists.
- * Set a new value if requested.
+ * Parse a single numeric value, append it to 'newbuf', and update
+ * 'newsize'. Returns true if the value was parsed and false if the
+ * value was invalid. Non-numeric types (strings) are handled
+ * directly in parse().
*/
-static int
-parse(const char *string, int lineno)
+static bool
+parse_numeric(const char *newvalstr, const char *fmt, u_int kind,
+ void **newbufp, size_t *newsizep)
{
- int len, i, j;
+ void *newbuf;
const void *newval;
- const char *newvalstr = NULL;
int8_t i8val;
uint8_t u8val;
int16_t i16val;
@@ -254,11 +256,111 @@ parse(const char *string, int lineno)
unsigned int uintval;
long longval;
unsigned long ulongval;
- size_t newsize = Bflag;
int64_t i64val;
uint64_t u64val;
+ size_t valsize;
+ char *endptr = NULL;
+
+ errno = 0;
+
+ switch (kind & CTLTYPE) {
+ case CTLTYPE_INT:
+ if (strncmp(fmt, "IK", 2) == 0)
+ intval = strIKtoi(newvalstr, &endptr, fmt);
+ else
+ intval = (int)strtol(newvalstr, &endptr, 0);
+ newval = &intval;
+ valsize = sizeof(intval);
+ break;
+ case CTLTYPE_UINT:
+ uintval = (int) strtoul(newvalstr, &endptr, 0);
+ newval = &uintval;
+ valsize = sizeof(uintval);
+ break;
+ case CTLTYPE_LONG:
+ longval = strtol(newvalstr, &endptr, 0);
+ newval = &longval;
+ valsize = sizeof(longval);
+ break;
+ case CTLTYPE_ULONG:
+ ulongval = strtoul(newvalstr, &endptr, 0);
+ newval = &ulongval;
+ valsize = sizeof(ulongval);
+ break;
+ case CTLTYPE_S8:
+ i8val = (int8_t)strtol(newvalstr, &endptr, 0);
+ newval = &i8val;
+ valsize = sizeof(i8val);
+ break;
+ case CTLTYPE_S16:
+ i16val = (int16_t)strtol(newvalstr, &endptr, 0);
+ newval = &i16val;
+ valsize = sizeof(i16val);
+ break;
+ case CTLTYPE_S32:
+ i32val = (int32_t)strtol(newvalstr, &endptr, 0);
+ newval = &i32val;
+ valsize = sizeof(i32val);
+ break;
+ case CTLTYPE_S64:
+ i64val = strtoimax(newvalstr, &endptr, 0);
+ newval = &i64val;
+ valsize = sizeof(i64val);
+ break;
+ case CTLTYPE_U8:
+ u8val = (uint8_t)strtoul(newvalstr, &endptr, 0);
+ newval = &u8val;
+ valsize = sizeof(u8val);
+ break;
+ case CTLTYPE_U16:
+ u16val = (uint16_t)strtoul(newvalstr, &endptr, 0);
+ newval = &u16val;
+ valsize = sizeof(u16val);
+ break;
+ case CTLTYPE_U32:
+ u32val = (uint32_t)strtoul(newvalstr, &endptr, 0);
+ newval = &u32val;
+ valsize = sizeof(u32val);
+ break;
+ case CTLTYPE_U64:
+ u64val = strtoumax(newvalstr, &endptr, 0);
+ newval = &u64val;
+ valsize = sizeof(u64val);
+ break;
+ default:
+ /* NOTREACHED */
+ abort();
+ }
+
+ if (errno != 0 || endptr == newvalstr ||
+ (endptr != NULL && *endptr != '\0'))
+ return (false);
+
+ newbuf = realloc(*newbufp, *newsizep + valsize);
+ if (newbuf == NULL)
+ err(1, "out of memory");
+ memcpy((char *)newbuf + *newsizep, newval, valsize);
+ *newbufp = newbuf;
+ *newsizep += valsize;
+
+ return (true);
+}
+
+/*
+ * Parse a name into a MIB entry.
+ * Lookup and print out the MIB entry if it exists.
+ * Set a new value if requested.
+ */
+static int
+parse(const char *string, int lineno)
+{
+ int len, i, j;
+ const void *newval;
+ char *newvalstr = NULL;
+ void *newbuf;
+ size_t newsize = Bflag;
int mib[CTL_MAXNAME];
- char *cp, *bufp, buf[BUFSIZ], *endptr = NULL, fmt[BUFSIZ], line[BUFSIZ];
+ char *cp, *bufp, buf[BUFSIZ], fmt[BUFSIZ], line[BUFSIZ];
u_int kind;
if (lineno)
@@ -377,94 +479,33 @@ parse(const char *string, int lineno)
return (1);
}
- errno = 0;
+ newbuf = NULL;
switch (kind & CTLTYPE) {
- case CTLTYPE_INT:
- if (strncmp(fmt, "IK", 2) == 0)
- intval = strIKtoi(newvalstr, &endptr, fmt);
- else
- intval = (int)strtol(newvalstr, &endptr,
- 0);
- newval = &intval;
- newsize = sizeof(intval);
- break;
- case CTLTYPE_UINT:
- uintval = (int) strtoul(newvalstr, &endptr, 0);
- newval = &uintval;
- newsize = sizeof(uintval);
- break;
- case CTLTYPE_LONG:
- longval = strtol(newvalstr, &endptr, 0);
- newval = &longval;
- newsize = sizeof(longval);
- break;
- case CTLTYPE_ULONG:
- ulongval = strtoul(newvalstr, &endptr, 0);
- newval = &ulongval;
- newsize = sizeof(ulongval);
- break;
- case CTLTYPE_STRING:
- newval = newvalstr;
- break;
- case CTLTYPE_S8:
- i8val = (int8_t)strtol(newvalstr, &endptr, 0);
- newval = &i8val;
- newsize = sizeof(i8val);
- break;
- case CTLTYPE_S16:
- i16val = (int16_t)strtol(newvalstr, &endptr,
- 0);
- newval = &i16val;
- newsize = sizeof(i16val);
- break;
- case CTLTYPE_S32:
- i32val = (int32_t)strtol(newvalstr, &endptr,
- 0);
- newval = &i32val;
- newsize = sizeof(i32val);
- break;
- case CTLTYPE_S64:
- i64val = strtoimax(newvalstr, &endptr, 0);
- newval = &i64val;
- newsize = sizeof(i64val);
- break;
- case CTLTYPE_U8:
- u8val = (uint8_t)strtoul(newvalstr, &endptr, 0);
- newval = &u8val;
- newsize = sizeof(u8val);
- break;
- case CTLTYPE_U16:
- u16val = (uint16_t)strtoul(newvalstr, &endptr,
- 0);
- newval = &u16val;
- newsize = sizeof(u16val);
- break;
- case CTLTYPE_U32:
- u32val = (uint32_t)strtoul(newvalstr, &endptr,
- 0);
- newval = &u32val;
- newsize = sizeof(u32val);
- break;
- case CTLTYPE_U64:
- u64val = strtoumax(newvalstr, &endptr, 0);
- newval = &u64val;
- newsize = sizeof(u64val);
- break;
- default:
- /* NOTREACHED */
- abort();
- }
-
- if (errno != 0 || endptr == newvalstr ||
- (endptr != NULL && *endptr != '\0')) {
- warnx("invalid %s '%s'%s", ctl_typename[kind & CTLTYPE],
- newvalstr, line);
- return (1);
+ case CTLTYPE_STRING:
+ newval = newvalstr;
+ break;
+ default:
+ newsize = 0;
+ while ((cp = strsep(&newvalstr, " ,")) != NULL) {
+ if (*cp == '\0')
+ continue;
+ if (!parse_numeric(cp, fmt, kind, &newbuf,
+ &newsize)) {
+ warnx("invalid %s '%s'%s",
+ ctl_typename[kind & CTLTYPE],
+ cp, line);
+ free(newbuf);
+ return (1);
+ }
+ }
+ newval = newbuf;
+ break;
}
i = show_var(mib, len);
if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
+ free(newbuf);
if (!i && !bflag)
putchar('\n');
switch (errno) {
@@ -485,6 +526,7 @@ parse(const char *string, int lineno)
return (1);
}
}
+ free(newbuf);
if (!bflag)
printf(" -> ");
i = nflag;