static struct mib_val *search_mib(struct rtl8192cd_priv *priv, char *id) { int i=0; struct mib_entry *mib=priv->snmp_mib.mib_tree, *pre_mib=NULL; int oid[100]; name2oid(id, oid); while (oid[i] != -1) { if (mib == NULL || mib->id == -1) return NULL; if (mib->id == oid[i]) { pre_mib = mib; mib = mib->next_level; i++; } else { pre_mib = NULL; mib = mib->next_node; } } if (pre_mib && pre_mib->val) return pre_mib->val; else return NULL; }
/* * 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; const void *newval; char *newvalstr = NULL; void *newbuf; size_t newsize = Bflag; int mib[CTL_MAXNAME]; char *cp, *bufp, buf[BUFSIZ], 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) { warnx("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++; } newvalstr = cp; newsize = strlen(cp); } /* Trim spaces */ cp = bufp + strlen(bufp) - 1; while (cp >= bufp && isspace((int)*cp)) { *cp = '\0'; cp--; } len = name2oid(bufp, mib); if (len < 0) { if (iflag) return (0); if (qflag) return (1); else { if (errno == ENOENT) { warnx("unknown oid '%s'%s", bufp, line); } 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 (newvalstr == 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) { 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); 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); if (!j && !bflag) putchar('\n'); nflag = i; } 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(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; const void *newval; const char *newvalstr = NULL; 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 = NULL, 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) { warnx("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++; } newvalstr = 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 (newvalstr == 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) { 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_S64: 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); } errno = 0; switch (kind & CTLTYPE) { case CTLTYPE_INT: if (strcmp(fmt, "IK") == 0) intval = strIKtoi(newvalstr, &endptr); else intval = (int)strtol(newvalstr, &endptr, 0); newval = &intval; newsize = sizeof(intval); break; case CTLTYPE_UINT: uintval = (int) strtoul(newvalstr, &endptr, 0); newval = &uintval; newsize = sizeof(uintval); break; case CTLTYPE_LONG: longval = strtol(newvalstr, &endptr, 0); newval = &longval; newsize = sizeof(longval); break; case CTLTYPE_ULONG: ulongval = strtoul(newvalstr, &endptr, 0); newval = &ulongval; newsize = sizeof(ulongval); break; case CTLTYPE_STRING: newval = newvalstr; break; case CTLTYPE_S64: i64val = strtoimax(newvalstr, &endptr, 0); newval = &i64val; newsize = sizeof(i64val); break; case CTLTYPE_U64: u64val = strtoumax(newvalstr, &endptr, 0); newval = &u64val; newsize = sizeof(u64val); break; default: /* NOTREACHED */ abort(); } if (errno != 0 || endptr == newvalstr || (endptr != NULL && *endptr != '\0')) { warnx("invalid %s '%s'%s", ctl_typename[kind & CTLTYPE], newvalstr, 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); }
int read_acpi_state(int battery) { #ifdef __linux__ if (acpi_sysfs) return read_acpi_state_sysfs(battery); FILE *acpi; char *ptr; char stat; int percent = 100; /* battery percentage */ int ptemp, rate, rtime = 0; if (!(acpi = fopen (batteries[battery], "r"))) { #ifdef DEBUG printf("DBG:Could not open %s (%d)\n",batteries[battery],battery); #endif return 0; } fread (buf, 512, 1, acpi); fclose (acpi); if (!acpistate) acpistate=(ACPIstate *)malloc(sizeof(ACPIstate)); if ((ptr = strstr (buf, "present:")) || (ptr = strstr (buf, "Present:"))) { #ifdef DEBUG printf("DBG:Battery state present...\n"); #endif stat = *(ptr + 25); if (stat == 'y') { acpistate->present = 1; if ((ptr = strstr (buf, "charging state:")) || (ptr = strstr (buf, "State:"))) { stat = *(ptr + 25); switch (stat) { case 'd': acpistate->state = 1; break; case 'c': if (*(ptr + 33) == '/') acpistate->state = 0; else acpistate->state = 2; break; case 'u': acpistate->state = 3; break; } } /* This section of the code will calculate "percentage remaining" * using battery capacity, and the following formula * (acpi spec 3.9.2): * * percentage = (current_capacity / last_full_capacity) * 100; * */ if ((ptr = strstr (buf, "remaining capacity:")) || (ptr = strstr (buf, "Remaining Capacity:"))) { ptr += 25; sscanf (ptr, "%d", &ptemp); acpistate->rcapacity = ptemp; percent = (float) ((float) ptemp / (float) acpiinfo->last_full_capacity) * 100; acpistate->percentage = percent; #ifdef DEBUG printf("DBG:remaining capacity:100 * %d/%d = %d\n", ptemp,acpiinfo->last_full_capacity,acpistate->percentage); #endif } if ((ptr = strstr (buf, "present rate:")) || (ptr = strstr (buf, "Present Rate:"))) { ptr += 25; sscanf (ptr, "%d", &rate); /* if something wrong */ if (rate <= 0) rate = 0; acpistate->prate = rate; /* time remaining in minutes */ rtime = ((float) ((float) acpistate->rcapacity / (float) acpistate->prate)) * 60; if (rtime <= 0) rtime = 0; acpistate->rtime = rtime; } if ((ptr = strstr (buf, "present voltage:")) || (ptr = strstr (buf, "Battery Voltage:"))) { ptr += 25; sscanf (ptr, "%d", &ptemp); acpistate->pvoltage = ptemp; } } else /* Battery not present */ { acpistate->present = 0; acpistate->state = UNKNOW; acpistate->prate = 0; acpistate->rcapacity = 0; acpistate->pvoltage = 0; acpistate->rtime = 0; acpistate->percentage = 0; return 0; } } return 1; #else #ifdef HAVE_SYSCTL char *string; static char buf[BUFSIZ]; char fmt[BUFSIZ]; char *bufp=buf; void *oldp=(void *)buf; size_t oldlenp=BUFSIZ; int len,mib[CTL_MAXNAME]; int retval; u_int kind; if (!acpistate) acpistate=(ACPIstate *)malloc(sizeof(ACPIstate)); acpistate->present = 0; acpistate->state = UNKNOW; acpistate->prate = 0; acpistate->rcapacity = 0; acpistate->pvoltage = 0; acpistate->rtime = 0; acpistate->percentage = 0; snprintf(buf, BUFSIZ, "%s", "hw.acpi.battery.time"); len = name2oid(bufp, mib); if (len <= 0) return(-1); if (oidfmt(mib, len, fmt, &kind)) err(1, "couldn't find format of oid '%s'", bufp); if (len < 0) errx(1, "unknown oid '%s'", bufp); if ((kind & CTLTYPE) == CTLTYPE_NODE) { printf("oh-oh...\n"); } else { retval=get_var(mib, len); #ifdef DEBUG printf("retval=%d\n",retval); #endif } acpistate->rtime =(retval<0)?0:retval; snprintf(buf, BUFSIZ, "%s", "hw.acpi.battery.life"); len = name2oid(bufp, mib); if (len <= 0) return(-1); if (oidfmt(mib, len, fmt, &kind)) err(1, "couldn't find format of oid '%s'", bufp); if (len < 0) errx(1, "unknown oid '%s'", bufp); if ((kind & CTLTYPE) == CTLTYPE_NODE) { printf("oh-oh...\n"); } else { retval=get_var(mib, len); #ifdef DEBUG printf("retval=%d\n",retval); #endif } acpistate->percentage =retval; #ifdef __FreeBSD__ union acpi_battery_ioctl_arg battio; acpifd = open(ACPIDEV, O_RDONLY); battio.unit = battery; if (ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) == -1) { return 0; } acpistate->state = battio.battinfo.state; acpistate->prate = battio.battinfo.rate; acpistate->rcapacity = acpiinfo->last_full_capacity * battio.battinfo.cap / 100; acpistate->rtime = battio.battinfo.min; acpistate->percentage = battio.battinfo.cap; battio.unit = battery; if (ioctl(acpifd, ACPIIO_BATT_GET_BATTINFO, &battio) == -1) { return 0; } close(acpifd); acpistate->pvoltage = battio.bst.volt; #endif return 1; #else return 0; #endif #endif }
int read_acad_state(void) { #ifdef __linux__ if (acpi_sysfs) return read_acad_state_sysfs(); FILE *acpi; char *ptr; char stat; char acpath[64]; char *name; DIR *acdir; struct dirent *ac; if (!(acdir=opendir(ACBASE))){ return -1; } while ((ac = readdir (acdir))){ name = ac->d_name; /* skip . and .. */ if (name[0] == '.') continue; sprintf (acpath, "%s/%s/state", ACBASE, name); if (access(acpath,R_OK)){ sprintf (acpath, "%s/%s/status", ACBASE, name); if (access(acpath,R_OK)){ return -1; } } break; //only one ac adapter supported } closedir(acdir); acpi = fopen (acpath, "r"); fread (buf, 512, 1, acpi); fclose (acpi); if (!acadstate) acadstate=(ACADstate *)malloc(sizeof(ACADstate)); if ( (ptr = strstr(buf, "state:")) ) { stat = *(ptr + 26); if (stat == 'n') acadstate->state = 1; if (stat == 'f') { acadstate->state = 0; return 0; } } if ( (ptr = strstr (buf, "Status:")) ) { stat = *(ptr + 26); if (stat == 'n') acadstate->state = 1; if (stat == 'f') { acadstate->state = 0; return 0; } } return 1; #else #ifdef HAVE_SYSCTL static char buf[BUFSIZ]; char fmt[BUFSIZ]; void *oldp=(void *)buf; char *bufp=buf; size_t oldlenp=BUFSIZ; int len,mib[CTL_MAXNAME]; u_int kind; int retval; snprintf(buf, BUFSIZ, "%s", "hw.acpi.acline"); len = name2oid(bufp, mib); if (len <= 0) return(-1); if (oidfmt(mib, len, fmt, &kind)) err(1, "couldn't find format of oid '%s'", bufp); if (len < 0) errx(1, "unknown oid '%s'", bufp); if ((kind & CTLTYPE) == CTLTYPE_NODE) { printf("oh-oh...\n"); } else { retval=get_var(mib, len); #ifdef DEBUG printf("retval=%d\n",retval); #endif } return retval; #else return 0; #endif #endif }
int read_acpi_info(int battery) { #ifdef __linux__ if (battery > MAXBATT) { #ifdef DEBUG printf("DBG: error, battery > MAXBATT (%d)\n",MAXBATT); #endif return 0; } if (acpi_sysfs) return read_acpi_info_sysfs(battery); FILE *acpi; char *ptr; char stat; int temp; if (!(acpi = fopen (battinfo[battery], "r"))) { #ifdef DEBUG printf("DBG:cannot open %s for read!\n",battinfo[battery]); #endif return 0; } #ifdef DEBUG { int jj= fread (buf, 1,512, acpi); printf("DBG:%d characters read from %s\n",jj,battinfo[battery]); } #else fread (buf, 1,512, acpi); #endif fclose (acpi); if (!acpiinfo) acpiinfo=(ACPIinfo *)malloc(sizeof(ACPIinfo)); if ((ptr = strstr (buf, "present:")) || (ptr = strstr (buf, "Present:"))) { #ifdef DEBUG printf("DBG:Battery present... and its called %s\n",battinfo[battery]); #endif stat = *(ptr + 25); if (stat == 'y') { acpiinfo->present = 1; if ((ptr = strstr (buf, "design capacity:")) || (ptr = strstr (buf, "Design Capacity:"))) { ptr += 25; sscanf (ptr, "%d", &temp); acpiinfo->design_capacity = temp; #ifdef DEBUG printf("DBG:design capacity:%d\n",temp); #endif } if ((ptr = strstr (buf, "last full capacity:")) || (ptr = strstr (buf, "Last Full Capacity:"))) { ptr += 25; sscanf (ptr, "%d", &temp); acpiinfo->last_full_capacity = temp; #ifdef DEBUG printf("DBG:last full capacity:%d\n",temp); #endif } if ((ptr = strstr (buf, "battery technology:")) || (ptr = strstr (buf, "Battery Technology:"))) { stat = *(ptr + 25); switch (stat) { case 'n': acpiinfo->battery_technology = 1; break; case 'r': acpiinfo->battery_technology = 0; break; } } if ((ptr = strstr (buf, "design voltage:")) || (ptr = strstr (buf, "Design Voltage:"))) { ptr += 25; sscanf (ptr, "%d", &temp); acpiinfo->design_voltage = temp; #ifdef DEBUG printf("DBG:design voltage:%d\n",temp); #endif } if ((ptr = strstr (buf, "design capacity warning:")) || (ptr = strstr (buf, "Design Capacity Warning:"))) { ptr += 25; sscanf (ptr, "%d", &temp); acpiinfo->design_capacity_warning = temp; #ifdef DEBUG printf("DBG:design capacity warning:%d\n",temp); #endif } if ((ptr = strstr (buf, "design capacity low:")) || (ptr = strstr (buf, "Design Capacity Low:"))) { ptr += 25; sscanf (ptr, "%d", &temp); acpiinfo->design_capacity_low = temp; #ifdef DEBUG printf("DBG:design capacity low:%d\n",temp); #endif } #ifdef DEBUG printf("DBG:ALL Battery information read...\n"); #endif } else /* Battery not present */ { #ifdef DEBUG printf("DBG:Battery not present!... and its called %s\n",battinfo[battery]); #endif acpiinfo->present = 0; acpiinfo->design_capacity = 0; acpiinfo->last_full_capacity = 0; acpiinfo->battery_technology = 0; acpiinfo->design_voltage = 0; acpiinfo->design_capacity_warning = 0; acpiinfo->design_capacity_low = 0; return 0; } } return 1; #else #ifdef HAVE_SYSCTL static char buf[BUFSIZ]; char *bufp=buf; int len,mib[CTL_MAXNAME]; char fmt[BUFSIZ]; u_int kind; int retval; if (!acpiinfo) acpiinfo=(ACPIinfo *)malloc(sizeof(ACPIinfo)); acpiinfo->present = 0; acpiinfo->design_capacity = 0; acpiinfo->last_full_capacity = 0; acpiinfo->battery_technology = 0; acpiinfo->design_voltage = 0; acpiinfo->design_capacity_warning = 0; acpiinfo->design_capacity_low = 0; snprintf(buf, BUFSIZ, "%s", "hw.acpi.battery.units"); len = name2oid(bufp, mib); if (len <= 0) return(-1); if (oidfmt(mib, len, fmt, &kind)) err(1, "couldn't find format of oid '%s'", bufp); if (len < 0) errx(1, "unknown oid '%s'", bufp); if ((kind & CTLTYPE) == CTLTYPE_NODE) { printf("oh-oh...\n"); } else { retval=get_var(mib, len); #ifdef DEBUG printf("retval=%d\n",retval); #endif } acpiinfo->present = retval; #ifdef __FreeBSD__ union acpi_battery_ioctl_arg battio; acpifd = open(ACPIDEV, O_RDONLY); battio.unit = battery; if (ioctl(acpifd, ACPIIO_BATT_GET_BIF, &battio) == -1) { return 0; } close(acpifd); acpiinfo->design_capacity = battio.bif.dcap; acpiinfo->last_full_capacity = battio.bif.lfcap; acpiinfo->battery_technology = battio.bif.btech; acpiinfo->design_voltage = battio.bif.dvol; acpiinfo->design_capacity_warning = battio.bif.wcap; acpiinfo->design_capacity_low = battio.bif.lcap; #endif return 1; #else return 0; #endif #endif }
const char *get_temperature(void) { #ifdef __linux__ FILE *fp; char *proc_temperature="/proc/acpi/thermal_zone/*/temperature"; char *sys_temperature="/sys/class/thermal/thermal_zone*/temp"; static char *p,*p2,line[256]; if ( (fp=fopen_glob(proc_temperature, "r")) != NULL ) { fgets(line,255,fp); fclose(fp); p=strtok(line," "); if (!p) return NULL; p=p+strlen(p)+1; while (p && *p ==' ') p++; if (*p==0) return NULL; if (strchr(p,'\n')) p=strtok(p,"\n"); return (const char *)p; } else if ( (fp=fopen_glob(sys_temperature, "r")) != NULL ) { fgets(line,255,fp); fclose(fp); p = line; if (strchr(p,'\n')) *strchr(p,'\n') = 0; if (strlen(p) <= 3) return NULL; p2 = p + strlen(p) - 3; strcpy(p2, " C"); return (const char *)p; } else { return NULL; } #else #ifdef HAVE_SYSCTL static char buf[BUFSIZ]; char fmt[BUFSIZ]; char *bufp=buf; void *oldp=(void *)buf; size_t oldlenp=BUFSIZ; int len,mib[CTL_MAXNAME]; int retval; u_int kind; snprintf(buf, BUFSIZ, "%s", "hw.acpi.thermal.tz0.temperature"); len = name2oid(bufp, mib); if (len <= 0) return(NULL); if (oidfmt(mib, len, fmt, &kind)) err(1, "couldn't find format of oid '%s'", bufp); if (len < 0) errx(1, "unknown oid '%s'", bufp); if ((kind & CTLTYPE) == CTLTYPE_NODE) { printf("oh-oh...\n"); } else { retval=get_var(mib, len); #ifdef DEBUG printf("retval=%d\n",retval); #endif } snprintf(buf, BUFSIZ, "%d C",(retval-2735)/10); return (const char *)buf; #else return ""; #endif #endif }
/* see if we have ACPI support */ int check_acpi(void) { #ifdef __linux__ if ( check_acpi_sysfs() == 0 ) return 0; #endif DIR *battdir; struct dirent *batt; char *name; #ifdef __linux__ FILE *acpi; if (!(acpi = fopen ("/proc/acpi/info", "r")) && !(acpi = fopen ("/sys/module/acpi/parameters/acpica_version", "r"))) { #ifdef DEBUG printf("DBG:no acpi: /proc/acpi/info or " "/sys/module/acpi/parameters/acpica_version not found!\n"); #endif return 1; } /* yep, all good */ fclose (acpi); /* now enumerate batteries */ batt_count = 0; battdir = opendir ("/proc/acpi/battery"); if (battdir == 0) { #ifdef DEBUG printf("DBG:No battery. /proc/acpi/battery not found!\n"); #endif return 2; } while ((batt = readdir (battdir))) { name = batt->d_name; /* skip . and .. */ if (!strncmp (".", name, 1) || !strncmp ("..", name, 2)) continue; sprintf (batteries[batt_count], "/proc/acpi/battery/%s/state", name); if (!(acpi = fopen (batteries[batt_count], "r"))) { sprintf (batteries[batt_count], "/proc/acpi/battery/%s/status", name); } else fclose (acpi); sprintf (battinfo[batt_count], "/proc/acpi/battery/%s/info", name); #ifdef DEBUG printf("DBG:battery number %d at:\n",batt_count); printf("DBG:info->%s\n",battinfo[batt_count]); printf("DBG:state->%s\n",batteries[batt_count]); printf("DBG:------------------------\n"); #endif batt_count++; } closedir (battdir); return 0; #else #ifdef HAVE_SYSCTL { static char buf[BUFSIZ]; char *bufp=buf; char fmt[BUFSIZ]; void *oldp=(void *)buf; size_t oldlenp=BUFSIZ; int len,mib[CTL_MAXNAME]; u_int kind; /* snprintf(buf, BUFSIZ, "%s", "hw.acpi.battery.time");*/ snprintf(buf, BUFSIZ, "%s", "hw.acpi.battery.units"); len = name2oid(bufp, mib); if (len <=0) return 1; if (oidfmt(mib, len, fmt, &kind)) return 1; if ((kind & CTLTYPE) == CTLTYPE_NODE) return 1; batt_count=get_var(mib, len); } return 0; #else return 1; #endif #endif }
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_get(lua_State *L) { int nlen, i, oid[CTL_MAXNAME]; size_t len, intlen; char fmt[BUFSIZ], buf[BUFSIZ], *val, *oval, *p; u_int kind; int (*func)(lua_State *, int, void *); uintmax_t umv; intmax_t mv; bzero(fmt, BUFSIZ); bzero(buf, BUFSIZ); len = strlcpy(buf, luaL_checkstring(L, 1), sizeof(buf)); /* get first argument from lua */ if (len >= sizeof(buf)) return (luaL_error(L, "first arg too long")); nlen = name2oid(buf, oid); if (nlen < 0) return (luaL_error(L, "unknown iod '%s'", buf)); if (oidfmt(oid, nlen, fmt, &kind) != 0) return (luaL_error(L, "couldn't find format of oid '%s'", buf)); if ((kind & CTLTYPE) == CTLTYPE_NODE) return (luaL_error(L, "can't handle CTLTYPE_NODE")); /* find an estimate of how much we need for this var */ len = 0; (void)sysctl(oid, nlen, 0, &len, 0, 0); len += len; /* we want to be sure :-) */ val = oval = malloc(len + 1); if (val == NULL) return (luaL_error(L, "malloc(3) failed")); i = sysctl(oid, nlen, val, &len, 0, 0); if (i || !len) { free(oval); return (luaL_error(L, "sysctl(3) failed")); } val[len] = '\0'; p = val; switch (*fmt) { case 'A': lua_pushstring(L, p); break; case 'I': case 'L': case 'Q': switch (*fmt) { case 'I': intlen = sizeof(int); break; case 'L': intlen = sizeof(long); break; case 'Q': intlen = sizeof(quad_t); break; default: return (luaL_error(L, "lua_sysctl internal error (bug)")); } i = 0; lua_newtable(L); while (len >= intlen) { i++; switch (*fmt) { case 'I': umv = *(u_int *)p; mv = *(int *)p; break; case 'L': umv = *(u_long *)p; mv = *(long *)p; break; case 'Q': umv = *(u_quad_t *)p; mv = *(quad_t *)p; break; default: return (luaL_error(L, "lua_sysctl internal error (bug)")); } lua_pushinteger(L, i); switch (*fmt) { case 'I': case 'L': if (fmt[1] == 'U') lua_pushinteger(L, umv); else lua_pushinteger(L, mv); break; case 'Q': if (fmt[1] == 'U') lua_pushnumber(L, umv); else lua_pushnumber(L, mv); break; default: return (luaL_error(L, "lua_sysctl internal error (bug)")); } lua_settable(L, -3); len -= intlen; p += intlen; } if (i == 1) { lua_pushinteger(L, i); lua_gettable(L, -2); lua_remove(L, lua_gettop(L) - 1); /* remove table */ } break; case 'T': case 'S': if (strcmp(fmt, "S,clockinfo") == 0) func = S_clockinfo; else if (strcmp(fmt, "S,loadavg") == 0) func = S_loadavg; else if (strcmp(fmt, "S,timeval") == 0) func = S_timeval; else if (strcmp(fmt, "S,vmtotal") == 0) func = S_vmtotal; else if (strcmp(fmt, "T,dev_t") == 0) func = T_dev_t; else func = NULL; if (func) { (*func)(L, len, val); break; } /* FALLTHROUGH */ default: free(oval); return (luaL_error(L, "unknown CTLTYPE: fmt=%s kind=%d", fmt, (kind & CTLTYPE))); } free(oval); lua_pushstring(L, fmt); return (2); /* two returned value */ }
static int luaA_sysctl_get(lua_State *L) { int i, nlen, sign, ctltype; int oid[CTL_MAXNAME]; u_int kind; size_t len; size_t intlen; uintmax_t umv; intmax_t mv; char fmt[BUFSIZ]; char buf[BUFSIZ]; char *val, *oval, *p; int (*func)(lua_State *, size_t, void *); bzero(fmt, BUFSIZ); bzero(buf, BUFSIZ); /* get first argument from lua */ len = strlcpy(buf, luaL_checkstring(L, 1), sizeof(buf)); if (len >= sizeof(buf)) return (luaL_error(L, "oid too long")); nlen = name2oid(buf, oid); if (nlen < 0) return (luaL_error(L, "%s: unknown iod", buf)); if (oidfmt(oid, nlen, fmt, sizeof(fmt), &kind) != 0) return (luaL_error(L, "couldn't find format of oid '%s'", buf)); if ((kind & CTLTYPE) == CTLTYPE_NODE) return (luaL_error(L, "can't handle CTLTYPE_NODE")); /* find an estimate of how much we need for this var */ len = 0; (void)sysctl(oid, nlen, NULL, &len, NULL, 0); len += len; /* we want to be sure :-) */ val = oval = malloc(len + 1); if (val == NULL) return (luaL_error(L, "malloc failed")); i = sysctl(oid, nlen, val, &len, NULL, 0); if (i || !len) { free(oval); return (luaL_error(L, "sysctl failed")); } val[len] = '\0'; p = val; ctltype = (kind & CTLTYPE); sign = ctl_sign[ctltype]; intlen = ctl_size[ctltype]; switch (ctltype) { case CTLTYPE_STRING: lua_pushstring(L, p); break; 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: i = 0; lua_newtable(L); while (len >= intlen) { i++; switch (ctltype) { case CTLTYPE_INT: case CTLTYPE_UINT: umv = *(u_int *)p; mv = *(int *)p; break; case CTLTYPE_LONG: case CTLTYPE_ULONG: umv = *(u_long *)p; mv = *(long *)p; break; case CTLTYPE_S8: case CTLTYPE_U8: umv = *(uint8_t *)p; mv = *(int8_t *)p; break; case CTLTYPE_S16: case CTLTYPE_U16: umv = *(uint16_t *)p; mv = *(int16_t *)p; break; case CTLTYPE_S32: case CTLTYPE_U32: umv = *(uint32_t *)p; mv = *(int32_t *)p; break; case CTLTYPE_S64: case CTLTYPE_U64: umv = *(uint64_t *)p; mv = *(int64_t *)p; break; } lua_pushinteger(L, i); if (sign) { if (intlen > sizeof(lua_Integer)) lua_pushnumber(L, mv); else lua_pushinteger(L, mv); } else { if (intlen > sizeof(lua_Unsigned)) lua_pushnumber(L, umv); else lua_pushunsigned(L, umv); } lua_settable(L, -3); len -= intlen; p += intlen; } if (i == 1) { /* only one number, replace the table by the numeric value directly */ lua_pushinteger(L, i); lua_gettable(L, -2); lua_remove(L, lua_gettop(L) - 1); /* remove table */ } break; case CTLTYPE_OPAQUE: if (strcmp(fmt, "S,clockinfo") == 0) func = S_clockinfo; else if (strcmp(fmt, "S,loadavg") == 0) func = S_loadavg; else if (strcmp(fmt, "S,timeval") == 0) func = S_timeval; else if (strcmp(fmt, "S,vmtotal") == 0) func = S_vmtotal; else func = NULL; if (func) { (*func)(L, len, val); break; } /* FALLTHROUGH */ default: free(oval); return (luaL_error(L, "unknown CTLTYPE: fmt=%s ctltype=%d", fmt, ctltype)); } free(oval); lua_pushstring(L, fmt); return (2); /* two returned value */ }
static int luaA_sysctl_set(lua_State *L) { int i; int len; int mib[CTL_MAXNAME]; int8_t i8val; uint8_t u8val; int16_t i16val; uint16_t u16val; int32_t i32val; uint32_t u32val; int intval; unsigned int uintval; long longval; unsigned long ulongval; int64_t i64val; uint64_t u64val; u_int kind; size_t s; size_t newsize = 0; char fmt[BUFSIZ]; char bufp[BUFSIZ]; char strerrorbuf[BUFSIZ]; char nvalbuf[BUFSIZ]; char *endptr; const void *newval = NULL; const char *newvalstr = NULL; /* get first argument from lua */ s = strlcpy(bufp, luaL_checkstring(L, 1), sizeof(bufp)); if (s >= sizeof(bufp)) return (luaL_error(L, "oid too long: '%s'", bufp)); /* 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")); newvalstr = nvalbuf; newsize = s; len = name2oid(bufp, mib); if (len < 0) return (luaL_error(L, "unknown iod '%s'", bufp)); if (oidfmt(mib, len, fmt, sizeof(fmt), &kind) != 0) return (luaL_error(L, "couldn't find format of oid '%s'", bufp)); if ((kind & CTLTYPE) == CTLTYPE_NODE) return (luaL_error(L, "oid '%s' isn't a leaf node", bufp)); 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", bufp)); else return (luaL_error(L, "oid '%s' is read only", bufp)); } 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) return (luaL_error(L, "empty numeric value")); /* FALLTHROUGH */ case CTLTYPE_STRING: break; default: return (luaL_error(L, "oid '%s' is type %d, cannot set that", bufp, kind & CTLTYPE)); } errno = 0; switch (kind & CTLTYPE) { case CTLTYPE_INT: if (strncmp(fmt, "IK", 2) == 0) intval = strIKtoi(newvalstr, &endptr, fmt); else intval = (int)strtol(newvalstr, &endptr, 0); newval = &intval; newsize = sizeof(intval); break; case CTLTYPE_UINT: uintval = (int) strtoul(newvalstr, &endptr, 0); newval = &uintval; newsize = sizeof(uintval); break; case CTLTYPE_LONG: longval = strtol(newvalstr, &endptr, 0); newval = &longval; newsize = sizeof(longval); break; case CTLTYPE_ULONG: ulongval = strtoul(newvalstr, &endptr, 0); newval = &ulongval; newsize = sizeof(ulongval); break; case CTLTYPE_STRING: newval = newvalstr; break; case CTLTYPE_S8: i8val = (int8_t)strtol(newvalstr, &endptr, 0); newval = &i8val; newsize = sizeof(i8val); break; case CTLTYPE_S16: i16val = (int16_t)strtol(newvalstr, &endptr, 0); newval = &i16val; newsize = sizeof(i16val); break; case CTLTYPE_S32: i32val = (int32_t)strtol(newvalstr, &endptr, 0); newval = &i32val; newsize = sizeof(i32val); break; case CTLTYPE_S64: i64val = strtoimax(newvalstr, &endptr, 0); newval = &i64val; newsize = sizeof(i64val); break; case CTLTYPE_U8: u8val = (uint8_t)strtoul(newvalstr, &endptr, 0); newval = &u8val; newsize = sizeof(u8val); break; case CTLTYPE_U16: u16val = (uint16_t)strtoul(newvalstr, &endptr, 0); newval = &u16val; newsize = sizeof(u16val); break; case CTLTYPE_U32: u32val = (uint32_t)strtoul(newvalstr, &endptr, 0); newval = &u32val; newsize = sizeof(u32val); break; case CTLTYPE_U64: u64val = strtoumax(newvalstr, &endptr, 0); newval = &u64val; newsize = sizeof(u64val); break; default: /* NOTREACHED */ return (luaL_error(L, "unexpected type %d (bug)", kind & CTLTYPE)); } if (errno != 0 || endptr == newvalstr || (endptr != NULL && *endptr != '\0')) { return (luaL_error(L, "invalid %s '%s'", ctl_typename[kind & CTLTYPE], newvalstr)); } if (sysctl(mib, len, NULL, NULL, newval, newsize) == -1) { switch (errno) { case EOPNOTSUPP: return (luaL_error(L, "%s: value is not available", newvalstr)); case ENOTDIR: return (luaL_error(L, "%s: specification is incomplete", newvalstr)); case ENOMEM: return (luaL_error(L, "%s: type is unknown to this program", newvalstr)); default: i = strerror_r(errno, strerrorbuf, sizeof(strerrorbuf)); if (i != 0) return (luaL_error(L, "strerror_r failed")); else return (luaL_error(L, "%s: %s", newvalstr, strerrorbuf)); } /* NOTREACHED */ } return (0); }
int setsysctlflagbyname(char *sysctlname, long flag) { int mib[CTL_MAXNAME]; int len = name2oid(sysctlname, mib); return sysctl(mib, len, 0, 0, &flag, sizeof(flag)); }
static int luaA_sysctl_get(lua_State *L) { int nlen; int i; int oid[CTL_MAXNAME]; int ctltype; u_int kind; size_t len; size_t intlen; uintmax_t umv; intmax_t mv; char fmt[BUFSIZ]; char buf[BUFSIZ]; char *val, *oval, *p; int (*func)(lua_State *, int, void *); bzero(fmt, BUFSIZ); bzero(buf, BUFSIZ); /* get first argument from lua */ len = strlcpy(buf, luaL_checkstring(L, 1), sizeof(buf)); if (len >= sizeof(buf)) return (luaL_error(L, "oid too long")); nlen = name2oid(buf, oid); if (nlen < 0) return (luaL_error(L, "%s: unknown iod", buf)); if (oidfmt(oid, nlen, fmt, sizeof(fmt), &kind) != 0) return (luaL_error(L, "couldn't find format of oid '%s'", buf)); if ((kind & CTLTYPE) == CTLTYPE_NODE) return (luaL_error(L, "can't handle CTLTYPE_NODE")); /* find an estimate of how much we need for this var */ len = 0; (void)sysctl(oid, nlen, NULL, &len, NULL, 0); len += len; /* we want to be sure :-) */ val = oval = malloc(len + 1); if (val == NULL) return (luaL_error(L, "malloc failed")); i = sysctl(oid, nlen, val, &len, NULL, 0); if (i || !len) { free(oval); return (luaL_error(L, "sysctl failed")); } val[len] = '\0'; p = val; ctltype = (kind & CTLTYPE); intlen = ctl_size[ctltype]; switch (ctltype) { case CTLTYPE_STRING: lua_pushstring(L, p); break; case CTLTYPE_INT: /* FALLTHROUGH */ case CTLTYPE_UINT: /* FALLTHROUGH */ case CTLTYPE_LONG: /* FALLTHROUGH */ case CTLTYPE_ULONG: /* FALLTHROUGH */ #if __FreeBSD_version < 900000 case CTLTYPE_QUAD: #else case CTLTYPE_S64: /* FALLTHROUGH */ case CTLTYPE_U64: #endif /* an intlen of 0 or less will make us loop indefinitely */ if (intlen <= 0) { free(oval); return (luaL_error(L, "sysctl error (intlen == %zd)", intlen)); } i = 0; lua_newtable(L); while (len >= intlen) { i++; switch (ctltype) { case CTLTYPE_INT: /* FALLTHROUGH */ case CTLTYPE_UINT: umv = *(u_int *)p; mv = *(int *)p; break; case CTLTYPE_LONG: /* FALLTHROUGH */ case CTLTYPE_ULONG: umv = *(u_long *)p; mv = *(long *)p; break; #if __FreeBSD_version < 900000 case CTLTYPE_QUAD: umv = *(u_quad_t *)p; mv = *(quad_t *)p; #else case CTLTYPE_S64: /* FALLTHROUGH */ case CTLTYPE_U64: umv = *(uint64_t *)p; mv = *(int64_t *)p; #endif break; default: return (luaL_error(L, "sysctl error (bug)")); /* NOTREACHED */ } lua_pushinteger(L, i); switch (ctltype) { case CTLTYPE_INT: /* FALLTHROUGH */ case CTLTYPE_LONG: lua_pushinteger(L, mv); break; case CTLTYPE_UINT: /* FALLTHROUGH */ case CTLTYPE_ULONG: lua_pushinteger(L, umv); break; #if __FreeBSD_version < 900000 case CTLTYPE_QUAD: lua_pushnumber(L, mv); break; #else case CTLTYPE_S64: lua_pushnumber(L, mv); break; case CTLTYPE_U64: lua_pushnumber(L, umv); break; #endif default: return (luaL_error(L, "sysctl error (bug)")); /* NOTREACHED */ } lua_settable(L, -3); len -= intlen; p += intlen; } if (i == 1) { lua_pushinteger(L, i); lua_gettable(L, -2); lua_remove(L, lua_gettop(L) - 1); /* remove table */ } break; case CTLTYPE_OPAQUE: if (strcmp(fmt, "S,clockinfo") == 0) func = S_clockinfo; else if (strcmp(fmt, "S,loadavg") == 0) func = S_loadavg; else if (strcmp(fmt, "S,timeval") == 0) func = S_timeval; else if (strcmp(fmt, "S,vmtotal") == 0) func = S_vmtotal; else if (strcmp(fmt, "T,dev_t") == 0) func = T_dev_t; else func = NULL; if (func) { (*func)(L, len, val); break; } /* FALLTHROUGH */ default: free(oval); return (luaL_error(L, "unknown CTLTYPE: fmt=%s ctltype=%d", fmt, ctltype)); } free(oval); lua_pushstring(L, fmt); return (2); /* two returned value */ }
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); }