Index: head/sbin/sysctl/sysctl.c =================================================================== --- head/sbin/sysctl/sysctl.c +++ head/sbin/sysctl/sysctl.c @@ -29,20 +29,9 @@ * 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 */ +#include +__FBSDID("$FreeBSD$"); -#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 #include #include @@ -221,7 +210,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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,105 +442,109 @@ if (!i && !bflag) putchar('\n'); } - } else { - if ((kind & CTLTYPE) == CTLTYPE_NODE) { - warnx("oid '%s' isn't a leaf node%s", bufp, line); - return (1); - } + return (0); + } - 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); - } + /* + * 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); + } - 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); + 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; + 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); + 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); - 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); } } + 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 (!bflag) - printf(" -> "); - i = nflag; - nflag = 1; - j = show_var(mib, len, false); - if (!j && !bflag) + if (!i && !bflag) putchar('\n'); - nflag = i; + 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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)