diff options
Diffstat (limited to 'usr/src/cmd/pptadm/pptadm.c')
| -rw-r--r-- | usr/src/cmd/pptadm/pptadm.c | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/usr/src/cmd/pptadm/pptadm.c b/usr/src/cmd/pptadm/pptadm.c new file mode 100644 index 0000000000..c6b9094408 --- /dev/null +++ b/usr/src/cmd/pptadm/pptadm.c @@ -0,0 +1,205 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * Copyright 2018 Joyent, Inc. + */ + +#include <stdlib.h> +#include <stdarg.h> +#include <getopt.h> +#include <string.h> +#include <ofmt.h> +#include <err.h> + +#include <libppt.h> + +typedef enum field { + PPT_DEV, + PPT_VENDOR, + PPT_DEVICE, + PPT_SUBVENDOR, + PPT_SUBDEVICE, + PPT_REV, + PPT_PATH, + PPT_LABEL +} field_t; + +const char *valname[] = { + "dev", + "vendor-id", + "device-id", + "subsystem-vendor-id", + "subsystem-id", + "revision-id", + "path", + "label" +}; + +static ofmt_cb_t print_field; + +static ofmt_field_t fields[] = { +/* name, field width, index, callback */ +{ "DEV", sizeof ("/dev/pptXX"), PPT_DEV, print_field }, +{ "VENDOR", sizeof ("VENDOR"), PPT_VENDOR, print_field }, +{ "DEVICE", sizeof ("DEVICE"), PPT_DEVICE, print_field }, +{ "SUBVENDOR", sizeof ("SUBVENDOR"), PPT_SUBVENDOR, print_field }, +{ "SUBDEVICE", sizeof ("SUBDEVICE"), PPT_SUBDEVICE, print_field }, +{ "REV", sizeof ("REV"), PPT_REV, print_field }, +{ "PATH", 50, PPT_PATH, print_field }, +{ "LABEL", 60, PPT_LABEL, print_field }, +{ NULL, 0, 0, NULL }, +}; + +static void +usage(const char *errmsg) +{ + if (errmsg != NULL) + (void) fprintf(stderr, "pptadm: %s\n", errmsg); + (void) fprintf(errmsg != NULL ? stderr : stdout, + "Usage:\n" + "pptadm list [ -j ]\n" + "pptadm list [-ap] [-o fields]\n"); + exit(errmsg != NULL ? EXIT_FAILURE : EXIT_SUCCESS); +} + +/* PRINTFLIKE1 */ +static void +die(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrx(EXIT_FAILURE, fmt, ap); + va_end(ap); +} + +static boolean_t +print_field(ofmt_arg_t *arg, char *buf, uint_t bufsize) +{ + nvlist_t *nvl = arg->ofmt_cbarg; + nvpair_t *nvp = NULL; + + while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { + const char *name = nvpair_name(nvp); + char *val = NULL; + + (void) nvpair_value_string(nvp, &val); + + if (strcmp(name, valname[arg->ofmt_id]) != 0) + continue; + + (void) snprintf(buf, bufsize, "%s", val); + return (B_TRUE); + } + + (void) snprintf(buf, bufsize, "--"); + return (B_TRUE); +} + +static int +list(int argc, char *argv[]) +{ + const char *fields_str = NULL; + boolean_t parsable = B_FALSE; + boolean_t json = B_FALSE; + boolean_t all = B_FALSE; + uint_t ofmtflags = 0; + ofmt_status_t oferr; + ofmt_handle_t ofmt; + int opt; + + while ((opt = getopt(argc, argv, "ahjo:p")) != -1) { + switch (opt) { + case 'a': + all = B_TRUE; + break; + case 'h': + usage(NULL); + break; + case 'j': + json = B_TRUE; + break; + case 'o': + fields_str = optarg; + break; + case 'p': + ofmtflags |= OFMT_PARSABLE; + parsable = B_TRUE; + break; + default: + usage("unrecognized option"); + break; + } + } + + if (optind == (argc - 1)) + usage("unused arguments"); + + if (json && (parsable || fields_str != NULL)) + usage("-j option cannot be used with -p or -o options"); + + if (fields_str == NULL) { + if (parsable) + usage("-o must be provided when using -p option"); + fields_str = "dev,vendor,device,path"; + } + + oferr = ofmt_open(fields_str, fields, ofmtflags, 0, &ofmt); + + ofmt_check(oferr, parsable, ofmt, die, warn); + + nvlist_t *nvl = all ? ppt_list() : ppt_list_assigned(); + nvpair_t *nvp = NULL; + + if (json) { + if (printf("{\n\t\"devices\": [\n") < 0) + err(EXIT_FAILURE, "failed to write JSON"); + } + + while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { + nvlist_t *props; + + (void) nvpair_value_nvlist(nvp, &props); + + if (json) { + if (printf("\t\t") < 0) + err(EXIT_FAILURE, "failed to write JSON"); + if (nvlist_print_json(stdout, props) < 0) + err(EXIT_FAILURE, "failed to write JSON"); + if (nvlist_next_nvpair(nvl, nvp) != NULL) + (void) printf(",\n"); + } else { + ofmt_print(ofmt, props); + } + } + + if (json) { + if (printf("\n\t]\n}\n") < 0) + err(EXIT_FAILURE, "failed to write JSON"); + } + + nvlist_free(nvl); + ofmt_close(ofmt); + return (EXIT_SUCCESS); +} + +int +main(int argc, char *argv[]) +{ + if (argc == 1) + return (list(argc - 1, argv)); + + if (strcmp(argv[1], "list") == 0) { + return (list(argc - 1, &argv[1])); + } else { + usage("unknown sub-command"); + } + + return (EXIT_SUCCESS); +} |
