14b844f8dSWarner Losh /*- 23c0dcbfcSWarner Losh * Copyright (c) 2016-2021 Netflix, Inc. 34b844f8dSWarner Losh * 44b844f8dSWarner Losh * Redistribution and use in source and binary forms, with or without 54b844f8dSWarner Losh * modification, are permitted provided that the following conditions 64b844f8dSWarner Losh * are met: 74b844f8dSWarner Losh * 1. Redistributions of source code must retain the above copyright 84b844f8dSWarner Losh * notice, this list of conditions and the following disclaimer. 94b844f8dSWarner Losh * 2. Redistributions in binary form must reproduce the above copyright 104b844f8dSWarner Losh * notice, this list of conditions and the following disclaimer in the 114b844f8dSWarner Losh * documentation and/or other materials provided with the distribution. 124b844f8dSWarner Losh * 13b2a7ac48SWarner Losh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 144b844f8dSWarner Losh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 154b844f8dSWarner Losh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16b2a7ac48SWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 174b844f8dSWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 184b844f8dSWarner Losh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 194b844f8dSWarner Losh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 204b844f8dSWarner Losh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 214b844f8dSWarner Losh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 224b844f8dSWarner Losh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 234b844f8dSWarner Losh * SUCH DAMAGE. 244b844f8dSWarner Losh */ 254b844f8dSWarner Losh 264b844f8dSWarner Losh #include <sys/cdefs.h> 274b844f8dSWarner Losh __FBSDID("$FreeBSD$"); 284b844f8dSWarner Losh 294b844f8dSWarner Losh #include <ctype.h> 304b844f8dSWarner Losh #include <efivar.h> 312f2f5c67SWarner Losh #include <efivar-dp.h> 324b844f8dSWarner Losh #include <err.h> 334b844f8dSWarner Losh #include <errno.h> 34e08bb109SWarner Losh #include <fcntl.h> 354b844f8dSWarner Losh #include <getopt.h> 363c0dcbfcSWarner Losh #include <stdarg.h> 373c0dcbfcSWarner Losh #include <stdbool.h> 384b844f8dSWarner Losh #include <stddef.h> 394b844f8dSWarner Losh #include <stdio.h> 404b844f8dSWarner Losh #include <stdlib.h> 414b844f8dSWarner Losh #include <string.h> 424b844f8dSWarner Losh #include <unistd.h> 435709a4b5SWarner Losh #include "efiutil.h" 44b0da7c79SWarner Losh #include "efichar.h" 454b844f8dSWarner Losh 464b844f8dSWarner Losh /* options descriptor */ 474b844f8dSWarner Losh static struct option longopts[] = { 484b844f8dSWarner Losh { "append", no_argument, NULL, 'a' }, 494b844f8dSWarner Losh { "ascii", no_argument, NULL, 'A' }, 504b844f8dSWarner Losh { "attributes", required_argument, NULL, 't' }, 514b844f8dSWarner Losh { "binary", no_argument, NULL, 'b' }, 524b844f8dSWarner Losh { "delete", no_argument, NULL, 'D' }, 539e4a51a8SWarner Losh { "device", no_argument, NULL, 'd' }, 549e4a51a8SWarner Losh { "device-path", no_argument, NULL, 'd' }, 554b844f8dSWarner Losh { "fromfile", required_argument, NULL, 'f' }, 5616445670SWarner Losh { "guid", no_argument, NULL, 'g' }, 574b844f8dSWarner Losh { "hex", no_argument, NULL, 'H' }, 584b844f8dSWarner Losh { "list-guids", no_argument, NULL, 'L' }, 594b844f8dSWarner Losh { "list", no_argument, NULL, 'l' }, 605709a4b5SWarner Losh { "load-option", no_argument, NULL, 'O' }, 614b844f8dSWarner Losh { "name", required_argument, NULL, 'n' }, 624b844f8dSWarner Losh { "no-name", no_argument, NULL, 'N' }, 634b844f8dSWarner Losh { "print", no_argument, NULL, 'p' }, 64f9f298a2SWarner Losh // { "print-decimal", no_argument, NULL, 'd' }, /* unimplemnted clash with linux version */ 653c0dcbfcSWarner Losh { "quiet", no_argument, NULL, 'q' }, 664b844f8dSWarner Losh { "raw-guid", no_argument, NULL, 'R' }, 67b0da7c79SWarner Losh { "utf8", no_argument, NULL, 'u' }, 684b844f8dSWarner Losh { "write", no_argument, NULL, 'w' }, 694b844f8dSWarner Losh { NULL, 0, NULL, 0 } 704b844f8dSWarner Losh }; 714b844f8dSWarner Losh 724b844f8dSWarner Losh 73*066b096dSWarner Losh static bool aflag, Aflag, bflag, dflag, Dflag, gflag, Hflag, Nflag, 74*066b096dSWarner Losh lflag, Lflag, Rflag, wflag, pflag, uflag, load_opt_flag, quiet; 754b844f8dSWarner Losh static char *varname; 76e08bb109SWarner Losh static char *fromfile; 7755ff82c0SWarner Losh static u_long attrib = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; 784b844f8dSWarner Losh 794b844f8dSWarner Losh static void 804b844f8dSWarner Losh usage(void) 814b844f8dSWarner Losh { 824b844f8dSWarner Losh 833c0dcbfcSWarner Losh errx(1, "efivar [-abdDHlLNpqRtuw] [-n name] [-f file] [--append] [--ascii]\n" 844b844f8dSWarner Losh "\t[--attributes] [--binary] [--delete] [--fromfile file] [--hex]\n" 855709a4b5SWarner Losh "\t[--list-guids] [--list] [--load-option] [--name name] [--no-name]\n" 865709a4b5SWarner Losh "\t[--print] [--print-decimal] [--raw-guid] [--utf8] [--write]\n" 873c0dcbfcSWarner Losh "\t[--quiet]\n" 885709a4b5SWarner Losh "\tname[=value]"); 894b844f8dSWarner Losh } 904b844f8dSWarner Losh 914b844f8dSWarner Losh static void 923c0dcbfcSWarner Losh rep_err(int eval, const char *fmt, ...) 933c0dcbfcSWarner Losh { 943c0dcbfcSWarner Losh va_list ap; 953c0dcbfcSWarner Losh 963c0dcbfcSWarner Losh if (quiet) 973c0dcbfcSWarner Losh exit(eval); 983c0dcbfcSWarner Losh 993c0dcbfcSWarner Losh va_start(ap, fmt); 1003c0dcbfcSWarner Losh verr(eval, fmt, ap); 1013c0dcbfcSWarner Losh va_end(ap); 1023c0dcbfcSWarner Losh } 1033c0dcbfcSWarner Losh 1043c0dcbfcSWarner Losh static void 1053c0dcbfcSWarner Losh rep_errx(int eval, const char *fmt, ...) 1063c0dcbfcSWarner Losh { 1073c0dcbfcSWarner Losh va_list ap; 1083c0dcbfcSWarner Losh 1093c0dcbfcSWarner Losh if (quiet) 1103c0dcbfcSWarner Losh exit(eval); 1113c0dcbfcSWarner Losh 1123c0dcbfcSWarner Losh va_start(ap, fmt); 1133c0dcbfcSWarner Losh verrx(eval, fmt, ap); 1143c0dcbfcSWarner Losh va_end(ap); 1153c0dcbfcSWarner Losh } 1163c0dcbfcSWarner Losh 1173c0dcbfcSWarner Losh static void 1184b844f8dSWarner Losh breakdown_name(char *name, efi_guid_t *guid, char **vname) 1194b844f8dSWarner Losh { 1200292a5c9SWarner Losh char *cp, *ocp; 1214b844f8dSWarner Losh 1220292a5c9SWarner Losh ocp = NULL; 1230292a5c9SWarner Losh while (true) { 1244b844f8dSWarner Losh cp = strrchr(name, '-'); 1250292a5c9SWarner Losh if (cp == NULL) { 1260292a5c9SWarner Losh if (ocp != NULL) 1270292a5c9SWarner Losh *ocp = '-'; 1280292a5c9SWarner Losh rep_errx(1, "Invalid guid in: %s", name); 1290292a5c9SWarner Losh } 1300292a5c9SWarner Losh if (ocp != NULL) 1310292a5c9SWarner Losh *ocp = '-'; 1324b844f8dSWarner Losh *vname = cp + 1; 1334b844f8dSWarner Losh *cp = '\0'; 1340292a5c9SWarner Losh ocp = cp; 1350292a5c9SWarner Losh if (efi_name_to_guid(name, guid) >= 0) 1360292a5c9SWarner Losh break; 1370292a5c9SWarner Losh } 1384b844f8dSWarner Losh } 1394b844f8dSWarner Losh 1404b844f8dSWarner Losh static uint8_t * 1414b844f8dSWarner Losh get_value(char *val, size_t *datalen) 1424b844f8dSWarner Losh { 1434b844f8dSWarner Losh static char buffer[16*1024]; 1444b844f8dSWarner Losh 1454b844f8dSWarner Losh if (val != NULL) { 1464b844f8dSWarner Losh *datalen = strlen(val); 1474b844f8dSWarner Losh return ((uint8_t *)val); 1484b844f8dSWarner Losh } 1494b844f8dSWarner Losh /* Read from stdin */ 1504b844f8dSWarner Losh *datalen = sizeof(buffer); 1514b844f8dSWarner Losh *datalen = read(0, buffer, *datalen); 1524b844f8dSWarner Losh return ((uint8_t *)buffer); 1534b844f8dSWarner Losh } 1544b844f8dSWarner Losh 1554b844f8dSWarner Losh static void 1564b844f8dSWarner Losh append_variable(char *name, char *val) 1574b844f8dSWarner Losh { 1584b844f8dSWarner Losh char *vname; 1594b844f8dSWarner Losh efi_guid_t guid; 1604b844f8dSWarner Losh size_t datalen; 1614b844f8dSWarner Losh uint8_t *data; 1624b844f8dSWarner Losh 1634b844f8dSWarner Losh breakdown_name(name, &guid, &vname); 1644b844f8dSWarner Losh data = get_value(val, &datalen); 1654b844f8dSWarner Losh if (efi_append_variable(guid, vname, data, datalen, attrib) < 0) 1663c0dcbfcSWarner Losh rep_err(1, "efi_append_variable"); 1674b844f8dSWarner Losh } 1684b844f8dSWarner Losh 1694b844f8dSWarner Losh static void 1704b844f8dSWarner Losh delete_variable(char *name) 1714b844f8dSWarner Losh { 1724b844f8dSWarner Losh char *vname; 1734b844f8dSWarner Losh efi_guid_t guid; 1744b844f8dSWarner Losh 1754b844f8dSWarner Losh breakdown_name(name, &guid, &vname); 1764b844f8dSWarner Losh if (efi_del_variable(guid, vname) < 0) 1773c0dcbfcSWarner Losh rep_err(1, "efi_del_variable"); 1784b844f8dSWarner Losh } 1794b844f8dSWarner Losh 1804b844f8dSWarner Losh static void 1814b844f8dSWarner Losh write_variable(char *name, char *val) 1824b844f8dSWarner Losh { 1834b844f8dSWarner Losh char *vname; 1844b844f8dSWarner Losh efi_guid_t guid; 1854b844f8dSWarner Losh size_t datalen; 1864b844f8dSWarner Losh uint8_t *data; 1874b844f8dSWarner Losh 1884b844f8dSWarner Losh breakdown_name(name, &guid, &vname); 1894b844f8dSWarner Losh data = get_value(val, &datalen); 190831bec11SWarner Losh if (efi_set_variable(guid, vname, data, datalen, attrib) < 0) 1913c0dcbfcSWarner Losh rep_err(1, "efi_set_variable"); 1924b844f8dSWarner Losh } 1934b844f8dSWarner Losh 1944b844f8dSWarner Losh static void 1959e4a51a8SWarner Losh devpath_dump(uint8_t *data, size_t datalen) 1969e4a51a8SWarner Losh { 1972f2f5c67SWarner Losh char buffer[1024]; 1989e4a51a8SWarner Losh 1992f2f5c67SWarner Losh efidp_format_device_path(buffer, sizeof(buffer), 2002f2f5c67SWarner Losh (const_efidp)data, datalen); 2012f2f5c67SWarner Losh if (!Nflag) 2022f2f5c67SWarner Losh printf(": "); 2032f2f5c67SWarner Losh printf("%s\n", buffer); 2049e4a51a8SWarner Losh } 2059e4a51a8SWarner Losh 2069e4a51a8SWarner Losh static void 20716445670SWarner Losh pretty_guid(efi_guid_t *guid, char **gname) 20816445670SWarner Losh { 20916445670SWarner Losh char *pretty = NULL; 21016445670SWarner Losh 21116445670SWarner Losh if (gflag) 21216445670SWarner Losh efi_guid_to_name(guid, &pretty); 21316445670SWarner Losh 21416445670SWarner Losh if (pretty == NULL) 21516445670SWarner Losh efi_guid_to_str(guid, gname); 21616445670SWarner Losh else 21716445670SWarner Losh *gname = pretty; 21816445670SWarner Losh } 21916445670SWarner Losh 22016445670SWarner Losh static void 2214b844f8dSWarner Losh print_var(efi_guid_t *guid, char *name) 2224b844f8dSWarner Losh { 2234b844f8dSWarner Losh uint32_t att; 2244b844f8dSWarner Losh uint8_t *data; 2254b844f8dSWarner Losh size_t datalen; 226e08bb109SWarner Losh char *gname = NULL; 2274b844f8dSWarner Losh int rv; 2284b844f8dSWarner Losh 229e08bb109SWarner Losh if (guid) 23016445670SWarner Losh pretty_guid(guid, &gname); 231e08bb109SWarner Losh if (pflag || fromfile) { 232e08bb109SWarner Losh if (fromfile) { 233e08bb109SWarner Losh int fd; 2344b844f8dSWarner Losh 235e08bb109SWarner Losh fd = open(fromfile, O_RDONLY); 236e08bb109SWarner Losh if (fd < 0) 2373c0dcbfcSWarner Losh rep_err(1, "open %s", fromfile); 238e08bb109SWarner Losh data = malloc(64 * 1024); 239e08bb109SWarner Losh if (data == NULL) 2403c0dcbfcSWarner Losh rep_err(1, "malloc"); 241e08bb109SWarner Losh datalen = read(fd, data, 64 * 1024); 242e08bb109SWarner Losh if (datalen <= 0) 2433c0dcbfcSWarner Losh rep_err(1, "read"); 244e08bb109SWarner Losh close(fd); 245e08bb109SWarner Losh } else { 246e08bb109SWarner Losh rv = efi_get_variable(*guid, name, &data, &datalen, &att); 2474b844f8dSWarner Losh if (rv < 0) 2483c0dcbfcSWarner Losh rep_err(1, "fetching %s-%s", gname, name); 249e08bb109SWarner Losh } 250e08bb109SWarner Losh 25135a419a2SWarner Losh 25235a419a2SWarner Losh if (!Nflag) 2535709a4b5SWarner Losh printf("%s-%s\n", gname, name); 2545709a4b5SWarner Losh if (load_opt_flag) 2555709a4b5SWarner Losh efi_print_load_option(data, datalen, Aflag, bflag, uflag); 2565709a4b5SWarner Losh else if (Aflag) 2574b844f8dSWarner Losh asciidump(data, datalen); 258b0da7c79SWarner Losh else if (uflag) 259b0da7c79SWarner Losh utf8dump(data, datalen); 2604b844f8dSWarner Losh else if (bflag) 2614b844f8dSWarner Losh bindump(data, datalen); 2629e4a51a8SWarner Losh else if (dflag) 2639e4a51a8SWarner Losh devpath_dump(data, datalen); 2644b844f8dSWarner Losh else 2654b844f8dSWarner Losh hexdump(data, datalen); 266902af7c6SWarner Losh } else { 267902af7c6SWarner Losh printf("%s-%s", gname, name); 2684b844f8dSWarner Losh } 2694b844f8dSWarner Losh free(gname); 2704b844f8dSWarner Losh if (!Nflag) 2714b844f8dSWarner Losh printf("\n"); 2724b844f8dSWarner Losh } 2734b844f8dSWarner Losh 2744b844f8dSWarner Losh static void 2754b844f8dSWarner Losh print_variable(char *name) 2764b844f8dSWarner Losh { 2774b844f8dSWarner Losh char *vname; 2784b844f8dSWarner Losh efi_guid_t guid; 2794b844f8dSWarner Losh 2804b844f8dSWarner Losh breakdown_name(name, &guid, &vname); 2814b844f8dSWarner Losh print_var(&guid, vname); 2824b844f8dSWarner Losh } 2834b844f8dSWarner Losh 2844b844f8dSWarner Losh static void 2854b844f8dSWarner Losh print_variables(void) 2864b844f8dSWarner Losh { 2874b844f8dSWarner Losh int rv; 2884b844f8dSWarner Losh char *name = NULL; 2894b844f8dSWarner Losh efi_guid_t *guid = NULL; 2904b844f8dSWarner Losh 2914b844f8dSWarner Losh while ((rv = efi_get_next_variable_name(&guid, &name)) > 0) 2924b844f8dSWarner Losh print_var(guid, name); 2934b844f8dSWarner Losh 2944b844f8dSWarner Losh if (rv < 0) 2953c0dcbfcSWarner Losh rep_err(1, "Error listing names"); 2964b844f8dSWarner Losh } 2974b844f8dSWarner Losh 2984b844f8dSWarner Losh static void 2994a110fbfSWarner Losh print_known_guid(void) 3004a110fbfSWarner Losh { 3014a110fbfSWarner Losh struct uuid_table *tbl; 3024a110fbfSWarner Losh int i, n; 3034a110fbfSWarner Losh 3044a110fbfSWarner Losh n = efi_known_guid(&tbl); 3054a110fbfSWarner Losh for (i = 0; i < n; i++) 3064a110fbfSWarner Losh printf("%s %s\n", tbl[i].uuid_str, tbl[i].name); 3074a110fbfSWarner Losh } 3084a110fbfSWarner Losh 3094a110fbfSWarner Losh static void 3104b844f8dSWarner Losh parse_args(int argc, char **argv) 3114b844f8dSWarner Losh { 3124b844f8dSWarner Losh int ch, i; 3134b844f8dSWarner Losh 3143c0dcbfcSWarner Losh while ((ch = getopt_long(argc, argv, "aAbdDf:gHlLNn:OpqRt:uw", 3154b844f8dSWarner Losh longopts, NULL)) != -1) { 3164b844f8dSWarner Losh switch (ch) { 3174b844f8dSWarner Losh case 'a': 318*066b096dSWarner Losh aflag = true; 3194b844f8dSWarner Losh break; 3204b844f8dSWarner Losh case 'A': 321*066b096dSWarner Losh Aflag = true; 3224b844f8dSWarner Losh break; 3234b844f8dSWarner Losh case 'b': 324*066b096dSWarner Losh bflag = true; 3254b844f8dSWarner Losh break; 3264b844f8dSWarner Losh case 'd': 327*066b096dSWarner Losh dflag = true; 3284b844f8dSWarner Losh break; 3294b844f8dSWarner Losh case 'D': 330*066b096dSWarner Losh Dflag = true; 3314b844f8dSWarner Losh break; 33216445670SWarner Losh case 'g': 333*066b096dSWarner Losh gflag = true; 33416445670SWarner Losh break; 3354b844f8dSWarner Losh case 'H': 336*066b096dSWarner Losh Hflag = true; 3374b844f8dSWarner Losh break; 3384b844f8dSWarner Losh case 'l': 339*066b096dSWarner Losh lflag = true; 3404b844f8dSWarner Losh break; 3414b844f8dSWarner Losh case 'L': 342*066b096dSWarner Losh Lflag = true; 3434b844f8dSWarner Losh break; 3444b844f8dSWarner Losh case 'n': 3454b844f8dSWarner Losh varname = optarg; 3464b844f8dSWarner Losh break; 3474b844f8dSWarner Losh case 'N': 348*066b096dSWarner Losh Nflag = true; 3494b844f8dSWarner Losh break; 3505709a4b5SWarner Losh case 'O': 351*066b096dSWarner Losh load_opt_flag = true; 3525709a4b5SWarner Losh break; 3534b844f8dSWarner Losh case 'p': 354*066b096dSWarner Losh pflag = true; 3554b844f8dSWarner Losh break; 3563c0dcbfcSWarner Losh case 'q': 3573c0dcbfcSWarner Losh quiet = true; 3583c0dcbfcSWarner Losh break; 3594b844f8dSWarner Losh case 'R': 360*066b096dSWarner Losh Rflag = true; 3614b844f8dSWarner Losh break; 36255ff82c0SWarner Losh case 't': 36355ff82c0SWarner Losh attrib = strtoul(optarg, NULL, 16); 36455ff82c0SWarner Losh break; 365b0da7c79SWarner Losh case 'u': 366*066b096dSWarner Losh uflag = true; 367b0da7c79SWarner Losh break; 3684b844f8dSWarner Losh case 'w': 369*066b096dSWarner Losh wflag = true; 3704b844f8dSWarner Losh break; 3714b844f8dSWarner Losh case 'f': 372e08bb109SWarner Losh free(fromfile); 373e08bb109SWarner Losh fromfile = strdup(optarg); 374e08bb109SWarner Losh break; 3754b844f8dSWarner Losh case 0: 3763c0dcbfcSWarner Losh rep_errx(1, "unknown or unimplemented option\n"); 3774b844f8dSWarner Losh break; 3784b844f8dSWarner Losh default: 3794b844f8dSWarner Losh usage(); 3804b844f8dSWarner Losh } 3814b844f8dSWarner Losh } 3824b844f8dSWarner Losh argc -= optind; 3834b844f8dSWarner Losh argv += optind; 3844b844f8dSWarner Losh 3854b844f8dSWarner Losh if (argc == 1) 3864b844f8dSWarner Losh varname = argv[0]; 3874b844f8dSWarner Losh 388*066b096dSWarner Losh if ((int)aflag + (int)Dflag + (int)wflag > 1) { 3894b844f8dSWarner Losh warnx("Can only use one of -a (--append), " 3904b844f8dSWarner Losh "-D (--delete) and -w (--write)"); 3914b844f8dSWarner Losh usage(); 3924b844f8dSWarner Losh } 3934b844f8dSWarner Losh 394*066b096dSWarner Losh if ((int)aflag + (int)Dflag + (int)wflag > 0 && varname == NULL) { 3954b844f8dSWarner Losh warnx("Must specify a variable for -a (--append), " 3964b844f8dSWarner Losh "-D (--delete) or -w (--write)"); 3974b844f8dSWarner Losh usage(); 3984b844f8dSWarner Losh } 3994b844f8dSWarner Losh 4004b844f8dSWarner Losh if (aflag) 4014b844f8dSWarner Losh append_variable(varname, NULL); 4024b844f8dSWarner Losh else if (Dflag) 4034b844f8dSWarner Losh delete_variable(varname); 4044b844f8dSWarner Losh else if (wflag) 4054b844f8dSWarner Losh write_variable(varname, NULL); 4064a110fbfSWarner Losh else if (Lflag) 4074a110fbfSWarner Losh print_known_guid(); 408e08bb109SWarner Losh else if (fromfile) { 409*066b096dSWarner Losh Nflag = true; 410e08bb109SWarner Losh print_var(NULL, NULL); 411e08bb109SWarner Losh } else if (varname) { 412*066b096dSWarner Losh pflag = true; 4134b844f8dSWarner Losh print_variable(varname); 4144b844f8dSWarner Losh } else if (argc > 0) { 415*066b096dSWarner Losh pflag = true; 4164b844f8dSWarner Losh for (i = 0; i < argc; i++) 4174b844f8dSWarner Losh print_variable(argv[i]); 4184b844f8dSWarner Losh } else 4194b844f8dSWarner Losh print_variables(); 4204b844f8dSWarner Losh } 4214b844f8dSWarner Losh 4224b844f8dSWarner Losh int 4234b844f8dSWarner Losh main(int argc, char **argv) 4244b844f8dSWarner Losh { 4254b844f8dSWarner Losh 4264b844f8dSWarner Losh parse_args(argc, argv); 4274b844f8dSWarner Losh } 428