1*29b76e53SScott Long /*- 2*29b76e53SScott Long * Copyright (c) 2008 Yahoo!, Inc. 3*29b76e53SScott Long * All rights reserved. 4*29b76e53SScott Long * Written by: John Baldwin <jhb@FreeBSD.org> 5*29b76e53SScott Long * 6*29b76e53SScott Long * Redistribution and use in source and binary forms, with or without 7*29b76e53SScott Long * modification, are permitted provided that the following conditions 8*29b76e53SScott Long * are met: 9*29b76e53SScott Long * 1. Redistributions of source code must retain the above copyright 10*29b76e53SScott Long * notice, this list of conditions and the following disclaimer. 11*29b76e53SScott Long * 2. Redistributions in binary form must reproduce the above copyright 12*29b76e53SScott Long * notice, this list of conditions and the following disclaimer in the 13*29b76e53SScott Long * documentation and/or other materials provided with the distribution. 14*29b76e53SScott Long * 3. Neither the name of the author nor the names of any co-contributors 15*29b76e53SScott Long * may be used to endorse or promote products derived from this software 16*29b76e53SScott Long * without specific prior written permission. 17*29b76e53SScott Long * 18*29b76e53SScott Long * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19*29b76e53SScott Long * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*29b76e53SScott Long * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*29b76e53SScott Long * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22*29b76e53SScott Long * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23*29b76e53SScott Long * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24*29b76e53SScott Long * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25*29b76e53SScott Long * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26*29b76e53SScott Long * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27*29b76e53SScott Long * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28*29b76e53SScott Long * SUCH DAMAGE. 29*29b76e53SScott Long */ 30*29b76e53SScott Long 31*29b76e53SScott Long #include <sys/cdefs.h> 32*29b76e53SScott Long __RCSID("$FreeBSD$"); 33*29b76e53SScott Long 34*29b76e53SScott Long #include <sys/param.h> 35*29b76e53SScott Long #include <sys/errno.h> 36*29b76e53SScott Long #include <err.h> 37*29b76e53SScott Long #include <stdio.h> 38*29b76e53SScott Long #include <stdlib.h> 39*29b76e53SScott Long #include <string.h> 40*29b76e53SScott Long #include <unistd.h> 41*29b76e53SScott Long #include "mpsutil.h" 42*29b76e53SScott Long 43*29b76e53SScott Long SET_DECLARE(MPS_DATASET(top), struct mpsutil_command); 44*29b76e53SScott Long SET_DECLARE(MPS_DATASET(usage), struct mpsutil_usage); 45*29b76e53SScott Long 46*29b76e53SScott Long int mps_unit; 47*29b76e53SScott Long 48*29b76e53SScott Long static void 49*29b76e53SScott Long usage(void) 50*29b76e53SScott Long { 51*29b76e53SScott Long struct mpsutil_usage **cmd; 52*29b76e53SScott Long const char *args, *desc; 53*29b76e53SScott Long 54*29b76e53SScott Long fprintf(stderr, "usage: mpsutil [-u unit] <command> ...\n\n"); 55*29b76e53SScott Long fprintf(stderr, "Commands include:\n"); 56*29b76e53SScott Long SET_FOREACH(cmd, MPS_DATASET(usage)) { 57*29b76e53SScott Long if (*cmd == NULL) 58*29b76e53SScott Long fprintf(stderr, "\n"); 59*29b76e53SScott Long else 60*29b76e53SScott Long (*cmd)->handler(&args, &desc); 61*29b76e53SScott Long if (strncmp((*cmd)->set, "top", 3) == 0) 62*29b76e53SScott Long fprintf(stderr, "%s %-30s\t%s\n", 63*29b76e53SScott Long (*cmd)->name, args, desc); 64*29b76e53SScott Long else 65*29b76e53SScott Long fprintf(stderr, "%s %s %-30s\t%s\n", 66*29b76e53SScott Long (*cmd)->set, (*cmd)->name, args, desc); 67*29b76e53SScott Long } 68*29b76e53SScott Long exit(1); 69*29b76e53SScott Long } 70*29b76e53SScott Long 71*29b76e53SScott Long static int 72*29b76e53SScott Long version(int ac, char **av) 73*29b76e53SScott Long { 74*29b76e53SScott Long 75*29b76e53SScott Long printf("mpsutil: version %s", MPSUTIL_VERSION); 76*29b76e53SScott Long #ifdef DEBUG 77*29b76e53SScott Long printf(" (DEBUG)"); 78*29b76e53SScott Long #endif 79*29b76e53SScott Long printf("\n"); 80*29b76e53SScott Long return (0); 81*29b76e53SScott Long } 82*29b76e53SScott Long 83*29b76e53SScott Long MPS_COMMAND(top, version, version, "", "version") 84*29b76e53SScott Long 85*29b76e53SScott Long int 86*29b76e53SScott Long main(int ac, char **av) 87*29b76e53SScott Long { 88*29b76e53SScott Long struct mpsutil_command **cmd; 89*29b76e53SScott Long int ch; 90*29b76e53SScott Long 91*29b76e53SScott Long while ((ch = getopt(ac, av, "u:h?")) != -1) { 92*29b76e53SScott Long switch (ch) { 93*29b76e53SScott Long case 'u': 94*29b76e53SScott Long mps_unit = atoi(optarg); 95*29b76e53SScott Long break; 96*29b76e53SScott Long case 'h': 97*29b76e53SScott Long case '?': 98*29b76e53SScott Long usage(); 99*29b76e53SScott Long return (1); 100*29b76e53SScott Long } 101*29b76e53SScott Long } 102*29b76e53SScott Long 103*29b76e53SScott Long av += optind; 104*29b76e53SScott Long ac -= optind; 105*29b76e53SScott Long 106*29b76e53SScott Long /* getopt() eats av[0], so we can't use mpt_table_handler() directly. */ 107*29b76e53SScott Long if (ac == 0) { 108*29b76e53SScott Long usage(); 109*29b76e53SScott Long return (1); 110*29b76e53SScott Long } 111*29b76e53SScott Long 112*29b76e53SScott Long SET_FOREACH(cmd, MPS_DATASET(top)) { 113*29b76e53SScott Long if (strcmp((*cmd)->name, av[0]) == 0) { 114*29b76e53SScott Long if ((*cmd)->handler(ac, av)) 115*29b76e53SScott Long return (1); 116*29b76e53SScott Long else 117*29b76e53SScott Long return (0); 118*29b76e53SScott Long } 119*29b76e53SScott Long } 120*29b76e53SScott Long warnx("Unknown command %s.", av[0]); 121*29b76e53SScott Long return (1); 122*29b76e53SScott Long } 123*29b76e53SScott Long 124*29b76e53SScott Long int 125*29b76e53SScott Long mps_table_handler(struct mpsutil_command **start, struct mpsutil_command **end, 126*29b76e53SScott Long int ac, char **av) 127*29b76e53SScott Long { 128*29b76e53SScott Long struct mpsutil_command **cmd; 129*29b76e53SScott Long 130*29b76e53SScott Long if (ac < 2) { 131*29b76e53SScott Long warnx("The %s command requires a sub-command.", av[0]); 132*29b76e53SScott Long return (EINVAL); 133*29b76e53SScott Long } 134*29b76e53SScott Long for (cmd = start; cmd < end; cmd++) { 135*29b76e53SScott Long if (strcmp((*cmd)->name, av[1]) == 0) 136*29b76e53SScott Long return ((*cmd)->handler(ac - 1, av + 1)); 137*29b76e53SScott Long } 138*29b76e53SScott Long 139*29b76e53SScott Long warnx("%s is not a valid sub-command of %s.", av[1], av[0]); 140*29b76e53SScott Long return (ENOENT); 141*29b76e53SScott Long } 142*29b76e53SScott Long 143*29b76e53SScott Long void 144*29b76e53SScott Long hexdump(const void *ptr, int length, const char *hdr, int flags) 145*29b76e53SScott Long { 146*29b76e53SScott Long int i, j, k; 147*29b76e53SScott Long int cols; 148*29b76e53SScott Long const unsigned char *cp; 149*29b76e53SScott Long char delim; 150*29b76e53SScott Long 151*29b76e53SScott Long if ((flags & HD_DELIM_MASK) != 0) 152*29b76e53SScott Long delim = (flags & HD_DELIM_MASK) >> 8; 153*29b76e53SScott Long else 154*29b76e53SScott Long delim = ' '; 155*29b76e53SScott Long 156*29b76e53SScott Long if ((flags & HD_COLUMN_MASK) != 0) 157*29b76e53SScott Long cols = flags & HD_COLUMN_MASK; 158*29b76e53SScott Long else 159*29b76e53SScott Long cols = 16; 160*29b76e53SScott Long 161*29b76e53SScott Long cp = ptr; 162*29b76e53SScott Long for (i = 0; i < length; i+= cols) { 163*29b76e53SScott Long if (hdr != NULL) 164*29b76e53SScott Long printf("%s", hdr); 165*29b76e53SScott Long 166*29b76e53SScott Long if ((flags & HD_OMIT_COUNT) == 0) 167*29b76e53SScott Long printf("%04x ", i); 168*29b76e53SScott Long 169*29b76e53SScott Long if ((flags & HD_OMIT_HEX) == 0) { 170*29b76e53SScott Long for (j = 0; j < cols; j++) { 171*29b76e53SScott Long if (flags & HD_REVERSED) 172*29b76e53SScott Long k = i + (cols - 1 - j); 173*29b76e53SScott Long else 174*29b76e53SScott Long k = i + j; 175*29b76e53SScott Long if (k < length) 176*29b76e53SScott Long printf("%c%02x", delim, cp[k]); 177*29b76e53SScott Long else 178*29b76e53SScott Long printf(" "); 179*29b76e53SScott Long } 180*29b76e53SScott Long } 181*29b76e53SScott Long 182*29b76e53SScott Long if ((flags & HD_OMIT_CHARS) == 0) { 183*29b76e53SScott Long printf(" |"); 184*29b76e53SScott Long for (j = 0; j < cols; j++) { 185*29b76e53SScott Long if (flags & HD_REVERSED) 186*29b76e53SScott Long k = i + (cols - 1 - j); 187*29b76e53SScott Long else 188*29b76e53SScott Long k = i + j; 189*29b76e53SScott Long if (k >= length) 190*29b76e53SScott Long printf(" "); 191*29b76e53SScott Long else if (cp[k] >= ' ' && cp[k] <= '~') 192*29b76e53SScott Long printf("%c", cp[k]); 193*29b76e53SScott Long else 194*29b76e53SScott Long printf("."); 195*29b76e53SScott Long } 196*29b76e53SScott Long printf("|"); 197*29b76e53SScott Long } 198*29b76e53SScott Long printf("\n"); 199*29b76e53SScott Long } 200*29b76e53SScott Long } 201