diff --git a/firehose.c b/firehose.c index 59ea220..4198a09 100644 --- a/firehose.c +++ b/firehose.c @@ -106,20 +106,24 @@ static xmlNode *firehose_response_parse(const void *buf, size_t len, int *error) static int firehose_generic_parser(xmlNode *node, void *data) { xmlChar *value; + int ret = -EINVAL; value = xmlGetProp(node, (xmlChar*)"value"); + if (!value) + return -EINVAL; if (xmlStrcmp(node->name, (xmlChar*)"log") == 0) { printf("LOG: %s\n", value); - return -EAGAIN; + ret = -EAGAIN; + } else if (xmlStrcmp(value, (xmlChar*)"ACK") == 0) { + ret = FIREHOSE_ACK; + } else if (xmlStrcmp(value, (xmlChar*)"NAK") == 0) { + ret = FIREHOSE_NAK; } - if (xmlStrcmp(value, (xmlChar*)"ACK") == 0) - return FIREHOSE_ACK; - if (xmlStrcmp(value, (xmlChar*)"NAK") == 0) - return FIREHOSE_NAK; + xmlFree(value); - return -EINVAL; + return ret; } static int firehose_read(struct qdl_device *qdl, int timeout_ms, @@ -213,16 +217,23 @@ static int firehose_configure_response_parser(xmlNode *node, void *data) size_t max_size; value = xmlGetProp(node, (xmlChar*)"value"); + if (!value) + return -EINVAL; + if (xmlStrcmp(node->name, (xmlChar*)"log") == 0) { printf("LOG: %s\n", value); + xmlFree(value); return -EAGAIN; } payload = xmlGetProp(node, (xmlChar*)"MaxPayloadSizeToTargetInBytes"); - if (!value || !payload) + if (!payload) { + xmlFree(value); return -EINVAL; + } max_size = strtoul((char*)payload, NULL, 10); + xmlFree(payload); /* * When receiving an ACK the remote may indicate that we should attempt @@ -234,9 +245,11 @@ static int firehose_configure_response_parser(xmlNode *node, void *data) return -EINVAL; max_size = strtoul((char*)payload, NULL, 10); + xmlFree(payload); } *(size_t*)data = max_size; + xmlFree(value); return FIREHOSE_ACK; } @@ -437,6 +450,8 @@ static int firehose_program(struct qdl_device *qdl, struct program *program, int out: xmlFreeDoc(doc); + free(buf); + return ret == FIREHOSE_ACK ? 0 : -1; } diff --git a/patch.c b/patch.c index 953fd90..fef8a6c 100644 --- a/patch.c +++ b/patch.c @@ -113,3 +113,20 @@ int patch_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, s return 0; } + +void free_patches(void) +{ + struct patch *patch = patches; + struct patch *next; + + for (patch = patches; patch; patch = next) { + next = patch->next; + free((void *)patch->filename); + free((void *)patch->start_sector); + free((void *)patch->value); + free((void *)patch->what); + free(patch); + } + + patches = NULL; +} diff --git a/patch.h b/patch.h index baade86..1e8d17f 100644 --- a/patch.h +++ b/patch.h @@ -18,5 +18,6 @@ struct patch { int patch_load(const char *patch_file); int patch_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct patch *patch)); +void free_patches(void); #endif diff --git a/program.c b/program.c index 4096518..78e6ad6 100644 --- a/program.c +++ b/program.c @@ -250,3 +250,19 @@ int program_find_bootable_partition(void) return part; } + +void free_programs(void) +{ + struct program *program = programes; + struct program *next; + + for (program = programes; program; program = next) { + next = program->next; + free((void *)program->filename); + free((void *)program->label); + free((void *)program->start_sector); + free(program); + } + + programes = NULL; +} diff --git a/program.h b/program.h index f084f4c..337c082 100644 --- a/program.h +++ b/program.h @@ -26,5 +26,6 @@ int program_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, const char *incdir, bool allow_missing); int erase_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct program *program)); int program_find_bootable_partition(void); +void free_programs(void); #endif diff --git a/qdl.c b/qdl.c index 7c60eba..460fcb9 100644 --- a/qdl.c +++ b/qdl.c @@ -206,16 +206,21 @@ int main(int argc, char **argv) ret = qdl_open(&qdl, serial); if (ret) - return 1; + goto out_cleanup; qdl.mappings[0] = prog_mbn; ret = sahara_run(&qdl, qdl.mappings, true, NULL, NULL); if (ret < 0) - return 1; + goto out_cleanup; ret = firehose_run(&qdl, incdir, storage, allow_missing); if (ret < 0) - return 1; + goto out_cleanup; + +out_cleanup: + qdl_close(&qdl); + free_programs(); + free_patches(); - return 0; + return !!ret; } diff --git a/qdl.h b/qdl.h index f780f73..e14f847 100644 --- a/qdl.h +++ b/qdl.h @@ -27,6 +27,7 @@ struct qdl_device { }; int qdl_open(struct qdl_device *qdl, const char *serial); +void qdl_close(struct qdl_device *qdl); int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout); int qdl_write(struct qdl_device *qdl, const void *buf, size_t len); void qdl_set_out_chunk_size(struct qdl_device *qdl, long size); diff --git a/sahara.c b/sahara.c index 870fe3f..1e06303 100644 --- a/sahara.c +++ b/sahara.c @@ -100,12 +100,14 @@ struct sahara_pkt { uint32_t compatible; uint32_t max_len; uint32_t mode; + uint32_t reserved[6]; } hello_req; struct { uint32_t version; uint32_t compatible; uint32_t status; uint32_t mode; + uint32_t reserved[6]; } hello_resp; struct { uint32_t image; @@ -153,7 +155,7 @@ static void sahara_send_reset(struct qdl_device *qdl) static void sahara_hello(struct qdl_device *qdl, struct sahara_pkt *pkt) { - struct sahara_pkt resp; + struct sahara_pkt resp = {}; assert(pkt->length == SAHARA_HELLO_LENGTH); @@ -490,7 +492,8 @@ int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image, } } - close(ramdump_dir); + if (ramdump_dir >= 0) + close(ramdump_dir); return done ? 0 : -1; } diff --git a/usb.c b/usb.c index cda5e74..e97c722 100644 --- a/usb.c +++ b/usb.c @@ -157,10 +157,12 @@ static int qdl_try_open(libusb_device *dev, struct qdl_device *qdl, const char * qdl->out_chunk_size); } - return 1; + break; } - return 0; + libusb_free_config_descriptor(config); + + return !!qdl->usb_handle; } int qdl_open(struct qdl_device *qdl, const char *serial) @@ -208,6 +210,12 @@ int qdl_open(struct qdl_device *qdl, const char *serial) return -1; } +void qdl_close(struct qdl_device *qdl) +{ + libusb_close(qdl->usb_handle); + libusb_exit(NULL); +} + int qdl_read(struct qdl_device *qdl, void *buf, size_t len, unsigned int timeout) { int actual; diff --git a/util.c b/util.c index f8138ae..3474f13 100644 --- a/util.c +++ b/util.c @@ -84,6 +84,7 @@ void print_hex_dump(const char *prefix, const void *buf, size_t len) unsigned attr_as_unsigned(xmlNode *node, const char *attr, int *errors) { + unsigned int ret; xmlChar *value; value = xmlGetProp(node, (xmlChar*)attr); @@ -92,12 +93,15 @@ unsigned attr_as_unsigned(xmlNode *node, const char *attr, int *errors) return 0; } - return (unsigned int) strtoul((char*)value, NULL, 0); + ret = (unsigned int) strtoul((char*)value, NULL, 0); + xmlFree(value); + return ret; } const char *attr_as_string(xmlNode *node, const char *attr, int *errors) { xmlChar *value; + char *ret = NULL; value = xmlGetProp(node, (xmlChar*)attr); if (!value) { @@ -105,8 +109,9 @@ const char *attr_as_string(xmlNode *node, const char *attr, int *errors) return NULL; } - if (value[0] == '\0') - return NULL; + if (value[0] != '\0') + ret = strdup((char*)value); - return strdup((char*)value); + xmlFree(value); + return ret; }