sysctl.c revision 121306
11553Srgrimes/* 21553Srgrimes * Copyright (c) 1993 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * Redistribution and use in source and binary forms, with or without 61553Srgrimes * modification, are permitted provided that the following conditions 71553Srgrimes * are met: 81553Srgrimes * 1. Redistributions of source code must retain the above copyright 91553Srgrimes * notice, this list of conditions and the following disclaimer. 101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111553Srgrimes * notice, this list of conditions and the following disclaimer in the 121553Srgrimes * documentation and/or other materials provided with the distribution. 131553Srgrimes * 3. All advertising materials mentioning features or use of this software 141553Srgrimes * must display the following acknowledgement: 151553Srgrimes * This product includes software developed by the University of 161553Srgrimes * California, Berkeley and its contributors. 171553Srgrimes * 4. Neither the name of the University nor the names of its contributors 181553Srgrimes * may be used to endorse or promote products derived from this software 191553Srgrimes * without specific prior written permission. 201553Srgrimes * 211553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311553Srgrimes * SUCH DAMAGE. 321553Srgrimes */ 331553Srgrimes 341553Srgrimes#ifndef lint 3530602Scharnierstatic const char copyright[] = 361553Srgrimes"@(#) Copyright (c) 1993\n\ 371553Srgrimes The Regents of the University of California. All rights reserved.\n"; 381553Srgrimes#endif /* not lint */ 391553Srgrimes 401553Srgrimes#ifndef lint 4130602Scharnier#if 0 4230602Scharnierstatic char sccsid[] = "@(#)from: sysctl.c 8.1 (Berkeley) 6/6/93"; 4330602Scharnier#endif 446284Swollmanstatic const char rcsid[] = 4550476Speter "$FreeBSD: head/sbin/sysctl/sysctl.c 121306 2003-10-21 16:49:30Z silby $"; 461553Srgrimes#endif /* not lint */ 471553Srgrimes 4892066Sluigi#ifdef __i386__ 4992066Sluigi#include <sys/reboot.h> /* used for bootdev parsing */ 5092066Sluigi#endif 5191217Sbde#include <sys/param.h> 5291217Sbde#include <sys/time.h> 5391217Sbde#include <sys/resource.h> 541553Srgrimes#include <sys/stat.h> 551553Srgrimes#include <sys/sysctl.h> 56109097Sdillon#include <sys/vmmeter.h> 571553Srgrimes 5830602Scharnier#include <ctype.h> 5930602Scharnier#include <err.h> 601553Srgrimes#include <errno.h> 611553Srgrimes#include <stdio.h> 621553Srgrimes#include <stdlib.h> 631553Srgrimes#include <string.h> 6430602Scharnier#include <unistd.h> 651553Srgrimes 6688006Sluigistatic int aflag, bflag, dflag, eflag, Nflag, nflag, oflag, xflag; 671553Srgrimes 6812946Sphkstatic int oidfmt(int *, int, char *, u_int *); 6912946Sphkstatic void parse(char *); 7012946Sphkstatic int show_var(int *, int); 7112946Sphkstatic int sysctl_all (int *oid, int len); 7212946Sphkstatic int name2oid(char *, int *); 731553Srgrimes 7488696Sphkstatic void set_T_dev_t (char *, void **, int *); 7588696Sphk 7612946Sphkstatic void 7712946Sphkusage(void) 7812946Sphk{ 791553Srgrimes 8077330Sdes (void)fprintf(stderr, "%s\n%s\n", 8188006Sluigi "usage: sysctl [-bdeNnox] variable[=value] ...", 8288006Sluigi " sysctl [-bdeNnox] -a"); 8312946Sphk exit(1); 8412946Sphk} 851553Srgrimes 861553Srgrimesint 8712946Sphkmain(int argc, char **argv) 881553Srgrimes{ 8912946Sphk int ch; 9012946Sphk setbuf(stdout,0); 9112946Sphk setbuf(stderr,0); 921553Srgrimes 9388006Sluigi while ((ch = getopt(argc, argv, "AabdeNnowxX")) != -1) { 941553Srgrimes switch (ch) { 9571034Sdes case 'A': 9677330Sdes /* compatibility */ 9777330Sdes aflag = oflag = 1; 9871034Sdes break; 9971034Sdes case 'a': 10071034Sdes aflag = 1; 10171034Sdes break; 10271034Sdes case 'b': 10371034Sdes bflag = 1; 10471034Sdes break; 10588006Sluigi case 'd': 10688006Sluigi dflag = 1; 10788006Sluigi break; 10885747Stobez case 'e': 10985747Stobez eflag = 1; 11085747Stobez break; 11171034Sdes case 'N': 11271034Sdes Nflag = 1; 11371034Sdes break; 11471034Sdes case 'n': 11571034Sdes nflag = 1; 11671034Sdes break; 11777330Sdes case 'o': 11877330Sdes oflag = 1; 11977330Sdes break; 12071034Sdes case 'w': 12177330Sdes /* compatibility */ 12277330Sdes /* ignored */ 12371034Sdes break; 12471034Sdes case 'X': 12577330Sdes /* compatibility */ 12677330Sdes aflag = xflag = 1; 12771034Sdes break; 12877330Sdes case 'x': 12977330Sdes xflag = 1; 13077330Sdes break; 13171034Sdes default: 13271034Sdes usage(); 1331553Srgrimes } 1341553Srgrimes } 1351553Srgrimes argc -= optind; 1361553Srgrimes argv += optind; 1371553Srgrimes 13877330Sdes if (Nflag && nflag) 13942456Sdes usage(); 14077330Sdes if (aflag && argc == 0) 14177330Sdes exit(sysctl_all(0, 0)); 1421553Srgrimes if (argc == 0) 1431553Srgrimes usage(); 1441553Srgrimes while (argc-- > 0) 14512946Sphk parse(*argv++); 1461553Srgrimes exit(0); 1471553Srgrimes} 1481553Srgrimes 1491553Srgrimes/* 1501553Srgrimes * Parse a name into a MIB entry. 1511553Srgrimes * Lookup and print out the MIB entry if it exists. 1521553Srgrimes * Set a new value if requested. 1531553Srgrimes */ 15412946Sphkstatic void 15512946Sphkparse(char *string) 1561553Srgrimes{ 15712946Sphk int len, i, j; 1581553Srgrimes void *newval = 0; 15978434Spirzyk int intval; 16078434Spirzyk unsigned int uintval; 16178434Spirzyk long longval; 16278434Spirzyk unsigned long ulongval; 16378434Spirzyk size_t newsize = 0; 1641553Srgrimes quad_t quadval; 1651553Srgrimes int mib[CTL_MAXNAME]; 166116383Srwatson char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ]; 16712946Sphk u_int kind; 1681553Srgrimes 1691553Srgrimes bufp = buf; 1701553Srgrimes snprintf(buf, BUFSIZ, "%s", string); 1711553Srgrimes if ((cp = strchr(string, '=')) != NULL) { 1721553Srgrimes *strchr(buf, '=') = '\0'; 1731553Srgrimes *cp++ = '\0'; 1741553Srgrimes while (isspace(*cp)) 1751553Srgrimes cp++; 1761553Srgrimes newval = cp; 1771553Srgrimes newsize = strlen(cp); 1781553Srgrimes } 17912946Sphk len = name2oid(bufp, mib); 1801553Srgrimes 18112946Sphk if (len < 0) 18230602Scharnier errx(1, "unknown oid '%s'", bufp); 1831553Srgrimes 18488696Sphk if (oidfmt(mib, len, fmt, &kind)) 18530602Scharnier err(1, "couldn't find format of oid '%s'", bufp); 1861553Srgrimes 18777330Sdes if (newval == NULL) { 18812946Sphk if ((kind & CTLTYPE) == CTLTYPE_NODE) { 18912946Sphk sysctl_all(mib, len); 19012946Sphk } else { 19112946Sphk i = show_var(mib, len); 19212946Sphk if (!i && !bflag) 19312946Sphk putchar('\n'); 1941553Srgrimes } 19512946Sphk } else { 19612946Sphk if ((kind & CTLTYPE) == CTLTYPE_NODE) 19712946Sphk errx(1, "oid '%s' isn't a leaf node", bufp); 1981553Srgrimes 19912946Sphk if (!(kind&CTLFLAG_WR)) 200121306Ssilby if (kind & CTLFLAG_TUN) { 201121306Ssilby fprintf(stderr, "Tunable values are set in /boot/loader.conf and require a reboot to take effect.\n"); 202121306Ssilby errx(1, "oid '%s' is a tunable.", bufp); 203121306Ssilby } else { 204121306Ssilby errx(1, "oid '%s' is read only", bufp); 205121306Ssilby } 206116383Srwatson 207116383Srwatson if ((kind & CTLTYPE) == CTLTYPE_INT || 208116383Srwatson (kind & CTLTYPE) == CTLTYPE_UINT || 209116383Srwatson (kind & CTLTYPE) == CTLTYPE_LONG || 210116383Srwatson (kind & CTLTYPE) == CTLTYPE_ULONG) { 211116383Srwatson if (strlen(newval) == 0) 212116383Srwatson errx(1, "empty numeric value"); 213116383Srwatson } 21412946Sphk 21512946Sphk switch (kind & CTLTYPE) { 21612946Sphk case CTLTYPE_INT: 217116383Srwatson intval = (int) strtol(newval, &endptr, 0); 218116383Srwatson if (endptr == newval || *endptr != '\0') 219116383Srwatson errx(1, "invalid integer '%s'", 220116383Srwatson newval); 22112946Sphk newval = &intval; 22277928Sdd newsize = sizeof(intval); 2231553Srgrimes break; 22478434Spirzyk case CTLTYPE_UINT: 225116383Srwatson uintval = (int) strtoul(newval, &endptr, 0); 226116383Srwatson if (endptr == newval || *endptr != '\0') 227116383Srwatson errx(1, "invalid unsigned integer '%s'", 228116383Srwatson newval); 22978434Spirzyk newval = &uintval; 23078434Spirzyk newsize = sizeof uintval; 23112946Sphk break; 23278434Spirzyk case CTLTYPE_LONG: 233116383Srwatson longval = strtol(newval, &endptr, 0); 234116383Srwatson if (endptr == newval || *endptr != '\0') 235116383Srwatson errx(1, "invalid long integer '%s'", 236116383Srwatson newval); 23778434Spirzyk newval = &longval; 23878434Spirzyk newsize = sizeof longval; 23978434Spirzyk break; 24078434Spirzyk case CTLTYPE_ULONG: 241116383Srwatson ulongval = strtoul(newval, &endptr, 0); 242116383Srwatson if (endptr == newval || *endptr != '\0') 243116383Srwatson errx(1, "invalid unsigned long integer" 244116383Srwatson " '%s'", newval); 24578434Spirzyk newval = &ulongval; 24678434Spirzyk newsize = sizeof ulongval; 24778434Spirzyk break; 24812946Sphk case CTLTYPE_STRING: 24912946Sphk break; 25012946Sphk case CTLTYPE_QUAD: 25112946Sphk sscanf(newval, "%qd", &quadval); 25212946Sphk newval = &quadval; 25377928Sdd newsize = sizeof(quadval); 25412946Sphk break; 25588696Sphk case CTLTYPE_OPAQUE: 25688696Sphk if (strcmp(fmt, "T,dev_t") == 0) { 25788696Sphk set_T_dev_t ((char*)newval, &newval, &newsize); 25888696Sphk break; 25988696Sphk } 26088696Sphk /* FALLTHROUGH */ 26112946Sphk default: 26212946Sphk errx(1, "oid '%s' is type %d," 26331214Sjdp " cannot set that", bufp, 26431214Sjdp kind & CTLTYPE); 2651553Srgrimes } 2661553Srgrimes 26712946Sphk i = show_var(mib, len); 26812946Sphk if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { 26912946Sphk if (!i && !bflag) 27012946Sphk putchar('\n'); 27112946Sphk switch (errno) { 27212946Sphk case EOPNOTSUPP: 27330602Scharnier errx(1, "%s: value is not available", 27412946Sphk string); 27512946Sphk case ENOTDIR: 27630602Scharnier errx(1, "%s: specification is incomplete", 27712946Sphk string); 27812946Sphk case ENOMEM: 27930602Scharnier errx(1, "%s: type is unknown to this program", 28012946Sphk string); 28112946Sphk default: 28230602Scharnier warn("%s", string); 28312946Sphk return; 28412946Sphk } 28512946Sphk } 28612946Sphk if (!bflag) 28712946Sphk printf(" -> "); 28812946Sphk i = nflag; 28912946Sphk nflag = 1; 29012946Sphk j = show_var(mib, len); 29112946Sphk if (!j && !bflag) 29212946Sphk putchar('\n'); 29312946Sphk nflag = i; 29412946Sphk } 29512946Sphk} 2961553Srgrimes 29712946Sphk/* These functions will dump out various interesting structures. */ 2981553Srgrimes 29912946Sphkstatic int 30012946SphkS_clockinfo(int l2, void *p) 30112946Sphk{ 30212946Sphk struct clockinfo *ci = (struct clockinfo*)p; 30397232Salfred if (l2 != sizeof(*ci)) { 30497232Salfred warnx("S_clockinfo %d != %d", l2, sizeof(*ci)); 30597232Salfred return (0); 30697232Salfred } 30794752Sphk printf("{ hz = %d, tick = %d, profhz = %d, stathz = %d }", 30894752Sphk ci->hz, ci->tick, ci->profhz, ci->stathz); 30912946Sphk return (0); 31012946Sphk} 3111553Srgrimes 31212946Sphkstatic int 31312946SphkS_loadavg(int l2, void *p) 31412946Sphk{ 31512946Sphk struct loadavg *tv = (struct loadavg*)p; 3168857Srgrimes 31797232Salfred if (l2 != sizeof(*tv)) { 31897232Salfred warnx("S_loadavg %d != %d", l2, sizeof(*tv)); 31997232Salfred return (0); 32097232Salfred } 32112946Sphk printf("{ %.2f %.2f %.2f }", 32212946Sphk (double)tv->ldavg[0]/(double)tv->fscale, 32312946Sphk (double)tv->ldavg[1]/(double)tv->fscale, 32412946Sphk (double)tv->ldavg[2]/(double)tv->fscale); 32512946Sphk return (0); 32612946Sphk} 3271553Srgrimes 32812946Sphkstatic int 32912946SphkS_timeval(int l2, void *p) 33012946Sphk{ 33112946Sphk struct timeval *tv = (struct timeval*)p; 33237266Sbde time_t tv_sec; 33312946Sphk char *p1, *p2; 3341553Srgrimes 33597232Salfred if (l2 != sizeof(*tv)) { 33697232Salfred warnx("S_timeval %d != %d", l2, sizeof(*tv)); 33797232Salfred return (0); 33897232Salfred } 33912946Sphk printf("{ sec = %ld, usec = %ld } ", 34012946Sphk tv->tv_sec, tv->tv_usec); 34137266Sbde tv_sec = tv->tv_sec; 34237266Sbde p1 = strdup(ctime(&tv_sec)); 34312946Sphk for (p2=p1; *p2 ; p2++) 34412946Sphk if (*p2 == '\n') 34512946Sphk *p2 = '\0'; 34612946Sphk fputs(p1, stdout); 34712946Sphk return (0); 34812946Sphk} 3491553Srgrimes 35012946Sphkstatic int 351109097SdillonS_vmtotal(int l2, void *p) 352109097Sdillon{ 353109097Sdillon struct vmtotal *v = (struct vmtotal *)p; 354109113Sdillon int pageKilo = getpagesize() / 1024; 355109097Sdillon 356109097Sdillon if (l2 != sizeof(*v)) { 357109097Sdillon warnx("S_vmtotal %d != %d", l2, sizeof(*v)); 358109097Sdillon return (0); 359109097Sdillon } 360109097Sdillon 361109113Sdillon printf( 362109113Sdillon "\nSystem wide totals computed every five seconds:" 363109113Sdillon " (values in kilobytes)\n"); 364109097Sdillon printf("===============================================\n"); 365109113Sdillon printf( 366109113Sdillon "Processes:\t\t(RUNQ: %hu Disk Wait: %hu Page Wait: " 367109113Sdillon "%hu Sleep: %hu)\n", 368109113Sdillon v->t_rq, v->t_dw, v->t_pw, v->t_sl); 369109113Sdillon printf( 370109113Sdillon "Virtual Memory:\t\t(Total: %luK, Active %lldK)\n", 371109113Sdillon (unsigned long)v->t_vm / 1024, 372109113Sdillon (long long)v->t_avm * pageKilo); 373109113Sdillon printf("Real Memory:\t\t(Total: %lldK Active %lldK)\n", 374109113Sdillon (long long)v->t_rm * pageKilo, (long long)v->t_arm * pageKilo); 375109113Sdillon printf("Shared Virtual Memory:\t(Total: %lldK Active: %lldK)\n", 376109113Sdillon (long long)v->t_vmshr * pageKilo, 377109113Sdillon (long long)v->t_avmshr * pageKilo); 378109113Sdillon printf("Shared Real Memory:\t(Total: %lldK Active: %lldK)\n", 379109113Sdillon (long long)v->t_rmshr * pageKilo, 380109113Sdillon (long long)v->t_armshr * pageKilo); 381109113Sdillon printf("Free Memory Pages:\t%ldK\n", (long long)v->t_free * pageKilo); 382109097Sdillon 383109097Sdillon return (0); 384109097Sdillon} 385109097Sdillon 386109097Sdillonstatic int 38712946SphkT_dev_t(int l2, void *p) 38812946Sphk{ 38912946Sphk dev_t *d = (dev_t *)p; 39097232Salfred if (l2 != sizeof(*d)) { 39197232Salfred warnx("T_dev_T %d != %d", l2, sizeof(*d)); 39297232Salfred return (0); 39397232Salfred } 39461514Sphk if ((int)(*d) != -1) { 39561514Sphk if (minor(*d) > 255 || minor(*d) < 0) 39661514Sphk printf("{ major = %d, minor = 0x%x }", 39761514Sphk major(*d), minor(*d)); 39861514Sphk else 39961514Sphk printf("{ major = %d, minor = %d }", 40061514Sphk major(*d), minor(*d)); 40161514Sphk } 40212946Sphk return (0); 40312946Sphk} 4041553Srgrimes 40588696Sphkstatic void 40688696Sphkset_T_dev_t (char *path, void **val, int *size) 40788696Sphk{ 40888696Sphk static struct stat statb; 40988696Sphk 41088696Sphk if (strcmp(path, "none") && strcmp(path, "off")) { 41188696Sphk int rc = stat (path, &statb); 41288696Sphk if (rc) { 41388696Sphk err(1, "cannot stat %s", path); 41488696Sphk } 41588696Sphk 41688696Sphk if (!S_ISCHR(statb.st_mode)) { 41788696Sphk errx(1, "must specify a device special file."); 41888696Sphk } 41988696Sphk } else { 42088696Sphk statb.st_rdev = NODEV; 42188696Sphk } 42288696Sphk *val = (char*) &statb.st_rdev; 42388696Sphk *size = sizeof statb.st_rdev; 42488696Sphk} 42588696Sphk 42612946Sphk/* 42712946Sphk * These functions uses a presently undocumented interface to the kernel 42812946Sphk * to walk the tree and get the type so it can print the value. 42912946Sphk * This interface is under work and consideration, and should probably 43012946Sphk * be killed with a big axe by the first person who can find the time. 43112946Sphk * (be aware though, that the proper interface isn't as obvious as it 43212946Sphk * may seem, there are various conflicting requirements. 43312946Sphk */ 4341553Srgrimes 43512946Sphkstatic int 43612946Sphkname2oid(char *name, int *oidp) 43712946Sphk{ 43812946Sphk int oid[2]; 43938533Sdfr int i; 44038533Sdfr size_t j; 4411553Srgrimes 44212946Sphk oid[0] = 0; 44312946Sphk oid[1] = 3; 4441553Srgrimes 44577928Sdd j = CTL_MAXNAME * sizeof(int); 44612946Sphk i = sysctl(oid, 2, oidp, &j, name, strlen(name)); 44712946Sphk if (i < 0) 44812946Sphk return i; 44977928Sdd j /= sizeof(int); 45012946Sphk return (j); 4511553Srgrimes} 4521553Srgrimes 45312946Sphkstatic int 45412946Sphkoidfmt(int *oid, int len, char *fmt, u_int *kind) 45512946Sphk{ 45612946Sphk int qoid[CTL_MAXNAME+2]; 45712946Sphk u_char buf[BUFSIZ]; 45838533Sdfr int i; 45938533Sdfr size_t j; 4601553Srgrimes 46112946Sphk qoid[0] = 0; 46212946Sphk qoid[1] = 4; 46312946Sphk memcpy(qoid + 2, oid, len * sizeof(int)); 4641553Srgrimes 46577928Sdd j = sizeof(buf); 46612946Sphk i = sysctl(qoid, len + 2, buf, &j, 0, 0); 46712946Sphk if (i) 46830602Scharnier err(1, "sysctl fmt %d %d %d", i, j, errno); 4691553Srgrimes 47012946Sphk if (kind) 47112946Sphk *kind = *(u_int *)buf; 47212946Sphk 47312946Sphk if (fmt) 47412946Sphk strcpy(fmt, (char *)(buf + sizeof(u_int))); 47512946Sphk return 0; 4761553Srgrimes} 4771553Srgrimes 4781553Srgrimes/* 47912946Sphk * This formats and outputs the value of one variable 48012946Sphk * 48112946Sphk * Returns zero if anything was actually output. 48212946Sphk * Returns one if didn't know what to do with this. 48312946Sphk * Return minus one if we had errors. 4841553Srgrimes */ 48512946Sphk 48612946Sphkstatic int 48712946Sphkshow_var(int *oid, int nlen) 4881553Srgrimes{ 48912946Sphk u_char buf[BUFSIZ], *val, *p; 49085747Stobez char name[BUFSIZ], *fmt, *sep; 49112946Sphk int qoid[CTL_MAXNAME+2]; 49238533Sdfr int i; 49338533Sdfr size_t j, len; 49412946Sphk u_int kind; 49577332Sdes int (*func)(int, void *); 4961553Srgrimes 49742456Sdes qoid[0] = 0; 49842456Sdes memcpy(qoid + 2, oid, nlen * sizeof(int)); 49942456Sdes 50042456Sdes qoid[1] = 1; 50177928Sdd j = sizeof(name); 50242456Sdes i = sysctl(qoid, nlen + 2, name, &j, 0, 0); 50342456Sdes if (i || !j) 50442456Sdes err(1, "sysctl name %d %d %d", i, j, errno); 50542456Sdes 50671034Sdes if (Nflag) { 50771034Sdes printf("%s", name); 50871034Sdes return (0); 50971034Sdes } 51071034Sdes 51185747Stobez if (eflag) 51285747Stobez sep = "="; 51385747Stobez else 51485747Stobez sep = ": "; 51585747Stobez 51688006Sluigi if (dflag) { /* just print description */ 51788006Sluigi qoid[1] = 5; 51888006Sluigi j = sizeof(buf); 51988006Sluigi i = sysctl(qoid, nlen + 2, buf, &j, 0, 0); 52088006Sluigi if (!nflag) 52188006Sluigi printf("%s%s", name, sep); 52288006Sluigi printf("%s", buf); 52388006Sluigi return (0); 52488006Sluigi } 52512946Sphk /* find an estimate of how much we need for this var */ 52612946Sphk j = 0; 52712946Sphk i = sysctl(oid, nlen, 0, &j, 0, 0); 52812946Sphk j += j; /* we want to be sure :-) */ 52912946Sphk 530109671Speter val = alloca(j + 1); 53112946Sphk len = j; 53212946Sphk i = sysctl(oid, nlen, val, &len, 0, 0); 53312946Sphk if (i || !len) 53412946Sphk return (1); 53512946Sphk 53612946Sphk if (bflag) { 53712946Sphk fwrite(val, 1, len, stdout); 53812946Sphk return (0); 5391553Srgrimes } 54096234Sache val[len] = '\0'; 54188696Sphk fmt = buf; 54288696Sphk oidfmt(oid, nlen, fmt, &kind); 54312946Sphk p = val; 54412946Sphk switch (*fmt) { 54512946Sphk case 'A': 54612946Sphk if (!nflag) 54785747Stobez printf("%s%s", name, sep); 548106829Speter printf("%.*s", len, p); 54912946Sphk return (0); 55012946Sphk 55112946Sphk case 'I': 55212946Sphk if (!nflag) 55385747Stobez printf("%s%s", name, sep); 55462622Sjhb fmt++; 55541019Sphk val = ""; 55641019Sphk while (len >= sizeof(int)) { 55762622Sjhb if(*fmt == 'U') 55862622Sjhb printf("%s%u", val, *(unsigned int *)p); 55962622Sjhb else 56062622Sjhb printf("%s%d", val, *(int *)p); 56141019Sphk val = " "; 56277332Sdes len -= sizeof(int); 56377332Sdes p += sizeof(int); 56441019Sphk } 56512946Sphk return (0); 56612946Sphk 56738533Sdfr case 'L': 56838533Sdfr if (!nflag) 56985747Stobez printf("%s%s", name, sep); 57062622Sjhb fmt++; 57162975Sphk val = ""; 57262975Sphk while (len >= sizeof(long)) { 57362975Sphk if(*fmt == 'U') 57462975Sphk printf("%s%lu", val, *(unsigned long *)p); 57562975Sphk else 57662975Sphk printf("%s%ld", val, *(long *)p); 57762975Sphk val = " "; 57877332Sdes len -= sizeof(long); 57977332Sdes p += sizeof(long); 58062975Sphk } 58138533Sdfr return (0); 58238533Sdfr 58338533Sdfr case 'P': 58438533Sdfr if (!nflag) 58585747Stobez printf("%s%s", name, sep); 58638533Sdfr printf("%p", *(void **)p); 58738533Sdfr return (0); 58838533Sdfr 58912946Sphk case 'T': 59012946Sphk case 'S': 59112946Sphk i = 0; 59277332Sdes if (strcmp(fmt, "S,clockinfo") == 0) 59377332Sdes func = S_clockinfo; 59477332Sdes else if (strcmp(fmt, "S,timeval") == 0) 59577332Sdes func = S_timeval; 59677332Sdes else if (strcmp(fmt, "S,loadavg") == 0) 59777332Sdes func = S_loadavg; 598109097Sdillon else if (strcmp(fmt, "S,vmtotal") == 0) 599109097Sdillon func = S_vmtotal; 60077332Sdes else if (strcmp(fmt, "T,dev_t") == 0) 60177332Sdes func = T_dev_t; 60277332Sdes else 60377332Sdes func = NULL; 60412946Sphk if (func) { 60512946Sphk if (!nflag) 60685747Stobez printf("%s%s", name, sep); 60712946Sphk return ((*func)(len, p)); 60812946Sphk } 609102411Scharnier /* FALLTHROUGH */ 61012946Sphk default: 61177330Sdes if (!oflag && !xflag) 61212946Sphk return (1); 61312946Sphk if (!nflag) 61485747Stobez printf("%s%s", name, sep); 61512946Sphk printf("Format:%s Length:%d Dump:0x", fmt, len); 61677332Sdes while (len-- && (xflag || p < val + 16)) 61712946Sphk printf("%02x", *p++); 61877332Sdes if (!xflag && len > 16) 61912946Sphk printf("..."); 62012946Sphk return (0); 6211553Srgrimes } 62212946Sphk return (1); 6231553Srgrimes} 6241553Srgrimes 62512946Sphkstatic int 62612946Sphksysctl_all (int *oid, int len) 6271553Srgrimes{ 62812946Sphk int name1[22], name2[22]; 62938533Sdfr int i, j; 63038533Sdfr size_t l1, l2; 6311553Srgrimes 63212946Sphk name1[0] = 0; 63312946Sphk name1[1] = 2; 63412946Sphk l1 = 2; 63512946Sphk if (len) { 63677928Sdd memcpy(name1+2, oid, len * sizeof(int)); 63712946Sphk l1 += len; 63812946Sphk } else { 63912946Sphk name1[2] = 1; 64012946Sphk l1++; 64112946Sphk } 64277332Sdes for (;;) { 64377928Sdd l2 = sizeof(name2); 64412946Sphk j = sysctl(name1, l1, name2, &l2, 0, 0); 64548956Sbillf if (j < 0) { 64612946Sphk if (errno == ENOENT) 64712946Sphk return 0; 64812946Sphk else 64930602Scharnier err(1, "sysctl(getnext) %d %d", j, l2); 65048956Sbillf } 65112946Sphk 65277928Sdd l2 /= sizeof(int); 65312946Sphk 65412946Sphk if (l2 < len) 65512946Sphk return 0; 65612946Sphk 65712946Sphk for (i = 0; i < len; i++) 65812946Sphk if (name2[i] != oid[i]) 65912946Sphk return 0; 66012946Sphk 66112946Sphk i = show_var(name2, l2); 66212946Sphk if (!i && !bflag) 66312946Sphk putchar('\n'); 66412946Sphk 66577928Sdd memcpy(name1+2, name2, l2 * sizeof(int)); 66612946Sphk l1 = 2 + l2; 66712946Sphk } 6681553Srgrimes} 669