1*81bd3d89SAdrian Chadd /*- 2*81bd3d89SAdrian Chadd * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting 3*81bd3d89SAdrian Chadd * All rights reserved. 4*81bd3d89SAdrian Chadd * 5*81bd3d89SAdrian Chadd * Redistribution and use in source and binary forms, with or without 6*81bd3d89SAdrian Chadd * modification, are permitted provided that the following conditions 7*81bd3d89SAdrian Chadd * are met: 8*81bd3d89SAdrian Chadd * 1. Redistributions of source code must retain the above copyright 9*81bd3d89SAdrian Chadd * notice, this list of conditions and the following disclaimer, 10*81bd3d89SAdrian Chadd * without modification. 11*81bd3d89SAdrian Chadd * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12*81bd3d89SAdrian Chadd * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13*81bd3d89SAdrian Chadd * redistribution must be conditioned upon including a substantially 14*81bd3d89SAdrian Chadd * similar Disclaimer requirement for further binary redistribution. 15*81bd3d89SAdrian Chadd * 16*81bd3d89SAdrian Chadd * NO WARRANTY 17*81bd3d89SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18*81bd3d89SAdrian Chadd * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19*81bd3d89SAdrian Chadd * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20*81bd3d89SAdrian Chadd * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21*81bd3d89SAdrian Chadd * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22*81bd3d89SAdrian Chadd * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23*81bd3d89SAdrian Chadd * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24*81bd3d89SAdrian Chadd * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25*81bd3d89SAdrian Chadd * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26*81bd3d89SAdrian Chadd * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27*81bd3d89SAdrian Chadd * THE POSSIBILITY OF SUCH DAMAGES. 28*81bd3d89SAdrian Chadd * 29*81bd3d89SAdrian Chadd * $FreeBSD$ 30*81bd3d89SAdrian Chadd */ 31*81bd3d89SAdrian Chadd 32*81bd3d89SAdrian Chadd #include <stdio.h> 33*81bd3d89SAdrian Chadd #include <string.h> 34*81bd3d89SAdrian Chadd 35*81bd3d89SAdrian Chadd #include "bsdstat.h" 36*81bd3d89SAdrian Chadd 37*81bd3d89SAdrian Chadd static void 38*81bd3d89SAdrian Chadd bsdstat_setfmt(struct bsdstat *sf, const char *fmt0) 39*81bd3d89SAdrian Chadd { 40*81bd3d89SAdrian Chadd #define N(a) (sizeof(a)/sizeof(a[0])) 41*81bd3d89SAdrian Chadd char fmt[4096]; 42*81bd3d89SAdrian Chadd char *fp, *tok; 43*81bd3d89SAdrian Chadd int i, j; 44*81bd3d89SAdrian Chadd 45*81bd3d89SAdrian Chadd j = 0; 46*81bd3d89SAdrian Chadd strlcpy(fmt, fmt0, sizeof(fmt)); 47*81bd3d89SAdrian Chadd for (fp = fmt; (tok = strsep(&fp, ", ")) != NULL;) { 48*81bd3d89SAdrian Chadd for (i = 0; i < sf->nstats; i++) 49*81bd3d89SAdrian Chadd if (strcasecmp(tok, sf->stats[i].name) == 0) 50*81bd3d89SAdrian Chadd break; 51*81bd3d89SAdrian Chadd if (i >= sf->nstats) { 52*81bd3d89SAdrian Chadd fprintf(stderr, "%s: unknown statistic name \"%s\" " 53*81bd3d89SAdrian Chadd "skipped\n", sf->name, tok); 54*81bd3d89SAdrian Chadd continue; 55*81bd3d89SAdrian Chadd } 56*81bd3d89SAdrian Chadd if (j+3 > (int) sizeof(sf->fmts)) { 57*81bd3d89SAdrian Chadd fprintf(stderr, "%s: not enough room for all stats; " 58*81bd3d89SAdrian Chadd "stopped at %s\n", sf->name, tok); 59*81bd3d89SAdrian Chadd break; 60*81bd3d89SAdrian Chadd } 61*81bd3d89SAdrian Chadd if (j != 0) 62*81bd3d89SAdrian Chadd sf->fmts[j++] = ' '; 63*81bd3d89SAdrian Chadd sf->fmts[j++] = FMTS_IS_STAT; 64*81bd3d89SAdrian Chadd sf->fmts[j++] = i & 0xff; 65*81bd3d89SAdrian Chadd sf->fmts[j++] = (i >> 8) & 0xff; 66*81bd3d89SAdrian Chadd } 67*81bd3d89SAdrian Chadd sf->fmts[j] = '\0'; 68*81bd3d89SAdrian Chadd #undef N 69*81bd3d89SAdrian Chadd } 70*81bd3d89SAdrian Chadd 71*81bd3d89SAdrian Chadd static void 72*81bd3d89SAdrian Chadd bsdstat_collect(struct bsdstat *sf) 73*81bd3d89SAdrian Chadd { 74*81bd3d89SAdrian Chadd fprintf(stderr, "%s: don't know how to collect data\n", sf->name); 75*81bd3d89SAdrian Chadd } 76*81bd3d89SAdrian Chadd 77*81bd3d89SAdrian Chadd static void 78*81bd3d89SAdrian Chadd bsdstat_update_tot(struct bsdstat *sf) 79*81bd3d89SAdrian Chadd { 80*81bd3d89SAdrian Chadd fprintf(stderr, "%s: don't know how to update total data\n", sf->name); 81*81bd3d89SAdrian Chadd } 82*81bd3d89SAdrian Chadd 83*81bd3d89SAdrian Chadd static int 84*81bd3d89SAdrian Chadd bsdstat_get(struct bsdstat *sf, int s, char b[], size_t bs) 85*81bd3d89SAdrian Chadd { 86*81bd3d89SAdrian Chadd fprintf(stderr, "%s: don't know how to get stat #%u\n", sf->name, s); 87*81bd3d89SAdrian Chadd return 0; 88*81bd3d89SAdrian Chadd } 89*81bd3d89SAdrian Chadd 90*81bd3d89SAdrian Chadd static void 91*81bd3d89SAdrian Chadd bsdstat_print_header(struct bsdstat *sf, FILE *fd) 92*81bd3d89SAdrian Chadd { 93*81bd3d89SAdrian Chadd const unsigned char *cp; 94*81bd3d89SAdrian Chadd int i; 95*81bd3d89SAdrian Chadd const struct fmt *f; 96*81bd3d89SAdrian Chadd 97*81bd3d89SAdrian Chadd for (cp = sf->fmts; *cp != '\0'; cp++) { 98*81bd3d89SAdrian Chadd if (*cp == FMTS_IS_STAT) { 99*81bd3d89SAdrian Chadd i = *(++cp); 100*81bd3d89SAdrian Chadd i |= ((int) *(++cp)) << 8; 101*81bd3d89SAdrian Chadd f = &sf->stats[i]; 102*81bd3d89SAdrian Chadd fprintf(fd, "%*s", f->width, f->label); 103*81bd3d89SAdrian Chadd } else 104*81bd3d89SAdrian Chadd putc(*cp, fd); 105*81bd3d89SAdrian Chadd } 106*81bd3d89SAdrian Chadd putc('\n', fd); 107*81bd3d89SAdrian Chadd } 108*81bd3d89SAdrian Chadd 109*81bd3d89SAdrian Chadd static void 110*81bd3d89SAdrian Chadd bsdstat_print_current(struct bsdstat *sf, FILE *fd) 111*81bd3d89SAdrian Chadd { 112*81bd3d89SAdrian Chadd char buf[32]; 113*81bd3d89SAdrian Chadd const unsigned char *cp; 114*81bd3d89SAdrian Chadd int i; 115*81bd3d89SAdrian Chadd const struct fmt *f; 116*81bd3d89SAdrian Chadd 117*81bd3d89SAdrian Chadd for (cp = sf->fmts; *cp != '\0'; cp++) { 118*81bd3d89SAdrian Chadd if (*cp == FMTS_IS_STAT) { 119*81bd3d89SAdrian Chadd i = *(++cp); 120*81bd3d89SAdrian Chadd i |= ((int) *(++cp)) << 8; 121*81bd3d89SAdrian Chadd f = &sf->stats[i]; 122*81bd3d89SAdrian Chadd if (sf->get_curstat(sf, i, buf, sizeof(buf))) 123*81bd3d89SAdrian Chadd fprintf(fd, "%*s", f->width, buf); 124*81bd3d89SAdrian Chadd } else 125*81bd3d89SAdrian Chadd putc(*cp, fd); 126*81bd3d89SAdrian Chadd } 127*81bd3d89SAdrian Chadd putc('\n', fd); 128*81bd3d89SAdrian Chadd } 129*81bd3d89SAdrian Chadd 130*81bd3d89SAdrian Chadd static void 131*81bd3d89SAdrian Chadd bsdstat_print_total(struct bsdstat *sf, FILE *fd) 132*81bd3d89SAdrian Chadd { 133*81bd3d89SAdrian Chadd char buf[32]; 134*81bd3d89SAdrian Chadd const unsigned char *cp; 135*81bd3d89SAdrian Chadd const struct fmt *f; 136*81bd3d89SAdrian Chadd int i; 137*81bd3d89SAdrian Chadd 138*81bd3d89SAdrian Chadd for (cp = sf->fmts; *cp != '\0'; cp++) { 139*81bd3d89SAdrian Chadd if (*cp == FMTS_IS_STAT) { 140*81bd3d89SAdrian Chadd i = *(++cp); 141*81bd3d89SAdrian Chadd i |= ((int) *(++cp)) << 8; 142*81bd3d89SAdrian Chadd f = &sf->stats[i]; 143*81bd3d89SAdrian Chadd if (sf->get_totstat(sf, i, buf, sizeof(buf))) 144*81bd3d89SAdrian Chadd fprintf(fd, "%*s", f->width, buf); 145*81bd3d89SAdrian Chadd } else 146*81bd3d89SAdrian Chadd putc(*cp, fd); 147*81bd3d89SAdrian Chadd } 148*81bd3d89SAdrian Chadd putc('\n', fd); 149*81bd3d89SAdrian Chadd } 150*81bd3d89SAdrian Chadd 151*81bd3d89SAdrian Chadd static void 152*81bd3d89SAdrian Chadd bsdstat_print_verbose(struct bsdstat *sf, FILE *fd) 153*81bd3d89SAdrian Chadd { 154*81bd3d89SAdrian Chadd const struct fmt *f; 155*81bd3d89SAdrian Chadd char s[32]; 156*81bd3d89SAdrian Chadd int i, width; 157*81bd3d89SAdrian Chadd 158*81bd3d89SAdrian Chadd width = 0; 159*81bd3d89SAdrian Chadd for (i = 0; i < sf->nstats; i++) { 160*81bd3d89SAdrian Chadd f = &sf->stats[i]; 161*81bd3d89SAdrian Chadd if (f->width > width) 162*81bd3d89SAdrian Chadd width = f->width; 163*81bd3d89SAdrian Chadd } 164*81bd3d89SAdrian Chadd for (i = 0; i < sf->nstats; i++) { 165*81bd3d89SAdrian Chadd f = &sf->stats[i]; 166*81bd3d89SAdrian Chadd if (sf->get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) 167*81bd3d89SAdrian Chadd fprintf(fd, "%-*s %s\n", width, s, f->desc); 168*81bd3d89SAdrian Chadd } 169*81bd3d89SAdrian Chadd } 170*81bd3d89SAdrian Chadd 171*81bd3d89SAdrian Chadd static void 172*81bd3d89SAdrian Chadd bsdstat_print_fields(struct bsdstat *sf, FILE *fd) 173*81bd3d89SAdrian Chadd { 174*81bd3d89SAdrian Chadd int i, w, width; 175*81bd3d89SAdrian Chadd 176*81bd3d89SAdrian Chadd width = 0; 177*81bd3d89SAdrian Chadd for (i = 0; i < sf->nstats; i++) { 178*81bd3d89SAdrian Chadd w = strlen(sf->stats[i].name); 179*81bd3d89SAdrian Chadd if (w > width) 180*81bd3d89SAdrian Chadd width = w; 181*81bd3d89SAdrian Chadd } 182*81bd3d89SAdrian Chadd for (i = 0; i < sf->nstats; i++) { 183*81bd3d89SAdrian Chadd const struct fmt *f = &sf->stats[i]; 184*81bd3d89SAdrian Chadd if (f->width != 0) 185*81bd3d89SAdrian Chadd fprintf(fd, "%-*s %s\n", width, f->name, f->desc); 186*81bd3d89SAdrian Chadd } 187*81bd3d89SAdrian Chadd } 188*81bd3d89SAdrian Chadd 189*81bd3d89SAdrian Chadd void 190*81bd3d89SAdrian Chadd bsdstat_init(struct bsdstat *sf, const char *name, const struct fmt *stats, int nstats) 191*81bd3d89SAdrian Chadd { 192*81bd3d89SAdrian Chadd sf->name = name; 193*81bd3d89SAdrian Chadd sf->stats = stats; 194*81bd3d89SAdrian Chadd sf->nstats = nstats; 195*81bd3d89SAdrian Chadd sf->setfmt = bsdstat_setfmt; 196*81bd3d89SAdrian Chadd sf->collect_cur = bsdstat_collect; 197*81bd3d89SAdrian Chadd sf->collect_tot = bsdstat_collect; 198*81bd3d89SAdrian Chadd sf->update_tot = bsdstat_update_tot; 199*81bd3d89SAdrian Chadd sf->get_curstat = bsdstat_get; 200*81bd3d89SAdrian Chadd sf->get_totstat = bsdstat_get; 201*81bd3d89SAdrian Chadd sf->print_header = bsdstat_print_header; 202*81bd3d89SAdrian Chadd sf->print_current = bsdstat_print_current; 203*81bd3d89SAdrian Chadd sf->print_total = bsdstat_print_total; 204*81bd3d89SAdrian Chadd sf->print_verbose = bsdstat_print_verbose; 205*81bd3d89SAdrian Chadd sf->print_fields = bsdstat_print_fields; 206*81bd3d89SAdrian Chadd } 207