diff --git a/firehose.c b/firehose.c index cf0b6af..515de8f 100644 --- a/firehose.c +++ b/firehose.c @@ -103,6 +103,8 @@ static void firehose_response_log(xmlNode *node) value = xmlGetProp(node, (xmlChar*)"value"); printf("LOG: %s\n", value); + + xmlFree(value); } static int firehose_read(struct qdl_device *qdl, int wait, int (*response_parser)(xmlNode *node)) @@ -153,8 +155,7 @@ static int firehose_read(struct qdl_device *qdl, int wait, int (*response_parser for (node = nodes; node; node = node->next) { if (xmlStrcmp(node->name, (xmlChar*)"log") == 0) { firehose_response_log(node); - } - else if (xmlStrcmp(node->name, (xmlChar*)"response") == 0) { + } else if (xmlStrcmp(node->name, (xmlChar*)"response") == 0) { if (!response_parser) fprintf(stderr, "received response with no parser\n"); else @@ -195,9 +196,14 @@ static int firehose_write(struct qdl_device *qdl, xmlDoc *doc) static int firehose_nop_parser(xmlNode *node) { xmlChar *value; + int ret; value = xmlGetProp(node, (xmlChar*)"value"); - return !!xmlStrcmp(value, (xmlChar*)"ACK"); + ret = !!xmlStrcmp(value, (xmlChar*)"ACK"); + + xmlFree(value); + + return ret; } static size_t max_payload_size = 1048576; @@ -215,9 +221,14 @@ static int firehose_configure_response_parser(xmlNode *node) size_t max_size; value = xmlGetProp(node, (xmlChar*)"value"); + if (!value) + return -EINVAL; + payload = xmlGetProp(node, (xmlChar*)"MaxPayloadSizeToTargetInBytes"); - if (!value || !payload) + if (!payload) { + xmlFree(value); return -EINVAL; + } max_size = strtoul((char*)payload, NULL, 10); @@ -226,6 +237,7 @@ static int firehose_configure_response_parser(xmlNode *node) * a larger payload size */ if (!xmlStrcmp(value, (xmlChar*)"ACK")) { + xmlFree(payload); payload = xmlGetProp(node, (xmlChar*)"MaxPayloadSizeToTargetInBytesSupported"); if (!payload) return -EINVAL; @@ -233,6 +245,9 @@ static int firehose_configure_response_parser(xmlNode *node) max_size = strtoul((char*)payload, NULL, 10); } + xmlFree(payload); + xmlFree(value); + return max_size; } @@ -380,8 +395,7 @@ static int firehose_program(struct qdl_device *qdl, struct program *program, int sparse_cb_info.total_write_count = sparse_file_len(s_file, false); num_sectors = (sparse_cb_info.total_write_count + program->sector_size - 1) / program->sector_size; - } - else { + } else { num_sectors = (sb.st_size + program->sector_size - 1) / program->sector_size; } @@ -432,8 +446,7 @@ static int firehose_program(struct qdl_device *qdl, struct program *program, int ret = sparse_stream_callback(s_file, false, firehose_program_sparse, &sparse_cb_info); sparse_file_destroy(s_file); - } - else { + } else { left = num_sectors; while (left > 0) { chunk_size = MIN(max_payload_size / program->sector_size, left); @@ -473,6 +486,7 @@ static int firehose_program(struct qdl_device *qdl, struct program *program, int out: xmlFreeDoc(doc); + free(buf); return ret; } diff --git a/patch.c b/patch.c index 445bc99..eefda5d 100644 --- a/patch.c +++ b/patch.c @@ -111,3 +111,28 @@ int patch_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, s return 0; } + +void patch_unload(void) +{ + struct patch *patch; + + patches_last = NULL; + + for (patch = patches; patch; patch = patch->next) { + if (patch->filename) + xmlFree(patch->filename); + if (patch->start_sector) + xmlFree(patch->start_sector); + if (patch->value) + xmlFree(patch->value); + if (patch->what) + xmlFree(patch->what); + + if (patches_last) + free(patches_last); + + patches_last = patch; + } + + free(patches_last); +} \ No newline at end of file diff --git a/patch.h b/patch.h index 108ec2f..ea0acdd 100644 --- a/patch.h +++ b/patch.h @@ -19,6 +19,7 @@ struct patch { }; int patch_load(const char *patch_file); +void patch_unload(void); int patch_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct patch *patch)); #endif diff --git a/program.c b/program.c index 9704f61..9ed2bd9 100644 --- a/program.c +++ b/program.c @@ -172,3 +172,26 @@ int program_find_bootable_partition(void) return part; } + +void program_unload(void) +{ + struct program *program; + + programes_last = NULL; + + for (program = programes; program; program = program->next) { + if (program->filename) + xmlFree(program->filename); + if (program->start_sector) + xmlFree(program->start_sector); + if (program->label) + xmlFree(program->label); + + if (programes_last) + free(programes_last); + + programes_last = program; + } + + free(programes_last); +} \ No newline at end of file diff --git a/program.h b/program.h index be81853..8aee68b 100644 --- a/program.h +++ b/program.h @@ -19,6 +19,7 @@ struct program { }; int program_load(const char *program_file); +void program_unload(void); int program_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct program *program, int fd), const char *incdir); int program_find_bootable_partition(void); diff --git a/qdl.c b/qdl.c index c8ebf7b..9f91bc3 100644 --- a/qdl.c +++ b/qdl.c @@ -265,17 +265,23 @@ static int usb_open(struct qdl_device *qdl) dev = udev_device_new_from_syspath(udev, path); dev_node = udev_device_get_devnode(dev); - if (!dev_node) + if (!dev_node) { + udev_device_unref(dev); continue; + } fd = open(dev_node, O_RDWR); - if (fd < 0) + if (fd < 0) { + udev_device_unref(dev); continue; + } ret = parse_usb_desc(fd, qdl, &intf); if (!ret) goto found; + udev_device_unref(dev); + close(fd); } @@ -297,19 +303,25 @@ static int usb_open(struct qdl_device *qdl) dev = udev_monitor_receive_device(mon); dev_node = udev_device_get_devnode(dev); - if (!dev_node) + if (!dev_node) { + udev_device_unref(dev); continue; + } printf("%s\n", dev_node); fd = open(dev_node, O_RDWR); - if (fd < 0) + if (fd < 0) { + udev_device_unref(dev); continue; + } ret = parse_usb_desc(fd, qdl, &intf); if (!ret) goto found; + udev_device_unref(dev); + close(fd); } @@ -323,6 +335,7 @@ static int usb_open(struct qdl_device *qdl) udev_enumerate_unref(enumerate); udev_monitor_unref(mon); udev_unref(udev); + udev_device_unref(dev); cmd.ifno = intf; cmd.ioctl_code = USBDEVFS_DISCONNECT; @@ -464,6 +477,8 @@ int main(int argc, char **argv) prog_mbn = argv[optind++]; + xmlInitParser(); + do { type = detect_type(argv[optind]); if (type < 0 || type == QDL_FILE_UNKNOWN) @@ -503,5 +518,10 @@ int main(int argc, char **argv) if (ret < 0) return 1; + ufs_unload(); + program_unload(); + patch_unload(); + xmlCleanupParser(); + return 0; } diff --git a/sahara.c b/sahara.c index 1e0234a..627fd02 100644 --- a/sahara.c +++ b/sahara.c @@ -196,8 +196,8 @@ static int sahara_done(struct qdl_device *qdl, struct sahara_pkt *pkt) int sahara_run(struct qdl_device *qdl, char *prog_mbn) { - struct sahara_pkt *pkt; - char buf[4096]; + struct sahara_pkt *pkt = NULL; + char buf[4096] = {0}; char tmp[32]; bool done = false; int n; diff --git a/ufs.c b/ufs.c index a65a9fb..2fe1336 100644 --- a/ufs.c +++ b/ufs.c @@ -305,3 +305,22 @@ int ufs_provisioning_execute(struct qdl_device *qdl, } return apply_ufs_epilogue(qdl, ufs_epilogue_p, true); } + +void ufs_unload(void) +{ + struct ufs_body *body; + + ufs_body_last = NULL; + + for (body = ufs_body_p; body; body = body->next) { + if (body->desc) + xmlFree(body->desc); + + if (ufs_body_last) + free(ufs_body_last); + + ufs_body_last = body; + } + + free(ufs_body_last); +} \ No newline at end of file diff --git a/util.c b/util.c index 0d3721d..843ad74 100644 --- a/util.c +++ b/util.c @@ -84,28 +84,35 @@ 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) { xmlChar *value; + unsigned int ret; - value = xmlGetProp(node, (xmlChar*)attr); + value = xmlGetProp(node, (xmlChar *) attr); if (!value) { (*errors)++; return 0; } - return (unsigned int) strtoul((char*)value, NULL, 10); + ret = (unsigned int) strtoul((const char*)value, NULL, 10); + + xmlFree(value); + + return ret; } xmlChar *attr_as_string(xmlNode *node, const char *attr, int *errors) { xmlChar *value; - value = xmlGetProp(node, (xmlChar*)attr); + value = xmlGetProp(node, (xmlChar *) attr); if (!value) { (*errors)++; return NULL; } - if (value[0] == '\0') + if (value[0] == '\0') { + xmlFree(value); return NULL; + } - return strdup((char*)value); + return value; }