sysctl.c revision 244106
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 * 4. Neither the name of the University nor the names of its contributors 141553Srgrimes * may be used to endorse or promote products derived from this software 151553Srgrimes * without specific prior written permission. 161553Srgrimes * 171553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271553Srgrimes * SUCH DAMAGE. 281553Srgrimes */ 291553Srgrimes 301553Srgrimes#ifndef lint 3130602Scharnierstatic const char copyright[] = 321553Srgrimes"@(#) Copyright (c) 1993\n\ 331553Srgrimes The Regents of the University of California. All rights reserved.\n"; 341553Srgrimes#endif /* not lint */ 351553Srgrimes 361553Srgrimes#ifndef lint 3730602Scharnier#if 0 3830602Scharnierstatic char sccsid[] = "@(#)from: sysctl.c 8.1 (Berkeley) 6/6/93"; 3930602Scharnier#endif 406284Swollmanstatic const char rcsid[] = 4150476Speter "$FreeBSD: head/sbin/sysctl/sysctl.c 244106 2012-12-11 01:28:06Z alfred $"; 421553Srgrimes#endif /* not lint */ 431553Srgrimes 4491217Sbde#include <sys/param.h> 4591217Sbde#include <sys/time.h> 4691217Sbde#include <sys/resource.h> 471553Srgrimes#include <sys/stat.h> 481553Srgrimes#include <sys/sysctl.h> 49109097Sdillon#include <sys/vmmeter.h> 501553Srgrimes 5130602Scharnier#include <ctype.h> 5230602Scharnier#include <err.h> 531553Srgrimes#include <errno.h> 54170287Sdwmalone#include <inttypes.h> 55122233Sdes#include <locale.h> 561553Srgrimes#include <stdio.h> 571553Srgrimes#include <stdlib.h> 581553Srgrimes#include <string.h> 5930602Scharnier#include <unistd.h> 601553Srgrimes 61203310Sgavinstatic int aflag, bflag, dflag, eflag, hflag, iflag; 62244106Salfredstatic int Nflag, nflag, oflag, qflag, Tflag, Wflag, xflag, warncount; 631553Srgrimes 6412946Sphkstatic int oidfmt(int *, int, char *, u_int *); 65244104Sdelphijstatic void parse(const char *); 6612946Sphkstatic int show_var(int *, int); 67170512Sdwmalonestatic int sysctl_all(int *oid, int len); 6812946Sphkstatic int name2oid(char *, int *); 691553Srgrimes 70198340Sedstatic int set_IK(const char *, int *); 7188696Sphk 7212946Sphkstatic void 7312946Sphkusage(void) 7412946Sphk{ 751553Srgrimes 7677330Sdes (void)fprintf(stderr, "%s\n%s\n", 77244106Salfred "usage: sysctl [-bdehiNnoqTWx] name[=value] ...", 78244106Salfred " sysctl [-bdehNnoqTWx] -a"); 7912946Sphk exit(1); 8012946Sphk} 811553Srgrimes 821553Srgrimesint 8312946Sphkmain(int argc, char **argv) 841553Srgrimes{ 8512946Sphk int ch; 86122233Sdes 87122233Sdes setlocale(LC_NUMERIC, ""); 8812946Sphk setbuf(stdout,0); 8912946Sphk setbuf(stderr,0); 901553Srgrimes 91244106Salfred while ((ch = getopt(argc, argv, "AabdehiNnoqTwWxX")) != -1) { 921553Srgrimes switch (ch) { 9371034Sdes case 'A': 9477330Sdes /* compatibility */ 9577330Sdes aflag = oflag = 1; 9671034Sdes break; 9771034Sdes case 'a': 9871034Sdes aflag = 1; 9971034Sdes break; 10071034Sdes case 'b': 10171034Sdes bflag = 1; 10271034Sdes break; 10388006Sluigi case 'd': 10488006Sluigi dflag = 1; 10588006Sluigi break; 10685747Stobez case 'e': 10785747Stobez eflag = 1; 10885747Stobez break; 109122233Sdes case 'h': 110122233Sdes hflag = 1; 111122233Sdes break; 112203310Sgavin case 'i': 113203310Sgavin iflag = 1; 114203310Sgavin break; 11571034Sdes case 'N': 11671034Sdes Nflag = 1; 11771034Sdes break; 11871034Sdes case 'n': 11971034Sdes nflag = 1; 12071034Sdes break; 12177330Sdes case 'o': 12277330Sdes oflag = 1; 12377330Sdes break; 124150167Srwatson case 'q': 125150167Srwatson qflag = 1; 126150167Srwatson break; 127244106Salfred case 'T': 128244106Salfred Tflag = 1; 129244106Salfred break; 13071034Sdes case 'w': 13177330Sdes /* compatibility */ 13277330Sdes /* ignored */ 13371034Sdes break; 134244106Salfred case 'W': 135244106Salfred Wflag = 1; 136244106Salfred break; 13771034Sdes case 'X': 13877330Sdes /* compatibility */ 13977330Sdes aflag = xflag = 1; 14071034Sdes break; 14177330Sdes case 'x': 14277330Sdes xflag = 1; 14377330Sdes break; 14471034Sdes default: 14571034Sdes usage(); 1461553Srgrimes } 1471553Srgrimes } 1481553Srgrimes argc -= optind; 1491553Srgrimes argv += optind; 1501553Srgrimes 15177330Sdes if (Nflag && nflag) 15242456Sdes usage(); 15377330Sdes if (aflag && argc == 0) 15477330Sdes exit(sysctl_all(0, 0)); 1551553Srgrimes if (argc == 0) 1561553Srgrimes usage(); 157179965Smtm 158179965Smtm warncount = 0; 1591553Srgrimes while (argc-- > 0) 16012946Sphk parse(*argv++); 161179965Smtm exit(warncount); 1621553Srgrimes} 1631553Srgrimes 1641553Srgrimes/* 1651553Srgrimes * Parse a name into a MIB entry. 1661553Srgrimes * Lookup and print out the MIB entry if it exists. 1671553Srgrimes * Set a new value if requested. 1681553Srgrimes */ 16912946Sphkstatic void 170244104Sdelphijparse(const char *string) 1711553Srgrimes{ 17212946Sphk int len, i, j; 1731553Srgrimes void *newval = 0; 17478434Spirzyk int intval; 17578434Spirzyk unsigned int uintval; 17678434Spirzyk long longval; 17778434Spirzyk unsigned long ulongval; 17878434Spirzyk size_t newsize = 0; 179217616Smdf int64_t i64val; 180217616Smdf uint64_t u64val; 1811553Srgrimes int mib[CTL_MAXNAME]; 182116383Srwatson char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ]; 18312946Sphk u_int kind; 1841553Srgrimes 185244104Sdelphij cp = buf; 186140818Sssouhlal if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ) 187140818Sssouhlal errx(1, "oid too long: '%s'", string); 188244104Sdelphij bufp = strsep(&cp, "="); 189244104Sdelphij if (cp != NULL) { 190244106Salfred /* Tflag just lists tunables, do not allow assignment */ 191244106Salfred if (Tflag || Wflag) { 192244106Salfred warnx("Can't set variables when using -T or -W"); 193244106Salfred usage(); 194244106Salfred } 1951553Srgrimes while (isspace(*cp)) 1961553Srgrimes cp++; 1971553Srgrimes newval = cp; 1981553Srgrimes newsize = strlen(cp); 1991553Srgrimes } 20012946Sphk len = name2oid(bufp, mib); 2011553Srgrimes 202150167Srwatson if (len < 0) { 203203310Sgavin if (iflag) 204203310Sgavin return; 205150167Srwatson if (qflag) 206150167Srwatson exit(1); 207150167Srwatson else 208150167Srwatson errx(1, "unknown oid '%s'", bufp); 209150167Srwatson } 2101553Srgrimes 21188696Sphk if (oidfmt(mib, len, fmt, &kind)) 21230602Scharnier err(1, "couldn't find format of oid '%s'", bufp); 2131553Srgrimes 214228181Sjhb if (newval == NULL || dflag) { 21512946Sphk if ((kind & CTLTYPE) == CTLTYPE_NODE) { 216144998Smdodd if (dflag) { 217144998Smdodd i = show_var(mib, len); 218144998Smdodd if (!i && !bflag) 219144998Smdodd putchar('\n'); 220144998Smdodd } 22112946Sphk sysctl_all(mib, len); 22212946Sphk } else { 22312946Sphk i = show_var(mib, len); 22412946Sphk if (!i && !bflag) 22512946Sphk putchar('\n'); 2261553Srgrimes } 22712946Sphk } else { 22812946Sphk if ((kind & CTLTYPE) == CTLTYPE_NODE) 22912946Sphk errx(1, "oid '%s' isn't a leaf node", bufp); 2301553Srgrimes 231121849Ssilby if (!(kind & CTLFLAG_WR)) { 232121306Ssilby if (kind & CTLFLAG_TUN) { 233121849Ssilby warnx("oid '%s' is a read only tunable", bufp); 234121849Ssilby errx(1, "Tunable values are set in /boot/loader.conf"); 235121306Ssilby } else { 236121306Ssilby errx(1, "oid '%s' is read only", bufp); 237121849Ssilby } 238121306Ssilby } 239116383Srwatson 240116383Srwatson if ((kind & CTLTYPE) == CTLTYPE_INT || 241116383Srwatson (kind & CTLTYPE) == CTLTYPE_UINT || 242116383Srwatson (kind & CTLTYPE) == CTLTYPE_LONG || 243126472Sdd (kind & CTLTYPE) == CTLTYPE_ULONG || 244217616Smdf (kind & CTLTYPE) == CTLTYPE_S64 || 245217616Smdf (kind & CTLTYPE) == CTLTYPE_U64) { 246116383Srwatson if (strlen(newval) == 0) 247116383Srwatson errx(1, "empty numeric value"); 248116383Srwatson } 249122234Sdes 25012946Sphk switch (kind & CTLTYPE) { 25112946Sphk case CTLTYPE_INT: 252161951Sume if (strcmp(fmt, "IK") == 0) { 253170512Sdwmalone if (!set_IK(newval, &intval)) 254161951Sume errx(1, "invalid value '%s'", 255170513Sdwmalone (char *)newval); 256161951Sume } else { 257161951Sume intval = (int)strtol(newval, &endptr, 258161951Sume 0); 259161951Sume if (endptr == newval || *endptr != '\0') 260161951Sume errx(1, "invalid integer '%s'", 261170513Sdwmalone (char *)newval); 262161951Sume } 26312946Sphk newval = &intval; 26477928Sdd newsize = sizeof(intval); 2651553Srgrimes break; 26678434Spirzyk case CTLTYPE_UINT: 267116383Srwatson uintval = (int) strtoul(newval, &endptr, 0); 268116383Srwatson if (endptr == newval || *endptr != '\0') 269116383Srwatson errx(1, "invalid unsigned integer '%s'", 270170513Sdwmalone (char *)newval); 27178434Spirzyk newval = &uintval; 272170512Sdwmalone newsize = sizeof(uintval); 27312946Sphk break; 27478434Spirzyk case CTLTYPE_LONG: 275116383Srwatson longval = strtol(newval, &endptr, 0); 276116383Srwatson if (endptr == newval || *endptr != '\0') 277116383Srwatson errx(1, "invalid long integer '%s'", 278170513Sdwmalone (char *)newval); 27978434Spirzyk newval = &longval; 280170512Sdwmalone newsize = sizeof(longval); 28178434Spirzyk break; 28278434Spirzyk case CTLTYPE_ULONG: 283116383Srwatson ulongval = strtoul(newval, &endptr, 0); 284116383Srwatson if (endptr == newval || *endptr != '\0') 285116383Srwatson errx(1, "invalid unsigned long integer" 286170513Sdwmalone " '%s'", (char *)newval); 28778434Spirzyk newval = &ulongval; 288170512Sdwmalone newsize = sizeof(ulongval); 28978434Spirzyk break; 29012946Sphk case CTLTYPE_STRING: 29112946Sphk break; 292217616Smdf case CTLTYPE_S64: 293217616Smdf i64val = strtoimax(newval, &endptr, 0); 294203917Suqs if (endptr == newval || *endptr != '\0') 295217616Smdf errx(1, "invalid int64_t '%s'", 296217616Smdf (char *)newval); 297217616Smdf newval = &i64val; 298217616Smdf newsize = sizeof(i64val); 29912946Sphk break; 300217616Smdf case CTLTYPE_U64: 301217616Smdf u64val = strtoumax(newval, &endptr, 0); 302217616Smdf if (endptr == newval || *endptr != '\0') 303217616Smdf errx(1, "invalid uint64_t '%s'", 304217616Smdf (char *)newval); 305217616Smdf newval = &u64val; 306217616Smdf newsize = sizeof(u64val); 307217616Smdf break; 30888696Sphk case CTLTYPE_OPAQUE: 30988696Sphk /* FALLTHROUGH */ 31012946Sphk default: 31112946Sphk errx(1, "oid '%s' is type %d," 31231214Sjdp " cannot set that", bufp, 31331214Sjdp kind & CTLTYPE); 3141553Srgrimes } 3151553Srgrimes 31612946Sphk i = show_var(mib, len); 31712946Sphk if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { 31812946Sphk if (!i && !bflag) 31912946Sphk putchar('\n'); 32012946Sphk switch (errno) { 32112946Sphk case EOPNOTSUPP: 322122234Sdes errx(1, "%s: value is not available", 32312946Sphk string); 32412946Sphk case ENOTDIR: 325122234Sdes errx(1, "%s: specification is incomplete", 32612946Sphk string); 32712946Sphk case ENOMEM: 328122234Sdes errx(1, "%s: type is unknown to this program", 32912946Sphk string); 33012946Sphk default: 33130602Scharnier warn("%s", string); 332179965Smtm warncount++; 33312946Sphk return; 33412946Sphk } 33512946Sphk } 33612946Sphk if (!bflag) 33712946Sphk printf(" -> "); 33812946Sphk i = nflag; 33912946Sphk nflag = 1; 34012946Sphk j = show_var(mib, len); 34112946Sphk if (!j && !bflag) 34212946Sphk putchar('\n'); 34312946Sphk nflag = i; 34412946Sphk } 34512946Sphk} 3461553Srgrimes 34712946Sphk/* These functions will dump out various interesting structures. */ 3481553Srgrimes 34912946Sphkstatic int 35012946SphkS_clockinfo(int l2, void *p) 35112946Sphk{ 35212946Sphk struct clockinfo *ci = (struct clockinfo*)p; 353170512Sdwmalone 35497232Salfred if (l2 != sizeof(*ci)) { 355203917Suqs warnx("S_clockinfo %d != %zu", l2, sizeof(*ci)); 356170558Sbde return (1); 35797232Salfred } 358122233Sdes printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" : 359122233Sdes "{ hz = %d, tick = %d, profhz = %d, stathz = %d }", 36094752Sphk ci->hz, ci->tick, ci->profhz, ci->stathz); 36112946Sphk return (0); 36212946Sphk} 3631553Srgrimes 36412946Sphkstatic int 36512946SphkS_loadavg(int l2, void *p) 36612946Sphk{ 36712946Sphk struct loadavg *tv = (struct loadavg*)p; 3688857Srgrimes 36997232Salfred if (l2 != sizeof(*tv)) { 370203917Suqs warnx("S_loadavg %d != %zu", l2, sizeof(*tv)); 371170558Sbde return (1); 37297232Salfred } 373122233Sdes printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }", 37412946Sphk (double)tv->ldavg[0]/(double)tv->fscale, 37512946Sphk (double)tv->ldavg[1]/(double)tv->fscale, 37612946Sphk (double)tv->ldavg[2]/(double)tv->fscale); 37712946Sphk return (0); 37812946Sphk} 3791553Srgrimes 38012946Sphkstatic int 38112946SphkS_timeval(int l2, void *p) 38212946Sphk{ 38312946Sphk struct timeval *tv = (struct timeval*)p; 38437266Sbde time_t tv_sec; 38512946Sphk char *p1, *p2; 3861553Srgrimes 38797232Salfred if (l2 != sizeof(*tv)) { 388203917Suqs warnx("S_timeval %d != %zu", l2, sizeof(*tv)); 389170558Sbde return (1); 39097232Salfred } 391194684Sjhay printf(hflag ? "{ sec = %'jd, usec = %'ld } " : 392194684Sjhay "{ sec = %jd, usec = %ld } ", 393194684Sjhay (intmax_t)tv->tv_sec, tv->tv_usec); 39437266Sbde tv_sec = tv->tv_sec; 39537266Sbde p1 = strdup(ctime(&tv_sec)); 39612946Sphk for (p2=p1; *p2 ; p2++) 39712946Sphk if (*p2 == '\n') 39812946Sphk *p2 = '\0'; 39912946Sphk fputs(p1, stdout); 400205118Sbrucec free(p1); 40112946Sphk return (0); 40212946Sphk} 4031553Srgrimes 40412946Sphkstatic int 405109097SdillonS_vmtotal(int l2, void *p) 406109097Sdillon{ 407109097Sdillon struct vmtotal *v = (struct vmtotal *)p; 408109113Sdillon int pageKilo = getpagesize() / 1024; 409109097Sdillon 410109097Sdillon if (l2 != sizeof(*v)) { 411203917Suqs warnx("S_vmtotal %d != %zu", l2, sizeof(*v)); 412170558Sbde return (1); 413109097Sdillon } 414109097Sdillon 415109113Sdillon printf( 416109113Sdillon "\nSystem wide totals computed every five seconds:" 417109113Sdillon " (values in kilobytes)\n"); 418109097Sdillon printf("===============================================\n"); 419109113Sdillon printf( 420164718Sru "Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: " 421164718Sru "%hd Sleep: %hd)\n", 422109113Sdillon v->t_rq, v->t_dw, v->t_pw, v->t_sl); 423109113Sdillon printf( 424212726Szec "Virtual Memory:\t\t(Total: %dK Active: %dK)\n", 425164718Sru v->t_vm * pageKilo, v->t_avm * pageKilo); 426212726Szec printf("Real Memory:\t\t(Total: %dK Active: %dK)\n", 427164718Sru v->t_rm * pageKilo, v->t_arm * pageKilo); 428164718Sru printf("Shared Virtual Memory:\t(Total: %dK Active: %dK)\n", 429164718Sru v->t_vmshr * pageKilo, v->t_avmshr * pageKilo); 430164718Sru printf("Shared Real Memory:\t(Total: %dK Active: %dK)\n", 431164718Sru v->t_rmshr * pageKilo, v->t_armshr * pageKilo); 432234134Seadler printf("Free Memory:\t%dK\n", v->t_free * pageKilo); 433122234Sdes 434109097Sdillon return (0); 435109097Sdillon} 436109097Sdillon 437109097Sdillonstatic int 438198340Sedset_IK(const char *str, int *val) 439161951Sume{ 440161951Sume float temp; 441161951Sume int len, kelv; 442198340Sed const char *p; 443198340Sed char *endptr; 444161951Sume 445161951Sume if ((len = strlen(str)) == 0) 446161951Sume return (0); 447161951Sume p = &str[len - 1]; 448161951Sume if (*p == 'C' || *p == 'F') { 449161951Sume temp = strtof(str, &endptr); 450198340Sed if (endptr == str || endptr != p) 451161951Sume return (0); 452161951Sume if (*p == 'F') 453161951Sume temp = (temp - 32) * 5 / 9; 454161951Sume kelv = temp * 10 + 2732; 455161951Sume } else { 456161951Sume kelv = (int)strtol(str, &endptr, 10); 457161951Sume if (endptr == str || *endptr != '\0') 458161951Sume return (0); 459161951Sume } 460161951Sume *val = kelv; 461161951Sume return (1); 462161951Sume} 463161951Sume 46412946Sphk/* 46512946Sphk * These functions uses a presently undocumented interface to the kernel 46612946Sphk * to walk the tree and get the type so it can print the value. 46712946Sphk * This interface is under work and consideration, and should probably 46812946Sphk * be killed with a big axe by the first person who can find the time. 46912946Sphk * (be aware though, that the proper interface isn't as obvious as it 47012946Sphk * may seem, there are various conflicting requirements. 47112946Sphk */ 4721553Srgrimes 47312946Sphkstatic int 47412946Sphkname2oid(char *name, int *oidp) 47512946Sphk{ 47612946Sphk int oid[2]; 47738533Sdfr int i; 47838533Sdfr size_t j; 4791553Srgrimes 48012946Sphk oid[0] = 0; 48112946Sphk oid[1] = 3; 4821553Srgrimes 48377928Sdd j = CTL_MAXNAME * sizeof(int); 48412946Sphk i = sysctl(oid, 2, oidp, &j, name, strlen(name)); 485122234Sdes if (i < 0) 486170512Sdwmalone return (i); 48777928Sdd j /= sizeof(int); 48812946Sphk return (j); 4891553Srgrimes} 4901553Srgrimes 49112946Sphkstatic int 49212946Sphkoidfmt(int *oid, int len, char *fmt, u_int *kind) 49312946Sphk{ 49412946Sphk int qoid[CTL_MAXNAME+2]; 49512946Sphk u_char buf[BUFSIZ]; 49638533Sdfr int i; 49738533Sdfr size_t j; 4981553Srgrimes 49912946Sphk qoid[0] = 0; 50012946Sphk qoid[1] = 4; 50112946Sphk memcpy(qoid + 2, oid, len * sizeof(int)); 5021553Srgrimes 50377928Sdd j = sizeof(buf); 50412946Sphk i = sysctl(qoid, len + 2, buf, &j, 0, 0); 50512946Sphk if (i) 506203917Suqs err(1, "sysctl fmt %d %zu %d", i, j, errno); 5071553Srgrimes 50812946Sphk if (kind) 50912946Sphk *kind = *(u_int *)buf; 51012946Sphk 51112946Sphk if (fmt) 51212946Sphk strcpy(fmt, (char *)(buf + sizeof(u_int))); 513170512Sdwmalone return (0); 5141553Srgrimes} 5151553Srgrimes 516217616Smdfstatic int ctl_sign[CTLTYPE+1] = { 517217616Smdf [CTLTYPE_INT] = 1, 518217616Smdf [CTLTYPE_LONG] = 1, 519217616Smdf [CTLTYPE_S64] = 1, 520217616Smdf}; 521217616Smdf 522217616Smdfstatic int ctl_size[CTLTYPE+1] = { 523217616Smdf [CTLTYPE_INT] = sizeof(int), 524217616Smdf [CTLTYPE_UINT] = sizeof(u_int), 525217616Smdf [CTLTYPE_LONG] = sizeof(long), 526217616Smdf [CTLTYPE_ULONG] = sizeof(u_long), 527217616Smdf [CTLTYPE_S64] = sizeof(int64_t), 528217616Smdf [CTLTYPE_U64] = sizeof(int64_t), 529217616Smdf}; 530217616Smdf 5311553Srgrimes/* 53212946Sphk * This formats and outputs the value of one variable 53312946Sphk * 53412946Sphk * Returns zero if anything was actually output. 53512946Sphk * Returns one if didn't know what to do with this. 53612946Sphk * Return minus one if we had errors. 5371553Srgrimes */ 53812946Sphkstatic int 53912946Sphkshow_var(int *oid, int nlen) 5401553Srgrimes{ 541162073Sru u_char buf[BUFSIZ], *val, *oval, *p; 542170513Sdwmalone char name[BUFSIZ], *fmt; 543170513Sdwmalone const char *sep, *sep1; 54412946Sphk int qoid[CTL_MAXNAME+2]; 545170512Sdwmalone uintmax_t umv; 546170512Sdwmalone intmax_t mv; 547217586Smdf int i, hexlen, sign, ctltype; 548170287Sdwmalone size_t intlen; 54938533Sdfr size_t j, len; 55012946Sphk u_int kind; 55177332Sdes int (*func)(int, void *); 5521553Srgrimes 553203917Suqs /* Silence GCC. */ 554203917Suqs umv = mv = intlen = 0; 555203917Suqs 556144997Smdodd bzero(buf, BUFSIZ); 557144997Smdodd bzero(name, BUFSIZ); 55842456Sdes qoid[0] = 0; 55942456Sdes memcpy(qoid + 2, oid, nlen * sizeof(int)); 56042456Sdes 56142456Sdes qoid[1] = 1; 56277928Sdd j = sizeof(name); 56342456Sdes i = sysctl(qoid, nlen + 2, name, &j, 0, 0); 56442456Sdes if (i || !j) 565203917Suqs err(1, "sysctl name %d %zu %d", i, j, errno); 56642456Sdes 56771034Sdes if (Nflag) { 56871034Sdes printf("%s", name); 56971034Sdes return (0); 57071034Sdes } 57171034Sdes 57285747Stobez if (eflag) 57385747Stobez sep = "="; 57485747Stobez else 57585747Stobez sep = ": "; 57685747Stobez 57788006Sluigi if (dflag) { /* just print description */ 57888006Sluigi qoid[1] = 5; 57988006Sluigi j = sizeof(buf); 58088006Sluigi i = sysctl(qoid, nlen + 2, buf, &j, 0, 0); 58188006Sluigi if (!nflag) 58288006Sluigi printf("%s%s", name, sep); 58388006Sluigi printf("%s", buf); 58488006Sluigi return (0); 58588006Sluigi } 58612946Sphk /* find an estimate of how much we need for this var */ 58712946Sphk j = 0; 58812946Sphk i = sysctl(oid, nlen, 0, &j, 0, 0); 58912946Sphk j += j; /* we want to be sure :-) */ 59012946Sphk 591162073Sru val = oval = malloc(j + 1); 592162073Sru if (val == NULL) { 593162073Sru warnx("malloc failed"); 594170558Sbde return (1); 595162073Sru } 59612946Sphk len = j; 59712946Sphk i = sysctl(oid, nlen, val, &len, 0, 0); 598162073Sru if (i || !len) { 599162073Sru free(oval); 60012946Sphk return (1); 601162073Sru } 60212946Sphk 60312946Sphk if (bflag) { 60412946Sphk fwrite(val, 1, len, stdout); 605162073Sru free(oval); 60612946Sphk return (0); 6071553Srgrimes } 60896234Sache val[len] = '\0'; 60988696Sphk fmt = buf; 61088696Sphk oidfmt(oid, nlen, fmt, &kind); 61112946Sphk p = val; 612217586Smdf ctltype = (kind & CTLTYPE); 613217616Smdf sign = ctl_sign[ctltype]; 614217616Smdf intlen = ctl_size[ctltype]; 615217616Smdf 616244106Salfred /* if Wflag then only list sysctls that are writeable and not stats. */ 617244106Salfred if (Wflag && ((kind & CTLFLAG_WR) == 0 || (kind & CTLFLAG_STATS) != 0)) 618244106Salfred return 1; 619244106Salfred 620244106Salfred /* if Tflag then only list sysctls that are tuneables. */ 621244106Salfred if (Tflag && (kind & CTLFLAG_TUN) == 0) 622244106Salfred return 1; 623244106Salfred 624217586Smdf switch (ctltype) { 625217586Smdf case CTLTYPE_STRING: 62612946Sphk if (!nflag) 62785747Stobez printf("%s%s", name, sep); 628203917Suqs printf("%.*s", (int)len, p); 629162073Sru free(oval); 63012946Sphk return (0); 631122234Sdes 632217586Smdf case CTLTYPE_INT: 633217586Smdf case CTLTYPE_UINT: 634217586Smdf case CTLTYPE_LONG: 635217586Smdf case CTLTYPE_ULONG: 636217616Smdf case CTLTYPE_S64: 637217616Smdf case CTLTYPE_U64: 63812946Sphk if (!nflag) 63985747Stobez printf("%s%s", name, sep); 640170514Sdwmalone hexlen = 2 + (intlen * CHAR_BIT + 3) / 4; 641170513Sdwmalone sep1 = ""; 642170287Sdwmalone while (len >= intlen) { 643217586Smdf switch (kind & CTLTYPE) { 644217586Smdf case CTLTYPE_INT: 645217586Smdf case CTLTYPE_UINT: 646170514Sdwmalone umv = *(u_int *)p; 647170514Sdwmalone mv = *(int *)p; 648170287Sdwmalone break; 649217586Smdf case CTLTYPE_LONG: 650217586Smdf case CTLTYPE_ULONG: 651170514Sdwmalone umv = *(u_long *)p; 652170514Sdwmalone mv = *(long *)p; 653170287Sdwmalone break; 654217616Smdf case CTLTYPE_S64: 655217616Smdf case CTLTYPE_U64: 656217616Smdf umv = *(uint64_t *)p; 657217616Smdf mv = *(int64_t *)p; 658170287Sdwmalone break; 659170287Sdwmalone } 660170513Sdwmalone fputs(sep1, stdout); 661217586Smdf if (xflag) 662217586Smdf printf("%#0*jx", hexlen, umv); 663217586Smdf else if (!sign) 664170512Sdwmalone printf(hflag ? "%'ju" : "%ju", umv); 665170287Sdwmalone else if (fmt[1] == 'K') { 666170514Sdwmalone if (mv < 0) 667170512Sdwmalone printf("%jd", mv); 668134541Speter else 669170512Sdwmalone printf("%.1fC", (mv - 2732.0) / 10); 670134541Speter } else 671170513Sdwmalone printf(hflag ? "%'jd" : "%jd", mv); 672170513Sdwmalone sep1 = " "; 673170287Sdwmalone len -= intlen; 674170287Sdwmalone p += intlen; 67541019Sphk } 676162073Sru free(oval); 67712946Sphk return (0); 67812946Sphk 679217586Smdf case CTLTYPE_OPAQUE: 68012946Sphk i = 0; 68177332Sdes if (strcmp(fmt, "S,clockinfo") == 0) 68277332Sdes func = S_clockinfo; 68377332Sdes else if (strcmp(fmt, "S,timeval") == 0) 68477332Sdes func = S_timeval; 68577332Sdes else if (strcmp(fmt, "S,loadavg") == 0) 68677332Sdes func = S_loadavg; 687109097Sdillon else if (strcmp(fmt, "S,vmtotal") == 0) 688109097Sdillon func = S_vmtotal; 68977332Sdes else 69077332Sdes func = NULL; 69112946Sphk if (func) { 69212946Sphk if (!nflag) 69385747Stobez printf("%s%s", name, sep); 694163275Sharti i = (*func)(len, p); 695162073Sru free(oval); 696163275Sharti return (i); 69712946Sphk } 698102411Scharnier /* FALLTHROUGH */ 69912946Sphk default: 700162073Sru if (!oflag && !xflag) { 701162073Sru free(oval); 70212946Sphk return (1); 703162073Sru } 70412946Sphk if (!nflag) 70585747Stobez printf("%s%s", name, sep); 706203917Suqs printf("Format:%s Length:%zu Dump:0x", fmt, len); 70777332Sdes while (len-- && (xflag || p < val + 16)) 70812946Sphk printf("%02x", *p++); 70977332Sdes if (!xflag && len > 16) 71012946Sphk printf("..."); 711162073Sru free(oval); 71212946Sphk return (0); 7131553Srgrimes } 714162073Sru free(oval); 71512946Sphk return (1); 7161553Srgrimes} 7171553Srgrimes 71812946Sphkstatic int 719170512Sdwmalonesysctl_all(int *oid, int len) 7201553Srgrimes{ 72112946Sphk int name1[22], name2[22]; 72238533Sdfr int i, j; 72338533Sdfr size_t l1, l2; 7241553Srgrimes 72512946Sphk name1[0] = 0; 72612946Sphk name1[1] = 2; 72712946Sphk l1 = 2; 72812946Sphk if (len) { 72977928Sdd memcpy(name1+2, oid, len * sizeof(int)); 73012946Sphk l1 += len; 73112946Sphk } else { 73212946Sphk name1[2] = 1; 73312946Sphk l1++; 73412946Sphk } 73577332Sdes for (;;) { 73677928Sdd l2 = sizeof(name2); 73712946Sphk j = sysctl(name1, l1, name2, &l2, 0, 0); 73848956Sbillf if (j < 0) { 73912946Sphk if (errno == ENOENT) 740170512Sdwmalone return (0); 74112946Sphk else 742203917Suqs err(1, "sysctl(getnext) %d %zu", j, l2); 74348956Sbillf } 74412946Sphk 74577928Sdd l2 /= sizeof(int); 74612946Sphk 747170513Sdwmalone if (len < 0 || l2 < (unsigned int)len) 748170512Sdwmalone return (0); 74912946Sphk 75012946Sphk for (i = 0; i < len; i++) 75112946Sphk if (name2[i] != oid[i]) 752170512Sdwmalone return (0); 75312946Sphk 75412946Sphk i = show_var(name2, l2); 75512946Sphk if (!i && !bflag) 75612946Sphk putchar('\n'); 75712946Sphk 75877928Sdd memcpy(name1+2, name2, l2 * sizeof(int)); 75912946Sphk l1 = 2 + l2; 76012946Sphk } 7611553Srgrimes} 762