sysctl.c revision 212726
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 212726 2010-09-16 10:53:01Z zec $"; 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; 62203310Sgavinstatic int Nflag, nflag, oflag, qflag, xflag, warncount; 631553Srgrimes 6412946Sphkstatic int oidfmt(int *, int, char *, u_int *); 6512946Sphkstatic void parse(char *); 6612946Sphkstatic int show_var(int *, int); 67170512Sdwmalonestatic int sysctl_all(int *oid, int len); 6812946Sphkstatic int name2oid(char *, int *); 691553Srgrimes 70170512Sdwmalonestatic void set_T_dev_t(char *, void **, size_t *); 71198340Sedstatic int set_IK(const char *, int *); 7288696Sphk 7312946Sphkstatic void 7412946Sphkusage(void) 7512946Sphk{ 761553Srgrimes 7777330Sdes (void)fprintf(stderr, "%s\n%s\n", 78203717Sgavin "usage: sysctl [-bdehiNnoqx] name[=value] ...", 79152995Sru " sysctl [-bdehNnoqx] -a"); 8012946Sphk exit(1); 8112946Sphk} 821553Srgrimes 831553Srgrimesint 8412946Sphkmain(int argc, char **argv) 851553Srgrimes{ 8612946Sphk int ch; 87122233Sdes 88122233Sdes setlocale(LC_NUMERIC, ""); 8912946Sphk setbuf(stdout,0); 9012946Sphk setbuf(stderr,0); 911553Srgrimes 92203310Sgavin while ((ch = getopt(argc, argv, "AabdehiNnoqwxX")) != -1) { 931553Srgrimes switch (ch) { 9471034Sdes case 'A': 9577330Sdes /* compatibility */ 9677330Sdes aflag = oflag = 1; 9771034Sdes break; 9871034Sdes case 'a': 9971034Sdes aflag = 1; 10071034Sdes break; 10171034Sdes case 'b': 10271034Sdes bflag = 1; 10371034Sdes break; 10488006Sluigi case 'd': 10588006Sluigi dflag = 1; 10688006Sluigi break; 10785747Stobez case 'e': 10885747Stobez eflag = 1; 10985747Stobez break; 110122233Sdes case 'h': 111122233Sdes hflag = 1; 112122233Sdes break; 113203310Sgavin case 'i': 114203310Sgavin iflag = 1; 115203310Sgavin break; 11671034Sdes case 'N': 11771034Sdes Nflag = 1; 11871034Sdes break; 11971034Sdes case 'n': 12071034Sdes nflag = 1; 12171034Sdes break; 12277330Sdes case 'o': 12377330Sdes oflag = 1; 12477330Sdes break; 125150167Srwatson case 'q': 126150167Srwatson qflag = 1; 127150167Srwatson break; 12871034Sdes case 'w': 12977330Sdes /* compatibility */ 13077330Sdes /* ignored */ 13171034Sdes break; 13271034Sdes case 'X': 13377330Sdes /* compatibility */ 13477330Sdes aflag = xflag = 1; 13571034Sdes break; 13677330Sdes case 'x': 13777330Sdes xflag = 1; 13877330Sdes break; 13971034Sdes default: 14071034Sdes usage(); 1411553Srgrimes } 1421553Srgrimes } 1431553Srgrimes argc -= optind; 1441553Srgrimes argv += optind; 1451553Srgrimes 14677330Sdes if (Nflag && nflag) 14742456Sdes usage(); 14877330Sdes if (aflag && argc == 0) 14977330Sdes exit(sysctl_all(0, 0)); 1501553Srgrimes if (argc == 0) 1511553Srgrimes usage(); 152179965Smtm 153179965Smtm warncount = 0; 1541553Srgrimes while (argc-- > 0) 15512946Sphk parse(*argv++); 156179965Smtm exit(warncount); 1571553Srgrimes} 1581553Srgrimes 1591553Srgrimes/* 1601553Srgrimes * Parse a name into a MIB entry. 1611553Srgrimes * Lookup and print out the MIB entry if it exists. 1621553Srgrimes * Set a new value if requested. 1631553Srgrimes */ 16412946Sphkstatic void 16512946Sphkparse(char *string) 1661553Srgrimes{ 16712946Sphk int len, i, j; 1681553Srgrimes void *newval = 0; 16978434Spirzyk int intval; 17078434Spirzyk unsigned int uintval; 17178434Spirzyk long longval; 17278434Spirzyk unsigned long ulongval; 17378434Spirzyk size_t newsize = 0; 1741553Srgrimes quad_t quadval; 1751553Srgrimes int mib[CTL_MAXNAME]; 176116383Srwatson char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ]; 17712946Sphk u_int kind; 1781553Srgrimes 1791553Srgrimes bufp = buf; 180140818Sssouhlal if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ) 181140818Sssouhlal errx(1, "oid too long: '%s'", string); 1821553Srgrimes if ((cp = strchr(string, '=')) != NULL) { 1831553Srgrimes *strchr(buf, '=') = '\0'; 1841553Srgrimes *cp++ = '\0'; 1851553Srgrimes while (isspace(*cp)) 1861553Srgrimes cp++; 1871553Srgrimes newval = cp; 1881553Srgrimes newsize = strlen(cp); 1891553Srgrimes } 19012946Sphk len = name2oid(bufp, mib); 1911553Srgrimes 192150167Srwatson if (len < 0) { 193203310Sgavin if (iflag) 194203310Sgavin return; 195150167Srwatson if (qflag) 196150167Srwatson exit(1); 197150167Srwatson else 198150167Srwatson errx(1, "unknown oid '%s'", bufp); 199150167Srwatson } 2001553Srgrimes 20188696Sphk if (oidfmt(mib, len, fmt, &kind)) 20230602Scharnier err(1, "couldn't find format of oid '%s'", bufp); 2031553Srgrimes 20477330Sdes if (newval == NULL) { 20512946Sphk if ((kind & CTLTYPE) == CTLTYPE_NODE) { 206144998Smdodd if (dflag) { 207144998Smdodd i = show_var(mib, len); 208144998Smdodd if (!i && !bflag) 209144998Smdodd putchar('\n'); 210144998Smdodd } 21112946Sphk sysctl_all(mib, len); 21212946Sphk } else { 21312946Sphk i = show_var(mib, len); 21412946Sphk if (!i && !bflag) 21512946Sphk putchar('\n'); 2161553Srgrimes } 21712946Sphk } else { 21812946Sphk if ((kind & CTLTYPE) == CTLTYPE_NODE) 21912946Sphk errx(1, "oid '%s' isn't a leaf node", bufp); 2201553Srgrimes 221121849Ssilby if (!(kind & CTLFLAG_WR)) { 222121306Ssilby if (kind & CTLFLAG_TUN) { 223121849Ssilby warnx("oid '%s' is a read only tunable", bufp); 224121849Ssilby errx(1, "Tunable values are set in /boot/loader.conf"); 225121306Ssilby } else { 226121306Ssilby errx(1, "oid '%s' is read only", bufp); 227121849Ssilby } 228121306Ssilby } 229116383Srwatson 230116383Srwatson if ((kind & CTLTYPE) == CTLTYPE_INT || 231116383Srwatson (kind & CTLTYPE) == CTLTYPE_UINT || 232116383Srwatson (kind & CTLTYPE) == CTLTYPE_LONG || 233126472Sdd (kind & CTLTYPE) == CTLTYPE_ULONG || 234126472Sdd (kind & CTLTYPE) == CTLTYPE_QUAD) { 235116383Srwatson if (strlen(newval) == 0) 236116383Srwatson errx(1, "empty numeric value"); 237116383Srwatson } 238122234Sdes 23912946Sphk switch (kind & CTLTYPE) { 24012946Sphk case CTLTYPE_INT: 241161951Sume if (strcmp(fmt, "IK") == 0) { 242170512Sdwmalone if (!set_IK(newval, &intval)) 243161951Sume errx(1, "invalid value '%s'", 244170513Sdwmalone (char *)newval); 245161951Sume } else { 246161951Sume intval = (int)strtol(newval, &endptr, 247161951Sume 0); 248161951Sume if (endptr == newval || *endptr != '\0') 249161951Sume errx(1, "invalid integer '%s'", 250170513Sdwmalone (char *)newval); 251161951Sume } 25212946Sphk newval = &intval; 25377928Sdd newsize = sizeof(intval); 2541553Srgrimes break; 25578434Spirzyk case CTLTYPE_UINT: 256116383Srwatson uintval = (int) strtoul(newval, &endptr, 0); 257116383Srwatson if (endptr == newval || *endptr != '\0') 258116383Srwatson errx(1, "invalid unsigned integer '%s'", 259170513Sdwmalone (char *)newval); 26078434Spirzyk newval = &uintval; 261170512Sdwmalone newsize = sizeof(uintval); 26212946Sphk break; 26378434Spirzyk case CTLTYPE_LONG: 264116383Srwatson longval = strtol(newval, &endptr, 0); 265116383Srwatson if (endptr == newval || *endptr != '\0') 266116383Srwatson errx(1, "invalid long integer '%s'", 267170513Sdwmalone (char *)newval); 26878434Spirzyk newval = &longval; 269170512Sdwmalone newsize = sizeof(longval); 27078434Spirzyk break; 27178434Spirzyk case CTLTYPE_ULONG: 272116383Srwatson ulongval = strtoul(newval, &endptr, 0); 273116383Srwatson if (endptr == newval || *endptr != '\0') 274116383Srwatson errx(1, "invalid unsigned long integer" 275170513Sdwmalone " '%s'", (char *)newval); 27678434Spirzyk newval = &ulongval; 277170512Sdwmalone newsize = sizeof(ulongval); 27878434Spirzyk break; 27912946Sphk case CTLTYPE_STRING: 28012946Sphk break; 28112946Sphk case CTLTYPE_QUAD: 282203917Suqs quadval = strtoq(newval, &endptr, 0); 283203917Suqs if (endptr == newval || *endptr != '\0') 284203917Suqs errx(1, "invalid quad integer" 285203917Suqs " '%s'", (char *)newval); 28612946Sphk newval = &quadval; 28777928Sdd newsize = sizeof(quadval); 28812946Sphk break; 28988696Sphk case CTLTYPE_OPAQUE: 29088696Sphk if (strcmp(fmt, "T,dev_t") == 0) { 291170512Sdwmalone set_T_dev_t (newval, &newval, &newsize); 29288696Sphk break; 29388696Sphk } 29488696Sphk /* FALLTHROUGH */ 29512946Sphk default: 29612946Sphk errx(1, "oid '%s' is type %d," 29731214Sjdp " cannot set that", bufp, 29831214Sjdp kind & CTLTYPE); 2991553Srgrimes } 3001553Srgrimes 30112946Sphk i = show_var(mib, len); 30212946Sphk if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { 30312946Sphk if (!i && !bflag) 30412946Sphk putchar('\n'); 30512946Sphk switch (errno) { 30612946Sphk case EOPNOTSUPP: 307122234Sdes errx(1, "%s: value is not available", 30812946Sphk string); 30912946Sphk case ENOTDIR: 310122234Sdes errx(1, "%s: specification is incomplete", 31112946Sphk string); 31212946Sphk case ENOMEM: 313122234Sdes errx(1, "%s: type is unknown to this program", 31412946Sphk string); 31512946Sphk default: 31630602Scharnier warn("%s", string); 317179965Smtm warncount++; 31812946Sphk return; 31912946Sphk } 32012946Sphk } 32112946Sphk if (!bflag) 32212946Sphk printf(" -> "); 32312946Sphk i = nflag; 32412946Sphk nflag = 1; 32512946Sphk j = show_var(mib, len); 32612946Sphk if (!j && !bflag) 32712946Sphk putchar('\n'); 32812946Sphk nflag = i; 32912946Sphk } 33012946Sphk} 3311553Srgrimes 33212946Sphk/* These functions will dump out various interesting structures. */ 3331553Srgrimes 33412946Sphkstatic int 33512946SphkS_clockinfo(int l2, void *p) 33612946Sphk{ 33712946Sphk struct clockinfo *ci = (struct clockinfo*)p; 338170512Sdwmalone 33997232Salfred if (l2 != sizeof(*ci)) { 340203917Suqs warnx("S_clockinfo %d != %zu", l2, sizeof(*ci)); 341170558Sbde return (1); 34297232Salfred } 343122233Sdes printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" : 344122233Sdes "{ hz = %d, tick = %d, profhz = %d, stathz = %d }", 34594752Sphk ci->hz, ci->tick, ci->profhz, ci->stathz); 34612946Sphk return (0); 34712946Sphk} 3481553Srgrimes 34912946Sphkstatic int 35012946SphkS_loadavg(int l2, void *p) 35112946Sphk{ 35212946Sphk struct loadavg *tv = (struct loadavg*)p; 3538857Srgrimes 35497232Salfred if (l2 != sizeof(*tv)) { 355203917Suqs warnx("S_loadavg %d != %zu", l2, sizeof(*tv)); 356170558Sbde return (1); 35797232Salfred } 358122233Sdes printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }", 35912946Sphk (double)tv->ldavg[0]/(double)tv->fscale, 36012946Sphk (double)tv->ldavg[1]/(double)tv->fscale, 36112946Sphk (double)tv->ldavg[2]/(double)tv->fscale); 36212946Sphk return (0); 36312946Sphk} 3641553Srgrimes 36512946Sphkstatic int 36612946SphkS_timeval(int l2, void *p) 36712946Sphk{ 36812946Sphk struct timeval *tv = (struct timeval*)p; 36937266Sbde time_t tv_sec; 37012946Sphk char *p1, *p2; 3711553Srgrimes 37297232Salfred if (l2 != sizeof(*tv)) { 373203917Suqs warnx("S_timeval %d != %zu", l2, sizeof(*tv)); 374170558Sbde return (1); 37597232Salfred } 376194684Sjhay printf(hflag ? "{ sec = %'jd, usec = %'ld } " : 377194684Sjhay "{ sec = %jd, usec = %ld } ", 378194684Sjhay (intmax_t)tv->tv_sec, tv->tv_usec); 37937266Sbde tv_sec = tv->tv_sec; 38037266Sbde p1 = strdup(ctime(&tv_sec)); 38112946Sphk for (p2=p1; *p2 ; p2++) 38212946Sphk if (*p2 == '\n') 38312946Sphk *p2 = '\0'; 38412946Sphk fputs(p1, stdout); 385205118Sbrucec free(p1); 38612946Sphk return (0); 38712946Sphk} 3881553Srgrimes 38912946Sphkstatic int 390109097SdillonS_vmtotal(int l2, void *p) 391109097Sdillon{ 392109097Sdillon struct vmtotal *v = (struct vmtotal *)p; 393109113Sdillon int pageKilo = getpagesize() / 1024; 394109097Sdillon 395109097Sdillon if (l2 != sizeof(*v)) { 396203917Suqs warnx("S_vmtotal %d != %zu", l2, sizeof(*v)); 397170558Sbde return (1); 398109097Sdillon } 399109097Sdillon 400109113Sdillon printf( 401109113Sdillon "\nSystem wide totals computed every five seconds:" 402109113Sdillon " (values in kilobytes)\n"); 403109097Sdillon printf("===============================================\n"); 404109113Sdillon printf( 405164718Sru "Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: " 406164718Sru "%hd Sleep: %hd)\n", 407109113Sdillon v->t_rq, v->t_dw, v->t_pw, v->t_sl); 408109113Sdillon printf( 409212726Szec "Virtual Memory:\t\t(Total: %dK Active: %dK)\n", 410164718Sru v->t_vm * pageKilo, v->t_avm * pageKilo); 411212726Szec printf("Real Memory:\t\t(Total: %dK Active: %dK)\n", 412164718Sru v->t_rm * pageKilo, v->t_arm * pageKilo); 413164718Sru printf("Shared Virtual Memory:\t(Total: %dK Active: %dK)\n", 414164718Sru v->t_vmshr * pageKilo, v->t_avmshr * pageKilo); 415164718Sru printf("Shared Real Memory:\t(Total: %dK Active: %dK)\n", 416164718Sru v->t_rmshr * pageKilo, v->t_armshr * pageKilo); 417164718Sru printf("Free Memory Pages:\t%dK\n", v->t_free * pageKilo); 418122234Sdes 419109097Sdillon return (0); 420109097Sdillon} 421109097Sdillon 422109097Sdillonstatic int 42312946SphkT_dev_t(int l2, void *p) 42412946Sphk{ 42512946Sphk dev_t *d = (dev_t *)p; 426170512Sdwmalone 42797232Salfred if (l2 != sizeof(*d)) { 428203917Suqs warnx("T_dev_T %d != %zu", l2, sizeof(*d)); 429170558Sbde return (1); 43097232Salfred } 431198850Sed printf("%s", devname(*d, S_IFCHR)); 43212946Sphk return (0); 43312946Sphk} 4341553Srgrimes 43588696Sphkstatic void 436170512Sdwmaloneset_T_dev_t(char *path, void **val, size_t *size) 43788696Sphk{ 43888696Sphk static struct stat statb; 43988696Sphk 44088696Sphk if (strcmp(path, "none") && strcmp(path, "off")) { 44188696Sphk int rc = stat (path, &statb); 44288696Sphk if (rc) { 44388696Sphk err(1, "cannot stat %s", path); 44488696Sphk } 44588696Sphk 44688696Sphk if (!S_ISCHR(statb.st_mode)) { 44788696Sphk errx(1, "must specify a device special file."); 44888696Sphk } 44988696Sphk } else { 45088696Sphk statb.st_rdev = NODEV; 45188696Sphk } 452170512Sdwmalone *val = (void *) &statb.st_rdev; 453170512Sdwmalone *size = sizeof(statb.st_rdev); 45488696Sphk} 45588696Sphk 456161951Sumestatic int 457198340Sedset_IK(const char *str, int *val) 458161951Sume{ 459161951Sume float temp; 460161951Sume int len, kelv; 461198340Sed const char *p; 462198340Sed char *endptr; 463161951Sume 464161951Sume if ((len = strlen(str)) == 0) 465161951Sume return (0); 466161951Sume p = &str[len - 1]; 467161951Sume if (*p == 'C' || *p == 'F') { 468161951Sume temp = strtof(str, &endptr); 469198340Sed if (endptr == str || endptr != p) 470161951Sume return (0); 471161951Sume if (*p == 'F') 472161951Sume temp = (temp - 32) * 5 / 9; 473161951Sume kelv = temp * 10 + 2732; 474161951Sume } else { 475161951Sume kelv = (int)strtol(str, &endptr, 10); 476161951Sume if (endptr == str || *endptr != '\0') 477161951Sume return (0); 478161951Sume } 479161951Sume *val = kelv; 480161951Sume return (1); 481161951Sume} 482161951Sume 48312946Sphk/* 48412946Sphk * These functions uses a presently undocumented interface to the kernel 48512946Sphk * to walk the tree and get the type so it can print the value. 48612946Sphk * This interface is under work and consideration, and should probably 48712946Sphk * be killed with a big axe by the first person who can find the time. 48812946Sphk * (be aware though, that the proper interface isn't as obvious as it 48912946Sphk * may seem, there are various conflicting requirements. 49012946Sphk */ 4911553Srgrimes 49212946Sphkstatic int 49312946Sphkname2oid(char *name, int *oidp) 49412946Sphk{ 49512946Sphk int oid[2]; 49638533Sdfr int i; 49738533Sdfr size_t j; 4981553Srgrimes 49912946Sphk oid[0] = 0; 50012946Sphk oid[1] = 3; 5011553Srgrimes 50277928Sdd j = CTL_MAXNAME * sizeof(int); 50312946Sphk i = sysctl(oid, 2, oidp, &j, name, strlen(name)); 504122234Sdes if (i < 0) 505170512Sdwmalone return (i); 50677928Sdd j /= sizeof(int); 50712946Sphk return (j); 5081553Srgrimes} 5091553Srgrimes 51012946Sphkstatic int 51112946Sphkoidfmt(int *oid, int len, char *fmt, u_int *kind) 51212946Sphk{ 51312946Sphk int qoid[CTL_MAXNAME+2]; 51412946Sphk u_char buf[BUFSIZ]; 51538533Sdfr int i; 51638533Sdfr size_t j; 5171553Srgrimes 51812946Sphk qoid[0] = 0; 51912946Sphk qoid[1] = 4; 52012946Sphk memcpy(qoid + 2, oid, len * sizeof(int)); 5211553Srgrimes 52277928Sdd j = sizeof(buf); 52312946Sphk i = sysctl(qoid, len + 2, buf, &j, 0, 0); 52412946Sphk if (i) 525203917Suqs err(1, "sysctl fmt %d %zu %d", i, j, errno); 5261553Srgrimes 52712946Sphk if (kind) 52812946Sphk *kind = *(u_int *)buf; 52912946Sphk 53012946Sphk if (fmt) 53112946Sphk strcpy(fmt, (char *)(buf + sizeof(u_int))); 532170512Sdwmalone return (0); 5331553Srgrimes} 5341553Srgrimes 5351553Srgrimes/* 53612946Sphk * This formats and outputs the value of one variable 53712946Sphk * 53812946Sphk * Returns zero if anything was actually output. 53912946Sphk * Returns one if didn't know what to do with this. 54012946Sphk * Return minus one if we had errors. 5411553Srgrimes */ 54212946Sphk 54312946Sphkstatic int 54412946Sphkshow_var(int *oid, int nlen) 5451553Srgrimes{ 546162073Sru u_char buf[BUFSIZ], *val, *oval, *p; 547170513Sdwmalone char name[BUFSIZ], *fmt; 548170513Sdwmalone const char *sep, *sep1; 54912946Sphk int qoid[CTL_MAXNAME+2]; 550170512Sdwmalone uintmax_t umv; 551170512Sdwmalone intmax_t mv; 552170514Sdwmalone int i, hexlen; 553170287Sdwmalone size_t intlen; 55438533Sdfr size_t j, len; 55512946Sphk u_int kind; 55677332Sdes int (*func)(int, void *); 5571553Srgrimes 558203917Suqs /* Silence GCC. */ 559203917Suqs umv = mv = intlen = 0; 560203917Suqs 561144997Smdodd bzero(buf, BUFSIZ); 562144997Smdodd bzero(name, BUFSIZ); 56342456Sdes qoid[0] = 0; 56442456Sdes memcpy(qoid + 2, oid, nlen * sizeof(int)); 56542456Sdes 56642456Sdes qoid[1] = 1; 56777928Sdd j = sizeof(name); 56842456Sdes i = sysctl(qoid, nlen + 2, name, &j, 0, 0); 56942456Sdes if (i || !j) 570203917Suqs err(1, "sysctl name %d %zu %d", i, j, errno); 57142456Sdes 57271034Sdes if (Nflag) { 57371034Sdes printf("%s", name); 57471034Sdes return (0); 57571034Sdes } 57671034Sdes 57785747Stobez if (eflag) 57885747Stobez sep = "="; 57985747Stobez else 58085747Stobez sep = ": "; 58185747Stobez 58288006Sluigi if (dflag) { /* just print description */ 58388006Sluigi qoid[1] = 5; 58488006Sluigi j = sizeof(buf); 58588006Sluigi i = sysctl(qoid, nlen + 2, buf, &j, 0, 0); 58688006Sluigi if (!nflag) 58788006Sluigi printf("%s%s", name, sep); 58888006Sluigi printf("%s", buf); 58988006Sluigi return (0); 59088006Sluigi } 59112946Sphk /* find an estimate of how much we need for this var */ 59212946Sphk j = 0; 59312946Sphk i = sysctl(oid, nlen, 0, &j, 0, 0); 59412946Sphk j += j; /* we want to be sure :-) */ 59512946Sphk 596162073Sru val = oval = malloc(j + 1); 597162073Sru if (val == NULL) { 598162073Sru warnx("malloc failed"); 599170558Sbde return (1); 600162073Sru } 60112946Sphk len = j; 60212946Sphk i = sysctl(oid, nlen, val, &len, 0, 0); 603162073Sru if (i || !len) { 604162073Sru free(oval); 60512946Sphk return (1); 606162073Sru } 60712946Sphk 60812946Sphk if (bflag) { 60912946Sphk fwrite(val, 1, len, stdout); 610162073Sru free(oval); 61112946Sphk return (0); 6121553Srgrimes } 61396234Sache val[len] = '\0'; 61488696Sphk fmt = buf; 61588696Sphk oidfmt(oid, nlen, fmt, &kind); 61612946Sphk p = val; 61712946Sphk switch (*fmt) { 61812946Sphk case 'A': 61912946Sphk if (!nflag) 62085747Stobez printf("%s%s", name, sep); 621203917Suqs printf("%.*s", (int)len, p); 622162073Sru free(oval); 62312946Sphk return (0); 624122234Sdes 62512946Sphk case 'I': 626170287Sdwmalone case 'L': 627170287Sdwmalone case 'Q': 62812946Sphk if (!nflag) 62985747Stobez printf("%s%s", name, sep); 630170287Sdwmalone switch (*fmt) { 631170514Sdwmalone case 'I': intlen = sizeof(int); break; 632170514Sdwmalone case 'L': intlen = sizeof(long); break; 633170514Sdwmalone case 'Q': intlen = sizeof(quad_t); break; 634170287Sdwmalone } 635170514Sdwmalone hexlen = 2 + (intlen * CHAR_BIT + 3) / 4; 636170513Sdwmalone sep1 = ""; 637170287Sdwmalone while (len >= intlen) { 638170287Sdwmalone switch (*fmt) { 639170287Sdwmalone case 'I': 640170514Sdwmalone umv = *(u_int *)p; 641170514Sdwmalone mv = *(int *)p; 642170287Sdwmalone break; 643170287Sdwmalone case 'L': 644170514Sdwmalone umv = *(u_long *)p; 645170514Sdwmalone mv = *(long *)p; 646170287Sdwmalone break; 647170287Sdwmalone case 'Q': 648170514Sdwmalone umv = *(u_quad_t *)p; 649170514Sdwmalone mv = *(quad_t *)p; 650170287Sdwmalone break; 651170287Sdwmalone } 652170513Sdwmalone fputs(sep1, stdout); 653170287Sdwmalone if (fmt[1] == 'U') 654170512Sdwmalone printf(hflag ? "%'ju" : "%ju", umv); 655170287Sdwmalone else if (fmt[1] == 'X') 656170514Sdwmalone printf("%#0*jx", hexlen, umv); 657170287Sdwmalone else if (fmt[1] == 'K') { 658170514Sdwmalone if (mv < 0) 659170512Sdwmalone printf("%jd", mv); 660134541Speter else 661170512Sdwmalone printf("%.1fC", (mv - 2732.0) / 10); 662134541Speter } else 663170513Sdwmalone printf(hflag ? "%'jd" : "%jd", mv); 664170513Sdwmalone sep1 = " "; 665170287Sdwmalone len -= intlen; 666170287Sdwmalone p += intlen; 66741019Sphk } 668162073Sru free(oval); 66912946Sphk return (0); 67012946Sphk 67138533Sdfr case 'P': 67238533Sdfr if (!nflag) 67385747Stobez printf("%s%s", name, sep); 67438533Sdfr printf("%p", *(void **)p); 675162073Sru free(oval); 67638533Sdfr return (0); 67738533Sdfr 67812946Sphk case 'T': 67912946Sphk case 'S': 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 if (strcmp(fmt, "T,dev_t") == 0) 69077332Sdes func = T_dev_t; 69177332Sdes else 69277332Sdes func = NULL; 69312946Sphk if (func) { 69412946Sphk if (!nflag) 69585747Stobez printf("%s%s", name, sep); 696163275Sharti i = (*func)(len, p); 697162073Sru free(oval); 698163275Sharti return (i); 69912946Sphk } 700102411Scharnier /* FALLTHROUGH */ 70112946Sphk default: 702162073Sru if (!oflag && !xflag) { 703162073Sru free(oval); 70412946Sphk return (1); 705162073Sru } 70612946Sphk if (!nflag) 70785747Stobez printf("%s%s", name, sep); 708203917Suqs printf("Format:%s Length:%zu Dump:0x", fmt, len); 70977332Sdes while (len-- && (xflag || p < val + 16)) 71012946Sphk printf("%02x", *p++); 71177332Sdes if (!xflag && len > 16) 71212946Sphk printf("..."); 713162073Sru free(oval); 71412946Sphk return (0); 7151553Srgrimes } 716162073Sru free(oval); 71712946Sphk return (1); 7181553Srgrimes} 7191553Srgrimes 72012946Sphkstatic int 721170512Sdwmalonesysctl_all(int *oid, int len) 7221553Srgrimes{ 72312946Sphk int name1[22], name2[22]; 72438533Sdfr int i, j; 72538533Sdfr size_t l1, l2; 7261553Srgrimes 72712946Sphk name1[0] = 0; 72812946Sphk name1[1] = 2; 72912946Sphk l1 = 2; 73012946Sphk if (len) { 73177928Sdd memcpy(name1+2, oid, len * sizeof(int)); 73212946Sphk l1 += len; 73312946Sphk } else { 73412946Sphk name1[2] = 1; 73512946Sphk l1++; 73612946Sphk } 73777332Sdes for (;;) { 73877928Sdd l2 = sizeof(name2); 73912946Sphk j = sysctl(name1, l1, name2, &l2, 0, 0); 74048956Sbillf if (j < 0) { 74112946Sphk if (errno == ENOENT) 742170512Sdwmalone return (0); 74312946Sphk else 744203917Suqs err(1, "sysctl(getnext) %d %zu", j, l2); 74548956Sbillf } 74612946Sphk 74777928Sdd l2 /= sizeof(int); 74812946Sphk 749170513Sdwmalone if (len < 0 || l2 < (unsigned int)len) 750170512Sdwmalone return (0); 75112946Sphk 75212946Sphk for (i = 0; i < len; i++) 75312946Sphk if (name2[i] != oid[i]) 754170512Sdwmalone return (0); 75512946Sphk 75612946Sphk i = show_var(name2, l2); 75712946Sphk if (!i && !bflag) 75812946Sphk putchar('\n'); 75912946Sphk 76077928Sdd memcpy(name1+2, name2, l2 * sizeof(int)); 76112946Sphk l1 = 2 + l2; 76212946Sphk } 7631553Srgrimes} 764