/* * 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 #include #include #include #include #include #include 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); }