sysctl.c revision 203310
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 203310 2010-01-31 19:33:25Z gavin $"; 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", 78152995Sru "usage: sysctl [-bdehNnoqx] 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: 28212946Sphk sscanf(newval, "%qd", &quadval); 28312946Sphk newval = &quadval; 28477928Sdd newsize = sizeof(quadval); 28512946Sphk break; 28688696Sphk case CTLTYPE_OPAQUE: 28788696Sphk if (strcmp(fmt, "T,dev_t") == 0) { 288170512Sdwmalone set_T_dev_t (newval, &newval, &newsize); 28988696Sphk break; 29088696Sphk } 29188696Sphk /* FALLTHROUGH */ 29212946Sphk default: 29312946Sphk errx(1, "oid '%s' is type %d," 29431214Sjdp " cannot set that", bufp, 29531214Sjdp kind & CTLTYPE); 2961553Srgrimes } 2971553Srgrimes 29812946Sphk i = show_var(mib, len); 29912946Sphk if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { 30012946Sphk if (!i && !bflag) 30112946Sphk putchar('\n'); 30212946Sphk switch (errno) { 30312946Sphk case EOPNOTSUPP: 304122234Sdes errx(1, "%s: value is not available", 30512946Sphk string); 30612946Sphk case ENOTDIR: 307122234Sdes errx(1, "%s: specification is incomplete", 30812946Sphk string); 30912946Sphk case ENOMEM: 310122234Sdes errx(1, "%s: type is unknown to this program", 31112946Sphk string); 31212946Sphk default: 31330602Scharnier warn("%s", string); 314179965Smtm warncount++; 31512946Sphk return; 31612946Sphk } 31712946Sphk } 31812946Sphk if (!bflag) 31912946Sphk printf(" -> "); 32012946Sphk i = nflag; 32112946Sphk nflag = 1; 32212946Sphk j = show_var(mib, len); 32312946Sphk if (!j && !bflag) 32412946Sphk putchar('\n'); 32512946Sphk nflag = i; 32612946Sphk } 32712946Sphk} 3281553Srgrimes 32912946Sphk/* These functions will dump out various interesting structures. */ 3301553Srgrimes 33112946Sphkstatic int 33212946SphkS_clockinfo(int l2, void *p) 33312946Sphk{ 33412946Sphk struct clockinfo *ci = (struct clockinfo*)p; 335170512Sdwmalone 33697232Salfred if (l2 != sizeof(*ci)) { 33797232Salfred warnx("S_clockinfo %d != %d", l2, sizeof(*ci)); 338170558Sbde return (1); 33997232Salfred } 340122233Sdes printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" : 341122233Sdes "{ hz = %d, tick = %d, profhz = %d, stathz = %d }", 34294752Sphk ci->hz, ci->tick, ci->profhz, ci->stathz); 34312946Sphk return (0); 34412946Sphk} 3451553Srgrimes 34612946Sphkstatic int 34712946SphkS_loadavg(int l2, void *p) 34812946Sphk{ 34912946Sphk struct loadavg *tv = (struct loadavg*)p; 3508857Srgrimes 35197232Salfred if (l2 != sizeof(*tv)) { 35297232Salfred warnx("S_loadavg %d != %d", l2, sizeof(*tv)); 353170558Sbde return (1); 35497232Salfred } 355122233Sdes printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }", 35612946Sphk (double)tv->ldavg[0]/(double)tv->fscale, 35712946Sphk (double)tv->ldavg[1]/(double)tv->fscale, 35812946Sphk (double)tv->ldavg[2]/(double)tv->fscale); 35912946Sphk return (0); 36012946Sphk} 3611553Srgrimes 36212946Sphkstatic int 36312946SphkS_timeval(int l2, void *p) 36412946Sphk{ 36512946Sphk struct timeval *tv = (struct timeval*)p; 36637266Sbde time_t tv_sec; 36712946Sphk char *p1, *p2; 3681553Srgrimes 36997232Salfred if (l2 != sizeof(*tv)) { 37097232Salfred warnx("S_timeval %d != %d", l2, sizeof(*tv)); 371170558Sbde return (1); 37297232Salfred } 373194684Sjhay printf(hflag ? "{ sec = %'jd, usec = %'ld } " : 374194684Sjhay "{ sec = %jd, usec = %ld } ", 375194684Sjhay (intmax_t)tv->tv_sec, tv->tv_usec); 37637266Sbde tv_sec = tv->tv_sec; 37737266Sbde p1 = strdup(ctime(&tv_sec)); 37812946Sphk for (p2=p1; *p2 ; p2++) 37912946Sphk if (*p2 == '\n') 38012946Sphk *p2 = '\0'; 38112946Sphk fputs(p1, stdout); 38212946Sphk return (0); 38312946Sphk} 3841553Srgrimes 38512946Sphkstatic int 386109097SdillonS_vmtotal(int l2, void *p) 387109097Sdillon{ 388109097Sdillon struct vmtotal *v = (struct vmtotal *)p; 389109113Sdillon int pageKilo = getpagesize() / 1024; 390109097Sdillon 391109097Sdillon if (l2 != sizeof(*v)) { 392109097Sdillon warnx("S_vmtotal %d != %d", l2, sizeof(*v)); 393170558Sbde return (1); 394109097Sdillon } 395109097Sdillon 396109113Sdillon printf( 397109113Sdillon "\nSystem wide totals computed every five seconds:" 398109113Sdillon " (values in kilobytes)\n"); 399109097Sdillon printf("===============================================\n"); 400109113Sdillon printf( 401164718Sru "Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: " 402164718Sru "%hd Sleep: %hd)\n", 403109113Sdillon v->t_rq, v->t_dw, v->t_pw, v->t_sl); 404109113Sdillon printf( 405164718Sru "Virtual Memory:\t\t(Total: %dK, Active %dK)\n", 406164718Sru v->t_vm * pageKilo, v->t_avm * pageKilo); 407164718Sru printf("Real Memory:\t\t(Total: %dK Active %dK)\n", 408164718Sru v->t_rm * pageKilo, v->t_arm * pageKilo); 409164718Sru printf("Shared Virtual Memory:\t(Total: %dK Active: %dK)\n", 410164718Sru v->t_vmshr * pageKilo, v->t_avmshr * pageKilo); 411164718Sru printf("Shared Real Memory:\t(Total: %dK Active: %dK)\n", 412164718Sru v->t_rmshr * pageKilo, v->t_armshr * pageKilo); 413164718Sru printf("Free Memory Pages:\t%dK\n", v->t_free * pageKilo); 414122234Sdes 415109097Sdillon return (0); 416109097Sdillon} 417109097Sdillon 418109097Sdillonstatic int 41912946SphkT_dev_t(int l2, void *p) 42012946Sphk{ 42112946Sphk dev_t *d = (dev_t *)p; 422170512Sdwmalone 42397232Salfred if (l2 != sizeof(*d)) { 42497232Salfred warnx("T_dev_T %d != %d", l2, sizeof(*d)); 425170558Sbde return (1); 42697232Salfred } 427198850Sed printf("%s", devname(*d, S_IFCHR)); 42812946Sphk return (0); 42912946Sphk} 4301553Srgrimes 43188696Sphkstatic void 432170512Sdwmaloneset_T_dev_t(char *path, void **val, size_t *size) 43388696Sphk{ 43488696Sphk static struct stat statb; 43588696Sphk 43688696Sphk if (strcmp(path, "none") && strcmp(path, "off")) { 43788696Sphk int rc = stat (path, &statb); 43888696Sphk if (rc) { 43988696Sphk err(1, "cannot stat %s", path); 44088696Sphk } 44188696Sphk 44288696Sphk if (!S_ISCHR(statb.st_mode)) { 44388696Sphk errx(1, "must specify a device special file."); 44488696Sphk } 44588696Sphk } else { 44688696Sphk statb.st_rdev = NODEV; 44788696Sphk } 448170512Sdwmalone *val = (void *) &statb.st_rdev; 449170512Sdwmalone *size = sizeof(statb.st_rdev); 45088696Sphk} 45188696Sphk 452161951Sumestatic int 453198340Sedset_IK(const char *str, int *val) 454161951Sume{ 455161951Sume float temp; 456161951Sume int len, kelv; 457198340Sed const char *p; 458198340Sed char *endptr; 459161951Sume 460161951Sume if ((len = strlen(str)) == 0) 461161951Sume return (0); 462161951Sume p = &str[len - 1]; 463161951Sume if (*p == 'C' || *p == 'F') { 464161951Sume temp = strtof(str, &endptr); 465198340Sed if (endptr == str || endptr != p) 466161951Sume return (0); 467161951Sume if (*p == 'F') 468161951Sume temp = (temp - 32) * 5 / 9; 469161951Sume kelv = temp * 10 + 2732; 470161951Sume } else { 471161951Sume kelv = (int)strtol(str, &endptr, 10); 472161951Sume if (endptr == str || *endptr != '\0') 473161951Sume return (0); 474161951Sume } 475161951Sume *val = kelv; 476161951Sume return (1); 477161951Sume} 478161951Sume 47912946Sphk/* 48012946Sphk * These functions uses a presently undocumented interface to the kernel 48112946Sphk * to walk the tree and get the type so it can print the value. 48212946Sphk * This interface is under work and consideration, and should probably 48312946Sphk * be killed with a big axe by the first person who can find the time. 48412946Sphk * (be aware though, that the proper interface isn't as obvious as it 48512946Sphk * may seem, there are various conflicting requirements. 48612946Sphk */ 4871553Srgrimes 48812946Sphkstatic int 48912946Sphkname2oid(char *name, int *oidp) 49012946Sphk{ 49112946Sphk int oid[2]; 49238533Sdfr int i; 49338533Sdfr size_t j; 4941553Srgrimes 49512946Sphk oid[0] = 0; 49612946Sphk oid[1] = 3; 4971553Srgrimes 49877928Sdd j = CTL_MAXNAME * sizeof(int); 49912946Sphk i = sysctl(oid, 2, oidp, &j, name, strlen(name)); 500122234Sdes if (i < 0) 501170512Sdwmalone return (i); 50277928Sdd j /= sizeof(int); 50312946Sphk return (j); 5041553Srgrimes} 5051553Srgrimes 50612946Sphkstatic int 50712946Sphkoidfmt(int *oid, int len, char *fmt, u_int *kind) 50812946Sphk{ 50912946Sphk int qoid[CTL_MAXNAME+2]; 51012946Sphk u_char buf[BUFSIZ]; 51138533Sdfr int i; 51238533Sdfr size_t j; 5131553Srgrimes 51412946Sphk qoid[0] = 0; 51512946Sphk qoid[1] = 4; 51612946Sphk memcpy(qoid + 2, oid, len * sizeof(int)); 5171553Srgrimes 51877928Sdd j = sizeof(buf); 51912946Sphk i = sysctl(qoid, len + 2, buf, &j, 0, 0); 52012946Sphk if (i) 52130602Scharnier err(1, "sysctl fmt %d %d %d", i, j, errno); 5221553Srgrimes 52312946Sphk if (kind) 52412946Sphk *kind = *(u_int *)buf; 52512946Sphk 52612946Sphk if (fmt) 52712946Sphk strcpy(fmt, (char *)(buf + sizeof(u_int))); 528170512Sdwmalone return (0); 5291553Srgrimes} 5301553Srgrimes 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 */ 53812946Sphk 53912946Sphkstatic int 54012946Sphkshow_var(int *oid, int nlen) 5411553Srgrimes{ 542162073Sru u_char buf[BUFSIZ], *val, *oval, *p; 543170513Sdwmalone char name[BUFSIZ], *fmt; 544170513Sdwmalone const char *sep, *sep1; 54512946Sphk int qoid[CTL_MAXNAME+2]; 546170512Sdwmalone uintmax_t umv; 547170512Sdwmalone intmax_t mv; 548170514Sdwmalone int i, hexlen; 549170287Sdwmalone size_t intlen; 55038533Sdfr size_t j, len; 55112946Sphk u_int kind; 55277332Sdes int (*func)(int, void *); 5531553Srgrimes 554144997Smdodd bzero(buf, BUFSIZ); 555144997Smdodd bzero(name, BUFSIZ); 55642456Sdes qoid[0] = 0; 55742456Sdes memcpy(qoid + 2, oid, nlen * sizeof(int)); 55842456Sdes 55942456Sdes qoid[1] = 1; 56077928Sdd j = sizeof(name); 56142456Sdes i = sysctl(qoid, nlen + 2, name, &j, 0, 0); 56242456Sdes if (i || !j) 56342456Sdes err(1, "sysctl name %d %d %d", i, j, errno); 56442456Sdes 56571034Sdes if (Nflag) { 56671034Sdes printf("%s", name); 56771034Sdes return (0); 56871034Sdes } 56971034Sdes 57085747Stobez if (eflag) 57185747Stobez sep = "="; 57285747Stobez else 57385747Stobez sep = ": "; 57485747Stobez 57588006Sluigi if (dflag) { /* just print description */ 57688006Sluigi qoid[1] = 5; 57788006Sluigi j = sizeof(buf); 57888006Sluigi i = sysctl(qoid, nlen + 2, buf, &j, 0, 0); 57988006Sluigi if (!nflag) 58088006Sluigi printf("%s%s", name, sep); 58188006Sluigi printf("%s", buf); 58288006Sluigi return (0); 58388006Sluigi } 58412946Sphk /* find an estimate of how much we need for this var */ 58512946Sphk j = 0; 58612946Sphk i = sysctl(oid, nlen, 0, &j, 0, 0); 58712946Sphk j += j; /* we want to be sure :-) */ 58812946Sphk 589162073Sru val = oval = malloc(j + 1); 590162073Sru if (val == NULL) { 591162073Sru warnx("malloc failed"); 592170558Sbde return (1); 593162073Sru } 59412946Sphk len = j; 59512946Sphk i = sysctl(oid, nlen, val, &len, 0, 0); 596162073Sru if (i || !len) { 597162073Sru free(oval); 59812946Sphk return (1); 599162073Sru } 60012946Sphk 60112946Sphk if (bflag) { 60212946Sphk fwrite(val, 1, len, stdout); 603162073Sru free(oval); 60412946Sphk return (0); 6051553Srgrimes } 60696234Sache val[len] = '\0'; 60788696Sphk fmt = buf; 60888696Sphk oidfmt(oid, nlen, fmt, &kind); 60912946Sphk p = val; 61012946Sphk switch (*fmt) { 61112946Sphk case 'A': 61212946Sphk if (!nflag) 61385747Stobez printf("%s%s", name, sep); 614106829Speter printf("%.*s", len, p); 615162073Sru free(oval); 61612946Sphk return (0); 617122234Sdes 61812946Sphk case 'I': 619170287Sdwmalone case 'L': 620170287Sdwmalone case 'Q': 62112946Sphk if (!nflag) 62285747Stobez printf("%s%s", name, sep); 623170287Sdwmalone switch (*fmt) { 624170514Sdwmalone case 'I': intlen = sizeof(int); break; 625170514Sdwmalone case 'L': intlen = sizeof(long); break; 626170514Sdwmalone case 'Q': intlen = sizeof(quad_t); break; 627170287Sdwmalone } 628170514Sdwmalone hexlen = 2 + (intlen * CHAR_BIT + 3) / 4; 629170513Sdwmalone sep1 = ""; 630170287Sdwmalone while (len >= intlen) { 631170287Sdwmalone switch (*fmt) { 632170287Sdwmalone case 'I': 633170514Sdwmalone umv = *(u_int *)p; 634170514Sdwmalone mv = *(int *)p; 635170287Sdwmalone break; 636170287Sdwmalone case 'L': 637170514Sdwmalone umv = *(u_long *)p; 638170514Sdwmalone mv = *(long *)p; 639170287Sdwmalone break; 640170287Sdwmalone case 'Q': 641170514Sdwmalone umv = *(u_quad_t *)p; 642170514Sdwmalone mv = *(quad_t *)p; 643170287Sdwmalone break; 644170287Sdwmalone } 645170513Sdwmalone fputs(sep1, stdout); 646170287Sdwmalone if (fmt[1] == 'U') 647170512Sdwmalone printf(hflag ? "%'ju" : "%ju", umv); 648170287Sdwmalone else if (fmt[1] == 'X') 649170514Sdwmalone printf("%#0*jx", hexlen, umv); 650170287Sdwmalone else if (fmt[1] == 'K') { 651170514Sdwmalone if (mv < 0) 652170512Sdwmalone printf("%jd", mv); 653134541Speter else 654170512Sdwmalone printf("%.1fC", (mv - 2732.0) / 10); 655134541Speter } else 656170513Sdwmalone printf(hflag ? "%'jd" : "%jd", mv); 657170513Sdwmalone sep1 = " "; 658170287Sdwmalone len -= intlen; 659170287Sdwmalone p += intlen; 66041019Sphk } 661162073Sru free(oval); 66212946Sphk return (0); 66312946Sphk 66438533Sdfr case 'P': 66538533Sdfr if (!nflag) 66685747Stobez printf("%s%s", name, sep); 66738533Sdfr printf("%p", *(void **)p); 668162073Sru free(oval); 66938533Sdfr return (0); 67038533Sdfr 67112946Sphk case 'T': 67212946Sphk case 'S': 67312946Sphk i = 0; 67477332Sdes if (strcmp(fmt, "S,clockinfo") == 0) 67577332Sdes func = S_clockinfo; 67677332Sdes else if (strcmp(fmt, "S,timeval") == 0) 67777332Sdes func = S_timeval; 67877332Sdes else if (strcmp(fmt, "S,loadavg") == 0) 67977332Sdes func = S_loadavg; 680109097Sdillon else if (strcmp(fmt, "S,vmtotal") == 0) 681109097Sdillon func = S_vmtotal; 68277332Sdes else if (strcmp(fmt, "T,dev_t") == 0) 68377332Sdes func = T_dev_t; 68477332Sdes else 68577332Sdes func = NULL; 68612946Sphk if (func) { 68712946Sphk if (!nflag) 68885747Stobez printf("%s%s", name, sep); 689163275Sharti i = (*func)(len, p); 690162073Sru free(oval); 691163275Sharti return (i); 69212946Sphk } 693102411Scharnier /* FALLTHROUGH */ 69412946Sphk default: 695162073Sru if (!oflag && !xflag) { 696162073Sru free(oval); 69712946Sphk return (1); 698162073Sru } 69912946Sphk if (!nflag) 70085747Stobez printf("%s%s", name, sep); 70112946Sphk printf("Format:%s Length:%d Dump:0x", fmt, len); 70277332Sdes while (len-- && (xflag || p < val + 16)) 70312946Sphk printf("%02x", *p++); 70477332Sdes if (!xflag && len > 16) 70512946Sphk printf("..."); 706162073Sru free(oval); 70712946Sphk return (0); 7081553Srgrimes } 709162073Sru free(oval); 71012946Sphk return (1); 7111553Srgrimes} 7121553Srgrimes 71312946Sphkstatic int 714170512Sdwmalonesysctl_all(int *oid, int len) 7151553Srgrimes{ 71612946Sphk int name1[22], name2[22]; 71738533Sdfr int i, j; 71838533Sdfr size_t l1, l2; 7191553Srgrimes 72012946Sphk name1[0] = 0; 72112946Sphk name1[1] = 2; 72212946Sphk l1 = 2; 72312946Sphk if (len) { 72477928Sdd memcpy(name1+2, oid, len * sizeof(int)); 72512946Sphk l1 += len; 72612946Sphk } else { 72712946Sphk name1[2] = 1; 72812946Sphk l1++; 72912946Sphk } 73077332Sdes for (;;) { 73177928Sdd l2 = sizeof(name2); 73212946Sphk j = sysctl(name1, l1, name2, &l2, 0, 0); 73348956Sbillf if (j < 0) { 73412946Sphk if (errno == ENOENT) 735170512Sdwmalone return (0); 73612946Sphk else 73730602Scharnier err(1, "sysctl(getnext) %d %d", j, l2); 73848956Sbillf } 73912946Sphk 74077928Sdd l2 /= sizeof(int); 74112946Sphk 742170513Sdwmalone if (len < 0 || l2 < (unsigned int)len) 743170512Sdwmalone return (0); 74412946Sphk 74512946Sphk for (i = 0; i < len; i++) 74612946Sphk if (name2[i] != oid[i]) 747170512Sdwmalone return (0); 74812946Sphk 74912946Sphk i = show_var(name2, l2); 75012946Sphk if (!i && !bflag) 75112946Sphk putchar('\n'); 75212946Sphk 75377928Sdd memcpy(name1+2, name2, l2 * sizeof(int)); 75412946Sphk l1 = 2 + l2; 75512946Sphk } 7561553Srgrimes} 757