1297590Ssbruno/*- 2297590Ssbruno * Copyright (c) 2015 Netflix, Inc. 3297590Ssbruno * All rights reserved. 4297590Ssbruno * Written by: Scott Long <scottl@freebsd.org> 5297590Ssbruno * 6297590Ssbruno * Copyright (c) 2008 Yahoo!, Inc. 7297590Ssbruno * All rights reserved. 8297590Ssbruno * Written by: John Baldwin <jhb@FreeBSD.org> 9297590Ssbruno * 10297590Ssbruno * Redistribution and use in source and binary forms, with or without 11297590Ssbruno * modification, are permitted provided that the following conditions 12297590Ssbruno * are met: 13297590Ssbruno * 1. Redistributions of source code must retain the above copyright 14297590Ssbruno * notice, this list of conditions and the following disclaimer. 15297590Ssbruno * 2. Redistributions in binary form must reproduce the above copyright 16297590Ssbruno * notice, this list of conditions and the following disclaimer in the 17297590Ssbruno * documentation and/or other materials provided with the distribution. 18297590Ssbruno * 3. Neither the name of the author nor the names of any co-contributors 19297590Ssbruno * may be used to endorse or promote products derived from this software 20297590Ssbruno * without specific prior written permission. 21297590Ssbruno * 22297590Ssbruno * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23297590Ssbruno * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24297590Ssbruno * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25297590Ssbruno * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26297590Ssbruno * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27297590Ssbruno * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28297590Ssbruno * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29297590Ssbruno * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30297590Ssbruno * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31297590Ssbruno * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32297590Ssbruno * SUCH DAMAGE. 33297590Ssbruno */ 34297590Ssbruno 35297590Ssbruno#include <sys/cdefs.h> 36297590Ssbruno__RCSID("$FreeBSD$"); 37297590Ssbruno 38297590Ssbruno#include <sys/param.h> 39297590Ssbruno#include <sys/errno.h> 40297590Ssbruno#include <err.h> 41297590Ssbruno#include <stdio.h> 42297590Ssbruno#include <stdlib.h> 43297590Ssbruno#include <string.h> 44297590Ssbruno#include <unistd.h> 45297590Ssbruno#include "mpsutil.h" 46297590Ssbruno 47297590SsbrunoSET_DECLARE(MPS_DATASET(top), struct mpsutil_command); 48297590SsbrunoSET_DECLARE(MPS_DATASET(usage), struct mpsutil_usage); 49297590Ssbruno 50297590Ssbrunoint mps_unit; 51297590Ssbrunoint is_mps; 52297590Ssbruno 53297590Ssbrunostatic void 54297590Ssbrunousage(void) 55297590Ssbruno{ 56297590Ssbruno struct mpsutil_usage **cmd; 57297590Ssbruno const char *args, *desc; 58297590Ssbruno 59297590Ssbruno fprintf(stderr, "usage: %s [-u unit] <command> ...\n\n", getprogname()); 60297590Ssbruno fprintf(stderr, "Commands include:\n"); 61297590Ssbruno SET_FOREACH(cmd, MPS_DATASET(usage)) { 62297590Ssbruno if (*cmd == NULL) 63297590Ssbruno fprintf(stderr, "\n"); 64297590Ssbruno else 65297590Ssbruno (*cmd)->handler(&args, &desc); 66297590Ssbruno if (strncmp((*cmd)->set, "top", 3) == 0) 67297590Ssbruno fprintf(stderr, "%s %-30s\t%s\n", 68297590Ssbruno (*cmd)->name, args, desc); 69297590Ssbruno else 70297590Ssbruno fprintf(stderr, "%s %s %-30s\t%s\n", 71297590Ssbruno (*cmd)->set, (*cmd)->name, args, desc); 72297590Ssbruno } 73297590Ssbruno exit(1); 74297590Ssbruno} 75297590Ssbruno 76297590Ssbrunostatic int 77297590Ssbrunoversion(int ac, char **av) 78297590Ssbruno{ 79297590Ssbruno 80297590Ssbruno printf("%s: version %s", MPSUTIL_VERSION, getprogname()); 81297590Ssbruno#ifdef DEBUG 82297590Ssbruno printf(" (DEBUG)"); 83297590Ssbruno#endif 84297590Ssbruno printf("\n"); 85297590Ssbruno return (0); 86297590Ssbruno} 87297590Ssbruno 88297590SsbrunoMPS_COMMAND(top, version, version, "", "version") 89297590Ssbruno 90297590Ssbrunoint 91297590Ssbrunomain(int ac, char **av) 92297590Ssbruno{ 93297590Ssbruno struct mpsutil_command **cmd; 94297590Ssbruno int ch; 95297590Ssbruno 96297590Ssbruno is_mps = !strcmp(getprogname(), "mpsutil"); 97297590Ssbruno 98297590Ssbruno while ((ch = getopt(ac, av, "u:h?")) != -1) { 99297590Ssbruno switch (ch) { 100297590Ssbruno case 'u': 101297590Ssbruno mps_unit = atoi(optarg); 102297590Ssbruno break; 103297590Ssbruno case 'h': 104297590Ssbruno case '?': 105297590Ssbruno usage(); 106297590Ssbruno return (1); 107297590Ssbruno } 108297590Ssbruno } 109297590Ssbruno 110297590Ssbruno av += optind; 111297590Ssbruno ac -= optind; 112297590Ssbruno 113297590Ssbruno /* getopt() eats av[0], so we can't use mpt_table_handler() directly. */ 114297590Ssbruno if (ac == 0) { 115297590Ssbruno usage(); 116297590Ssbruno return (1); 117297590Ssbruno } 118297590Ssbruno 119297590Ssbruno SET_FOREACH(cmd, MPS_DATASET(top)) { 120297590Ssbruno if (strcmp((*cmd)->name, av[0]) == 0) { 121297590Ssbruno if ((*cmd)->handler(ac, av)) 122297590Ssbruno return (1); 123297590Ssbruno else 124297590Ssbruno return (0); 125297590Ssbruno } 126297590Ssbruno } 127297590Ssbruno warnx("Unknown command %s.", av[0]); 128297590Ssbruno return (1); 129297590Ssbruno} 130297590Ssbruno 131297590Ssbrunoint 132297590Ssbrunomps_table_handler(struct mpsutil_command **start, struct mpsutil_command **end, 133297590Ssbruno int ac, char **av) 134297590Ssbruno{ 135297590Ssbruno struct mpsutil_command **cmd; 136297590Ssbruno 137297590Ssbruno if (ac < 2) { 138297590Ssbruno warnx("The %s command requires a sub-command.", av[0]); 139297590Ssbruno return (EINVAL); 140297590Ssbruno } 141297590Ssbruno for (cmd = start; cmd < end; cmd++) { 142297590Ssbruno if (strcmp((*cmd)->name, av[1]) == 0) 143297590Ssbruno return ((*cmd)->handler(ac - 1, av + 1)); 144297590Ssbruno } 145297590Ssbruno 146297590Ssbruno warnx("%s is not a valid sub-command of %s.", av[1], av[0]); 147297590Ssbruno return (ENOENT); 148297590Ssbruno} 149297590Ssbruno 150297590Ssbrunovoid 151297590Ssbrunohexdump(const void *ptr, int length, const char *hdr, int flags) 152297590Ssbruno{ 153297590Ssbruno int i, j, k; 154297590Ssbruno int cols; 155297590Ssbruno const unsigned char *cp; 156297590Ssbruno char delim; 157297590Ssbruno 158297590Ssbruno if ((flags & HD_DELIM_MASK) != 0) 159297590Ssbruno delim = (flags & HD_DELIM_MASK) >> 8; 160297590Ssbruno else 161297590Ssbruno delim = ' '; 162297590Ssbruno 163297590Ssbruno if ((flags & HD_COLUMN_MASK) != 0) 164297590Ssbruno cols = flags & HD_COLUMN_MASK; 165297590Ssbruno else 166297590Ssbruno cols = 16; 167297590Ssbruno 168297590Ssbruno cp = ptr; 169297590Ssbruno for (i = 0; i < length; i+= cols) { 170297590Ssbruno if (hdr != NULL) 171297590Ssbruno printf("%s", hdr); 172297590Ssbruno 173297590Ssbruno if ((flags & HD_OMIT_COUNT) == 0) 174297590Ssbruno printf("%04x ", i); 175297590Ssbruno 176297590Ssbruno if ((flags & HD_OMIT_HEX) == 0) { 177297590Ssbruno for (j = 0; j < cols; j++) { 178297590Ssbruno if (flags & HD_REVERSED) 179297590Ssbruno k = i + (cols - 1 - j); 180297590Ssbruno else 181297590Ssbruno k = i + j; 182297590Ssbruno if (k < length) 183297590Ssbruno printf("%c%02x", delim, cp[k]); 184297590Ssbruno else 185297590Ssbruno printf(" "); 186297590Ssbruno } 187297590Ssbruno } 188297590Ssbruno 189297590Ssbruno if ((flags & HD_OMIT_CHARS) == 0) { 190297590Ssbruno printf(" |"); 191297590Ssbruno for (j = 0; j < cols; j++) { 192297590Ssbruno if (flags & HD_REVERSED) 193297590Ssbruno k = i + (cols - 1 - j); 194297590Ssbruno else 195297590Ssbruno k = i + j; 196297590Ssbruno if (k >= length) 197297590Ssbruno printf(" "); 198297590Ssbruno else if (cp[k] >= ' ' && cp[k] <= '~') 199297590Ssbruno printf("%c", cp[k]); 200297590Ssbruno else 201297590Ssbruno printf("."); 202297590Ssbruno } 203297590Ssbruno printf("|"); 204297590Ssbruno } 205297590Ssbruno printf("\n"); 206297590Ssbruno } 207297590Ssbruno} 208