Skip to content

Commit 91d401b

Browse files
committed
Add support for cpio and multi-elf in zip archives.
Teach flashmaps how to contain cpio and multi-elf programmers so that it's on parity with the command-line options available to qdl. Signed-off-by: Nicholas Clark <nicholas.clark.github@gm.com>
1 parent aebce73 commit 91d401b

4 files changed

Lines changed: 78 additions & 23 deletions

File tree

file.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ int qdl_zip_open(const char *filename, struct qdl_zip **__qdl_zip)
183183
qdl_zip = calloc(1, sizeof(*qdl_zip));
184184
if (!qdl_zip) {
185185
zip_close(zip);
186+
*__qdl_zip = NULL;
186187
return -1;
187188
}
188189

flashmap.c

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,55 @@ static int flashmap_get_programmers(struct qdl_zip *zip, struct json_value *layo
2626
const char *filename;
2727
char path[PATH_MAX];
2828
int count;
29+
const char *spec;
30+
char *tail;
31+
unsigned long id;
32+
int i;
2933

3034
programmers = json_get_child(layout, "programmer");
3135
count = json_count_children(programmers);
32-
if (count != 1) {
33-
ux_err("flashmap: single programmer expected, found %d\n", count);
36+
if (count < 1) {
37+
ux_err("flashmap: programmer list is missing or empty\n");
3438
return -1;
3539
}
3640

41+
if (count > 1) {
42+
for (i = 0; i < count; i++) {
43+
spec = json_get_element_string(programmers, i);
44+
if (!spec) {
45+
ux_err("flashmap: parse error when decoding programmer\n");
46+
return -1;
47+
}
48+
49+
id = strtoul(spec, &tail, 0);
50+
51+
if (tail == spec || *tail != ':' || tail[1] == '\0') {
52+
ux_err("flashmap: invalid programmer entry \"%s\"\n", spec);
53+
return -1;
54+
}
55+
56+
if (id == 0 || id >= MAPPING_SZ) {
57+
ux_err("flashmap: invalid programmer id for \"%s\"\n", spec);
58+
return -1;
59+
}
60+
61+
filename = tail + 1;
62+
63+
if (incdir) {
64+
snprintf(path, PATH_MAX, "%s/%s", incdir, filename);
65+
if (access(path, F_OK))
66+
snprintf(path, PATH_MAX, "%s", filename);
67+
} else {
68+
snprintf(path, PATH_MAX, "%s", filename);
69+
}
70+
71+
if (load_sahara_image(zip, path, images + id))
72+
return -1;
73+
}
74+
75+
return 0;
76+
}
77+
3778
filename = json_get_element_string(programmers, 0);
3879
if (!filename) {
3980
ux_err("flashmap: parse error when decoding programmer\n");
@@ -50,7 +91,7 @@ static int flashmap_get_programmers(struct qdl_zip *zip, struct json_value *layo
5091

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

53-
return load_sahara_image(zip, path, &images[SAHARA_ID_EHOSTDL_IMG]);
94+
return load_programmers(path, images, zip);
5495
}
5596

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

285326
ret = flashmap_get_programmers(zip, layout, images, zip ? NULL : incdir);
286-
if (ret)
327+
if (ret) {
328+
sahara_images_free(images, MAPPING_SZ);
287329
goto out_free_json;
330+
}
288331

289332
programmable = json_get_child(layout, "programmable");
290333
if (!programmable) {

qdl.c

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ static int decode_programmer_archive(struct sahara_image *blob, struct sahara_im
266266
*
267267
* Returns: 0 if no archive was found, 1 if archive was decoded, -1 on error
268268
*/
269-
static int decode_sahara_config(struct sahara_image *blob, struct sahara_image *images)
269+
static int decode_sahara_config(struct sahara_image *blob, struct sahara_image *images, struct qdl_zip *zip)
270270
{
271271
char image_path_full[PATH_MAX];
272272
const char *image_path;
@@ -294,6 +294,8 @@ static int decode_sahara_config(struct sahara_image *blob, struct sahara_image *
294294
blob_name_buf = strdup(blob->name);
295295
base_path = dirname(blob_name_buf);
296296
base_path_len = strlen(base_path);
297+
if (base_path_len == 1 && base_path[0] == '.')
298+
base_path_len = 0;
297299

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

329331
image_path_len = strlen(image_path);
330332

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

348350
free((void *)image_path);
349351

350-
ret = load_sahara_image(NULL, image_path_full, &images[image_id]);
352+
ret = load_sahara_image(zip, image_path_full, &images[image_id]);
351353
if (ret < 0)
352354
goto err_free_doc;
353355
}
@@ -385,15 +387,12 @@ static int decode_sahara_config(struct sahara_image *blob, struct sahara_image *
385387
* second case, each comma-separated entry will be split on ':' and the given
386388
* <filename> will be assigned to the @image entry indicated by the given <id>.
387389
*
388-
* Memory is not allocated for the various strings, instead @s will be modified
389-
* by the tokenizer and pointers to the individual parts will be stored in the
390-
* @images array.
391-
*
392390
* Returns: 0 on success, -1 otherwise.
393391
*/
394-
static int decode_programmer(char *s, struct sahara_image *images)
392+
int load_programmers(const char *s, struct sahara_image *images, struct qdl_zip *zip)
395393
{
396394
struct sahara_image archive;
395+
char *copy;
397396
char *filename;
398397
char *save1;
399398
char *pair;
@@ -403,35 +402,46 @@ static int decode_programmer(char *s, struct sahara_image *images)
403402

404403
strtoul(s, &tail, 0);
405404
if (tail != s && tail[0] == ':') {
406-
for (pair = strtok_r(s, ",", &save1); pair; pair = strtok_r(NULL, ",", &save1)) {
405+
copy = strdup(s);
406+
if (!copy) {
407+
ux_err("internal error: unable to allocate memory for argument\n");
408+
return -1;
409+
}
410+
411+
for (pair = strtok_r(copy, ",", &save1); pair; pair = strtok_r(NULL, ",", &save1)) {
407412
id = strtoul(pair, &tail, 0);
408-
if (tail == pair) {
413+
if (tail == pair || *tail != ':' || tail[1] == '\0') {
409414
ux_err("invalid programmer specifier\n");
415+
free(copy);
410416
return -1;
411417
}
412418

413419
if (id == 0 || id >= MAPPING_SZ) {
414420
ux_err("invalid image id \"%s\"\n", pair);
421+
free(copy);
415422
return -1;
416423
}
417424

418425
filename = &tail[1];
419-
ret = load_sahara_image(NULL, filename, &images[id]);
420-
if (ret < 0)
426+
ret = load_sahara_image(zip, filename, &images[id]);
427+
if (ret < 0) {
428+
free(copy);
421429
return -1;
430+
}
422431
}
432+
free(copy);
423433
} else {
424-
ret = load_sahara_image(NULL, s, &archive);
434+
ret = load_sahara_image(zip, s, &archive);
425435
if (ret < 0)
426436
return -1;
427437

428438
ret = decode_programmer_archive(&archive, images);
429-
if (ret < 0 || ret == 1)
430-
return ret;
439+
if (ret != 0)
440+
return (ret == 1) ? 0 : -1;
431441

432-
ret = decode_sahara_config(&archive, images);
433-
if (ret < 0 || ret == 1)
434-
return ret;
442+
ret = decode_sahara_config(&archive, images, zip);
443+
if (ret != 0)
444+
return (ret == 1) ? 0 : -1;
435445

436446
images[SAHARA_ID_EHOSTDL_IMG] = archive;
437447
}
@@ -823,7 +833,7 @@ static int qdl_flash(int argc, char **argv)
823833
* "flash" subcommand. Handling of "flash" happens in the loop below.
824834
*/
825835
if (strcmp(argv[optind], "flash")) {
826-
ret = decode_programmer(argv[optind++], sahara_images);
836+
ret = load_programmers(argv[optind++], sahara_images, NULL);
827837
if (ret < 0)
828838
goto out_cleanup;
829839
}

qdl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ struct qdl_device_desc {
108108

109109
struct qdl_device_desc *usb_list(unsigned int *devices_found);
110110

111+
int load_programmers(const char *s, struct sahara_image *images, struct qdl_zip *zip);
111112
int firehose_run(struct qdl_device *qdl, struct list_head *ops);
112113
int firehose_provision(struct qdl_device *qdl);
113114
int firehose_read_buf(struct qdl_device *qdl, struct firehose_op *read_op, void *out_buf, size_t out_size);

0 commit comments

Comments
 (0)