Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ int qdl_zip_open(const char *filename, struct qdl_zip **__qdl_zip)
qdl_zip = calloc(1, sizeof(*qdl_zip));
if (!qdl_zip) {
zip_close(zip);
*__qdl_zip = NULL;
return -1;
}

Expand Down
51 changes: 47 additions & 4 deletions flashmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,55 @@ static int flashmap_get_programmers(struct qdl_zip *zip, struct json_value *layo
const char *filename;
char path[PATH_MAX];
int count;
const char *spec;
char *tail;
unsigned long id;
int i;

programmers = json_get_child(layout, "programmer");
count = json_count_children(programmers);
if (count != 1) {
ux_err("flashmap: single programmer expected, found %d\n", count);
if (count < 1) {
ux_err("flashmap: programmer list is missing or empty\n");
return -1;
}

if (count > 1) {
for (i = 0; i < count; i++) {
spec = json_get_element_string(programmers, i);
if (!spec) {
ux_err("flashmap: parse error when decoding programmer\n");
return -1;
}

id = strtoul(spec, &tail, 0);

if (tail == spec || *tail != ':' || tail[1] == '\0') {
ux_err("flashmap: invalid programmer entry \"%s\"\n", spec);
return -1;
}

if (id == 0 || id >= MAPPING_SZ) {
ux_err("flashmap: invalid programmer id for \"%s\"\n", spec);
return -1;
}

filename = tail + 1;

if (incdir) {
snprintf(path, PATH_MAX, "%s/%s", incdir, filename);
if (access(path, F_OK))
snprintf(path, PATH_MAX, "%s", filename);
} else {
snprintf(path, PATH_MAX, "%s", filename);
}

if (load_sahara_image(zip, path, images + id))
return -1;
}

return 0;
}

filename = json_get_element_string(programmers, 0);
if (!filename) {
ux_err("flashmap: parse error when decoding programmer\n");
Expand All @@ -50,7 +91,7 @@ static int flashmap_get_programmers(struct qdl_zip *zip, struct json_value *layo

ux_debug("flashmap: selected programmer: %s\n", path);

return load_sahara_image(zip, path, &images[SAHARA_ID_EHOSTDL_IMG]);
return load_programmers(path, images, zip);
}

static int flashmap_load_xml(struct list_head *ops, struct qdl_zip *zip, const char *filename,
Expand Down Expand Up @@ -283,8 +324,10 @@ int flashmap_load(struct list_head *ops, const char *filename, struct sahara_ima
layout = json_get_element_object(obj, 0);

ret = flashmap_get_programmers(zip, layout, images, zip ? NULL : incdir);
if (ret)
if (ret) {
sahara_images_free(images, MAPPING_SZ);
goto out_free_json;
}

programmable = json_get_child(layout, "programmable");
if (!programmable) {
Expand Down
48 changes: 29 additions & 19 deletions qdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,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, struct qdl_zip *zip)
{
char image_path_full[PATH_MAX];
const char *image_path;
Expand Down Expand Up @@ -294,6 +294,8 @@ static int decode_sahara_config(struct sahara_image *blob, struct sahara_image *
blob_name_buf = strdup(blob->name);
base_path = dirname(blob_name_buf);
base_path_len = strlen(base_path);
if (base_path_len == 1 && base_path[0] == '.')
base_path_len = 0;

root = xmlDocGetRootElement(doc);
if (xmlStrcmp(root->name, (xmlChar *)"sahara_config")) {
Expand Down Expand Up @@ -328,7 +330,7 @@ static int decode_sahara_config(struct sahara_image *blob, struct sahara_image *

image_path_len = strlen(image_path);

if (path_is_absolute(image_path)) {
if (path_is_absolute(image_path) || base_path_len == 0) {
if (image_path_len + 1 > PATH_MAX) {
free((void *)image_path);
goto err_free_doc;
Expand All @@ -347,7 +349,7 @@ static int decode_sahara_config(struct sahara_image *blob, struct sahara_image *

free((void *)image_path);

ret = load_sahara_image(NULL, image_path_full, &images[image_id]);
ret = load_sahara_image(zip, image_path_full, &images[image_id]);
if (ret < 0)
goto err_free_doc;
}
Expand Down Expand Up @@ -385,15 +387,12 @@ static int decode_sahara_config(struct sahara_image *blob, struct sahara_image *
* second case, each comma-separated entry will be split on ':' and the given
* <filename> will be assigned to the @image entry indicated by the given <id>.
*
* Memory is not allocated for the various strings, instead @s will be modified
* by the tokenizer and pointers to the individual parts will be stored in the
* @images array.
*
* Returns: 0 on success, -1 otherwise.
*/
static int decode_programmer(char *s, struct sahara_image *images)
int load_programmers(const char *s, struct sahara_image *images, struct qdl_zip *zip)
{
struct sahara_image archive;
char *copy;
char *filename;
char *save1;
char *pair;
Expand All @@ -403,35 +402,46 @@ static int decode_programmer(char *s, struct sahara_image *images)

strtoul(s, &tail, 0);
if (tail != s && tail[0] == ':') {
for (pair = strtok_r(s, ",", &save1); pair; pair = strtok_r(NULL, ",", &save1)) {
copy = strdup(s);
if (!copy) {
ux_err("internal error: unable to allocate memory for argument\n");
return -1;
}

for (pair = strtok_r(copy, ",", &save1); pair; pair = strtok_r(NULL, ",", &save1)) {
id = strtoul(pair, &tail, 0);
if (tail == pair) {
if (tail == pair || *tail != ':' || tail[1] == '\0') {
ux_err("invalid programmer specifier\n");
free(copy);
return -1;
}

if (id == 0 || id >= MAPPING_SZ) {
ux_err("invalid image id \"%s\"\n", pair);
free(copy);
return -1;
}

filename = &tail[1];
ret = load_sahara_image(NULL, filename, &images[id]);
if (ret < 0)
ret = load_sahara_image(zip, filename, &images[id]);
if (ret < 0) {
free(copy);
return -1;
}
}
free(copy);
} else {
ret = load_sahara_image(NULL, s, &archive);
ret = load_sahara_image(zip, s, &archive);
if (ret < 0)
return -1;

ret = decode_programmer_archive(&archive, images);
if (ret < 0 || ret == 1)
return ret;
if (ret != 0)
return (ret == 1) ? 0 : -1;

ret = decode_sahara_config(&archive, images);
if (ret < 0 || ret == 1)
return ret;
ret = decode_sahara_config(&archive, images, zip);
if (ret != 0)
return (ret == 1) ? 0 : -1;

images[SAHARA_ID_EHOSTDL_IMG] = archive;
}
Expand Down Expand Up @@ -829,7 +839,7 @@ static int qdl_flash(int argc, char **argv)
* "flash" subcommand. Handling of "flash" happens in the loop below.
*/
if (strcmp(argv[optind], "flash")) {
ret = decode_programmer(argv[optind++], sahara_images);
ret = load_programmers(argv[optind++], sahara_images, NULL);
if (ret < 0)
goto out_cleanup;
}
Expand Down
1 change: 1 addition & 0 deletions qdl.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ struct qdl_device_desc {

struct qdl_device_desc *usb_list(unsigned int *devices_found);

int load_programmers(const char *s, struct sahara_image *images, struct qdl_zip *zip);
int firehose_run(struct qdl_device *qdl, struct list_head *ops);
int firehose_provision(struct qdl_device *qdl, bool skip_reset);
int firehose_read_buf(struct qdl_device *qdl, struct firehose_op *read_op, void *out_buf, size_t out_size);
Expand Down