129b76e53SScott Long /*- 2*883bb7e9SScott Long * Copyright (c) 2015 Netflix, Inc. 3*883bb7e9SScott Long * All rights reserved. 4*883bb7e9SScott Long * Written by: Scott Long <scottl@freebsd.org> 5*883bb7e9SScott Long * 629b76e53SScott Long * Copyright (c) 2008 Yahoo!, Inc. 729b76e53SScott Long * All rights reserved. 829b76e53SScott Long * Written by: John Baldwin <jhb@FreeBSD.org> 929b76e53SScott Long * 1029b76e53SScott Long * Redistribution and use in source and binary forms, with or without 1129b76e53SScott Long * modification, are permitted provided that the following conditions 1229b76e53SScott Long * are met: 1329b76e53SScott Long * 1. Redistributions of source code must retain the above copyright 1429b76e53SScott Long * notice, this list of conditions and the following disclaimer. 1529b76e53SScott Long * 2. Redistributions in binary form must reproduce the above copyright 1629b76e53SScott Long * notice, this list of conditions and the following disclaimer in the 1729b76e53SScott Long * documentation and/or other materials provided with the distribution. 1829b76e53SScott Long * 3. Neither the name of the author nor the names of any co-contributors 1929b76e53SScott Long * may be used to endorse or promote products derived from this software 2029b76e53SScott Long * without specific prior written permission. 2129b76e53SScott Long * 2229b76e53SScott Long * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2329b76e53SScott Long * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2429b76e53SScott Long * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2529b76e53SScott Long * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2629b76e53SScott Long * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2729b76e53SScott Long * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2829b76e53SScott Long * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2929b76e53SScott Long * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3029b76e53SScott Long * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3129b76e53SScott Long * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3229b76e53SScott Long * SUCH DAMAGE. 3329b76e53SScott Long */ 3429b76e53SScott Long 3529b76e53SScott Long #include <sys/cdefs.h> 3629b76e53SScott Long __RCSID("$FreeBSD$"); 3729b76e53SScott Long 3829b76e53SScott Long #include <sys/param.h> 3929b76e53SScott Long #include <sys/errno.h> 4029b76e53SScott Long #include <err.h> 4129b76e53SScott Long #include <stdio.h> 4229b76e53SScott Long #include <stdlib.h> 4329b76e53SScott Long #include <string.h> 4429b76e53SScott Long #include <unistd.h> 4529b76e53SScott Long #include "mpsutil.h" 4629b76e53SScott Long 4729b76e53SScott Long SET_DECLARE(MPS_DATASET(top), struct mpsutil_command); 4829b76e53SScott Long SET_DECLARE(MPS_DATASET(usage), struct mpsutil_usage); 4929b76e53SScott Long 5029b76e53SScott Long int mps_unit; 5148f31f4fSBaptiste Daroussin int is_mps; 5229b76e53SScott Long 5329b76e53SScott Long static void 5429b76e53SScott Long usage(void) 5529b76e53SScott Long { 5629b76e53SScott Long struct mpsutil_usage **cmd; 5729b76e53SScott Long const char *args, *desc; 5829b76e53SScott Long 5948f31f4fSBaptiste Daroussin fprintf(stderr, "usage: %s [-u unit] <command> ...\n\n", getprogname()); 6029b76e53SScott Long fprintf(stderr, "Commands include:\n"); 6129b76e53SScott Long SET_FOREACH(cmd, MPS_DATASET(usage)) { 6229b76e53SScott Long if (*cmd == NULL) 6329b76e53SScott Long fprintf(stderr, "\n"); 6429b76e53SScott Long else 6529b76e53SScott Long (*cmd)->handler(&args, &desc); 6629b76e53SScott Long if (strncmp((*cmd)->set, "top", 3) == 0) 6729b76e53SScott Long fprintf(stderr, "%s %-30s\t%s\n", 6829b76e53SScott Long (*cmd)->name, args, desc); 6929b76e53SScott Long else 7029b76e53SScott Long fprintf(stderr, "%s %s %-30s\t%s\n", 7129b76e53SScott Long (*cmd)->set, (*cmd)->name, args, desc); 7229b76e53SScott Long } 7329b76e53SScott Long exit(1); 7429b76e53SScott Long } 7529b76e53SScott Long 7629b76e53SScott Long static int 7729b76e53SScott Long version(int ac, char **av) 7829b76e53SScott Long { 7929b76e53SScott Long 8048f31f4fSBaptiste Daroussin printf("%s: version %s", MPSUTIL_VERSION, getprogname()); 8129b76e53SScott Long #ifdef DEBUG 8229b76e53SScott Long printf(" (DEBUG)"); 8329b76e53SScott Long #endif 8429b76e53SScott Long printf("\n"); 8529b76e53SScott Long return (0); 8629b76e53SScott Long } 8729b76e53SScott Long 8829b76e53SScott Long MPS_COMMAND(top, version, version, "", "version") 8929b76e53SScott Long 9029b76e53SScott Long int 9129b76e53SScott Long main(int ac, char **av) 9229b76e53SScott Long { 9329b76e53SScott Long struct mpsutil_command **cmd; 9429b76e53SScott Long int ch; 9529b76e53SScott Long 9648f31f4fSBaptiste Daroussin is_mps = !strcmp(getprogname(), "mpsutil"); 9748f31f4fSBaptiste Daroussin 9829b76e53SScott Long while ((ch = getopt(ac, av, "u:h?")) != -1) { 9929b76e53SScott Long switch (ch) { 10029b76e53SScott Long case 'u': 10129b76e53SScott Long mps_unit = atoi(optarg); 10229b76e53SScott Long break; 10329b76e53SScott Long case 'h': 10429b76e53SScott Long case '?': 10529b76e53SScott Long usage(); 10629b76e53SScott Long return (1); 10729b76e53SScott Long } 10829b76e53SScott Long } 10929b76e53SScott Long 11029b76e53SScott Long av += optind; 11129b76e53SScott Long ac -= optind; 11229b76e53SScott Long 11329b76e53SScott Long /* getopt() eats av[0], so we can't use mpt_table_handler() directly. */ 11429b76e53SScott Long if (ac == 0) { 11529b76e53SScott Long usage(); 11629b76e53SScott Long return (1); 11729b76e53SScott Long } 11829b76e53SScott Long 11929b76e53SScott Long SET_FOREACH(cmd, MPS_DATASET(top)) { 12029b76e53SScott Long if (strcmp((*cmd)->name, av[0]) == 0) { 12129b76e53SScott Long if ((*cmd)->handler(ac, av)) 12229b76e53SScott Long return (1); 12329b76e53SScott Long else 12429b76e53SScott Long return (0); 12529b76e53SScott Long } 12629b76e53SScott Long } 12729b76e53SScott Long warnx("Unknown command %s.", av[0]); 12829b76e53SScott Long return (1); 12929b76e53SScott Long } 13029b76e53SScott Long 13129b76e53SScott Long int 13229b76e53SScott Long mps_table_handler(struct mpsutil_command **start, struct mpsutil_command **end, 13329b76e53SScott Long int ac, char **av) 13429b76e53SScott Long { 13529b76e53SScott Long struct mpsutil_command **cmd; 13629b76e53SScott Long 13729b76e53SScott Long if (ac < 2) { 13829b76e53SScott Long warnx("The %s command requires a sub-command.", av[0]); 13929b76e53SScott Long return (EINVAL); 14029b76e53SScott Long } 14129b76e53SScott Long for (cmd = start; cmd < end; cmd++) { 14229b76e53SScott Long if (strcmp((*cmd)->name, av[1]) == 0) 14329b76e53SScott Long return ((*cmd)->handler(ac - 1, av + 1)); 14429b76e53SScott Long } 14529b76e53SScott Long 14629b76e53SScott Long warnx("%s is not a valid sub-command of %s.", av[1], av[0]); 14729b76e53SScott Long return (ENOENT); 14829b76e53SScott Long } 14929b76e53SScott Long 15029b76e53SScott Long void 15129b76e53SScott Long hexdump(const void *ptr, int length, const char *hdr, int flags) 15229b76e53SScott Long { 15329b76e53SScott Long int i, j, k; 15429b76e53SScott Long int cols; 15529b76e53SScott Long const unsigned char *cp; 15629b76e53SScott Long char delim; 15729b76e53SScott Long 15829b76e53SScott Long if ((flags & HD_DELIM_MASK) != 0) 15929b76e53SScott Long delim = (flags & HD_DELIM_MASK) >> 8; 16029b76e53SScott Long else 16129b76e53SScott Long delim = ' '; 16229b76e53SScott Long 16329b76e53SScott Long if ((flags & HD_COLUMN_MASK) != 0) 16429b76e53SScott Long cols = flags & HD_COLUMN_MASK; 16529b76e53SScott Long else 16629b76e53SScott Long cols = 16; 16729b76e53SScott Long 16829b76e53SScott Long cp = ptr; 16929b76e53SScott Long for (i = 0; i < length; i+= cols) { 17029b76e53SScott Long if (hdr != NULL) 17129b76e53SScott Long printf("%s", hdr); 17229b76e53SScott Long 17329b76e53SScott Long if ((flags & HD_OMIT_COUNT) == 0) 17429b76e53SScott Long printf("%04x ", i); 17529b76e53SScott Long 17629b76e53SScott Long if ((flags & HD_OMIT_HEX) == 0) { 17729b76e53SScott Long for (j = 0; j < cols; j++) { 17829b76e53SScott Long if (flags & HD_REVERSED) 17929b76e53SScott Long k = i + (cols - 1 - j); 18029b76e53SScott Long else 18129b76e53SScott Long k = i + j; 18229b76e53SScott Long if (k < length) 18329b76e53SScott Long printf("%c%02x", delim, cp[k]); 18429b76e53SScott Long else 18529b76e53SScott Long printf(" "); 18629b76e53SScott Long } 18729b76e53SScott Long } 18829b76e53SScott Long 18929b76e53SScott Long if ((flags & HD_OMIT_CHARS) == 0) { 19029b76e53SScott Long printf(" |"); 19129b76e53SScott Long for (j = 0; j < cols; j++) { 19229b76e53SScott Long if (flags & HD_REVERSED) 19329b76e53SScott Long k = i + (cols - 1 - j); 19429b76e53SScott Long else 19529b76e53SScott Long k = i + j; 19629b76e53SScott Long if (k >= length) 19729b76e53SScott Long printf(" "); 19829b76e53SScott Long else if (cp[k] >= ' ' && cp[k] <= '~') 19929b76e53SScott Long printf("%c", cp[k]); 20029b76e53SScott Long else 20129b76e53SScott Long printf("."); 20229b76e53SScott Long } 20329b76e53SScott Long printf("|"); 20429b76e53SScott Long } 20529b76e53SScott Long printf("\n"); 20629b76e53SScott Long } 20729b76e53SScott Long } 208