From c61bbb1f9ff4456c0eb384a49e8a7a2b026cd234 Mon Sep 17 00:00:00 2001 From: Alexander Goncharov Date: Thu, 2 Mar 2023 15:23:20 +0400 Subject: cli_classic: refactor arguments parsing into separate func Move variables that represent parsed options to `cli_options` structure. This patchset also introduces the following functions: - parse_options() which parses command line arguments and fills the structure. - free_options() that releases an allocated data from the structure. This is one of the steps on the way to simplify the main function by using helper functions with descriptive names. TOPIC=split_main_func TEST=the following scenarious run successfully ./flashrom -p dummy:emulate=S25FL128L -V ./flashrom -p dummy:size=8388608,emulate=VARIABLE_SIZE \ -r /tmp/dump.rom ./flashrom -p dummy:emulate=W25Q128FV -l /tmp/rom.layout \ -i boot -w /tmp/rom.tr.img ./flashrom -p dummy:emulate=W25Q128FV --wp-list ./flashrom -p dummy:emulate=W25Q128FV,hwwp=yes \ --wp-enable \ --wp-range=0x00c00000,0x00400000 \ --wp-status $ head -c 16MiB /tmp/image.rom ./flashrom -p dummy:image=/tmp/image.rom,emulate=S25FL128L \ -c S25FL128L -E -V Change-Id: Id573bc74e3bb46b7dc42f1452fff6394d4f091bc Signed-off-by: Alexander Goncharov Reviewed-on: https://review.coreboot.org/c/flashrom/+/66343 Tested-by: build bot (Jenkins) Reviewed-by: Anastasia Klimchuk --- cli_classic.c | 515 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 270 insertions(+), 245 deletions(-) diff --git a/cli_classic.c b/cli_classic.c index da689196..787de67a 100644 --- a/cli_classic.c +++ b/cli_classic.c @@ -31,6 +31,53 @@ #include "programmer.h" #include "libflashrom.h" +enum { + OPTION_IFD = 0x0100, + OPTION_FMAP, + OPTION_FMAP_FILE, + OPTION_FLASH_CONTENTS, + OPTION_FLASH_NAME, + OPTION_FLASH_SIZE, + OPTION_WP_STATUS, + OPTION_WP_SET_RANGE, + OPTION_WP_SET_REGION, + OPTION_WP_ENABLE, + OPTION_WP_DISABLE, + OPTION_WP_LIST, + OPTION_PROGRESS, +}; + +struct cli_options { + bool read_it, extract_it, write_it, erase_it, verify_it; + bool dont_verify_it, dont_verify_all; + bool list_supported; +#if CONFIG_PRINT_WIKI == 1 + bool list_supported_wiki; +#endif + char *filename; + + const struct programmer_entry *prog; + char *pparam; + + bool ifd, fmap; + struct flashrom_layout *layout; + struct layout_include_args *include_args; + char *layoutfile; + char *fmapfile; + + unsigned int wp_start, wp_len; + bool enable_wp, disable_wp, print_wp_status; + bool set_wp_range, set_wp_region, print_wp_ranges; + char *wp_region; + + bool force; + bool flash_name, flash_size; + bool show_progress; + char *logfile; + char *referencefile; + const char *chip_to_probe; +}; + static void cli_classic_usage(const char *name) { printf("Usage: %s [-h|-R|-L|" @@ -565,114 +612,14 @@ static unsigned int count_max_decode_exceedings(const struct flashctx *flash, return limitexceeded; } -int main(int argc, char *argv[]) +static void parse_options(int argc, char **argv, const char *optstring, + const struct option *long_options, + struct cli_options *options) { - const struct flashchip *chip = NULL; - /* Probe for up to eight flash chips. */ - struct flashctx flashes[8] = {{0}}; - struct flashctx *fill_flash; const char *name; - int namelen, opt, i, j; - int startchip = -1, chipcount = 0, option_index = 0; - int operation_specified = 0; - unsigned int wp_start = 0, wp_len = 0; - bool force = false, ifd = false, fmap = false; -#if CONFIG_PRINT_WIKI == 1 - bool list_supported_wiki = false; -#endif - bool flash_name = false, flash_size = false; - bool enable_wp = false, disable_wp = false, print_wp_status = false; - bool set_wp_range = false, set_wp_region = false, print_wp_ranges = false; - bool read_it = false, extract_it = false, write_it = false, erase_it = false, verify_it = false; - bool dont_verify_it = false, dont_verify_all = false; - bool list_supported = false; - bool show_progress = false; - struct flashrom_layout *layout = NULL; - static const struct programmer_entry *prog = NULL; - enum { - OPTION_IFD = 0x0100, - OPTION_FMAP, - OPTION_FMAP_FILE, - OPTION_FLASH_CONTENTS, - OPTION_FLASH_NAME, - OPTION_FLASH_SIZE, - OPTION_WP_STATUS, - OPTION_WP_SET_RANGE, - OPTION_WP_SET_REGION, - OPTION_WP_ENABLE, - OPTION_WP_DISABLE, - OPTION_WP_LIST, - OPTION_PROGRESS, - }; - int ret = 0; + int namelen, opt; + int option_index = 0, operation_specified = 0; - static const char optstring[] = "r:Rw:v:nNVEfc:l:i:p:Lzho:x"; - static const struct option long_options[] = { - {"read", 1, NULL, 'r'}, - {"write", 1, NULL, 'w'}, - {"erase", 0, NULL, 'E'}, - {"verify", 1, NULL, 'v'}, - {"noverify", 0, NULL, 'n'}, - {"noverify-all", 0, NULL, 'N'}, - {"extract", 0, NULL, 'x'}, - {"chip", 1, NULL, 'c'}, - {"verbose", 0, NULL, 'V'}, - {"force", 0, NULL, 'f'}, - {"layout", 1, NULL, 'l'}, - {"ifd", 0, NULL, OPTION_IFD}, - {"fmap", 0, NULL, OPTION_FMAP}, - {"fmap-file", 1, NULL, OPTION_FMAP_FILE}, - {"image", 1, NULL, 'i'}, // (deprecated): back compatibility. - {"include", 1, NULL, 'i'}, - {"flash-contents", 1, NULL, OPTION_FLASH_CONTENTS}, - {"flash-name", 0, NULL, OPTION_FLASH_NAME}, - {"flash-size", 0, NULL, OPTION_FLASH_SIZE}, - {"get-size", 0, NULL, OPTION_FLASH_SIZE}, // (deprecated): back compatibility. - {"wp-status", 0, NULL, OPTION_WP_STATUS}, - {"wp-list", 0, NULL, OPTION_WP_LIST}, - {"wp-range", 1, NULL, OPTION_WP_SET_RANGE}, - {"wp-region", 1, NULL, OPTION_WP_SET_REGION}, - {"wp-enable", 0, NULL, OPTION_WP_ENABLE}, - {"wp-disable", 0, NULL, OPTION_WP_DISABLE}, - {"list-supported", 0, NULL, 'L'}, - {"list-supported-wiki", 0, NULL, 'z'}, - {"programmer", 1, NULL, 'p'}, - {"help", 0, NULL, 'h'}, - {"version", 0, NULL, 'R'}, - {"output", 1, NULL, 'o'}, - {"progress", 0, NULL, OPTION_PROGRESS}, - {NULL, 0, NULL, 0}, - }; - - char *filename = NULL; - char *referencefile = NULL; - char *layoutfile = NULL; - char *fmapfile = NULL; - char *logfile = NULL; - char *tempstr = NULL; - char *pparam = NULL; - struct layout_include_args *include_args = NULL; - char *wp_region = NULL; - const char *chip_to_probe = NULL; - - /* - * Safety-guard against a user who has (mistakenly) closed - * stdout or stderr before exec'ing flashrom. We disable - * logging in this case to prevent writing log data to a flash - * chip when a flash device gets opened with fd 1 or 2. - */ - if (check_file(stdout) && check_file(stderr)) { - flashrom_set_log_callback(&flashrom_print_cb); - } - - print_version(); - print_banner(); - - /* FIXME: Delay calibration should happen in programmer code. */ - if (flashrom_init(1)) - exit(1); - - setbuf(stdout, NULL); /* FIXME: Delay all operation_specified checks until after command * line parsing to allow --help overriding everything else. */ @@ -681,38 +628,38 @@ int main(int argc, char *argv[]) switch (opt) { case 'r': cli_classic_validate_singleop(&operation_specified); - filename = strdup(optarg); - read_it = true; + options->filename = strdup(optarg); + options->read_it = true; break; case 'w': cli_classic_validate_singleop(&operation_specified); - filename = strdup(optarg); - write_it = true; + options->filename = strdup(optarg); + options->write_it = true; break; case 'v': //FIXME: gracefully handle superfluous -v cli_classic_validate_singleop(&operation_specified); - if (dont_verify_it) { + if (options->dont_verify_it) { cli_classic_abort_usage("--verify and --noverify are mutually exclusive. Aborting.\n"); } - filename = strdup(optarg); - verify_it = true; + options->filename = strdup(optarg); + options->verify_it = true; break; case 'n': - if (verify_it) { + if (options->verify_it) { cli_classic_abort_usage("--verify and --noverify are mutually exclusive. Aborting.\n"); } - dont_verify_it = true; + options->dont_verify_it = true; break; case 'N': - dont_verify_all = true; + options->dont_verify_all = true; break; case 'x': cli_classic_validate_singleop(&operation_specified); - extract_it = true; + options->extract_it = true; break; case 'c': - chip_to_probe = strdup(optarg); + options->chip_to_probe = strdup(optarg); break; case 'V': verbose_screen++; @@ -721,103 +668,103 @@ int main(int argc, char *argv[]) break; case 'E': cli_classic_validate_singleop(&operation_specified); - erase_it = true; + options->erase_it = true; break; case 'f': - force = true; + options->force = true; break; case 'l': - if (layoutfile) + if (options->layoutfile) cli_classic_abort_usage("Error: --layout specified more than once. Aborting.\n"); - if (ifd) + if (options->ifd) cli_classic_abort_usage("Error: --layout and --ifd both specified. Aborting.\n"); - if (fmap) + if (options->fmap) cli_classic_abort_usage("Error: --layout and --fmap-file both specified. Aborting.\n"); - layoutfile = strdup(optarg); + options->layoutfile = strdup(optarg); break; case OPTION_IFD: - if (layoutfile) + if (options->layoutfile) cli_classic_abort_usage("Error: --layout and --ifd both specified. Aborting.\n"); - if (fmap) + if (options->fmap) cli_classic_abort_usage("Error: --fmap-file and --ifd both specified. Aborting.\n"); - ifd = true; + options->ifd = true; break; case OPTION_FMAP_FILE: - if (fmap) + if (options->fmap) cli_classic_abort_usage("Error: --fmap or --fmap-file specified " "more than once. Aborting.\n"); - if (ifd) + if (options->ifd) cli_classic_abort_usage("Error: --fmap-file and --ifd both specified. Aborting.\n"); - if (layoutfile) + if (options->layoutfile) cli_classic_abort_usage("Error: --fmap-file and --layout both specified. Aborting.\n"); - fmapfile = strdup(optarg); - fmap = true; + options->fmapfile = strdup(optarg); + options->fmap = true; break; case OPTION_FMAP: - if (fmap) + if (options->fmap) cli_classic_abort_usage("Error: --fmap or --fmap-file specified " "more than once. Aborting.\n"); - if (ifd) + if (options->ifd) cli_classic_abort_usage("Error: --fmap and --ifd both specified. Aborting.\n"); - if (layoutfile) + if (options->layoutfile) cli_classic_abort_usage("Error: --layout and --fmap both specified. Aborting.\n"); - fmap = true; + options->fmap = true; break; case 'i': - if (register_include_arg(&include_args, optarg)) + if (register_include_arg(&options->include_args, optarg)) cli_classic_abort_usage(NULL); break; case OPTION_FLASH_CONTENTS: - if (referencefile) + if (options->referencefile) cli_classic_abort_usage("Error: --flash-contents specified more than once." "Aborting.\n"); - referencefile = strdup(optarg); + options->referencefile = strdup(optarg); break; case OPTION_FLASH_NAME: cli_classic_validate_singleop(&operation_specified); - flash_name = true; + options->flash_name = true; break; case OPTION_FLASH_SIZE: cli_classic_validate_singleop(&operation_specified); - flash_size = true; + options->flash_size = true; break; case OPTION_WP_STATUS: - print_wp_status = true; + options->print_wp_status = true; break; case OPTION_WP_LIST: - print_wp_ranges = true; + options->print_wp_ranges = true; break; case OPTION_WP_SET_RANGE: - if (parse_wp_range(&wp_start, &wp_len) < 0) + if (parse_wp_range(&options->wp_start, &options->wp_len) < 0) cli_classic_abort_usage("Incorrect wp-range arguments provided.\n"); - set_wp_range = true; + options->set_wp_range = true; break; case OPTION_WP_SET_REGION: - set_wp_region = true; - wp_region = strdup(optarg); + options->set_wp_region = true; + options->wp_region = strdup(optarg); break; case OPTION_WP_ENABLE: - enable_wp = true; + options->enable_wp = true; break; case OPTION_WP_DISABLE: - disable_wp = true; + options->disable_wp = true; break; case 'L': cli_classic_validate_singleop(&operation_specified); - list_supported = true; + options->list_supported = true; break; case 'z': #if CONFIG_PRINT_WIKI == 1 cli_classic_validate_singleop(&operation_specified); - list_supported_wiki = true; + options->list_supported_wiki = true; #else cli_classic_abort_usage("Error: Wiki output was not " "compiled in. Aborting.\n"); #endif break; case 'p': - if (prog != NULL) { + if (options->prog != NULL) { cli_classic_abort_usage("Error: --programmer specified " "more than once. You can separate " "multiple\nparameters for a programmer " @@ -831,15 +778,15 @@ int main(int argc, char *argv[]) if (strncmp(optarg, name, namelen) == 0) { switch (optarg[namelen]) { case ':': - pparam = strdup(optarg + namelen + 1); - if (!strlen(pparam)) { - free(pparam); - pparam = NULL; + options->pparam = strdup(optarg + namelen + 1); + if (!strlen(options->pparam)) { + free(options->pparam); + options->pparam = NULL; } - prog = programmer_table[p]; + options->prog = programmer_table[p]; break; case '\0': - prog = programmer_table[p]; + options->prog = programmer_table[p]; break; default: /* The continue refers to the @@ -852,7 +799,7 @@ int main(int argc, char *argv[]) break; } } - if (prog == NULL) { + if (options->prog == NULL) { fprintf(stderr, "Error: Unknown programmer \"%s\". Valid choices are:\n", optarg); list_programmers_linebreak(0, 80, 0); @@ -871,18 +818,18 @@ int main(int argc, char *argv[]) exit(0); break; case 'o': - if (logfile) { + if (options->logfile) { fprintf(stderr, "Warning: -o/--output specified multiple times.\n"); - free(logfile); + free(options->logfile); } - logfile = strdup(optarg); - if (logfile[0] == '\0') { + options->logfile = strdup(optarg); + if (options->logfile[0] == '\0') { cli_classic_abort_usage("No log filename specified.\n"); } break; case OPTION_PROGRESS: - show_progress = true; + options->show_progress = true; break; default: cli_classic_abort_usage(NULL); @@ -892,27 +839,113 @@ int main(int argc, char *argv[]) if (optind < argc) cli_classic_abort_usage("Error: Extra parameter found.\n"); - if ((read_it | write_it | verify_it) && check_filename(filename, "image")) +} + +static void free_options(struct cli_options *options) +{ + cleanup_include_args(&options->include_args); + free(options->filename); + free(options->fmapfile); + free(options->referencefile); + free(options->layoutfile); + free(options->pparam); + free(options->wp_region); + free(options->logfile); + free((char *)options->chip_to_probe); +} + +int main(int argc, char *argv[]) +{ + const struct flashchip *chip = NULL; + /* Probe for up to eight flash chips. */ + struct flashctx flashes[8] = {{0}}; + struct flashctx *fill_flash; + char *tempstr = NULL; + int startchip = -1, chipcount = 0; + int i, j; + int ret = 0; + + struct cli_options options = { 0 }; + static const char optstring[] = "r:Rw:v:nNVEfc:l:i:p:Lzho:x"; + static const struct option long_options[] = { + {"read", 1, NULL, 'r'}, + {"write", 1, NULL, 'w'}, + {"erase", 0, NULL, 'E'}, + {"verify", 1, NULL, 'v'}, + {"noverify", 0, NULL, 'n'}, + {"noverify-all", 0, NULL, 'N'}, + {"extract", 0, NULL, 'x'}, + {"chip", 1, NULL, 'c'}, + {"verbose", 0, NULL, 'V'}, + {"force", 0, NULL, 'f'}, + {"layout", 1, NULL, 'l'}, + {"ifd", 0, NULL, OPTION_IFD}, + {"fmap", 0, NULL, OPTION_FMAP}, + {"fmap-file", 1, NULL, OPTION_FMAP_FILE}, + {"image", 1, NULL, 'i'}, // (deprecated): back compatibility. + {"include", 1, NULL, 'i'}, + {"flash-contents", 1, NULL, OPTION_FLASH_CONTENTS}, + {"flash-name", 0, NULL, OPTION_FLASH_NAME}, + {"flash-size", 0, NULL, OPTION_FLASH_SIZE}, + {"get-size", 0, NULL, OPTION_FLASH_SIZE}, // (deprecated): back compatibility. + {"wp-status", 0, NULL, OPTION_WP_STATUS}, + {"wp-list", 0, NULL, OPTION_WP_LIST}, + {"wp-range", 1, NULL, OPTION_WP_SET_RANGE}, + {"wp-region", 1, NULL, OPTION_WP_SET_REGION}, + {"wp-enable", 0, NULL, OPTION_WP_ENABLE}, + {"wp-disable", 0, NULL, OPTION_WP_DISABLE}, + {"list-supported", 0, NULL, 'L'}, + {"list-supported-wiki", 0, NULL, 'z'}, + {"programmer", 1, NULL, 'p'}, + {"help", 0, NULL, 'h'}, + {"version", 0, NULL, 'R'}, + {"output", 1, NULL, 'o'}, + {"progress", 0, NULL, OPTION_PROGRESS}, + {NULL, 0, NULL, 0}, + }; + + /* + * Safety-guard against a user who has (mistakenly) closed + * stdout or stderr before exec'ing flashrom. We disable + * logging in this case to prevent writing log data to a flash + * chip when a flash device gets opened with fd 1 or 2. + */ + if (check_file(stdout) && check_file(stderr)) { + flashrom_set_log_callback(&flashrom_print_cb); + } + + print_version(); + print_banner(); + + /* FIXME: Delay calibration should happen in programmer code. */ + if (flashrom_init(1)) + exit(1); + + setbuf(stdout, NULL); + + parse_options(argc, argv, optstring, long_options, &options); + + if ((options.read_it | options.write_it | options.verify_it) && check_filename(options.filename, "image")) cli_classic_abort_usage(NULL); - if (layoutfile && check_filename(layoutfile, "layout")) + if (options.layoutfile && check_filename(options.layoutfile, "layout")) cli_classic_abort_usage(NULL); - if (fmapfile && check_filename(fmapfile, "fmap")) + if (options.fmapfile && check_filename(options.fmapfile, "fmap")) cli_classic_abort_usage(NULL); - if (referencefile && check_filename(referencefile, "reference")) + if (options.referencefile && check_filename(options.referencefile, "reference")) cli_classic_abort_usage(NULL); - if (logfile && check_filename(logfile, "log")) + if (options.logfile && check_filename(options.logfile, "log")) cli_classic_abort_usage(NULL); - if (logfile && open_logfile(logfile)) + if (options.logfile && open_logfile(options.logfile)) cli_classic_abort_usage(NULL); #if CONFIG_PRINT_WIKI == 1 - if (list_supported_wiki) { + if (options.list_supported_wiki) { print_supported_wiki(); goto out; } #endif - if (list_supported) { + if (options.list_supported) { if (print_supported()) ret = 1; goto out; @@ -927,22 +960,22 @@ int main(int argc, char *argv[]) } msg_gdbg("\n"); - if (layoutfile && layout_from_file(&layout, layoutfile)) { + if (options.layoutfile && layout_from_file(&options.layout, options.layoutfile)) { ret = 1; goto out; } - if (!ifd && !fmap && process_include_args(layout, include_args)) { + if (!options.ifd && !options.fmap && process_include_args(options.layout, options.include_args)) { ret = 1; goto out; } /* Does a chip with the requested name exist in the flashchips array? */ - if (chip_to_probe) { + if (options.chip_to_probe) { for (chip = flashchips; chip && chip->name; chip++) - if (!strcmp(chip->name, chip_to_probe)) + if (!strcmp(chip->name, options.chip_to_probe)) break; if (!chip || !chip->name) { - msg_cerr("Error: Unknown chip '%s' specified.\n", chip_to_probe); + msg_cerr("Error: Unknown chip '%s' specified.\n", options.chip_to_probe); msg_gerr("Run flashrom -L to view the hardware supported in this flashrom version.\n"); ret = 1; goto out; @@ -950,15 +983,15 @@ int main(int argc, char *argv[]) /* Keep chip around for later usage in case a forced read is requested. */ } - if (prog == NULL) { + if (options.prog == NULL) { const struct programmer_entry *const default_programmer = CONFIG_DEFAULT_PROGRAMMER_NAME; if (default_programmer) { - prog = default_programmer; + options.prog = default_programmer; /* We need to strdup here because we free(pparam) unconditionally later. */ - pparam = strdup(CONFIG_DEFAULT_PROGRAMMER_ARGS); + options.pparam = strdup(CONFIG_DEFAULT_PROGRAMMER_ARGS); msg_pinfo("Using default programmer \"%s\" with arguments \"%s\".\n", - default_programmer->name, pparam); + default_programmer->name, options.pparam); } else { msg_perr("Please select a programmer with the --programmer parameter.\n" #if CONFIG_INTERNAL == 1 @@ -972,7 +1005,7 @@ int main(int argc, char *argv[]) } } - if (programmer_init(prog, pparam)) { + if (programmer_init(options.prog, options.pparam)) { msg_perr("Error: Programmer initialization failed.\n"); ret = 1; goto out_shutdown; @@ -984,7 +1017,7 @@ int main(int argc, char *argv[]) for (j = 0; j < registered_master_count; j++) { startchip = 0; while (chipcount < (int)ARRAY_SIZE(flashes)) { - startchip = probe_flash(®istered_masters[j], startchip, &flashes[chipcount], 0, chip_to_probe); + startchip = probe_flash(®istered_masters[j], startchip, &flashes[chipcount], 0, options.chip_to_probe); if (startchip == -1) break; chipcount++; @@ -1002,11 +1035,11 @@ int main(int argc, char *argv[]) goto out_shutdown; } else if (!chipcount) { msg_cinfo("No EEPROM/flash device found.\n"); - if (!force || !chip_to_probe) { + if (!options.force || !options.chip_to_probe) { msg_cinfo("Note: flashrom can never write if the flash chip isn't found " "automatically.\n"); } - if (force && read_it && chip_to_probe) { + if (options.force && options.read_it && options.chip_to_probe) { struct registered_master *mst; int compatible_masters = 0; msg_cinfo("Force read (-f -r -c) requested, pretending the chip is there:\n"); @@ -1027,25 +1060,25 @@ int main(int argc, char *argv[]) "chip, using the first one.\n"); for (j = 0; j < registered_master_count; j++) { mst = ®istered_masters[j]; - startchip = probe_flash(mst, 0, &flashes[0], 1, chip_to_probe); + startchip = probe_flash(mst, 0, &flashes[0], 1, options.chip_to_probe); if (startchip != -1) break; } if (startchip == -1) { // FIXME: This should never happen! Ask for a bug report? - msg_cinfo("Probing for flash chip '%s' failed.\n", chip_to_probe); + msg_cinfo("Probing for flash chip '%s' failed.\n", options.chip_to_probe); ret = 1; goto out_shutdown; } msg_cinfo("Please note that forced reads most likely contain garbage.\n"); - flashrom_flag_set(&flashes[0], FLASHROM_FLAG_FORCE, force); - ret = do_read(&flashes[0], filename); + flashrom_flag_set(&flashes[0], FLASHROM_FLAG_FORCE, options.force); + ret = do_read(&flashes[0], options.filename); free(flashes[0].chip); goto out_shutdown; } ret = 1; goto out_shutdown; - } else if (!chip_to_probe) { + } else if (!options.chip_to_probe) { /* repeat for convenience when looking at foreign logs */ tempstr = flashbuses_to_text(flashes[0].chip->bustype); msg_gdbg("Found %s flash chip \"%s\" (%d kB, %s).\n", @@ -1059,13 +1092,13 @@ int main(int argc, char *argv[]) struct flashrom_progress progress_state = { .user_data = progress_user_data }; - if (show_progress) + if (options.show_progress) flashrom_set_progress_callback(fill_flash, &flashrom_progress_cb, &progress_state); print_chip_support_status(fill_flash->chip); unsigned int limitexceeded = count_max_decode_exceedings(fill_flash, &max_rom_decode); - if (limitexceeded > 0 && !force) { + if (limitexceeded > 0 && !options.force) { enum chipbustype commonbuses = fill_flash->mst->buses_supported & fill_flash->chip->bustype; /* Sometimes chip and programmer have more than one bus in common, @@ -1081,29 +1114,30 @@ int main(int argc, char *argv[]) } const bool any_wp_op = - set_wp_range || set_wp_region || enable_wp || - disable_wp || print_wp_status || print_wp_ranges; + options.set_wp_range || options.set_wp_region || options.enable_wp || + options.disable_wp || options.print_wp_status || options.print_wp_ranges; - const bool any_op = read_it || write_it || verify_it || erase_it || - flash_name || flash_size || extract_it || any_wp_op; + const bool any_op = options.read_it || options.write_it || options.verify_it || + options.erase_it || options.flash_name || options.flash_size || + options.extract_it || any_wp_op; if (!any_op) { msg_ginfo("No operations were specified.\n"); goto out_shutdown; } - if (enable_wp && disable_wp) { + if (options.enable_wp && options.disable_wp) { msg_ginfo("Error: --wp-enable and --wp-disable are mutually exclusive\n"); ret = 1; goto out_shutdown; } - if (set_wp_range && set_wp_region) { + if (options.set_wp_range && options.set_wp_region) { msg_gerr("Error: Cannot use both --wp-range and --wp-region simultaneously.\n"); ret = 1; goto out_shutdown; } - if (flash_name) { + if (options.flash_name) { if (fill_flash->chip->vendor && fill_flash->chip->name) { printf("vendor=\"%s\" name=\"%s\"\n", fill_flash->chip->vendor, @@ -1114,19 +1148,19 @@ int main(int argc, char *argv[]) goto out_shutdown; } - if (flash_size) { + if (options.flash_size) { printf("%zu\n", flashrom_flash_getsize(fill_flash)); goto out_shutdown; } - if (ifd && (flashrom_layout_read_from_ifd(&layout, fill_flash, NULL, 0) || - process_include_args(layout, include_args))) { + if (options.ifd && (flashrom_layout_read_from_ifd(&options.layout, fill_flash, NULL, 0) || + process_include_args(options.layout, options.include_args))) { ret = 1; goto out_shutdown; - } else if (fmap && fmapfile) { + } else if (options.fmap && options.fmapfile) { struct stat s; - if (stat(fmapfile, &s) != 0) { - msg_gerr("Failed to stat fmapfile \"%s\"\n", fmapfile); + if (stat(options.fmapfile, &s) != 0) { + msg_gerr("Failed to stat fmapfile \"%s\"\n", options.fmapfile); ret = 1; goto out_shutdown; } @@ -1138,72 +1172,73 @@ int main(int argc, char *argv[]) goto out_shutdown; } - if (read_buf_from_file(fmapfile_buffer, fmapfile_size, fmapfile)) { + if (read_buf_from_file(fmapfile_buffer, fmapfile_size, options.fmapfile)) { ret = 1; free(fmapfile_buffer); goto out_shutdown; } - if (flashrom_layout_read_fmap_from_buffer(&layout, fill_flash, fmapfile_buffer, fmapfile_size) || - process_include_args(layout, include_args)) { + if (flashrom_layout_read_fmap_from_buffer(&options.layout, fill_flash, fmapfile_buffer, fmapfile_size) || + process_include_args(options.layout, options.include_args)) { ret = 1; free(fmapfile_buffer); goto out_shutdown; } free(fmapfile_buffer); - } else if (fmap && (flashrom_layout_read_fmap_from_rom(&layout, fill_flash, 0, - flashrom_flash_getsize(fill_flash)) || process_include_args(layout, include_args))) { + } else if (options.fmap && (flashrom_layout_read_fmap_from_rom(&options.layout, fill_flash, 0, + flashrom_flash_getsize(fill_flash)) || + process_include_args(options.layout, options.include_args))) { ret = 1; goto out_shutdown; } - flashrom_layout_set(fill_flash, layout); + flashrom_layout_set(fill_flash, options.layout); if (any_wp_op) { - if (set_wp_region && wp_region) { - if (!layout) { + if (options.set_wp_region && options.wp_region) { + if (!options.layout) { msg_gerr("Error: A flash layout must be specified to use --wp-region.\n"); ret = 1; goto out_release; } - ret = flashrom_layout_get_region_range(layout, wp_region, &wp_start, &wp_len); + ret = flashrom_layout_get_region_range(options.layout, options.wp_region, &options.wp_start, &options.wp_len); if (ret) { - msg_gerr("Error: Region %s not found in flash layout.\n", wp_region); + msg_gerr("Error: Region %s not found in flash layout.\n", options.wp_region); goto out_release; } - set_wp_range = true; + options.set_wp_range = true; } ret = wp_cli( fill_flash, - enable_wp, - disable_wp, - print_wp_status, - print_wp_ranges, - set_wp_range, - wp_start, - wp_len + options.enable_wp, + options.disable_wp, + options.print_wp_status, + options.print_wp_ranges, + options.set_wp_range, + options.wp_start, + options.wp_len ); if (ret) goto out_release; } - flashrom_flag_set(fill_flash, FLASHROM_FLAG_FORCE, force); + flashrom_flag_set(fill_flash, FLASHROM_FLAG_FORCE, options.force); #if CONFIG_INTERNAL == 1 flashrom_flag_set(fill_flash, FLASHROM_FLAG_FORCE_BOARDMISMATCH, force_boardmismatch); #endif - flashrom_flag_set(fill_flash, FLASHROM_FLAG_VERIFY_AFTER_WRITE, !dont_verify_it); - flashrom_flag_set(fill_flash, FLASHROM_FLAG_VERIFY_WHOLE_CHIP, !dont_verify_all); + flashrom_flag_set(fill_flash, FLASHROM_FLAG_VERIFY_AFTER_WRITE, !options.dont_verify_it); + flashrom_flag_set(fill_flash, FLASHROM_FLAG_VERIFY_WHOLE_CHIP, !options.dont_verify_all); /* FIXME: We should issue an unconditional chip reset here. This can be * done once we have a .reset function in struct flashchip. * Give the chip time to settle. */ programmer_delay(fill_flash, 100000); - if (read_it) - ret = do_read(fill_flash, filename); - else if (extract_it) + if (options.read_it) + ret = do_read(fill_flash, options.filename); + else if (options.extract_it) ret = do_extract(fill_flash); - else if (erase_it) { + else if (options.erase_it) { ret = flashrom_flash_erase(fill_flash); /* * FIXME: Do we really want the scary warning if erase failed? @@ -1215,13 +1250,13 @@ int main(int argc, char *argv[]) if (ret) emergency_help_message(); } - else if (write_it) - ret = do_write(fill_flash, filename, referencefile); - else if (verify_it) - ret = do_verify(fill_flash, filename); + else if (options.write_it) + ret = do_write(fill_flash, options.filename, options.referencefile); + else if (options.verify_it) + ret = do_verify(fill_flash, options.filename); out_release: - flashrom_layout_release(layout); + flashrom_layout_release(options.layout); out_shutdown: flashrom_programmer_shutdown(NULL); out: @@ -1230,17 +1265,7 @@ out: free(flashes[i].chip); } - cleanup_include_args(&include_args); - free(filename); - free(fmapfile); - free(referencefile); - free(layoutfile); - free(pparam); - free(wp_region); - /* clean up global variables */ - free((char *)chip_to_probe); /* Silence! Freeing is not modifying contents. */ - chip_to_probe = NULL; - free(logfile); + free_options(&options); ret |= close_logfile(); return ret; } -- cgit v1.2.3