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$"; 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> 59244198Sdelphij#include <sysexits.h> 6030602Scharnier#include <unistd.h> 611553Srgrimes 62244198Sdelphijstatic const char *conffile; 63244198Sdelphij 64203310Sgavinstatic int aflag, bflag, dflag, eflag, hflag, iflag; 65244198Sdelphijstatic int Nflag, nflag, oflag, qflag, Tflag, Wflag, xflag; 661553Srgrimes 6712946Sphkstatic int oidfmt(int *, int, char *, u_int *); 68244198Sdelphijstatic int parsefile(const char *); 69244198Sdelphijstatic int parse(const char *, int); 7012946Sphkstatic int show_var(int *, int); 71170512Sdwmalonestatic int sysctl_all(int *oid, int len); 7212946Sphkstatic int name2oid(char *, int *); 731553Srgrimes 74198340Sedstatic int set_IK(const char *, int *); 7588696Sphk 7612946Sphkstatic void 7712946Sphkusage(void) 7812946Sphk{ 791553Srgrimes 8077330Sdes (void)fprintf(stderr, "%s\n%s\n", 81244198Sdelphij "usage: sysctl [-bdehiNnoqTWx] [-f filename] name[=value] ...", 82244106Salfred " sysctl [-bdehNnoqTWx] -a"); 8312946Sphk exit(1); 8412946Sphk} 851553Srgrimes 861553Srgrimesint 8712946Sphkmain(int argc, char **argv) 881553Srgrimes{ 8912946Sphk int ch; 90244198Sdelphij int warncount = 0; 91122233Sdes 92122233Sdes setlocale(LC_NUMERIC, ""); 9312946Sphk setbuf(stdout,0); 9412946Sphk setbuf(stderr,0); 951553Srgrimes 96244198Sdelphij while ((ch = getopt(argc, argv, "Aabdef:hiNnoqTwWxX")) != -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; 114244198Sdelphij case 'f': 115244198Sdelphij conffile = optarg; 116244198Sdelphij break; 117122233Sdes case 'h': 118122233Sdes hflag = 1; 119122233Sdes break; 120203310Sgavin case 'i': 121203310Sgavin iflag = 1; 122203310Sgavin break; 12371034Sdes case 'N': 12471034Sdes Nflag = 1; 12571034Sdes break; 12671034Sdes case 'n': 12771034Sdes nflag = 1; 12871034Sdes break; 12977330Sdes case 'o': 13077330Sdes oflag = 1; 13177330Sdes break; 132150167Srwatson case 'q': 133150167Srwatson qflag = 1; 134150167Srwatson break; 135244106Salfred case 'T': 136244106Salfred Tflag = 1; 137244106Salfred break; 13871034Sdes case 'w': 13977330Sdes /* compatibility */ 14077330Sdes /* ignored */ 14171034Sdes break; 142244106Salfred case 'W': 143244106Salfred Wflag = 1; 144244106Salfred break; 14571034Sdes case 'X': 14677330Sdes /* compatibility */ 14777330Sdes aflag = xflag = 1; 14871034Sdes break; 14977330Sdes case 'x': 15077330Sdes xflag = 1; 15177330Sdes break; 15271034Sdes default: 15371034Sdes usage(); 1541553Srgrimes } 1551553Srgrimes } 1561553Srgrimes argc -= optind; 1571553Srgrimes argv += optind; 1581553Srgrimes 15977330Sdes if (Nflag && nflag) 16042456Sdes usage(); 16177330Sdes if (aflag && argc == 0) 16277330Sdes exit(sysctl_all(0, 0)); 163244198Sdelphij if (argc == 0 && conffile == NULL) 1641553Srgrimes usage(); 165179965Smtm 166179965Smtm warncount = 0; 167244198Sdelphij if (conffile != NULL) 168244198Sdelphij warncount += parsefile(conffile); 169244198Sdelphij 1701553Srgrimes while (argc-- > 0) 171244198Sdelphij warncount += parse(*argv++, 0); 172244198Sdelphij 173244198Sdelphij return (warncount); 1741553Srgrimes} 1751553Srgrimes 1761553Srgrimes/* 1771553Srgrimes * Parse a name into a MIB entry. 1781553Srgrimes * Lookup and print out the MIB entry if it exists. 1791553Srgrimes * Set a new value if requested. 1801553Srgrimes */ 181244198Sdelphijstatic int 182244198Sdelphijparse(const char *string, int lineno) 1831553Srgrimes{ 18412946Sphk int len, i, j; 1851553Srgrimes void *newval = 0; 18678434Spirzyk int intval; 18778434Spirzyk unsigned int uintval; 18878434Spirzyk long longval; 18978434Spirzyk unsigned long ulongval; 19078434Spirzyk size_t newsize = 0; 191217616Smdf int64_t i64val; 192217616Smdf uint64_t u64val; 1931553Srgrimes int mib[CTL_MAXNAME]; 194244198Sdelphij char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ], line[BUFSIZ]; 19512946Sphk u_int kind; 1961553Srgrimes 197244198Sdelphij if (lineno) 198244198Sdelphij snprintf(line, sizeof(line), " at line %d", lineno); 199244198Sdelphij else 200244198Sdelphij line[0] = '\0'; 201244198Sdelphij 202244104Sdelphij cp = buf; 203244198Sdelphij if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ) { 204260193Strasz warnx("oid too long: '%s'%s", string, line); 205244198Sdelphij return (1); 206244198Sdelphij } 207244198Sdelphij bufp = strsep(&cp, "=:"); 208244104Sdelphij if (cp != NULL) { 209244106Salfred /* Tflag just lists tunables, do not allow assignment */ 210244106Salfred if (Tflag || Wflag) { 211244106Salfred warnx("Can't set variables when using -T or -W"); 212244106Salfred usage(); 213244106Salfred } 2141553Srgrimes while (isspace(*cp)) 2151553Srgrimes cp++; 216244198Sdelphij /* Strip a pair of " or ' if any. */ 217244198Sdelphij switch (*cp) { 218244198Sdelphij case '\"': 219244198Sdelphij case '\'': 220244198Sdelphij if (cp[strlen(cp) - 1] == *cp) 221244198Sdelphij cp[strlen(cp) - 1] = '\0'; 222244198Sdelphij cp++; 223244198Sdelphij } 2241553Srgrimes newval = cp; 2251553Srgrimes newsize = strlen(cp); 2261553Srgrimes } 22712946Sphk len = name2oid(bufp, mib); 2281553Srgrimes 229150167Srwatson if (len < 0) { 230203310Sgavin if (iflag) 231244198Sdelphij return (0); 232150167Srwatson if (qflag) 233244198Sdelphij return (1); 234244198Sdelphij else { 235244198Sdelphij warn("unknown oid '%s'%s", bufp, line); 236244198Sdelphij return (1); 237244198Sdelphij } 238244198Sdelphij } 239244198Sdelphij 240244198Sdelphij if (oidfmt(mib, len, fmt, &kind)) { 241244198Sdelphij warn("couldn't find format of oid '%s'%s", bufp, line); 242244198Sdelphij if (iflag) 243244198Sdelphij return (1); 244244198Sdelphij else 245150167Srwatson exit(1); 246150167Srwatson } 2471553Srgrimes 248228181Sjhb if (newval == NULL || dflag) { 24912946Sphk if ((kind & CTLTYPE) == CTLTYPE_NODE) { 250144998Smdodd if (dflag) { 251144998Smdodd i = show_var(mib, len); 252144998Smdodd if (!i && !bflag) 253144998Smdodd putchar('\n'); 254144998Smdodd } 25512946Sphk sysctl_all(mib, len); 25612946Sphk } else { 25712946Sphk i = show_var(mib, len); 25812946Sphk if (!i && !bflag) 25912946Sphk putchar('\n'); 2601553Srgrimes } 26112946Sphk } else { 262244198Sdelphij if ((kind & CTLTYPE) == CTLTYPE_NODE) { 263260193Strasz warnx("oid '%s' isn't a leaf node%s", bufp, line); 264244198Sdelphij return (1); 265244198Sdelphij } 2661553Srgrimes 267121849Ssilby if (!(kind & CTLFLAG_WR)) { 268121306Ssilby if (kind & CTLFLAG_TUN) { 269245361Sdelphij warnx("oid '%s' is a read only tunable%s", bufp, line); 270244198Sdelphij warnx("Tunable values are set in /boot/loader.conf"); 271244198Sdelphij } else 272244198Sdelphij warnx("oid '%s' is read only%s", bufp, line); 273244198Sdelphij return (1); 274121306Ssilby } 275116383Srwatson 276116383Srwatson if ((kind & CTLTYPE) == CTLTYPE_INT || 277116383Srwatson (kind & CTLTYPE) == CTLTYPE_UINT || 278116383Srwatson (kind & CTLTYPE) == CTLTYPE_LONG || 279126472Sdd (kind & CTLTYPE) == CTLTYPE_ULONG || 280217616Smdf (kind & CTLTYPE) == CTLTYPE_S64 || 281217616Smdf (kind & CTLTYPE) == CTLTYPE_U64) { 282244198Sdelphij if (strlen(newval) == 0) { 283244198Sdelphij warnx("empty numeric value"); 284244198Sdelphij return (1); 285244198Sdelphij } 286116383Srwatson } 287122234Sdes 28812946Sphk switch (kind & CTLTYPE) { 28912946Sphk case CTLTYPE_INT: 290161951Sume if (strcmp(fmt, "IK") == 0) { 291244198Sdelphij if (!set_IK(newval, &intval)) { 292244198Sdelphij warnx("invalid value '%s'%s", 293244198Sdelphij (char *)newval, line); 294244198Sdelphij return (1); 295244198Sdelphij } 296161951Sume } else { 297161951Sume intval = (int)strtol(newval, &endptr, 298161951Sume 0); 299244198Sdelphij if (endptr == newval || *endptr != '\0') { 300244198Sdelphij warnx("invalid integer '%s'%s", 301244198Sdelphij (char *)newval, line); 302244198Sdelphij return (1); 303244198Sdelphij } 304161951Sume } 30512946Sphk newval = &intval; 30677928Sdd newsize = sizeof(intval); 3071553Srgrimes break; 30878434Spirzyk case CTLTYPE_UINT: 309116383Srwatson uintval = (int) strtoul(newval, &endptr, 0); 310244198Sdelphij if (endptr == newval || *endptr != '\0') { 311244198Sdelphij warnx("invalid unsigned integer '%s'%s", 312244198Sdelphij (char *)newval, line); 313244198Sdelphij return (1); 314244198Sdelphij } 31578434Spirzyk newval = &uintval; 316170512Sdwmalone newsize = sizeof(uintval); 31712946Sphk break; 31878434Spirzyk case CTLTYPE_LONG: 319116383Srwatson longval = strtol(newval, &endptr, 0); 320244198Sdelphij if (endptr == newval || *endptr != '\0') { 321244198Sdelphij warnx("invalid long integer '%s'%s", 322244198Sdelphij (char *)newval, line); 323244198Sdelphij return (1); 324244198Sdelphij } 32578434Spirzyk newval = &longval; 326170512Sdwmalone newsize = sizeof(longval); 32778434Spirzyk break; 32878434Spirzyk case CTLTYPE_ULONG: 329116383Srwatson ulongval = strtoul(newval, &endptr, 0); 330244198Sdelphij if (endptr == newval || *endptr != '\0') { 331244198Sdelphij warnx("invalid unsigned long integer" 332244198Sdelphij " '%s'%s", (char *)newval, line); 333244198Sdelphij return (1); 334244198Sdelphij } 33578434Spirzyk newval = &ulongval; 336170512Sdwmalone newsize = sizeof(ulongval); 33778434Spirzyk break; 33812946Sphk case CTLTYPE_STRING: 33912946Sphk break; 340217616Smdf case CTLTYPE_S64: 341217616Smdf i64val = strtoimax(newval, &endptr, 0); 342244198Sdelphij if (endptr == newval || *endptr != '\0') { 343244198Sdelphij warnx("invalid int64_t '%s'%s", 344244198Sdelphij (char *)newval, line); 345244198Sdelphij return (1); 346244198Sdelphij } 347217616Smdf newval = &i64val; 348217616Smdf newsize = sizeof(i64val); 34912946Sphk break; 350217616Smdf case CTLTYPE_U64: 351217616Smdf u64val = strtoumax(newval, &endptr, 0); 352244198Sdelphij if (endptr == newval || *endptr != '\0') { 353244198Sdelphij warnx("invalid uint64_t '%s'%s", 354244198Sdelphij (char *)newval, line); 355244198Sdelphij return (1); 356244198Sdelphij } 357217616Smdf newval = &u64val; 358217616Smdf newsize = sizeof(u64val); 359217616Smdf break; 36088696Sphk case CTLTYPE_OPAQUE: 36188696Sphk /* FALLTHROUGH */ 36212946Sphk default: 363244198Sdelphij warnx("oid '%s' is type %d," 364244198Sdelphij " cannot set that%s", bufp, 365244198Sdelphij kind & CTLTYPE, line); 366244198Sdelphij return (1); 3671553Srgrimes } 3681553Srgrimes 36912946Sphk i = show_var(mib, len); 37012946Sphk if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { 37112946Sphk if (!i && !bflag) 37212946Sphk putchar('\n'); 37312946Sphk switch (errno) { 37412946Sphk case EOPNOTSUPP: 375244198Sdelphij warnx("%s: value is not available%s", 376244198Sdelphij string, line); 377244198Sdelphij return (1); 37812946Sphk case ENOTDIR: 379244198Sdelphij warnx("%s: specification is incomplete%s", 380244198Sdelphij string, line); 381244198Sdelphij return (1); 38212946Sphk case ENOMEM: 383244198Sdelphij warnx("%s: type is unknown to this program%s", 384244198Sdelphij string, line); 385244198Sdelphij return (1); 38612946Sphk default: 387244198Sdelphij warn("%s%s", string, line); 388244198Sdelphij return (1); 38912946Sphk } 39012946Sphk } 39112946Sphk if (!bflag) 39212946Sphk printf(" -> "); 39312946Sphk i = nflag; 39412946Sphk nflag = 1; 39512946Sphk j = show_var(mib, len); 39612946Sphk if (!j && !bflag) 39712946Sphk putchar('\n'); 39812946Sphk nflag = i; 39912946Sphk } 400244198Sdelphij 401244198Sdelphij return (0); 40212946Sphk} 4031553Srgrimes 404244198Sdelphijstatic int 405244198Sdelphijparsefile(const char *filename) 406244198Sdelphij{ 407244198Sdelphij FILE *file; 408244198Sdelphij char line[BUFSIZ], *p, *pq, *pdq; 409244198Sdelphij int warncount = 0, lineno = 0; 410244198Sdelphij 411244198Sdelphij file = fopen(filename, "r"); 412244198Sdelphij if (file == NULL) 413244198Sdelphij err(EX_NOINPUT, "%s", filename); 414244198Sdelphij while (fgets(line, sizeof(line), file) != NULL) { 415244198Sdelphij lineno++; 416244198Sdelphij p = line; 417244198Sdelphij pq = strchr(line, '\''); 418244198Sdelphij pdq = strchr(line, '\"'); 419244198Sdelphij /* Replace the first # with \0. */ 420244198Sdelphij while((p = strchr(p, '#')) != NULL) { 421244198Sdelphij if (pq != NULL && p > pq) { 422244198Sdelphij if ((p = strchr(pq+1, '\'')) != NULL) 423244198Sdelphij *(++p) = '\0'; 424244198Sdelphij break; 425244198Sdelphij } else if (pdq != NULL && p > pdq) { 426244198Sdelphij if ((p = strchr(pdq+1, '\"')) != NULL) 427244198Sdelphij *(++p) = '\0'; 428244198Sdelphij break; 429244198Sdelphij } else if (p == line || *(p-1) != '\\') { 430244198Sdelphij *p = '\0'; 431244198Sdelphij break; 432244198Sdelphij } 433244198Sdelphij p++; 434244198Sdelphij } 435244198Sdelphij /* Trim spaces */ 436244198Sdelphij p = line + strlen(line) - 1; 437244198Sdelphij while (p >= line && isspace((int)*p)) { 438244198Sdelphij *p = '\0'; 439244198Sdelphij p--; 440244198Sdelphij } 441244198Sdelphij p = line; 442244198Sdelphij while (isspace((int)*p)) 443244198Sdelphij p++; 444244198Sdelphij if (*p == '\0') 445244198Sdelphij continue; 446244198Sdelphij else 447244198Sdelphij warncount += parse(p, lineno); 448244198Sdelphij } 449244198Sdelphij fclose(file); 450244198Sdelphij 451244198Sdelphij return (warncount); 452244198Sdelphij} 453244198Sdelphij 45412946Sphk/* These functions will dump out various interesting structures. */ 4551553Srgrimes 45612946Sphkstatic int 45712946SphkS_clockinfo(int l2, void *p) 45812946Sphk{ 45912946Sphk struct clockinfo *ci = (struct clockinfo*)p; 460170512Sdwmalone 46197232Salfred if (l2 != sizeof(*ci)) { 462203917Suqs warnx("S_clockinfo %d != %zu", l2, sizeof(*ci)); 463170558Sbde return (1); 46497232Salfred } 465122233Sdes printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" : 466122233Sdes "{ hz = %d, tick = %d, profhz = %d, stathz = %d }", 46794752Sphk ci->hz, ci->tick, ci->profhz, ci->stathz); 46812946Sphk return (0); 46912946Sphk} 4701553Srgrimes 47112946Sphkstatic int 47212946SphkS_loadavg(int l2, void *p) 47312946Sphk{ 47412946Sphk struct loadavg *tv = (struct loadavg*)p; 4758857Srgrimes 47697232Salfred if (l2 != sizeof(*tv)) { 477203917Suqs warnx("S_loadavg %d != %zu", l2, sizeof(*tv)); 478170558Sbde return (1); 47997232Salfred } 480122233Sdes printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }", 48112946Sphk (double)tv->ldavg[0]/(double)tv->fscale, 48212946Sphk (double)tv->ldavg[1]/(double)tv->fscale, 48312946Sphk (double)tv->ldavg[2]/(double)tv->fscale); 48412946Sphk return (0); 48512946Sphk} 4861553Srgrimes 48712946Sphkstatic int 48812946SphkS_timeval(int l2, void *p) 48912946Sphk{ 49012946Sphk struct timeval *tv = (struct timeval*)p; 49137266Sbde time_t tv_sec; 49212946Sphk char *p1, *p2; 4931553Srgrimes 49497232Salfred if (l2 != sizeof(*tv)) { 495203917Suqs warnx("S_timeval %d != %zu", l2, sizeof(*tv)); 496170558Sbde return (1); 49797232Salfred } 498194684Sjhay printf(hflag ? "{ sec = %'jd, usec = %'ld } " : 499194684Sjhay "{ sec = %jd, usec = %ld } ", 500194684Sjhay (intmax_t)tv->tv_sec, tv->tv_usec); 50137266Sbde tv_sec = tv->tv_sec; 50237266Sbde p1 = strdup(ctime(&tv_sec)); 50312946Sphk for (p2=p1; *p2 ; p2++) 50412946Sphk if (*p2 == '\n') 50512946Sphk *p2 = '\0'; 50612946Sphk fputs(p1, stdout); 507205118Sbrucec free(p1); 50812946Sphk return (0); 50912946Sphk} 5101553Srgrimes 51112946Sphkstatic int 512109097SdillonS_vmtotal(int l2, void *p) 513109097Sdillon{ 514109097Sdillon struct vmtotal *v = (struct vmtotal *)p; 515109113Sdillon int pageKilo = getpagesize() / 1024; 516109097Sdillon 517109097Sdillon if (l2 != sizeof(*v)) { 518203917Suqs warnx("S_vmtotal %d != %zu", l2, sizeof(*v)); 519170558Sbde return (1); 520109097Sdillon } 521109097Sdillon 522109113Sdillon printf( 523109113Sdillon "\nSystem wide totals computed every five seconds:" 524109113Sdillon " (values in kilobytes)\n"); 525109097Sdillon printf("===============================================\n"); 526109113Sdillon printf( 527164718Sru "Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: " 528164718Sru "%hd Sleep: %hd)\n", 529109113Sdillon v->t_rq, v->t_dw, v->t_pw, v->t_sl); 530109113Sdillon printf( 531212726Szec "Virtual Memory:\t\t(Total: %dK Active: %dK)\n", 532164718Sru v->t_vm * pageKilo, v->t_avm * pageKilo); 533212726Szec printf("Real Memory:\t\t(Total: %dK Active: %dK)\n", 534164718Sru v->t_rm * pageKilo, v->t_arm * pageKilo); 535164718Sru printf("Shared Virtual Memory:\t(Total: %dK Active: %dK)\n", 536164718Sru v->t_vmshr * pageKilo, v->t_avmshr * pageKilo); 537164718Sru printf("Shared Real Memory:\t(Total: %dK Active: %dK)\n", 538164718Sru v->t_rmshr * pageKilo, v->t_armshr * pageKilo); 539234134Seadler printf("Free Memory:\t%dK\n", v->t_free * pageKilo); 540122234Sdes 541109097Sdillon return (0); 542109097Sdillon} 543109097Sdillon 544109097Sdillonstatic int 545198340Sedset_IK(const char *str, int *val) 546161951Sume{ 547161951Sume float temp; 548161951Sume int len, kelv; 549198340Sed const char *p; 550198340Sed char *endptr; 551161951Sume 552161951Sume if ((len = strlen(str)) == 0) 553161951Sume return (0); 554161951Sume p = &str[len - 1]; 555161951Sume if (*p == 'C' || *p == 'F') { 556161951Sume temp = strtof(str, &endptr); 557198340Sed if (endptr == str || endptr != p) 558161951Sume return (0); 559161951Sume if (*p == 'F') 560161951Sume temp = (temp - 32) * 5 / 9; 561161951Sume kelv = temp * 10 + 2732; 562161951Sume } else { 563161951Sume kelv = (int)strtol(str, &endptr, 10); 564161951Sume if (endptr == str || *endptr != '\0') 565161951Sume return (0); 566161951Sume } 567161951Sume *val = kelv; 568161951Sume return (1); 569161951Sume} 570161951Sume 57112946Sphk/* 57212946Sphk * These functions uses a presently undocumented interface to the kernel 57312946Sphk * to walk the tree and get the type so it can print the value. 57412946Sphk * This interface is under work and consideration, and should probably 57512946Sphk * be killed with a big axe by the first person who can find the time. 57612946Sphk * (be aware though, that the proper interface isn't as obvious as it 57712946Sphk * may seem, there are various conflicting requirements. 57812946Sphk */ 5791553Srgrimes 58012946Sphkstatic int 58112946Sphkname2oid(char *name, int *oidp) 58212946Sphk{ 58312946Sphk int oid[2]; 58438533Sdfr int i; 58538533Sdfr size_t j; 5861553Srgrimes 58712946Sphk oid[0] = 0; 58812946Sphk oid[1] = 3; 5891553Srgrimes 59077928Sdd j = CTL_MAXNAME * sizeof(int); 59112946Sphk i = sysctl(oid, 2, oidp, &j, name, strlen(name)); 592122234Sdes if (i < 0) 593170512Sdwmalone return (i); 59477928Sdd j /= sizeof(int); 59512946Sphk return (j); 5961553Srgrimes} 5971553Srgrimes 59812946Sphkstatic int 59912946Sphkoidfmt(int *oid, int len, char *fmt, u_int *kind) 60012946Sphk{ 60112946Sphk int qoid[CTL_MAXNAME+2]; 60212946Sphk u_char buf[BUFSIZ]; 60338533Sdfr int i; 60438533Sdfr size_t j; 6051553Srgrimes 60612946Sphk qoid[0] = 0; 60712946Sphk qoid[1] = 4; 60812946Sphk memcpy(qoid + 2, oid, len * sizeof(int)); 6091553Srgrimes 61077928Sdd j = sizeof(buf); 61112946Sphk i = sysctl(qoid, len + 2, buf, &j, 0, 0); 61212946Sphk if (i) 613203917Suqs err(1, "sysctl fmt %d %zu %d", i, j, errno); 6141553Srgrimes 61512946Sphk if (kind) 61612946Sphk *kind = *(u_int *)buf; 61712946Sphk 61812946Sphk if (fmt) 61912946Sphk strcpy(fmt, (char *)(buf + sizeof(u_int))); 620170512Sdwmalone return (0); 6211553Srgrimes} 6221553Srgrimes 623217616Smdfstatic int ctl_sign[CTLTYPE+1] = { 624217616Smdf [CTLTYPE_INT] = 1, 625217616Smdf [CTLTYPE_LONG] = 1, 626217616Smdf [CTLTYPE_S64] = 1, 627217616Smdf}; 628217616Smdf 629217616Smdfstatic int ctl_size[CTLTYPE+1] = { 630217616Smdf [CTLTYPE_INT] = sizeof(int), 631217616Smdf [CTLTYPE_UINT] = sizeof(u_int), 632217616Smdf [CTLTYPE_LONG] = sizeof(long), 633217616Smdf [CTLTYPE_ULONG] = sizeof(u_long), 634217616Smdf [CTLTYPE_S64] = sizeof(int64_t), 635217616Smdf [CTLTYPE_U64] = sizeof(int64_t), 636217616Smdf}; 637217616Smdf 6381553Srgrimes/* 63912946Sphk * This formats and outputs the value of one variable 64012946Sphk * 64112946Sphk * Returns zero if anything was actually output. 64212946Sphk * Returns one if didn't know what to do with this. 64312946Sphk * Return minus one if we had errors. 6441553Srgrimes */ 64512946Sphkstatic int 64612946Sphkshow_var(int *oid, int nlen) 6471553Srgrimes{ 648162073Sru u_char buf[BUFSIZ], *val, *oval, *p; 649244133Salfred char name[BUFSIZ], fmt[BUFSIZ]; 650170513Sdwmalone const char *sep, *sep1; 65112946Sphk int qoid[CTL_MAXNAME+2]; 652170512Sdwmalone uintmax_t umv; 653170512Sdwmalone intmax_t mv; 654217586Smdf int i, hexlen, sign, ctltype; 655170287Sdwmalone size_t intlen; 65638533Sdfr size_t j, len; 65712946Sphk u_int kind; 65877332Sdes int (*func)(int, void *); 6591553Srgrimes 660203917Suqs /* Silence GCC. */ 661203917Suqs umv = mv = intlen = 0; 662203917Suqs 663144997Smdodd bzero(buf, BUFSIZ); 664244133Salfred bzero(fmt, BUFSIZ); 665144997Smdodd bzero(name, BUFSIZ); 66642456Sdes qoid[0] = 0; 66742456Sdes memcpy(qoid + 2, oid, nlen * sizeof(int)); 66842456Sdes 66942456Sdes qoid[1] = 1; 67077928Sdd j = sizeof(name); 67142456Sdes i = sysctl(qoid, nlen + 2, name, &j, 0, 0); 67242456Sdes if (i || !j) 673203917Suqs err(1, "sysctl name %d %zu %d", i, j, errno); 67442456Sdes 675244133Salfred oidfmt(oid, nlen, fmt, &kind); 676244133Salfred /* if Wflag then only list sysctls that are writeable and not stats. */ 677244133Salfred if (Wflag && ((kind & CTLFLAG_WR) == 0 || (kind & CTLFLAG_STATS) != 0)) 678244133Salfred return 1; 679244133Salfred 680244133Salfred /* if Tflag then only list sysctls that are tuneables. */ 681244133Salfred if (Tflag && (kind & CTLFLAG_TUN) == 0) 682244133Salfred return 1; 683244133Salfred 68471034Sdes if (Nflag) { 68571034Sdes printf("%s", name); 68671034Sdes return (0); 68771034Sdes } 68871034Sdes 68985747Stobez if (eflag) 69085747Stobez sep = "="; 69185747Stobez else 69285747Stobez sep = ": "; 69385747Stobez 69488006Sluigi if (dflag) { /* just print description */ 69588006Sluigi qoid[1] = 5; 69688006Sluigi j = sizeof(buf); 69788006Sluigi i = sysctl(qoid, nlen + 2, buf, &j, 0, 0); 69888006Sluigi if (!nflag) 69988006Sluigi printf("%s%s", name, sep); 70088006Sluigi printf("%s", buf); 70188006Sluigi return (0); 70288006Sluigi } 70312946Sphk /* find an estimate of how much we need for this var */ 70412946Sphk j = 0; 70512946Sphk i = sysctl(oid, nlen, 0, &j, 0, 0); 70612946Sphk j += j; /* we want to be sure :-) */ 70712946Sphk 708162073Sru val = oval = malloc(j + 1); 709162073Sru if (val == NULL) { 710162073Sru warnx("malloc failed"); 711170558Sbde return (1); 712162073Sru } 713268243Shselasky ctltype = (kind & CTLTYPE); 71412946Sphk len = j; 71512946Sphk i = sysctl(oid, nlen, val, &len, 0, 0); 716268243Shselasky if (i != 0 || (len == 0 && ctltype != CTLTYPE_STRING)) { 717162073Sru free(oval); 71812946Sphk return (1); 719162073Sru } 72012946Sphk 72112946Sphk if (bflag) { 72212946Sphk fwrite(val, 1, len, stdout); 723162073Sru free(oval); 72412946Sphk return (0); 7251553Srgrimes } 72696234Sache val[len] = '\0'; 72712946Sphk p = val; 728217616Smdf sign = ctl_sign[ctltype]; 729217616Smdf intlen = ctl_size[ctltype]; 730217616Smdf 731217586Smdf switch (ctltype) { 732217586Smdf case CTLTYPE_STRING: 73312946Sphk if (!nflag) 73485747Stobez printf("%s%s", name, sep); 735203917Suqs printf("%.*s", (int)len, p); 736162073Sru free(oval); 73712946Sphk return (0); 738122234Sdes 739217586Smdf case CTLTYPE_INT: 740217586Smdf case CTLTYPE_UINT: 741217586Smdf case CTLTYPE_LONG: 742217586Smdf case CTLTYPE_ULONG: 743217616Smdf case CTLTYPE_S64: 744217616Smdf case CTLTYPE_U64: 74512946Sphk if (!nflag) 74685747Stobez printf("%s%s", name, sep); 747170514Sdwmalone hexlen = 2 + (intlen * CHAR_BIT + 3) / 4; 748170513Sdwmalone sep1 = ""; 749170287Sdwmalone while (len >= intlen) { 750217586Smdf switch (kind & CTLTYPE) { 751217586Smdf case CTLTYPE_INT: 752217586Smdf case CTLTYPE_UINT: 753170514Sdwmalone umv = *(u_int *)p; 754170514Sdwmalone mv = *(int *)p; 755170287Sdwmalone break; 756217586Smdf case CTLTYPE_LONG: 757217586Smdf case CTLTYPE_ULONG: 758170514Sdwmalone umv = *(u_long *)p; 759170514Sdwmalone mv = *(long *)p; 760170287Sdwmalone break; 761217616Smdf case CTLTYPE_S64: 762217616Smdf case CTLTYPE_U64: 763217616Smdf umv = *(uint64_t *)p; 764217616Smdf mv = *(int64_t *)p; 765170287Sdwmalone break; 766170287Sdwmalone } 767170513Sdwmalone fputs(sep1, stdout); 768217586Smdf if (xflag) 769217586Smdf printf("%#0*jx", hexlen, umv); 770217586Smdf else if (!sign) 771170512Sdwmalone printf(hflag ? "%'ju" : "%ju", umv); 772170287Sdwmalone else if (fmt[1] == 'K') { 773170514Sdwmalone if (mv < 0) 774170512Sdwmalone printf("%jd", mv); 775134541Speter else 776170512Sdwmalone printf("%.1fC", (mv - 2732.0) / 10); 777134541Speter } else 778170513Sdwmalone printf(hflag ? "%'jd" : "%jd", mv); 779170513Sdwmalone sep1 = " "; 780170287Sdwmalone len -= intlen; 781170287Sdwmalone p += intlen; 78241019Sphk } 783162073Sru free(oval); 78412946Sphk return (0); 78512946Sphk 786217586Smdf case CTLTYPE_OPAQUE: 78712946Sphk i = 0; 78877332Sdes if (strcmp(fmt, "S,clockinfo") == 0) 78977332Sdes func = S_clockinfo; 79077332Sdes else if (strcmp(fmt, "S,timeval") == 0) 79177332Sdes func = S_timeval; 79277332Sdes else if (strcmp(fmt, "S,loadavg") == 0) 79377332Sdes func = S_loadavg; 794109097Sdillon else if (strcmp(fmt, "S,vmtotal") == 0) 795109097Sdillon func = S_vmtotal; 79677332Sdes else 79777332Sdes func = NULL; 79812946Sphk if (func) { 79912946Sphk if (!nflag) 80085747Stobez printf("%s%s", name, sep); 801163275Sharti i = (*func)(len, p); 802162073Sru free(oval); 803163275Sharti return (i); 80412946Sphk } 805102411Scharnier /* FALLTHROUGH */ 80612946Sphk default: 807162073Sru if (!oflag && !xflag) { 808162073Sru free(oval); 80912946Sphk return (1); 810162073Sru } 81112946Sphk if (!nflag) 81285747Stobez printf("%s%s", name, sep); 813203917Suqs printf("Format:%s Length:%zu Dump:0x", fmt, len); 81477332Sdes while (len-- && (xflag || p < val + 16)) 81512946Sphk printf("%02x", *p++); 81677332Sdes if (!xflag && len > 16) 81712946Sphk printf("..."); 818162073Sru free(oval); 81912946Sphk return (0); 8201553Srgrimes } 821162073Sru free(oval); 82212946Sphk return (1); 8231553Srgrimes} 8241553Srgrimes 82512946Sphkstatic int 826170512Sdwmalonesysctl_all(int *oid, int len) 8271553Srgrimes{ 82812946Sphk int name1[22], name2[22]; 82938533Sdfr int i, j; 83038533Sdfr size_t l1, l2; 8311553Srgrimes 83212946Sphk name1[0] = 0; 83312946Sphk name1[1] = 2; 83412946Sphk l1 = 2; 83512946Sphk if (len) { 83677928Sdd memcpy(name1+2, oid, len * sizeof(int)); 83712946Sphk l1 += len; 83812946Sphk } else { 83912946Sphk name1[2] = 1; 84012946Sphk l1++; 84112946Sphk } 84277332Sdes for (;;) { 84377928Sdd l2 = sizeof(name2); 84412946Sphk j = sysctl(name1, l1, name2, &l2, 0, 0); 84548956Sbillf if (j < 0) { 84612946Sphk if (errno == ENOENT) 847170512Sdwmalone return (0); 84812946Sphk else 849203917Suqs err(1, "sysctl(getnext) %d %zu", j, l2); 85048956Sbillf } 85112946Sphk 85277928Sdd l2 /= sizeof(int); 85312946Sphk 854170513Sdwmalone if (len < 0 || l2 < (unsigned int)len) 855170512Sdwmalone return (0); 85612946Sphk 85712946Sphk for (i = 0; i < len; i++) 85812946Sphk if (name2[i] != oid[i]) 859170512Sdwmalone return (0); 86012946Sphk 86112946Sphk i = show_var(name2, l2); 86212946Sphk if (!i && !bflag) 86312946Sphk putchar('\n'); 86412946Sphk 86577928Sdd memcpy(name1+2, name2, l2 * sizeof(int)); 86612946Sphk l1 = 2 + l2; 86712946Sphk } 8681553Srgrimes} 869