From 712f2d241d3447ebc7b97abd591afe9737ac7fa8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 23 Nov 2007 12:17:26 +0100 Subject: [PATCH] b43-fwcutter: unsupported file support This patch makes fwcutter support only those files we know are working and marks the other one unsupported. To allow developers to still work with such files, an --unsupported command line option is added that allows one to extract firmware from such unsupported files. Some code restructuring was necessary to support the --unsupported flag with other flags in any order. Also, because this is a significant change, bump the version number. Signed-off-by: Johannes Berg Signed-off-by: Michael Buesch --- fwcutter/Makefile | 2 +- fwcutter/fwcutter.c | 39 ++++++++++++++++++++++++++++++--------- fwcutter/fwcutter.h | 14 +++++++++++--- fwcutter/fwcutter_list.h | 2 +- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/fwcutter/Makefile b/fwcutter/Makefile index 2ddd8bd..29d9b5e 100644 --- a/fwcutter/Makefile +++ b/fwcutter/Makefile @@ -1,4 +1,4 @@ -VERSION = 008 +VERSION = 009 CC ?= cc PREFIX ?= /usr/local diff --git a/fwcutter/fwcutter.c b/fwcutter/fwcutter.c index fef9099..ae1c63a 100644 --- a/fwcutter/fwcutter.c +++ b/fwcutter/fwcutter.c @@ -59,6 +59,12 @@ static struct cmdline_args cmdargs; +/* check whether file will be listed/extracted from */ +static int file_ok(const struct file *f) +{ + return !(f->flags & FW_FLAG_UNSUPPORTED) || cmdargs.unsupported; +} + /* Convert a CPU-endian 16bit integer to Big-Endian */ static be16_t to_be16(uint16_t v) { @@ -398,7 +404,7 @@ static void extract_or_identify(FILE *f, const struct extract *extract, exit(255); } - if (!cmdargs.identify_only) + if (cmdargs.mode == FWCM_EXTRACT) write_file(extract->name, buf, data_length, &hdr, flags); free(buf); @@ -449,10 +455,10 @@ static void print_supported_files(void) "\n\n"); /* print for legacy driver first */ for (i = 0; i < FILES; i++) - if (!(files[i].flags & FW_FLAG_V4)) + if (file_ok(&files[i]) && !(files[i].flags & FW_FLAG_V4)) print_file(&files[i]); for (i = 0; i < FILES; i++) - if (files[i].flags & FW_FLAG_V4) + if (file_ok(&files[i]) && files[i].flags & FW_FLAG_V4) print_file(&files[i]); printf("\n"); } @@ -478,7 +484,8 @@ static const struct file *find_file(FILE *fd) signature[12], signature[13], signature[14], signature[15]); for (i = 0; i < FILES; ++i) { - if (strcasecmp(md5sig, files[i].md5) == 0) { + if (file_ok(&files[i]) && + strcasecmp(md5sig, files[i].md5) == 0) { printf("This file is recognised as:\n"); printf(" filename : %s\n", files[i].name); printf(" version : %s\n", files[i].ucode_version); @@ -497,6 +504,8 @@ static void print_usage(int argc, char *argv[]) { print_banner(); printf("\nUsage: %s [OPTION] [driver.sys]\n", argv[0]); + printf(" --unsupported " + "Allow working on extractable but unsupported drivers\n"); printf(" -l|--list " "List supported driver versions\n"); printf(" -i|--identify " @@ -584,8 +593,8 @@ static int parse_args(int argc, char *argv[]) for (i = 1; i < argc; i++) { res = cmp_arg(argv, &i, "--list", "-l", 0); if (res == ARG_MATCH) { - print_supported_files(); - return 1; + cmdargs.mode = FWCM_LIST; + continue; } else if (res == ARG_ERROR) goto out; @@ -604,7 +613,14 @@ static int parse_args(int argc, char *argv[]) res = cmp_arg(argv, &i, "--identify", "-i", 0); if (res == ARG_MATCH) { - cmdargs.identify_only = 1; + cmdargs.mode = FWCM_IDENTIFY; + continue; + } else if (res == ARG_ERROR) + goto out; + + res = cmp_arg(argv, &i, "--unsupported", NULL, 0); + if (res == ARG_MATCH) { + cmdargs.unsupported = 1; continue; } else if (res == ARG_ERROR) goto out; @@ -620,7 +636,7 @@ static int parse_args(int argc, char *argv[]) break; } - if (!cmdargs.infile) + if (!cmdargs.infile && cmdargs.mode != FWCM_LIST) goto out_usage; return 0; @@ -645,6 +661,11 @@ int main(int argc, char *argv[]) else if (err != 0) return err; + if (cmdargs.mode == FWCM_LIST) { + print_supported_files(); + return 0; + } + fd = fopen(cmdargs.infile, "rb"); if (!fd) { fprintf(stderr, "Cannot open input file %s\n", cmdargs.infile); @@ -664,7 +685,7 @@ int main(int argc, char *argv[]) extract = file->extract; while (extract->name) { printf("%s %s/%s.fw\n", - cmdargs.identify_only ? "Contains" : "Extracting", + cmdargs.mode == FWCM_IDENTIFY ? "Contains" : "Extracting", dir, extract->name); extract_or_identify(fd, extract, file->flags); extract++; diff --git a/fwcutter/fwcutter.h b/fwcutter/fwcutter.h index 2f23d81..2e47073 100644 --- a/fwcutter/fwcutter.h +++ b/fwcutter/fwcutter.h @@ -1,8 +1,9 @@ #ifndef _FWCUTTER_H_ #define _FWCUTTER_H_ -#define FW_FLAG_LE 0x01 /* little endian? convert */ -#define FW_FLAG_V4 0x02 /* b43 vs. b43legacy */ +#define FW_FLAG_LE 0x01 /* little endian? convert */ +#define FW_FLAG_V4 0x02 /* b43 vs. b43legacy */ +#define FW_FLAG_UNSUPPORTED 0x04 /* not supported/working */ #define fwcutter_stringify_1(x) #x #define fwcutter_stringify(x) fwcutter_stringify_1(x) @@ -20,10 +21,17 @@ typedef uint32_t be32_t; /* Big-endian 32bit */ #define ARG_NOMATCH 1 #define ARG_ERROR -1 +enum fwcutter_mode { + FWCM_EXTRACT = 0, /* default */ + FWCM_LIST, + FWCM_IDENTIFY, +}; + struct cmdline_args { const char *infile; const char *target_dir; - int identify_only; + enum fwcutter_mode mode; + int unsupported; }; struct insn { diff --git a/fwcutter/fwcutter_list.h b/fwcutter/fwcutter_list.h index c3631ce..bed370a 100644 --- a/fwcutter/fwcutter_list.h +++ b/fwcutter/fwcutter_list.h @@ -147,7 +147,7 @@ static const struct file files[] = .name = "wl_ap.o", .ucode_version = "410.2160", .md5 = "1e4763b4cb8cfbaae43e5c6d3d6b2ae7", - .flags = FW_FLAG_LE | FW_FLAG_V4, + .flags = FW_FLAG_LE | FW_FLAG_V4 | FW_FLAG_UNSUPPORTED, .extract = _1e4763b4cb8cfbaae43e5c6d3d6b2ae7, }, }; -- 2.31.1