sysctl: Misc code cleanup

* Use defined SYS_SYSCTL names
* Use memcmp instead of explicit loop
* Use NULL instead of 0 for pointer value
* Use __FBSDID
* Reformat, improve comments in parse()

No functional changes.

Reviewed by:	imp
MFC after:	1 week
Sponsored by:	iXsystems, Inc.
Differential Revision:	https://reviews.freebsd.org/D26832
This commit is contained in:
Ryan Moeller 2020-10-24 16:05:37 +00:00
parent 6f26c71d76
commit 8077b9bc60
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=367006

View File

@ -29,19 +29,8 @@
* SUCH DAMAGE.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)from: sysctl.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/time.h>
@ -221,7 +210,7 @@ main(int argc, char **argv)
if (Nflag && nflag)
usage();
if (aflag && argc == 0)
exit(sysctl_all(0, 0));
exit(sysctl_all(NULL, 0));
if (argc == 0 && conffile == NULL)
usage();
@ -369,6 +358,13 @@ parse(const char *string, int lineno)
else
line[0] = '\0';
/*
* Split the string into name and value.
*
* Either = or : may be used as the delimiter.
* Whitespace surrounding the delimiter is trimmed.
* Quotes around the value are stripped.
*/
cp = buf;
if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ) {
warnx("oid too long: '%s'%s", string, line);
@ -381,6 +377,7 @@ parse(const char *string, int lineno)
warnx("Can't set variables when using -T or -W");
usage();
}
/* Trim whitespace before the value. */
while (isspace(*cp))
cp++;
/* Strip a pair of " or ' if any. */
@ -394,14 +391,17 @@ parse(const char *string, int lineno)
newvalstr = cp;
newsize = strlen(cp);
}
/* Trim spaces */
/* Trim whitespace after the name. */
cp = bufp + strlen(bufp) - 1;
while (cp >= bufp && isspace((int)*cp)) {
*cp = '\0';
cp--;
}
len = name2oid(bufp, mib);
/*
* Check the name is a useable oid.
*/
len = name2oid(bufp, mib);
if (len < 0) {
if (iflag)
return (0);
@ -425,6 +425,10 @@ parse(const char *string, int lineno)
exit(1);
}
/*
* We have a useable oid to work with. If there is no value given,
* show the node and its children. Otherwise, set the new value.
*/
if (newvalstr == NULL || dflag) {
if ((kind & CTLTYPE) == CTLTYPE_NODE) {
if (dflag) {
@ -438,106 +442,110 @@ parse(const char *string, int lineno)
if (!i && !bflag)
putchar('\n');
}
} else {
if ((kind & CTLTYPE) == CTLTYPE_NODE) {
warnx("oid '%s' isn't a leaf node%s", bufp, line);
return (1);
}
if (!(kind & CTLFLAG_WR)) {
if (kind & CTLFLAG_TUN) {
warnx("oid '%s' is a read only tunable%s", bufp, line);
warnx("Tunable values are set in /boot/loader.conf");
} else
warnx("oid '%s' is read only%s", bufp, line);
return (1);
}
switch (kind & CTLTYPE) {
case CTLTYPE_INT:
case CTLTYPE_UINT:
case CTLTYPE_LONG:
case CTLTYPE_ULONG:
case CTLTYPE_S8:
case CTLTYPE_S16:
case CTLTYPE_S32:
case CTLTYPE_S64:
case CTLTYPE_U8:
case CTLTYPE_U16:
case CTLTYPE_U32:
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);
}
newbuf = NULL;
switch (kind & CTLTYPE) {
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, false);
if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
free(newbuf);
if (!i && !bflag)
putchar('\n');
switch (errno) {
case EOPNOTSUPP:
warnx("%s: value is not available%s",
string, line);
return (1);
case ENOTDIR:
warnx("%s: specification is incomplete%s",
string, line);
return (1);
case ENOMEM:
warnx("%s: type is unknown to this program%s",
string, line);
return (1);
default:
warn("%s%s", string, line);
return (1);
}
}
free(newbuf);
if (!bflag)
printf(" -> ");
i = nflag;
nflag = 1;
j = show_var(mib, len, false);
if (!j && !bflag)
putchar('\n');
nflag = i;
return (0);
}
/*
* We have a new value to set. Check its validity and parse if numeric.
*/
if ((kind & CTLTYPE) == CTLTYPE_NODE) {
warnx("oid '%s' isn't a leaf node%s", bufp, line);
return (1);
}
if (!(kind & CTLFLAG_WR)) {
if (kind & CTLFLAG_TUN) {
warnx("oid '%s' is a read only tunable%s", bufp, line);
warnx("Tunable values are set in /boot/loader.conf");
} else
warnx("oid '%s' is read only%s", bufp, line);
return (1);
}
switch (kind & CTLTYPE) {
case CTLTYPE_INT:
case CTLTYPE_UINT:
case CTLTYPE_LONG:
case CTLTYPE_ULONG:
case CTLTYPE_S8:
case CTLTYPE_S16:
case CTLTYPE_S32:
case CTLTYPE_S64:
case CTLTYPE_U8:
case CTLTYPE_U16:
case CTLTYPE_U32:
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);
}
newbuf = NULL;
switch (kind & CTLTYPE) {
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;
}
/*
* Show the current value, then set and show the new value.
*/
i = show_var(mib, len, false);
if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
free(newbuf);
if (!i && !bflag)
putchar('\n');
switch (errno) {
case EOPNOTSUPP:
warnx("%s: value is not available%s",
string, line);
return (1);
case ENOTDIR:
warnx("%s: specification is incomplete%s",
string, line);
return (1);
case ENOMEM:
warnx("%s: type is unknown to this program%s",
string, line);
return (1);
default:
warn("%s%s", string, line);
return (1);
}
}
free(newbuf);
if (!bflag)
printf(" -> ");
i = nflag;
nflag = 1;
j = show_var(mib, len, false);
if (!j && !bflag)
putchar('\n');
nflag = i;
return (0);
}
@ -898,8 +906,8 @@ name2oid(const char *name, int *oidp)
int i;
size_t j;
oid[0] = 0;
oid[1] = 3;
oid[0] = CTL_SYSCTL;
oid[1] = CTL_SYSCTL_NAME2OID;
j = CTL_MAXNAME * sizeof(int);
i = sysctl(oid, 2, oidp, &j, name, strlen(name));
@ -917,8 +925,8 @@ oidfmt(int *oid, int len, char *fmt, u_int *kind)
int i;
size_t j;
qoid[0] = 0;
qoid[1] = 4;
qoid[0] = CTL_SYSCTL;
qoid[1] = CTL_SYSCTL_OIDFMT;
memcpy(qoid + 2, oid, len * sizeof(int));
j = sizeof(buf);
@ -964,10 +972,10 @@ show_var(int *oid, int nlen, bool honor_skip)
bzero(buf, BUFSIZ);
bzero(fmt, BUFSIZ);
bzero(name, BUFSIZ);
qoid[0] = 0;
qoid[0] = CTL_SYSCTL;
memcpy(qoid + 2, oid, nlen * sizeof(int));
qoid[1] = 1;
qoid[1] = CTL_SYSCTL_NAME;
j = sizeof(name);
i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
if (i || !j)
@ -1006,7 +1014,7 @@ show_var(int *oid, int nlen, bool honor_skip)
printf("%s", prntype);
return (0);
}
qoid[1] = 5;
qoid[1] = CTL_SYSCTL_OIDDESCR;
j = sizeof(buf);
i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
printf("%s", buf);
@ -1227,9 +1235,8 @@ sysctl_all(int *oid, int len)
if (len < 0 || l2 < (unsigned int)len)
return (0);
for (i = 0; i < len; i++)
if (name2[i] != oid[i])
return (0);
if (memcmp(name2, oid, len * sizeof(int)) != 0)
return (0);
i = show_var(name2, l2, honor_skip);
if (!i && !bflag)