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 <johannes@sipsolutions.net>
Signed-off-by: Michael Buesch <mb@bu3sch.de>
CC ?= cc
PREFIX ?= /usr/local
CC ?= cc
PREFIX ?= /usr/local
static struct cmdline_args cmdargs;
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)
{
/* Convert a CPU-endian 16bit integer to Big-Endian */
static be16_t to_be16(uint16_t v)
{
- if (!cmdargs.identify_only)
+ if (cmdargs.mode == FWCM_EXTRACT)
write_file(extract->name, buf, data_length, &hdr, flags);
free(buf);
write_file(extract->name, buf, data_length, &hdr, flags);
free(buf);
"<MD5 checksum>\n\n");
/* print for legacy driver first */
for (i = 0; i < FILES; i++)
"<MD5 checksum>\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++)
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");
}
print_file(&files[i]);
printf("\n");
}
signature[12], signature[13], signature[14], signature[15]);
for (i = 0; i < FILES; ++i) {
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);
printf("This file is recognised as:\n");
printf(" filename : %s\n", files[i].name);
printf(" version : %s\n", files[i].ucode_version);
{
print_banner();
printf("\nUsage: %s [OPTION] [driver.sys]\n", argv[0]);
{
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 "
printf(" -l|--list "
"List supported driver versions\n");
printf(" -i|--identify "
for (i = 1; i < argc; i++) {
res = cmp_arg(argv, &i, "--list", "-l", 0);
if (res == ARG_MATCH) {
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;
} else if (res == ARG_ERROR)
goto out;
res = cmp_arg(argv, &i, "--identify", "-i", 0);
if (res == ARG_MATCH) {
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;
continue;
} else if (res == ARG_ERROR)
goto out;
+ if (!cmdargs.infile && cmdargs.mode != FWCM_LIST)
goto out_usage;
return 0;
goto out_usage;
return 0;
else if (err != 0)
return err;
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);
fd = fopen(cmdargs.infile, "rb");
if (!fd) {
fprintf(stderr, "Cannot open input file %s\n", cmdargs.infile);
extract = file->extract;
while (extract->name) {
printf("%s %s/%s.fw\n",
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++;
dir, extract->name);
extract_or_identify(fd, extract, file->flags);
extract++;
#ifndef _FWCUTTER_H_
#define _FWCUTTER_H_
#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)
#define fwcutter_stringify_1(x) #x
#define fwcutter_stringify(x) fwcutter_stringify_1(x)
#define ARG_NOMATCH 1
#define ARG_ERROR -1
#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;
struct cmdline_args {
const char *infile;
const char *target_dir;
+ enum fwcutter_mode mode;
+ int unsupported;
.name = "wl_ap.o",
.ucode_version = "410.2160",
.md5 = "1e4763b4cb8cfbaae43e5c6d3d6b2ae7",
.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,
},
};
.extract = _1e4763b4cb8cfbaae43e5c6d3d6b2ae7,
},
};