/* * Parse a name into a MIB entry. * Lookup and print out the MIB entry if it exists. * Set a new value if requested. */ static void parse(const char *string) { size_t len; int i, j; void *newval = NULL; int intval; unsigned int uintval; long longval; unsigned long ulongval; size_t newsize = 0; quad_t quadval; u_quad_t uquadval; int mib[CTL_MAXNAME]; char *cp, fmt[BUFSIZ]; const char *name; char *name_allocated = NULL; u_int kind; if ((cp = strchr(string, '=')) != NULL) { if ((name_allocated = malloc(cp - string + 1)) == NULL) err(1, "malloc failed"); strlcpy(name_allocated, string, cp - string + 1); name = name_allocated; while (isspace(*++cp)) ; newval = cp; newsize = strlen(cp); } else { name = string; } len = CTL_MAXNAME; if (sysctlnametomib(name, mib, &len) < 0) { if (errno == ENOENT) { errx(1, "unknown oid '%s'", name); } else { err(1, "sysctlnametomib(\"%s\")", name); } } if (oidfmt(mib, len, fmt, &kind)) err(1, "couldn't find format of oid '%s'", name); if (newval == NULL) { if ((kind & CTLTYPE) == CTLTYPE_NODE) { sysctl_all(mib, len); } else { i = show_var(mib, len); if (!i && !bflag) putchar('\n'); } } else { if ((kind & CTLTYPE) == CTLTYPE_NODE) errx(1, "oid '%s' isn't a leaf node", name); if (!(kind&CTLFLAG_WR)) errx(1, "oid '%s' is read only", name); switch (kind & CTLTYPE) { case CTLTYPE_INT: if (!(strcmp(fmt, "IK") == 0)) { if (!set_IK(newval, &intval)) errx(1, "invalid value '%s'", (char *)newval); } else intval = (int) strtol(newval, NULL, 0); newval = &intval; newsize = sizeof(intval); break; case CTLTYPE_UINT: uintval = (int) strtoul(newval, NULL, 0); newval = &uintval; newsize = sizeof uintval; break; case CTLTYPE_LONG: longval = strtol(newval, NULL, 0); newval = &longval; newsize = sizeof longval; break; case CTLTYPE_ULONG: ulongval = strtoul(newval, NULL, 0); newval = &ulongval; newsize = sizeof ulongval; break; case CTLTYPE_STRING: break; case CTLTYPE_QUAD: quadval = strtoq(newval, NULL, 0); newval = &quadval; newsize = sizeof(quadval); break; case CTLTYPE_UQUAD: uquadval = strtouq(newval, NULL, 0); newval = &uquadval; newsize = sizeof(uquadval); break; case CTLTYPE_OPAQUE: if (strcmp(fmt, "T,dev_t") == 0 || strcmp(fmt, "T,udev_t") == 0 ) { set_T_dev_t((char*)newval, &newval, &newsize); break; } /* FALLTHROUGH */ default: errx(1, "oid '%s' is type %d," " cannot set that", name, kind & CTLTYPE); } i = show_var(mib, len); if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { if (!i && !bflag) putchar('\n'); switch (errno) { case EOPNOTSUPP: errx(1, "%s: value is not available", string); case ENOTDIR: errx(1, "%s: specification is incomplete", string); case ENOMEM: errx(1, "%s: type is unknown to this program", string); default: warn("%s", string); return; } } if (!bflag) printf(" -> "); i = nflag; nflag = 1; j = show_var(mib, len); if (!j && !bflag) putchar('\n'); nflag = i; } if (name_allocated != NULL) free(name_allocated); }
/* * Parse a name into a MIB entry. * Lookup and print out the MIB entry if it exists. * Set a new value if requested. */ static void parse(char *string) { int len, i, j; void *newval = 0; int intval; unsigned int uintval; long longval; unsigned long ulongval; size_t newsize = 0; int64_t i64val; uint64_t u64val; int mib[CTL_MAXNAME]; char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ]; u_int kind; bufp = buf; if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ) errx(1, "oid too long: '%s'", string); if ((cp = strchr(string, '=')) != NULL) { *strchr(buf, '=') = '\0'; *cp++ = '\0'; while (isspace(*cp)) cp++; newval = cp; newsize = strlen(cp); } len = name2oid(bufp, mib); if (len < 0) { if (iflag) return; if (qflag) exit(1); else errx(1, "unknown oid '%s'", bufp); } if (oidfmt(mib, len, fmt, &kind)) err(1, "couldn't find format of oid '%s'", bufp); if (newval == NULL) { if ((kind & CTLTYPE) == CTLTYPE_NODE) { if (dflag) { i = show_var(mib, len); if (!i && !bflag) putchar('\n'); } sysctl_all(mib, len); } else { i = show_var(mib, len); if (!i && !bflag) putchar('\n'); } } else { if ((kind & CTLTYPE) == CTLTYPE_NODE) errx(1, "oid '%s' isn't a leaf node", bufp); if (!(kind & CTLFLAG_WR)) { if (kind & CTLFLAG_TUN) { warnx("oid '%s' is a read only tunable", bufp); errx(1, "Tunable values are set in /boot/loader.conf"); } else { errx(1, "oid '%s' is read only", bufp); } } 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) errx(1, "empty numeric value"); } switch (kind & CTLTYPE) { case CTLTYPE_INT: if (strcmp(fmt, "IK") == 0) { if (!set_IK(newval, &intval)) errx(1, "invalid value '%s'", (char *)newval); } else { intval = (int)strtol(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') errx(1, "invalid integer '%s'", (char *)newval); } newval = &intval; newsize = sizeof(intval); break; case CTLTYPE_UINT: uintval = (int) strtoul(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') errx(1, "invalid unsigned integer '%s'", (char *)newval); newval = &uintval; newsize = sizeof(uintval); break; case CTLTYPE_LONG: longval = strtol(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') errx(1, "invalid long integer '%s'", (char *)newval); newval = &longval; newsize = sizeof(longval); break; case CTLTYPE_ULONG: ulongval = strtoul(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') errx(1, "invalid unsigned long integer" " '%s'", (char *)newval); newval = &ulongval; newsize = sizeof(ulongval); break; case CTLTYPE_STRING: break; case CTLTYPE_S64: i64val = strtoimax(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') errx(1, "invalid int64_t '%s'", (char *)newval); newval = &i64val; newsize = sizeof(i64val); break; case CTLTYPE_U64: u64val = strtoumax(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') errx(1, "invalid uint64_t '%s'", (char *)newval); newval = &u64val; newsize = sizeof(u64val); break; case CTLTYPE_OPAQUE: /* FALLTHROUGH */ default: errx(1, "oid '%s' is type %d," " cannot set that", bufp, kind & CTLTYPE); } i = show_var(mib, len); if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { if (!i && !bflag) putchar('\n'); switch (errno) { case EOPNOTSUPP: errx(1, "%s: value is not available", string); case ENOTDIR: errx(1, "%s: specification is incomplete", string); case ENOMEM: errx(1, "%s: type is unknown to this program", string); default: warn("%s", string); warncount++; return; } } if (!bflag) printf(" -> "); i = nflag; nflag = 1; j = show_var(mib, len); if (!j && !bflag) putchar('\n'); nflag = i; } }
/* * 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; void *newval = 0; int intval; unsigned int uintval; long longval; unsigned long ulongval; size_t newsize = 0; int64_t i64val; uint64_t u64val; int mib[CTL_MAXNAME]; char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ], line[BUFSIZ]; u_int kind; if (lineno) snprintf(line, sizeof(line), " at line %d", lineno); else line[0] = '\0'; cp = buf; if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ) { warn("oid too long: '%s'%s", string, line); return (1); } bufp = strsep(&cp, "=:"); if (cp != NULL) { /* Tflag just lists tunables, do not allow assignment */ if (Tflag || Wflag) { warnx("Can't set variables when using -T or -W"); usage(); } while (isspace(*cp)) cp++; /* Strip a pair of " or ' if any. */ switch (*cp) { case '\"': case '\'': if (cp[strlen(cp) - 1] == *cp) cp[strlen(cp) - 1] = '\0'; cp++; } newval = cp; newsize = strlen(cp); } len = name2oid(bufp, mib); if (len < 0) { if (iflag) return (0); if (qflag) return (1); else { warn("unknown oid '%s'%s", bufp, line); return (1); } } if (oidfmt(mib, len, fmt, &kind)) { warn("couldn't find format of oid '%s'%s", bufp, line); if (iflag) return (1); else exit(1); } if (newval == NULL || dflag) { if ((kind & CTLTYPE) == CTLTYPE_NODE) { if (dflag) { i = show_var(mib, len); if (!i && !bflag) putchar('\n'); } sysctl_all(mib, len); } else { i = show_var(mib, len); if (!i && !bflag) putchar('\n'); } } else { if ((kind & CTLTYPE) == CTLTYPE_NODE) { warn("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); } 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) { warnx("empty numeric value"); return (1); } } 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, 0); if (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 (endptr == newval || *endptr != '\0') { warnx("invalid unsigned integer '%s'%s", (char *)newval, line); return (1); } newval = &uintval; newsize = sizeof(uintval); break; case CTLTYPE_LONG: longval = strtol(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') { warnx("invalid long integer '%s'%s", (char *)newval, line); return (1); } newval = &longval; newsize = sizeof(longval); break; case CTLTYPE_ULONG: ulongval = strtoul(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') { warnx("invalid unsigned long integer" " '%s'%s", (char *)newval, line); return (1); } newval = &ulongval; newsize = sizeof(ulongval); break; case CTLTYPE_STRING: break; case CTLTYPE_S64: i64val = strtoimax(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') { warnx("invalid int64_t '%s'%s", (char *)newval, line); return (1); } newval = &i64val; newsize = sizeof(i64val); break; case CTLTYPE_U64: u64val = strtoumax(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') { warnx("invalid uint64_t '%s'%s", (char *)newval, line); return (1); } 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); } i = show_var(mib, len); if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { 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); } } if (!bflag) printf(" -> "); i = nflag; nflag = 1; j = show_var(mib, len); if (!j && !bflag) putchar('\n'); nflag = i; } return (0); }
static int luaA_sysctl_set(lua_State *L) { int i, len, intval, mib[CTL_MAXNAME]; unsigned int uintval; long longval; unsigned long ulongval; quad_t quadval; size_t s, newsize = 0; u_int kind; char fmt[BUFSIZ], key[BUFSIZ], nvalbuf[BUFSIZ]; const char *errmsg; void *newval = NULL; /* get first argument from lua */ s = strlcpy(key, luaL_checkstring(L, 1), sizeof(key)); if (s >= sizeof(key)) return (luaL_error(L, "first arg too long")); /* get second argument from lua */ s = strlcpy(nvalbuf, luaL_checkstring(L, 2), sizeof(nvalbuf)); if (s >= sizeof(nvalbuf)) return (luaL_error(L, "second arg too long")); newval = nvalbuf; newsize = s; len = name2oid(key, mib); if (len < 0) return (luaL_error(L, "unknown iod '%s'", key)); if (oidfmt(mib, len, fmt, &kind) != 0) return (luaL_error(L, "couldn't find format of oid '%s'", key)); if ((kind & CTLTYPE) == CTLTYPE_NODE) return (luaL_error(L, "oid '%s' isn't a leaf node", key)); if (!(kind & CTLFLAG_WR)) { return (luaL_error(L, "oid '%s' is %s", key, (kind & CTLFLAG_TUN) ? "read only tunable" : "read only")); } 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) return (luaL_error(L, "empty numeric value")); } switch (kind & CTLTYPE) { case CTLTYPE_INT: if (strcmp(fmt, "IK") == 0) { if (!set_IK(newval, &intval)) return (luaL_error(L, "invalid value '%s'", (char *)newval)); } else { intval = (int)strtonum(newval, INT_MIN, INT_MAX, &errmsg); if (errmsg) { return (luaL_error(L, "bad integer: %s (%s)", (char *)newval, errmsg)); } } newval = &intval; newsize = sizeof(intval); break; case CTLTYPE_UINT: uintval = (unsigned int)strtonum(newval, 0, UINT_MAX, &errmsg); if (errmsg) { return (luaL_error(L, "bad unsigned integer: %s (%s)", (char *)newval, errmsg)); } newval = &uintval; newsize = sizeof(uintval); break; case CTLTYPE_LONG: longval = (long)strtonum(newval, LONG_MIN, LONG_MAX, &errmsg); if (errmsg) { return (luaL_error(L,"bad long integer: %s (%s)", (char *)newval, errmsg)); } newval = &longval; newsize = sizeof(longval); break; case CTLTYPE_ULONG: ulongval = (unsigned long)strtonum(newval, 0, ULONG_MAX, &errmsg); if (errmsg) { return (luaL_error(L, "bad unsigned long integer: %s (%s)", (char *)newval, errmsg)); } newval = &ulongval; newsize = sizeof(ulongval); break; case CTLTYPE_STRING: break; case CTLTYPE_S64: case CTLTYPE_U64: quadval = (quad_t)strtonum(newval, LLONG_MIN, LLONG_MAX, &errmsg); if (errmsg) { return (luaL_error(L, "bad quad_t integer: %s (%s)", (char *)newval, errmsg)); } newval = &quadval; newsize = sizeof(quadval); break; case CTLTYPE_OPAQUE: if (strcmp(fmt, "T,dev_t") == 0) { set_T_dev_t(L, newval, &newval, &newsize); break; } /* FALLTHROUGH */ default: return (luaL_error(L, "oid '%s' is type %d, cannot set that", key, kind & CTLTYPE)); } if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { switch (errno) { case EOPNOTSUPP: return (luaL_error(L, "%s: value is not available", key)); case ENOTDIR: return (luaL_error(L, "%s: specification is incomplete", key)); case ENOMEM: /* really? with ENOMEM !?! */ return (luaL_error(L, "%s: type is unknown to this program", key)); default: i = strerror_r(errno, nvalbuf, sizeof(nvalbuf)); if (i != 0) return (luaL_error(L, "strerror_r(3) failed")); else return (luaL_error(L, "%s: %s", key, nvalbuf)); } } return (0); }
static int luaA_sysctl_set(lua_State *L) { int i; int len; int intval; int mib[CTL_MAXNAME]; unsigned int uintval; u_int kind; long longval; unsigned long ulongval; size_t s; size_t newsize = 0; #if __FreeBSD_version < 900000 quad_t quadval; #else int64_t i64val; uint64_t u64val; intmax_t intmaxval; uintmax_t uintmaxval; #endif char fmt[BUFSIZ]; char oid[BUFSIZ]; char nvalbuf[BUFSIZ]; char *endptr; void *newval = NULL; /* get first argument from lua */ s = strlcpy(oid, luaL_checkstring(L, 1), sizeof(oid)); if (s >= sizeof(oid)) return (luaL_error(L, "oid too long: '%s'", oid)); /* get second argument from lua */ s = strlcpy(nvalbuf, luaL_checkstring(L, 2), sizeof(nvalbuf)); if (s >= sizeof(nvalbuf)) return (luaL_error(L, "new value too long")); newval = nvalbuf; newsize = s; len = name2oid(oid, mib); if (len < 0) return (luaL_error(L, "unknown iod '%s'", oid)); if (oidfmt(mib, len, fmt, sizeof(fmt), &kind) != 0) return (luaL_error(L, "couldn't find format of oid '%s'", oid)); if ((kind & CTLTYPE) == CTLTYPE_NODE) return (luaL_error(L, "oid '%s' isn't a leaf node", oid)); if (!(kind & CTLFLAG_WR)) { if (kind & CTLFLAG_TUN) return (luaL_error(L, "oid '%s' is a read only tunable. " "Tunable values are set in /boot/loader.conf", oid)); else return (luaL_error(L, "oid '%s' is read only", oid)); } if ((kind & CTLTYPE) == CTLTYPE_INT || (kind & CTLTYPE) == CTLTYPE_UINT || (kind & CTLTYPE) == CTLTYPE_LONG || (kind & CTLTYPE) == CTLTYPE_ULONG || #if __FreeBSD_version < 900000 (kind & CTLTYPE) == CTLTYPE_QUAD #else (kind & CTLTYPE) == CTLTYPE_S64 || (kind & CTLTYPE) == CTLTYPE_U64 #endif ) { if (strlen(newval) == 0) return (luaL_error(L, "empty numeric value")); } switch (kind & CTLTYPE) { case CTLTYPE_INT: if (strcmp(fmt, "IK") == 0) { if (!set_IK(newval, &intval)) return (luaL_error(L, "invalid value '%s'", (char *)newval)); } else { longval = strtol(newval, &endptr, 0); if (endptr == newval || *endptr != '\0' || longval > INT_MAX || longval < INT_MIN) { return (luaL_error(L, "invalid integer: '%s'", (char *)newval)); } intval = (int)longval; } newval = &intval; newsize = sizeof(intval); break; case CTLTYPE_UINT: ulongval = strtoul(newval, &endptr, 0); if (endptr == newval || *endptr != '\0' || ulongval > UINT_MAX) { return (luaL_error(L, "invalid unsigned integer: '%s'", (char *)newval)); } uintval = (unsigned int)ulongval; newval = &uintval; newsize = sizeof(uintval); break; case CTLTYPE_LONG: longval = strtol(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') { return (luaL_error(L, "invalid long integer: '%s'", (char *)newval)); } newval = &longval; newsize = sizeof(longval); break; case CTLTYPE_ULONG: ulongval = strtoul(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') { return (luaL_error(L, "invalid unsigned long integer: '%s'", (char *)newval)); } newval = &ulongval; newsize = sizeof(ulongval); break; case CTLTYPE_STRING: break; #if __FreeBSD_version < 900000 case CTLTYPE_QUAD: quadval = strtoq(newval, &endptr, 0); if (endptr == newval || *endptr != '\0') { return (luaL_error(L, "invalid quad_t: '%s'", (char *)newval)); } newval = &quadval; newsize = sizeof(quadval); break; #else case CTLTYPE_S64: intmaxval = strtoimax(newval, &endptr, 0); if (endptr == newval || *endptr != '\0' || intmaxval > INT64_MAX || intmaxval < INT64_MIN) { return (luaL_error(L, "invalid int64_t integer: '%s'", (char *)newval)); } i64val = (int64_t)intmaxval; newval = &i64val; newsize = sizeof(i64val); break; case CTLTYPE_U64: uintmaxval = strtoumax(newval, &endptr, 0); if (endptr == newval || *endptr != '\0' || uintmaxval > UINT64_MAX) { return (luaL_error(L, "invalid int64_t integer: '%s'", (char *)newval)); } u64val = (uint64_t)uintmaxval; newval = &u64val; newsize = sizeof(u64val); break; #endif case CTLTYPE_OPAQUE: if (strcmp(fmt, "T,dev_t") == 0) { set_T_dev_t(L, newval, &newval, &newsize); break; } /* FALLTHROUGH */ default: return (luaL_error(L, "oid '%s' is type %d, cannot set that", oid, kind & CTLTYPE)); } if (sysctl(mib, len, NULL, NULL, newval, newsize) == -1) { switch (errno) { case EOPNOTSUPP: return (luaL_error(L, "%s: value is not available", oid)); case ENOTDIR: return (luaL_error(L, "%s: specification is incomplete", oid)); case ENOMEM: /* really? with ENOMEM !?! */ return (luaL_error(L, "%s: type is unknown to this program", oid)); default: i = strerror_r(errno, nvalbuf, sizeof(nvalbuf)); if (i != 0) return (luaL_error(L, "strerror_r failed")); else return (luaL_error(L, "%s: %s", oid, nvalbuf)); } /* NOTREACHED */ } return (0); }