1262821Sadrian/*- 2262821Sadrian * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting 3262821Sadrian * All rights reserved. 4262821Sadrian * 5262821Sadrian * Redistribution and use in source and binary forms, with or without 6262821Sadrian * modification, are permitted provided that the following conditions 7262821Sadrian * are met: 8262821Sadrian * 1. Redistributions of source code must retain the above copyright 9262821Sadrian * notice, this list of conditions and the following disclaimer, 10262821Sadrian * without modification. 11262821Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12262821Sadrian * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13262821Sadrian * redistribution must be conditioned upon including a substantially 14262821Sadrian * similar Disclaimer requirement for further binary redistribution. 15262821Sadrian * 16262821Sadrian * NO WARRANTY 17262821Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18262821Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19262821Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20262821Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21262821Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22262821Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23262821Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24262821Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25262821Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26262821Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27262821Sadrian * THE POSSIBILITY OF SUCH DAMAGES. 28262821Sadrian * 29262821Sadrian * $FreeBSD$ 30262821Sadrian */ 31262821Sadrian 32262821Sadrian#include <stdio.h> 33262821Sadrian#include <string.h> 34262821Sadrian 35262821Sadrian#include "bsdstat.h" 36262821Sadrian 37262821Sadrianstatic void 38262821Sadrianbsdstat_setfmt(struct bsdstat *sf, const char *fmt0) 39262821Sadrian{ 40262821Sadrian#define N(a) (sizeof(a)/sizeof(a[0])) 41262821Sadrian char fmt[4096]; 42262821Sadrian char *fp, *tok; 43262821Sadrian int i, j; 44262821Sadrian 45262821Sadrian j = 0; 46262821Sadrian strlcpy(fmt, fmt0, sizeof(fmt)); 47262821Sadrian for (fp = fmt; (tok = strsep(&fp, ", ")) != NULL;) { 48262821Sadrian for (i = 0; i < sf->nstats; i++) 49262821Sadrian if (strcasecmp(tok, sf->stats[i].name) == 0) 50262821Sadrian break; 51262821Sadrian if (i >= sf->nstats) { 52262821Sadrian fprintf(stderr, "%s: unknown statistic name \"%s\" " 53262821Sadrian "skipped\n", sf->name, tok); 54262821Sadrian continue; 55262821Sadrian } 56299950Struckman if (j+4 > (int) sizeof(sf->fmts)) { 57262821Sadrian fprintf(stderr, "%s: not enough room for all stats; " 58262821Sadrian "stopped at %s\n", sf->name, tok); 59262821Sadrian break; 60262821Sadrian } 61262821Sadrian if (j != 0) 62262821Sadrian sf->fmts[j++] = ' '; 63262821Sadrian sf->fmts[j++] = FMTS_IS_STAT; 64262821Sadrian sf->fmts[j++] = i & 0xff; 65262821Sadrian sf->fmts[j++] = (i >> 8) & 0xff; 66262821Sadrian } 67262821Sadrian sf->fmts[j] = '\0'; 68262821Sadrian#undef N 69262821Sadrian} 70262821Sadrian 71262821Sadrianstatic void 72262821Sadrianbsdstat_collect(struct bsdstat *sf) 73262821Sadrian{ 74262821Sadrian fprintf(stderr, "%s: don't know how to collect data\n", sf->name); 75262821Sadrian} 76262821Sadrian 77262821Sadrianstatic void 78262821Sadrianbsdstat_update_tot(struct bsdstat *sf) 79262821Sadrian{ 80262821Sadrian fprintf(stderr, "%s: don't know how to update total data\n", sf->name); 81262821Sadrian} 82262821Sadrian 83262821Sadrianstatic int 84262992Seadlerbsdstat_get(struct bsdstat *sf, int s, char b[] __unused, size_t bs __unused) 85262821Sadrian{ 86262821Sadrian fprintf(stderr, "%s: don't know how to get stat #%u\n", sf->name, s); 87262821Sadrian return 0; 88262821Sadrian} 89262821Sadrian 90262821Sadrianstatic void 91262821Sadrianbsdstat_print_header(struct bsdstat *sf, FILE *fd) 92262821Sadrian{ 93262821Sadrian const unsigned char *cp; 94262821Sadrian int i; 95262821Sadrian const struct fmt *f; 96262821Sadrian 97262821Sadrian for (cp = sf->fmts; *cp != '\0'; cp++) { 98262821Sadrian if (*cp == FMTS_IS_STAT) { 99262821Sadrian i = *(++cp); 100262821Sadrian i |= ((int) *(++cp)) << 8; 101262821Sadrian f = &sf->stats[i]; 102262821Sadrian fprintf(fd, "%*s", f->width, f->label); 103262821Sadrian } else 104262821Sadrian putc(*cp, fd); 105262821Sadrian } 106262821Sadrian putc('\n', fd); 107262821Sadrian} 108262821Sadrian 109262821Sadrianstatic void 110262821Sadrianbsdstat_print_current(struct bsdstat *sf, FILE *fd) 111262821Sadrian{ 112262821Sadrian char buf[32]; 113262821Sadrian const unsigned char *cp; 114262821Sadrian int i; 115262821Sadrian const struct fmt *f; 116262821Sadrian 117262821Sadrian for (cp = sf->fmts; *cp != '\0'; cp++) { 118262821Sadrian if (*cp == FMTS_IS_STAT) { 119262821Sadrian i = *(++cp); 120262821Sadrian i |= ((int) *(++cp)) << 8; 121262821Sadrian f = &sf->stats[i]; 122262821Sadrian if (sf->get_curstat(sf, i, buf, sizeof(buf))) 123262821Sadrian fprintf(fd, "%*s", f->width, buf); 124262821Sadrian } else 125262821Sadrian putc(*cp, fd); 126262821Sadrian } 127262821Sadrian putc('\n', fd); 128262821Sadrian} 129262821Sadrian 130262821Sadrianstatic void 131262821Sadrianbsdstat_print_total(struct bsdstat *sf, FILE *fd) 132262821Sadrian{ 133262821Sadrian char buf[32]; 134262821Sadrian const unsigned char *cp; 135262821Sadrian const struct fmt *f; 136262821Sadrian int i; 137262821Sadrian 138262821Sadrian for (cp = sf->fmts; *cp != '\0'; cp++) { 139262821Sadrian if (*cp == FMTS_IS_STAT) { 140262821Sadrian i = *(++cp); 141262821Sadrian i |= ((int) *(++cp)) << 8; 142262821Sadrian f = &sf->stats[i]; 143262821Sadrian if (sf->get_totstat(sf, i, buf, sizeof(buf))) 144262821Sadrian fprintf(fd, "%*s", f->width, buf); 145262821Sadrian } else 146262821Sadrian putc(*cp, fd); 147262821Sadrian } 148262821Sadrian putc('\n', fd); 149262821Sadrian} 150262821Sadrian 151262821Sadrianstatic void 152262821Sadrianbsdstat_print_verbose(struct bsdstat *sf, FILE *fd) 153262821Sadrian{ 154262821Sadrian const struct fmt *f; 155262821Sadrian char s[32]; 156262821Sadrian int i, width; 157262821Sadrian 158262821Sadrian width = 0; 159262821Sadrian for (i = 0; i < sf->nstats; i++) { 160262821Sadrian f = &sf->stats[i]; 161262821Sadrian if (f->width > width) 162262821Sadrian width = f->width; 163262821Sadrian } 164262821Sadrian for (i = 0; i < sf->nstats; i++) { 165262821Sadrian f = &sf->stats[i]; 166262821Sadrian if (sf->get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) 167262821Sadrian fprintf(fd, "%-*s %s\n", width, s, f->desc); 168262821Sadrian } 169262821Sadrian} 170262821Sadrian 171262821Sadrianstatic void 172262821Sadrianbsdstat_print_fields(struct bsdstat *sf, FILE *fd) 173262821Sadrian{ 174262821Sadrian int i, w, width; 175262821Sadrian 176262821Sadrian width = 0; 177262821Sadrian for (i = 0; i < sf->nstats; i++) { 178262821Sadrian w = strlen(sf->stats[i].name); 179262821Sadrian if (w > width) 180262821Sadrian width = w; 181262821Sadrian } 182262821Sadrian for (i = 0; i < sf->nstats; i++) { 183262821Sadrian const struct fmt *f = &sf->stats[i]; 184262821Sadrian if (f->width != 0) 185262821Sadrian fprintf(fd, "%-*s %s\n", width, f->name, f->desc); 186262821Sadrian } 187262821Sadrian} 188262821Sadrian 189262821Sadrianvoid 190262821Sadrianbsdstat_init(struct bsdstat *sf, const char *name, const struct fmt *stats, int nstats) 191262821Sadrian{ 192262821Sadrian sf->name = name; 193262821Sadrian sf->stats = stats; 194262821Sadrian sf->nstats = nstats; 195262821Sadrian sf->setfmt = bsdstat_setfmt; 196262821Sadrian sf->collect_cur = bsdstat_collect; 197262821Sadrian sf->collect_tot = bsdstat_collect; 198262821Sadrian sf->update_tot = bsdstat_update_tot; 199262821Sadrian sf->get_curstat = bsdstat_get; 200262821Sadrian sf->get_totstat = bsdstat_get; 201262821Sadrian sf->print_header = bsdstat_print_header; 202262821Sadrian sf->print_current = bsdstat_print_current; 203262821Sadrian sf->print_total = bsdstat_print_total; 204262821Sadrian sf->print_verbose = bsdstat_print_verbose; 205262821Sadrian sf->print_fields = bsdstat_print_fields; 206262821Sadrian} 207