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); }
/* * 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); }
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); }