diff --git a/program.c b/program.c index e11f5ab8..edf35989 100644 --- a/program.c +++ b/program.c @@ -148,13 +148,15 @@ static int program_load_sparse(struct program *program, int fd) return 0; } -static int load_program_tag(xmlNode *node, bool is_nand, bool allow_missing, const char *incdir) +static int load_program_tag(xmlNode *node, bool is_nand, bool allow_missing, struct list_head *incdirs) { + struct incdir_entry *incdir; struct program *program; char tmp[PATH_MAX]; int errors = 0; int ret; int fd = -1; + bool found = false; program = calloc(1, sizeof(struct program)); @@ -184,11 +186,14 @@ static int load_program_tag(xmlNode *node, bool is_nand, bool allow_missing, con } if (program->filename) { - if (incdir) { - snprintf(tmp, PATH_MAX, "%s/%s", incdir, program->filename); + list_for_each_entry(incdir, incdirs, node) { + snprintf(tmp, PATH_MAX, "%s/%s", incdir->path, program->filename); if (access(tmp, F_OK) != -1) { free((void *)program->filename); program->filename = strdup(tmp); + if (found) + ux_info("multiple files found for %s, using %s\n", program->filename, tmp); + found = true; } } @@ -227,7 +232,7 @@ static int load_program_tag(xmlNode *node, bool is_nand, bool allow_missing, con return 0; } -int program_load(const char *program_file, bool is_nand, bool allow_missing, const char *incdir) +int program_load(const char *program_file, bool is_nand, bool allow_missing, struct list_head *incdirs) { xmlNode *node; xmlNode *root; @@ -248,7 +253,7 @@ int program_load(const char *program_file, bool is_nand, bool allow_missing, con if (!xmlStrcmp(node->name, (xmlChar *)"erase")) errors = load_erase_tag(node, is_nand); else if (!xmlStrcmp(node->name, (xmlChar *)"program")) - errors = load_program_tag(node, is_nand, allow_missing, incdir); + errors = load_program_tag(node, is_nand, allow_missing, incdirs); else { ux_err("unrecognized tag \"%s\" in program-type file \"%s\"\n", node->name, program_file); errors = -EINVAL; diff --git a/program.h b/program.h index c86d12e2..f3a2ac27 100644 --- a/program.h +++ b/program.h @@ -33,7 +33,7 @@ struct program { struct qdl_device; -int program_load(const char *program_file, bool is_nand, bool allow_missing, const char *incdir); +int program_load(const char *program_file, bool is_nand, bool allow_missing, struct list_head *incdirs); int program_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct program *program, int fd)); int erase_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct program *program)); int program_find_bootable_partition(bool *multiple_found); diff --git a/qdl.c b/qdl.c index 0f7cdc66..a3485e7d 100644 --- a/qdl.c +++ b/qdl.c @@ -557,11 +557,20 @@ static int qdl_ramdump(int argc, char **argv) return ret; } +static void free_incdirs(struct list_head *incdirs) +{ + struct incdir_entry *incdir, *tmp; + + list_for_each_entry_safe(incdir, tmp, incdirs, node) + free(incdir); +} + static int qdl_flash(int argc, char **argv) { enum qdl_storage_type storage_type = QDL_STORAGE_UFS; struct sahara_image sahara_images[MAPPING_SZ] = {}; - char *incdir = NULL; + struct list_head incdirs = LIST_INIT(incdirs); + struct incdir_entry *incdir; char *serial = NULL; const char *vip_generate_dir = NULL; const char *vip_table_path = NULL; @@ -614,7 +623,9 @@ static int qdl_flash(int argc, char **argv) allow_missing = true; break; case 'i': - incdir = optarg; + incdir = calloc(1, sizeof(*incdir)); + incdir->path = optarg; + list_add(&incdirs, &incdir->node); break; case 'l': qdl_finalize_provisioning = true; @@ -698,7 +709,7 @@ static int qdl_flash(int argc, char **argv) errx(1, "patch_load %s failed", argv[optind]); break; case QDL_FILE_PROGRAM: - ret = program_load(argv[optind], storage_type == QDL_STORAGE_NAND, allow_missing, incdir); + ret = program_load(argv[optind], storage_type == QDL_STORAGE_NAND, allow_missing, &incdirs); if (ret < 0) errx(1, "program_load %s failed", argv[optind]); @@ -707,7 +718,7 @@ static int qdl_flash(int argc, char **argv) " changes. Allow explicitly with --allow-fusing parameter"); break; case QDL_FILE_READ: - ret = read_op_load(argv[optind], incdir); + ret = read_op_load(argv[optind], &incdirs); if (ret < 0) errx(1, "read_op_load %s failed", argv[optind]); break; @@ -770,6 +781,7 @@ static int qdl_flash(int argc, char **argv) free_programs(); free_patches(); + free_incdirs(&incdirs); if (qdl) { if (qdl->vip_data.state != VIP_DISABLED) diff --git a/qdl.h b/qdl.h index 6b515381..c86cce0a 100644 --- a/qdl.h +++ b/qdl.h @@ -41,6 +41,11 @@ (__typeof__(p))(((uintptr_t)(p) + _mask) & ~_mask); \ }) +struct incdir_entry { + const char *path; + struct list_head node; +}; + #define MAPPING_SZ 64 #define SAHARA_ID_EHOSTDL_IMG 13 diff --git a/read.c b/read.c index 697102e4..1190cf7c 100644 --- a/read.c +++ b/read.c @@ -19,14 +19,16 @@ static struct list_head read_ops = LIST_INIT(read_ops); -int read_op_load(const char *read_op_file, const char *incdir) +int read_op_load(const char *read_op_file, struct list_head *incdirs) { + struct incdir_entry *incdir; struct read_op *read_op; xmlNode *node; xmlNode *root; xmlDoc *doc; int errors; char tmp[PATH_MAX]; + bool found = false; doc = xmlReadFile(read_op_file, NULL, 0); if (!doc) { @@ -61,10 +63,18 @@ int read_op_load(const char *read_op_file, const char *incdir) continue; } - if (incdir) { - snprintf(tmp, PATH_MAX, "%s/%s", incdir, read_op->filename); - if (access(tmp, F_OK) != -1) - read_op->filename = strdup(tmp); + if (read_op->filename) { + list_for_each_entry(incdir, incdirs, node) { + snprintf(tmp, PATH_MAX, "%s/%s", incdir->path, read_op->filename); + if (access(tmp, F_OK) != -1) { + free((void *)read_op->filename); + read_op->filename = strdup(tmp); + if (found) + ux_info("multiple files found for %s, using %s\n", + read_op->filename, tmp); + found = true; + } + } } list_add(&read_ops, &read_op->node); diff --git a/read.h b/read.h index 164555ee..60f0799a 100644 --- a/read.h +++ b/read.h @@ -19,7 +19,7 @@ struct read_op { struct list_head node; }; -int read_op_load(const char *read_op_file, const char *incdir); +int read_op_load(const char *read_op_file, struct list_head *incdirs); int read_op_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct read_op *read_op, int fd)); int read_cmd_add(const char *source, const char *filename);