Index: sbin/sysctl/sysctl.c =================================================================== --- sbin/sysctl/sysctl.c +++ sbin/sysctl/sysctl.c @@ -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 +__FBSDID("$FreeBSD$"); #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,14 @@ 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 +378,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 +392,18 @@ 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 +427,11 @@ 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 +445,111 @@ 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. + */ - 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); - } + if ((kind & CTLTYPE) == CTLTYPE_NODE) { + warnx("oid '%s' isn't a leaf node%s", bufp, line); + return (1); + } - newbuf = NULL; + 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_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; + 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); + } - 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); + 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 (!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); } @@ -1227,9 +1240,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) Index: sys/kern/kern_sysctl.c =================================================================== --- sys/kern/kern_sysctl.c +++ sys/kern/kern_sysctl.c @@ -573,7 +573,7 @@ } } - /* + /* * This can happen when a module fails to register and is * being unloaded afterwards. It should not be a panic() * for normal use. @@ -939,7 +939,7 @@ /* * "Staff-functions" * - * These functions implement a presently undocumented interface + * These functions implement a presently undocumented interface * used by the sysctl program to walk the tree, and get the type * so it can print the value. * This interface is under work and consideration, and should probably @@ -1076,7 +1076,7 @@ namelen--; name++; - if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE) + if ((oid->oid_kind & CTLTYPE) != CTLTYPE_NODE) break; if (oid->oid_handler) @@ -1101,7 +1101,7 @@ CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_name, ""); static int -sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, +sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen, int *next, int *len, int level, struct sysctl_oid **oidpp, bool honor_skip) { struct sysctl_oid *oidp; @@ -1119,14 +1119,14 @@ continue; if (!namelen) { - if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) + if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) return (0); - if (oidp->oid_handler) + if (oidp->oid_handler) /* We really should call the handler here...*/ return (0); lsp = SYSCTL_CHILDREN(oidp); - if (!sysctl_sysctl_next_ls(lsp, 0, 0, next+1, - len, level+1, oidpp, honor_skip)) + if (!sysctl_sysctl_next_ls(lsp, 0, 0, next + 1, + len, level + 1, oidpp, honor_skip)) return (0); goto emptynode; } @@ -1140,8 +1140,8 @@ if (oidp->oid_handler) return (0); lsp = SYSCTL_CHILDREN(oidp); - if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, - next+1, len, level+1, oidpp, honor_skip)) + if (!sysctl_sysctl_next_ls(lsp, name + 1, namelen - 1, + next + 1, len, level + 1, oidpp, honor_skip)) return (0); goto next; } @@ -1152,8 +1152,8 @@ continue; lsp = SYSCTL_CHILDREN(oidp); - if (!sysctl_sysctl_next_ls(lsp, name+1, namelen-1, next+1, - len, level+1, oidpp, honor_skip)) + if (!sysctl_sysctl_next_ls(lsp, name + 1, namelen - 1, next + 1, + len, level + 1, oidpp, honor_skip)) return (0); next: namelen = 1; @@ -1242,7 +1242,7 @@ struct rm_priotracker tracker; char buf[32]; - if (!req->newlen) + if (!req->newlen) return (ENOENT); if (req->newlen >= MAXPATHLEN) /* XXX arbitrary, undocumented */ return (ENAMETOOLONG);