From c6d1b81ae1c238a0c489b428f003256f3c0584ec Mon Sep 17 00:00:00 2001 From: Nicholas Hunn Date: Mon, 20 Apr 2026 15:14:31 +1000 Subject: [PATCH] misc: changed file loading so that all files are searched for in the include directory This changes the file path search logic everywhere so that it looks for every file in the include dir This changes someone calling it like this qdl -i foo foo/prog_firehose_ddr.elf foo/rawprogram*.xml foo/patch*.xml to qdl -i foo prog_firehose_ddr.elf rawprogram*.xml patch*.xml which makes running scripts from external directories easier Signed-off-by: Nicholas Hunn --- ks.c | 2 +- patch.c | 9 +++++++-- patch.h | 2 +- program.c | 15 +++++++-------- program.h | 2 +- qdl.c | 34 +++++++++++++++++++++------------- qdl.h | 3 ++- read.c | 7 ++++++- ufs.c | 7 ++++++- ufs.h | 2 +- util.c | 29 +++++++++++++++++++++++++++-- 11 files changed, 80 insertions(+), 32 deletions(-) diff --git a/ks.c b/ks.c index f9d72d8a..f3acb3d8 100644 --- a/ks.c +++ b/ks.c @@ -103,7 +103,7 @@ int main(int argc, char **argv) return 1; } filename = &optarg[colon - optarg + 1]; - ret = load_sahara_image(filename, &mappings[file_id]); + ret = load_sahara_image(filename, &mappings[file_id], NULL); if (ret < 0) return 1; diff --git a/patch.c b/patch.c index 5c21c7a0..23f7006a 100644 --- a/patch.c +++ b/patch.c @@ -16,7 +16,7 @@ static struct list_head patches = LIST_INIT(patches); static bool patches_loaded; -int patch_load(const char *patch_file) +int patch_load(const char *patch_file, const char *incdir) { struct patch *patch; xmlNode *node; @@ -24,11 +24,16 @@ int patch_load(const char *patch_file) xmlDoc *doc; int errors; - doc = xmlReadFile(patch_file, NULL, 0); + char *patch_file_resolved = strdup(patch_file); + + resolve_path(&patch_file_resolved, incdir); + doc = xmlReadFile(patch_file_resolved, NULL, 0); if (!doc) { ux_err("failed to parse patch-type file \"%s\"\n", patch_file); + free(patch_file_resolved); return -EINVAL; } + free(patch_file_resolved); root = xmlDocGetRootElement(doc); for (node = root->children; node ; node = node->next) { diff --git a/patch.h b/patch.h index 30f5df43..d14d56f0 100644 --- a/patch.h +++ b/patch.h @@ -19,7 +19,7 @@ struct patch { struct list_head node; }; -int patch_load(const char *patch_file); +int patch_load(const char *patch_file, const char *incdir); int patch_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct patch *patch)); void free_patches(void); diff --git a/program.c b/program.c index c4dcaf4d..a0d64839 100644 --- a/program.c +++ b/program.c @@ -185,13 +185,7 @@ 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); - if (access(tmp, F_OK) != -1) { - free((void *)program->filename); - program->filename = strdup(tmp); - } - } + resolve_path(&program->filename, incdir); fd = open(program->filename, O_RDONLY | O_BINARY); if (fd < 0) { @@ -234,12 +228,17 @@ int program_load(const char *program_file, bool is_nand, bool allow_missing, con xmlNode *root; xmlDoc *doc; int errors = 0; + char *program_file_resolved = strdup(program_file); + + resolve_path(&program_file_resolved, incdir); - doc = xmlReadFile(program_file, NULL, 0); + doc = xmlReadFile(program_file_resolved, NULL, 0); if (!doc) { ux_err("failed to parse program-type file \"%s\"\n", program_file); + free(program_file_resolved); return -EINVAL; } + free(program_file_resolved); root = xmlDocGetRootElement(doc); for (node = root->children; node ; node = node->next) { diff --git a/program.h b/program.h index 5583d0d3..65ad31ee 100644 --- a/program.h +++ b/program.h @@ -11,7 +11,7 @@ struct program { unsigned int pages_per_block; unsigned int sector_size; unsigned int file_offset; - const char *filename; + char *filename; const char *label; unsigned int num_sectors; int partition; diff --git a/qdl.c b/qdl.c index 94301b94..2d1154aa 100644 --- a/qdl.c +++ b/qdl.c @@ -43,7 +43,7 @@ enum { bool qdl_debug; -static int detect_type(const char *verb) +static int detect_type(const char *verb, const char *incdir) { xmlNode *root; xmlDoc *doc; @@ -57,16 +57,22 @@ static int detect_type(const char *verb) if (!strcmp(verb, "erase")) return QDL_CMD_ERASE; - if (access(verb, F_OK)) { + char *filename = strdup(verb); + resolve_path(&filename, incdir); + + if (access(filename, F_OK)) { ux_err("%s is not a verb and not a XML file\n", verb); + free(filename); return -EINVAL; } - doc = xmlReadFile(verb, NULL, 0); + doc = xmlReadFile(filename, NULL, 0); if (!doc) { ux_err("failed to parse XML file \"%s\"\n", verb); + free(filename); return -EINVAL; } + free(filename); root = xmlDocGetRootElement(doc); if (!xmlStrcmp(root->name, (xmlChar *)"patches")) { @@ -251,6 +257,7 @@ static int decode_programmer_archive(struct sahara_image *blob, struct sahara_im * decode_sahara_config() - Attempt to decode a Sahara config XML document * @blob: Loaded image to be decoded as Sahara config * @images: List of Sahara images, with @images[0] populated + * @incdir: include directory to be searched for the files specified in the Sahara config * * The single blob provided in @images[0] might be a XML blob containing * a sahara_config document with definitions of the various Sahara images that @@ -261,7 +268,7 @@ static int decode_programmer_archive(struct sahara_image *blob, struct sahara_im * * Returns: 0 if no archive was found, 1 if archive was decoded, -1 on error */ -static int decode_sahara_config(struct sahara_image *blob, struct sahara_image *images) +static int decode_sahara_config(struct sahara_image *blob, struct sahara_image *images, const char *incdir) { char image_path_full[PATH_MAX]; const char *image_path; @@ -342,7 +349,7 @@ static int decode_sahara_config(struct sahara_image *blob, struct sahara_image * free((void *)image_path); - ret = load_sahara_image(image_path_full, &images[image_id]); + ret = load_sahara_image(image_path_full, &images[image_id], incdir); if (ret < 0) goto err_free_doc; } @@ -370,6 +377,7 @@ static int decode_sahara_config(struct sahara_image *blob, struct sahara_image * * decode_programmer() - decodes the programmer specifier * @s: programmer specifier, from the user * @images: array of images to populate + * @incdir: include directory to be searched for the files specified in @s * * This parses the programmer specifier @s, which can either be a single * filename, or a comma-separated series of : entries. @@ -386,7 +394,7 @@ static int decode_sahara_config(struct sahara_image *blob, struct sahara_image * * * Returns: 0 on success, -1 otherwise. */ -static int decode_programmer(char *s, struct sahara_image *images) +static int decode_programmer(char *s, struct sahara_image *images, const char *incdir) { struct sahara_image archive; char *filename; @@ -411,12 +419,12 @@ static int decode_programmer(char *s, struct sahara_image *images) } filename = &tail[1]; - ret = load_sahara_image(filename, &images[id]); + ret = load_sahara_image(filename, &images[id], incdir); if (ret < 0) return -1; } } else { - ret = load_sahara_image(s, &archive); + ret = load_sahara_image(s, &archive, incdir); if (ret < 0) return -1; @@ -424,7 +432,7 @@ static int decode_programmer(char *s, struct sahara_image *images) if (ret < 0 || ret == 1) return ret; - ret = decode_sahara_config(&archive, images); + ret = decode_sahara_config(&archive, images, incdir); if (ret < 0 || ret == 1) return ret; @@ -695,18 +703,18 @@ static int qdl_flash(int argc, char **argv) if (qdl_debug) print_version(); - ret = decode_programmer(argv[optind++], sahara_images); + ret = decode_programmer(argv[optind++], sahara_images, incdir); if (ret < 0) goto out_cleanup; do { - type = detect_type(argv[optind]); + type = detect_type(argv[optind], incdir); if (type < 0 || type == QDL_FILE_UNKNOWN) errx(1, "failed to detect file type of %s\n", argv[optind]); switch (type) { case QDL_FILE_PATCH: - ret = patch_load(argv[optind]); + ret = patch_load(argv[optind], incdir); if (ret < 0) errx(1, "patch_load %s failed", argv[optind]); break; @@ -728,7 +736,7 @@ static int qdl_flash(int argc, char **argv) if (storage_type != QDL_STORAGE_UFS) errx(1, "attempting to load provisioning config when storage isn't \"ufs\""); - ret = ufs_load(argv[optind], qdl_finalize_provisioning); + ret = ufs_load(argv[optind], qdl_finalize_provisioning, incdir); if (ret < 0) errx(1, "ufs_load %s failed", argv[optind]); break; diff --git a/qdl.h b/qdl.h index 6b515381..c1f4e3b4 100644 --- a/qdl.h +++ b/qdl.h @@ -112,12 +112,13 @@ int firehose_read_buf(struct qdl_device *qdl, struct read_op *read_op, void *out int sahara_run(struct qdl_device *qdl, const struct sahara_image *images, const char *ramdump_path, const char *ramdump_filter); -int load_sahara_image(const char *filename, struct sahara_image *image); +int load_sahara_image(const char *filename, struct sahara_image *image, const char *incdir); void sahara_images_free(struct sahara_image *images, size_t count); void print_hex_dump(const char *prefix, const void *buf, size_t len); unsigned int attr_as_unsigned(xmlNode *node, const char *attr, int *errors); const char *attr_as_string(xmlNode *node, const char *attr, int *errors); bool attr_as_bool(xmlNode *node, const char *attr, int *errors); +void resolve_path(char **filename, const char *incdir); void ux_init(void); void ux_err(const char *fmt, ...); diff --git a/read.c b/read.c index 697102e4..22333e17 100644 --- a/read.c +++ b/read.c @@ -27,12 +27,17 @@ int read_op_load(const char *read_op_file, const char *incdir) xmlDoc *doc; int errors; char tmp[PATH_MAX]; + char *read_op_file_resolved = strdup(read_op_file); - doc = xmlReadFile(read_op_file, NULL, 0); + resolve_path(&read_op_file_resolved, incdir); + + doc = xmlReadFile(read_op_file_resolved, NULL, 0); if (!doc) { ux_err("failed to parse read-type file \"%s\"\n", read_op_file); + free(read_op_file_resolved); return -EINVAL; } + free(read_op_file_resolved); root = xmlDocGetRootElement(doc); for (node = root->children; node ; node = node->next) { diff --git a/ufs.c b/ufs.c index b7cada48..67a9e17f 100644 --- a/ufs.c +++ b/ufs.c @@ -116,7 +116,7 @@ struct ufs_epilogue *ufs_parse_epilogue(xmlNode *node) return result; } -int ufs_load(const char *ufs_file, bool finalize_provisioning) +int ufs_load(const char *ufs_file, bool finalize_provisioning, const char *incdir) { xmlNode *node; xmlNode *root; @@ -130,12 +130,17 @@ int ufs_load(const char *ufs_file, bool finalize_provisioning) ufs_file); return -EEXIST; } + char *ufs_file_resolved = strdup(ufs_file); + + resolve_path(&ufs_file_resolved, incdir); doc = xmlReadFile(ufs_file, NULL, 0); if (!doc) { ux_err("failed to parse ufs-type file \"%s\"\n", ufs_file); + free(ufs_file_resolved); return -EINVAL; } + free(ufs_file_resolved); root = xmlDocGetRootElement(doc); diff --git a/ufs.h b/ufs.h index 5c174496..ad1b3b6b 100644 --- a/ufs.h +++ b/ufs.h @@ -47,7 +47,7 @@ struct ufs_epilogue { bool commit; }; -int ufs_load(const char *ufs_file, bool finalize_provisioning); +int ufs_load(const char *ufs_file, bool finalize_provisioning, const char *incdir); int ufs_provisioning_execute(struct qdl_device *qdl, int (*apply_ufs_common)(struct qdl_device *qdl, struct ufs_common *ufs), int (*apply_ufs_body)(struct qdl_device *qdl, struct ufs_body *ufs), diff --git a/util.c b/util.c index c8194016..8a8dc83d 100644 --- a/util.c +++ b/util.c @@ -211,26 +211,49 @@ int parse_storage_address(const char *address, int *physical_partition, return 0; } +/** + * @brief Resolves a given filename and determines if it's found in the include dir + * + * @filename: file to be found + * @incdir: include directory to be searched for the file + */ +void resolve_path(char **filename, const char *incdir) +{ + char tmp[PATH_MAX]; + if (incdir) { + snprintf(tmp, PATH_MAX, "%s/%s", incdir, *filename); + if (access(tmp, F_OK) != -1) { + free((void *)*filename); + *filename = strdup(tmp); + } + } +} + /** * load_sahara_image() - Load the content of the given file into the image * @filename: file to be loaded * @image: Sahara image object to be populated + * @incdir: include directory to be searched for the file * * Read the content of the given @filename into the given @image, update the * @image->len, and then populate the @image->name for debugging purposes. * * Returns: 0 on success, -1 on error */ -int load_sahara_image(const char *filename, struct sahara_image *image) +int load_sahara_image(const char *filename, struct sahara_image *image, const char *incdir) { ssize_t n; off_t len; void *ptr; int fd; + char *filename_resolved = strdup(filename); + + resolve_path(&filename_resolved, incdir); - fd = open(filename, O_RDONLY | O_BINARY); + fd = open(filename_resolved, O_RDONLY | O_BINARY); if (fd < 0) { ux_err("failed to read \"%s\"\n", filename); + free(filename_resolved); return -1; } @@ -254,6 +277,7 @@ int load_sahara_image(const char *filename, struct sahara_image *image) goto err_close; } + free(filename_resolved); close(fd); image->name = strdup(filename); @@ -263,6 +287,7 @@ int load_sahara_image(const char *filename, struct sahara_image *image) return 0; err_close: + free(filename_resolved); close(fd); return -1; }