sysctl.c revision 122234
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 122234 2003-11-07 16:41:47Z des $"; 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> 61122233Sdes#include <locale.h> 621553Srgrimes#include <stdio.h> 631553Srgrimes#include <stdlib.h> 641553Srgrimes#include <string.h> 6530602Scharnier#include <unistd.h> 661553Srgrimes 67122233Sdesstatic int aflag, bflag, dflag, eflag, hflag, Nflag, nflag, oflag, xflag; 681553Srgrimes 6912946Sphkstatic int oidfmt(int *, int, char *, u_int *); 7012946Sphkstatic void parse(char *); 7112946Sphkstatic int show_var(int *, int); 7212946Sphkstatic int sysctl_all (int *oid, int len); 7312946Sphkstatic int name2oid(char *, int *); 741553Srgrimes 75121542Speterstatic void set_T_dev_t (char *, void **, size_t *); 7688696Sphk 7712946Sphkstatic void 7812946Sphkusage(void) 7912946Sphk{ 801553Srgrimes 8177330Sdes (void)fprintf(stderr, "%s\n%s\n", 82122233Sdes "usage: sysctl [-bdehNnox] variable[=value] ...", 83122233Sdes " sysctl [-bdehNnox] -a"); 8412946Sphk exit(1); 8512946Sphk} 861553Srgrimes 871553Srgrimesint 8812946Sphkmain(int argc, char **argv) 891553Srgrimes{ 9012946Sphk int ch; 91122233Sdes 92122233Sdes setlocale(LC_NUMERIC, ""); 9312946Sphk setbuf(stdout,0); 9412946Sphk setbuf(stderr,0); 951553Srgrimes 96122233Sdes while ((ch = getopt(argc, argv, "AabdehNnowxX")) != -1) { 971553Srgrimes switch (ch) { 9871034Sdes case 'A': 9977330Sdes /* compatibility */ 10077330Sdes aflag = oflag = 1; 10171034Sdes break; 10271034Sdes case 'a': 10371034Sdes aflag = 1; 10471034Sdes break; 10571034Sdes case 'b': 10671034Sdes bflag = 1; 10771034Sdes break; 10888006Sluigi case 'd': 10988006Sluigi dflag = 1; 11088006Sluigi break; 11185747Stobez case 'e': 11285747Stobez eflag = 1; 11385747Stobez break; 114122233Sdes case 'h': 115122233Sdes hflag = 1; 116122233Sdes break; 11771034Sdes case 'N': 11871034Sdes Nflag = 1; 11971034Sdes break; 12071034Sdes case 'n': 12171034Sdes nflag = 1; 12271034Sdes break; 12377330Sdes case 'o': 12477330Sdes oflag = 1; 12577330Sdes break; 12671034Sdes case 'w': 12777330Sdes /* compatibility */ 12877330Sdes /* ignored */ 12971034Sdes break; 13071034Sdes case 'X': 13177330Sdes /* compatibility */ 13277330Sdes aflag = xflag = 1; 13371034Sdes break; 13477330Sdes case 'x': 13577330Sdes xflag = 1; 13677330Sdes break; 13771034Sdes default: 13871034Sdes usage(); 1391553Srgrimes } 1401553Srgrimes } 1411553Srgrimes argc -= optind; 1421553Srgrimes argv += optind; 1431553Srgrimes 14477330Sdes if (Nflag && nflag) 14542456Sdes usage(); 14677330Sdes if (aflag && argc == 0) 14777330Sdes exit(sysctl_all(0, 0)); 1481553Srgrimes if (argc == 0) 1491553Srgrimes usage(); 1501553Srgrimes while (argc-- > 0) 15112946Sphk parse(*argv++); 1521553Srgrimes exit(0); 1531553Srgrimes} 1541553Srgrimes 1551553Srgrimes/* 1561553Srgrimes * Parse a name into a MIB entry. 1571553Srgrimes * Lookup and print out the MIB entry if it exists. 1581553Srgrimes * Set a new value if requested. 1591553Srgrimes */ 16012946Sphkstatic void 16112946Sphkparse(char *string) 1621553Srgrimes{ 16312946Sphk int len, i, j; 1641553Srgrimes void *newval = 0; 16578434Spirzyk int intval; 16678434Spirzyk unsigned int uintval; 16778434Spirzyk long longval; 16878434Spirzyk unsigned long ulongval; 16978434Spirzyk size_t newsize = 0; 1701553Srgrimes quad_t quadval; 1711553Srgrimes int mib[CTL_MAXNAME]; 172116383Srwatson char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ]; 17312946Sphk u_int kind; 1741553Srgrimes 1751553Srgrimes bufp = buf; 1761553Srgrimes snprintf(buf, BUFSIZ, "%s", string); 1771553Srgrimes if ((cp = strchr(string, '=')) != NULL) { 1781553Srgrimes *strchr(buf, '=') = '\0'; 1791553Srgrimes *cp++ = '\0'; 1801553Srgrimes while (isspace(*cp)) 1811553Srgrimes cp++; 1821553Srgrimes newval = cp; 1831553Srgrimes newsize = strlen(cp); 1841553Srgrimes } 18512946Sphk len = name2oid(bufp, mib); 1861553Srgrimes 187122234Sdes if (len < 0) 18830602Scharnier errx(1, "unknown oid '%s'", bufp); 1891553Srgrimes 19088696Sphk if (oidfmt(mib, len, fmt, &kind)) 19130602Scharnier err(1, "couldn't find format of oid '%s'", bufp); 1921553Srgrimes 19377330Sdes if (newval == NULL) { 19412946Sphk if ((kind & CTLTYPE) == CTLTYPE_NODE) { 19512946Sphk sysctl_all(mib, len); 19612946Sphk } else { 19712946Sphk i = show_var(mib, len); 19812946Sphk if (!i && !bflag) 19912946Sphk putchar('\n'); 2001553Srgrimes } 20112946Sphk } else { 20212946Sphk if ((kind & CTLTYPE) == CTLTYPE_NODE) 20312946Sphk errx(1, "oid '%s' isn't a leaf node", bufp); 2041553Srgrimes 205121849Ssilby if (!(kind & CTLFLAG_WR)) { 206121306Ssilby if (kind & CTLFLAG_TUN) { 207121849Ssilby warnx("oid '%s' is a read only tunable", bufp); 208121849Ssilby errx(1, "Tunable values are set in /boot/loader.conf"); 209121306Ssilby } else { 210121306Ssilby errx(1, "oid '%s' is read only", bufp); 211121849Ssilby } 212121306Ssilby } 213116383Srwatson 214116383Srwatson if ((kind & CTLTYPE) == CTLTYPE_INT || 215116383Srwatson (kind & CTLTYPE) == CTLTYPE_UINT || 216116383Srwatson (kind & CTLTYPE) == CTLTYPE_LONG || 217116383Srwatson (kind & CTLTYPE) == CTLTYPE_ULONG) { 218116383Srwatson if (strlen(newval) == 0) 219116383Srwatson errx(1, "empty numeric value"); 220116383Srwatson } 221122234Sdes 22212946Sphk switch (kind & CTLTYPE) { 22312946Sphk case CTLTYPE_INT: 224121849Ssilby intval = (int)strtol(newval, &endptr, 0); 225116383Srwatson if (endptr == newval || *endptr != '\0') 226116383Srwatson errx(1, "invalid integer '%s'", 227116383Srwatson newval); 22812946Sphk newval = &intval; 22977928Sdd newsize = sizeof(intval); 2301553Srgrimes break; 23178434Spirzyk case CTLTYPE_UINT: 232116383Srwatson uintval = (int) strtoul(newval, &endptr, 0); 233116383Srwatson if (endptr == newval || *endptr != '\0') 234116383Srwatson errx(1, "invalid unsigned integer '%s'", 235116383Srwatson newval); 23678434Spirzyk newval = &uintval; 23778434Spirzyk newsize = sizeof uintval; 23812946Sphk break; 23978434Spirzyk case CTLTYPE_LONG: 240116383Srwatson longval = strtol(newval, &endptr, 0); 241116383Srwatson if (endptr == newval || *endptr != '\0') 242116383Srwatson errx(1, "invalid long integer '%s'", 243116383Srwatson newval); 24478434Spirzyk newval = &longval; 24578434Spirzyk newsize = sizeof longval; 24678434Spirzyk break; 24778434Spirzyk case CTLTYPE_ULONG: 248116383Srwatson ulongval = strtoul(newval, &endptr, 0); 249116383Srwatson if (endptr == newval || *endptr != '\0') 250116383Srwatson errx(1, "invalid unsigned long integer" 251116383Srwatson " '%s'", newval); 25278434Spirzyk newval = &ulongval; 25378434Spirzyk newsize = sizeof ulongval; 25478434Spirzyk break; 25512946Sphk case CTLTYPE_STRING: 25612946Sphk break; 25712946Sphk case CTLTYPE_QUAD: 25812946Sphk sscanf(newval, "%qd", &quadval); 25912946Sphk newval = &quadval; 26077928Sdd newsize = sizeof(quadval); 26112946Sphk break; 26288696Sphk case CTLTYPE_OPAQUE: 26388696Sphk if (strcmp(fmt, "T,dev_t") == 0) { 26488696Sphk set_T_dev_t ((char*)newval, &newval, &newsize); 26588696Sphk break; 26688696Sphk } 26788696Sphk /* FALLTHROUGH */ 26812946Sphk default: 26912946Sphk errx(1, "oid '%s' is type %d," 27031214Sjdp " cannot set that", bufp, 27131214Sjdp kind & CTLTYPE); 2721553Srgrimes } 2731553Srgrimes 27412946Sphk i = show_var(mib, len); 27512946Sphk if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { 27612946Sphk if (!i && !bflag) 27712946Sphk putchar('\n'); 27812946Sphk switch (errno) { 27912946Sphk case EOPNOTSUPP: 280122234Sdes errx(1, "%s: value is not available", 28112946Sphk string); 28212946Sphk case ENOTDIR: 283122234Sdes errx(1, "%s: specification is incomplete", 28412946Sphk string); 28512946Sphk case ENOMEM: 286122234Sdes errx(1, "%s: type is unknown to this program", 28712946Sphk string); 28812946Sphk default: 28930602Scharnier warn("%s", string); 29012946Sphk return; 29112946Sphk } 29212946Sphk } 29312946Sphk if (!bflag) 29412946Sphk printf(" -> "); 29512946Sphk i = nflag; 29612946Sphk nflag = 1; 29712946Sphk j = show_var(mib, len); 29812946Sphk if (!j && !bflag) 29912946Sphk putchar('\n'); 30012946Sphk nflag = i; 30112946Sphk } 30212946Sphk} 3031553Srgrimes 30412946Sphk/* These functions will dump out various interesting structures. */ 3051553Srgrimes 30612946Sphkstatic int 30712946SphkS_clockinfo(int l2, void *p) 30812946Sphk{ 30912946Sphk struct clockinfo *ci = (struct clockinfo*)p; 31097232Salfred if (l2 != sizeof(*ci)) { 31197232Salfred warnx("S_clockinfo %d != %d", l2, sizeof(*ci)); 31297232Salfred return (0); 31397232Salfred } 314122233Sdes printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" : 315122233Sdes "{ hz = %d, tick = %d, profhz = %d, stathz = %d }", 31694752Sphk ci->hz, ci->tick, ci->profhz, ci->stathz); 31712946Sphk return (0); 31812946Sphk} 3191553Srgrimes 32012946Sphkstatic int 32112946SphkS_loadavg(int l2, void *p) 32212946Sphk{ 32312946Sphk struct loadavg *tv = (struct loadavg*)p; 3248857Srgrimes 32597232Salfred if (l2 != sizeof(*tv)) { 32697232Salfred warnx("S_loadavg %d != %d", l2, sizeof(*tv)); 32797232Salfred return (0); 32897232Salfred } 329122233Sdes printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }", 33012946Sphk (double)tv->ldavg[0]/(double)tv->fscale, 33112946Sphk (double)tv->ldavg[1]/(double)tv->fscale, 33212946Sphk (double)tv->ldavg[2]/(double)tv->fscale); 33312946Sphk return (0); 33412946Sphk} 3351553Srgrimes 33612946Sphkstatic int 33712946SphkS_timeval(int l2, void *p) 33812946Sphk{ 33912946Sphk struct timeval *tv = (struct timeval*)p; 34037266Sbde time_t tv_sec; 34112946Sphk char *p1, *p2; 3421553Srgrimes 34397232Salfred if (l2 != sizeof(*tv)) { 34497232Salfred warnx("S_timeval %d != %d", l2, sizeof(*tv)); 34597232Salfred return (0); 34697232Salfred } 347122233Sdes printf(hflag ? "{ sec = %'ld, usec = %'ld } " : 348122233Sdes "{ sec = %ld, usec = %ld } ", 34912946Sphk tv->tv_sec, tv->tv_usec); 35037266Sbde tv_sec = tv->tv_sec; 35137266Sbde p1 = strdup(ctime(&tv_sec)); 35212946Sphk for (p2=p1; *p2 ; p2++) 35312946Sphk if (*p2 == '\n') 35412946Sphk *p2 = '\0'; 35512946Sphk fputs(p1, stdout); 35612946Sphk return (0); 35712946Sphk} 3581553Srgrimes 35912946Sphkstatic int 360109097SdillonS_vmtotal(int l2, void *p) 361109097Sdillon{ 362109097Sdillon struct vmtotal *v = (struct vmtotal *)p; 363109113Sdillon int pageKilo = getpagesize() / 1024; 364109097Sdillon 365109097Sdillon if (l2 != sizeof(*v)) { 366109097Sdillon warnx("S_vmtotal %d != %d", l2, sizeof(*v)); 367109097Sdillon return (0); 368109097Sdillon } 369109097Sdillon 370109113Sdillon printf( 371109113Sdillon "\nSystem wide totals computed every five seconds:" 372109113Sdillon " (values in kilobytes)\n"); 373109097Sdillon printf("===============================================\n"); 374109113Sdillon printf( 375109113Sdillon "Processes:\t\t(RUNQ: %hu Disk Wait: %hu Page Wait: " 376109113Sdillon "%hu Sleep: %hu)\n", 377109113Sdillon v->t_rq, v->t_dw, v->t_pw, v->t_sl); 378109113Sdillon printf( 379109113Sdillon "Virtual Memory:\t\t(Total: %luK, Active %lldK)\n", 380109113Sdillon (unsigned long)v->t_vm / 1024, 381109113Sdillon (long long)v->t_avm * pageKilo); 382109113Sdillon printf("Real Memory:\t\t(Total: %lldK Active %lldK)\n", 383109113Sdillon (long long)v->t_rm * pageKilo, (long long)v->t_arm * pageKilo); 384109113Sdillon printf("Shared Virtual Memory:\t(Total: %lldK Active: %lldK)\n", 385122234Sdes (long long)v->t_vmshr * pageKilo, 386109113Sdillon (long long)v->t_avmshr * pageKilo); 387109113Sdillon printf("Shared Real Memory:\t(Total: %lldK Active: %lldK)\n", 388109113Sdillon (long long)v->t_rmshr * pageKilo, 389109113Sdillon (long long)v->t_armshr * pageKilo); 390109113Sdillon printf("Free Memory Pages:\t%ldK\n", (long long)v->t_free * pageKilo); 391122234Sdes 392109097Sdillon return (0); 393109097Sdillon} 394109097Sdillon 395109097Sdillonstatic int 39612946SphkT_dev_t(int l2, void *p) 39712946Sphk{ 39812946Sphk dev_t *d = (dev_t *)p; 39997232Salfred if (l2 != sizeof(*d)) { 40097232Salfred warnx("T_dev_T %d != %d", l2, sizeof(*d)); 40197232Salfred return (0); 40297232Salfred } 40361514Sphk if ((int)(*d) != -1) { 40461514Sphk if (minor(*d) > 255 || minor(*d) < 0) 40561514Sphk printf("{ major = %d, minor = 0x%x }", 40661514Sphk major(*d), minor(*d)); 40761514Sphk else 40861514Sphk printf("{ major = %d, minor = %d }", 40961514Sphk major(*d), minor(*d)); 41061514Sphk } 41112946Sphk return (0); 41212946Sphk} 4131553Srgrimes 41488696Sphkstatic void 415121542Speterset_T_dev_t (char *path, void **val, size_t *size) 41688696Sphk{ 41788696Sphk static struct stat statb; 41888696Sphk 41988696Sphk if (strcmp(path, "none") && strcmp(path, "off")) { 42088696Sphk int rc = stat (path, &statb); 42188696Sphk if (rc) { 42288696Sphk err(1, "cannot stat %s", path); 42388696Sphk } 42488696Sphk 42588696Sphk if (!S_ISCHR(statb.st_mode)) { 42688696Sphk errx(1, "must specify a device special file."); 42788696Sphk } 42888696Sphk } else { 42988696Sphk statb.st_rdev = NODEV; 43088696Sphk } 43188696Sphk *val = (char*) &statb.st_rdev; 43288696Sphk *size = sizeof statb.st_rdev; 43388696Sphk} 43488696Sphk 43512946Sphk/* 43612946Sphk * These functions uses a presently undocumented interface to the kernel 43712946Sphk * to walk the tree and get the type so it can print the value. 43812946Sphk * This interface is under work and consideration, and should probably 43912946Sphk * be killed with a big axe by the first person who can find the time. 44012946Sphk * (be aware though, that the proper interface isn't as obvious as it 44112946Sphk * may seem, there are various conflicting requirements. 44212946Sphk */ 4431553Srgrimes 44412946Sphkstatic int 44512946Sphkname2oid(char *name, int *oidp) 44612946Sphk{ 44712946Sphk int oid[2]; 44838533Sdfr int i; 44938533Sdfr size_t j; 4501553Srgrimes 45112946Sphk oid[0] = 0; 45212946Sphk oid[1] = 3; 4531553Srgrimes 45477928Sdd j = CTL_MAXNAME * sizeof(int); 45512946Sphk i = sysctl(oid, 2, oidp, &j, name, strlen(name)); 456122234Sdes if (i < 0) 45712946Sphk return i; 45877928Sdd j /= sizeof(int); 45912946Sphk return (j); 4601553Srgrimes} 4611553Srgrimes 46212946Sphkstatic int 46312946Sphkoidfmt(int *oid, int len, char *fmt, u_int *kind) 46412946Sphk{ 46512946Sphk int qoid[CTL_MAXNAME+2]; 46612946Sphk u_char buf[BUFSIZ]; 46738533Sdfr int i; 46838533Sdfr size_t j; 4691553Srgrimes 47012946Sphk qoid[0] = 0; 47112946Sphk qoid[1] = 4; 47212946Sphk memcpy(qoid + 2, oid, len * sizeof(int)); 4731553Srgrimes 47477928Sdd j = sizeof(buf); 47512946Sphk i = sysctl(qoid, len + 2, buf, &j, 0, 0); 47612946Sphk if (i) 47730602Scharnier err(1, "sysctl fmt %d %d %d", i, j, errno); 4781553Srgrimes 47912946Sphk if (kind) 48012946Sphk *kind = *(u_int *)buf; 48112946Sphk 48212946Sphk if (fmt) 48312946Sphk strcpy(fmt, (char *)(buf + sizeof(u_int))); 48412946Sphk return 0; 4851553Srgrimes} 4861553Srgrimes 4871553Srgrimes/* 48812946Sphk * This formats and outputs the value of one variable 48912946Sphk * 49012946Sphk * Returns zero if anything was actually output. 49112946Sphk * Returns one if didn't know what to do with this. 49212946Sphk * Return minus one if we had errors. 4931553Srgrimes */ 49412946Sphk 49512946Sphkstatic int 49612946Sphkshow_var(int *oid, int nlen) 4971553Srgrimes{ 49812946Sphk u_char buf[BUFSIZ], *val, *p; 49985747Stobez char name[BUFSIZ], *fmt, *sep; 50012946Sphk int qoid[CTL_MAXNAME+2]; 50138533Sdfr int i; 50238533Sdfr size_t j, len; 50312946Sphk u_int kind; 50477332Sdes int (*func)(int, void *); 5051553Srgrimes 50642456Sdes qoid[0] = 0; 50742456Sdes memcpy(qoid + 2, oid, nlen * sizeof(int)); 50842456Sdes 50942456Sdes qoid[1] = 1; 51077928Sdd j = sizeof(name); 51142456Sdes i = sysctl(qoid, nlen + 2, name, &j, 0, 0); 51242456Sdes if (i || !j) 51342456Sdes err(1, "sysctl name %d %d %d", i, j, errno); 51442456Sdes 51571034Sdes if (Nflag) { 51671034Sdes printf("%s", name); 51771034Sdes return (0); 51871034Sdes } 51971034Sdes 52085747Stobez if (eflag) 52185747Stobez sep = "="; 52285747Stobez else 52385747Stobez sep = ": "; 52485747Stobez 52588006Sluigi if (dflag) { /* just print description */ 52688006Sluigi qoid[1] = 5; 52788006Sluigi j = sizeof(buf); 52888006Sluigi i = sysctl(qoid, nlen + 2, buf, &j, 0, 0); 52988006Sluigi if (!nflag) 53088006Sluigi printf("%s%s", name, sep); 53188006Sluigi printf("%s", buf); 53288006Sluigi return (0); 53388006Sluigi } 53412946Sphk /* find an estimate of how much we need for this var */ 53512946Sphk j = 0; 53612946Sphk i = sysctl(oid, nlen, 0, &j, 0, 0); 53712946Sphk j += j; /* we want to be sure :-) */ 53812946Sphk 539109671Speter val = alloca(j + 1); 54012946Sphk len = j; 54112946Sphk i = sysctl(oid, nlen, val, &len, 0, 0); 54212946Sphk if (i || !len) 54312946Sphk return (1); 54412946Sphk 54512946Sphk if (bflag) { 54612946Sphk fwrite(val, 1, len, stdout); 54712946Sphk return (0); 5481553Srgrimes } 54996234Sache val[len] = '\0'; 55088696Sphk fmt = buf; 55188696Sphk oidfmt(oid, nlen, fmt, &kind); 55212946Sphk p = val; 55312946Sphk switch (*fmt) { 55412946Sphk case 'A': 55512946Sphk if (!nflag) 55685747Stobez printf("%s%s", name, sep); 557106829Speter printf("%.*s", len, p); 55812946Sphk return (0); 559122234Sdes 56012946Sphk case 'I': 56112946Sphk if (!nflag) 56285747Stobez printf("%s%s", name, sep); 56362622Sjhb fmt++; 56441019Sphk val = ""; 56541019Sphk while (len >= sizeof(int)) { 566122233Sdes fputs(val, stdout); 56762622Sjhb if(*fmt == 'U') 568122233Sdes printf(hflag ? "%'u" : "%u", *(unsigned int *)p); 56962622Sjhb else 570122233Sdes printf(hflag ? "%'d" : "%d", *(int *)p); 57141019Sphk val = " "; 57277332Sdes len -= sizeof(int); 57377332Sdes p += sizeof(int); 57441019Sphk } 57512946Sphk return (0); 57612946Sphk 57738533Sdfr case 'L': 57838533Sdfr if (!nflag) 57985747Stobez printf("%s%s", name, sep); 58062622Sjhb fmt++; 58162975Sphk val = ""; 58262975Sphk while (len >= sizeof(long)) { 583122233Sdes fputs(val, stdout); 58462975Sphk if(*fmt == 'U') 585122233Sdes printf(hflag ? "%'lu" : "%lu", *(unsigned long *)p); 58662975Sphk else 587122233Sdes printf(hflag ? "%'ld" : "%ld", *(long *)p); 58862975Sphk val = " "; 58977332Sdes len -= sizeof(long); 59077332Sdes p += sizeof(long); 59162975Sphk } 59238533Sdfr return (0); 59338533Sdfr 59438533Sdfr case 'P': 59538533Sdfr if (!nflag) 59685747Stobez printf("%s%s", name, sep); 59738533Sdfr printf("%p", *(void **)p); 59838533Sdfr return (0); 59938533Sdfr 60012946Sphk case 'T': 60112946Sphk case 'S': 60212946Sphk i = 0; 60377332Sdes if (strcmp(fmt, "S,clockinfo") == 0) 60477332Sdes func = S_clockinfo; 60577332Sdes else if (strcmp(fmt, "S,timeval") == 0) 60677332Sdes func = S_timeval; 60777332Sdes else if (strcmp(fmt, "S,loadavg") == 0) 60877332Sdes func = S_loadavg; 609109097Sdillon else if (strcmp(fmt, "S,vmtotal") == 0) 610109097Sdillon func = S_vmtotal; 61177332Sdes else if (strcmp(fmt, "T,dev_t") == 0) 61277332Sdes func = T_dev_t; 61377332Sdes else 61477332Sdes func = NULL; 61512946Sphk if (func) { 61612946Sphk if (!nflag) 61785747Stobez printf("%s%s", name, sep); 61812946Sphk return ((*func)(len, p)); 61912946Sphk } 620102411Scharnier /* FALLTHROUGH */ 62112946Sphk default: 62277330Sdes if (!oflag && !xflag) 62312946Sphk return (1); 62412946Sphk if (!nflag) 62585747Stobez printf("%s%s", name, sep); 62612946Sphk printf("Format:%s Length:%d Dump:0x", fmt, len); 62777332Sdes while (len-- && (xflag || p < val + 16)) 62812946Sphk printf("%02x", *p++); 62977332Sdes if (!xflag && len > 16) 63012946Sphk printf("..."); 63112946Sphk return (0); 6321553Srgrimes } 63312946Sphk return (1); 6341553Srgrimes} 6351553Srgrimes 63612946Sphkstatic int 63712946Sphksysctl_all (int *oid, int len) 6381553Srgrimes{ 63912946Sphk int name1[22], name2[22]; 64038533Sdfr int i, j; 64138533Sdfr size_t l1, l2; 6421553Srgrimes 64312946Sphk name1[0] = 0; 64412946Sphk name1[1] = 2; 64512946Sphk l1 = 2; 64612946Sphk if (len) { 64777928Sdd memcpy(name1+2, oid, len * sizeof(int)); 64812946Sphk l1 += len; 64912946Sphk } else { 65012946Sphk name1[2] = 1; 65112946Sphk l1++; 65212946Sphk } 65377332Sdes for (;;) { 65477928Sdd l2 = sizeof(name2); 65512946Sphk j = sysctl(name1, l1, name2, &l2, 0, 0); 65648956Sbillf if (j < 0) { 65712946Sphk if (errno == ENOENT) 65812946Sphk return 0; 65912946Sphk else 66030602Scharnier err(1, "sysctl(getnext) %d %d", j, l2); 66148956Sbillf } 66212946Sphk 66377928Sdd l2 /= sizeof(int); 66412946Sphk 66512946Sphk if (l2 < len) 66612946Sphk return 0; 66712946Sphk 66812946Sphk for (i = 0; i < len; i++) 66912946Sphk if (name2[i] != oid[i]) 67012946Sphk return 0; 67112946Sphk 67212946Sphk i = show_var(name2, l2); 67312946Sphk if (!i && !bflag) 67412946Sphk putchar('\n'); 67512946Sphk 67677928Sdd memcpy(name1+2, name2, l2 * sizeof(int)); 67712946Sphk l1 = 2 + l2; 67812946Sphk } 6791553Srgrimes} 680