From da0e44cd2b78d4c1d4439c23a842fa3952ebe893 Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Wed, 19 Apr 2023 11:06:57 -0400 Subject: ustar: Make seek names struct opaque Simplify main() a little and fix memory leak on success. --- (limited to 'src') diff --git a/src/main.c b/src/main.c index c3cea7c..7b18541 100644 --- a/src/main.c +++ b/src/main.c @@ -25,19 +25,16 @@ int main(int argc, char *argv[]) { - struct opkg_opk_ustar_seek_name *control_files_head; - struct opkg_opk_ustar_seek_name *control_files_tail; + struct opkg_opk_ustar_seek_name *control_files; struct opkg_opk_opk *opk; - control_files_head = control_files_tail = NULL; - if (opkg_opk_ustar_add_seek_name( - &control_files_head, &control_files_tail, - "control") != OPKG_OPK_OK) { + control_files = NULL; + if (opkg_opk_ustar_add_seek_name(&control_files, "control") != + OPKG_OPK_OK) { goto error0; } - if (opkg_opk_ustar_add_seek_name( - &control_files_head, &control_files_tail, - "md5sums") != OPKG_OPK_OK) { + if (opkg_opk_ustar_add_seek_name(&control_files, "md5sums") != + OPKG_OPK_OK) { goto error0; } @@ -51,7 +48,7 @@ main(int argc, char *argv[]) if (opkg_opk_opk_init_inner(opk, "control.tar.gz") != OPKG_OPK_OK) { goto error1; } - if (opkg_opk_opk_read_control(opk, control_files_head) != OPKG_OPK_OK) { + if (opkg_opk_opk_read_control(opk, control_files) != OPKG_OPK_OK) { goto error2; } opkg_opk_opk_free_inner(opk); @@ -66,6 +63,7 @@ main(int argc, char *argv[]) opkg_opk_opk_free_inner(opk); opkg_opk_opk_free_outer(opk); + opkg_opk_ustar_free_seek_names(control_files); return EXIT_SUCCESS; error2: @@ -73,10 +71,6 @@ main(int argc, char *argv[]) error1: opkg_opk_opk_free_outer(opk); error0: - while (control_files_head != NULL) { - control_files_tail = control_files_head; - control_files_head = control_files_head->next; - free(control_files_tail); - } + opkg_opk_ustar_free_seek_names(control_files); return EXIT_FAILURE; } diff --git a/src/opk.c b/src/opk.c index cdb3f58..45da6fd 100644 --- a/src/opk.c +++ b/src/opk.c @@ -59,8 +59,7 @@ _opkg_opk_opk_file_read(void *user_data, char **buffer, size_t *size) struct opkg_opk_opk * opkg_opk_opk_init_outer(const char *file_name) { - struct opkg_opk_opk *opk; - struct opkg_opk_ustar_seek_name seek_name; + struct opkg_opk_opk *opk; opk = malloc(sizeof(*opk)); if (opk == NULL) { @@ -90,11 +89,8 @@ opkg_opk_opk_init_outer(const char *file_name) } /* Check package version. */ - seek_name.name = "debian-binary"; - seek_name.found = 0; - seek_name.next = NULL; - if (opkg_opk_ustar_seek(opk->outer_ustar, &seek_name) == OPKG_OPK_ERROR) - { + if (opkg_opk_ustar_seek_one(opk->outer_ustar, "debian-binary") != + OPKG_OPK_OK) { fputs("Error: Failed to find \"debian-binary\" in archive\n", stderr); goto error3; @@ -129,8 +125,7 @@ opkg_opk_opk_init_outer(const char *file_name) int opkg_opk_opk_init_inner(struct opkg_opk_opk *opk, const char *member) { - int ret; - struct opkg_opk_ustar_seek_name seek_name; + int ret; /* Finish reading previous inner archive, if any. */ while ((ret = opkg_opk_ustar_read(opk->outer_ustar, NULL, NULL)) == @@ -141,11 +136,7 @@ opkg_opk_opk_init_inner(struct opkg_opk_opk *opk, const char *member) } /* Find requested inner archive. */ - seek_name.name = member; - seek_name.found = 0; - seek_name.next = NULL; - if (opkg_opk_ustar_seek(opk->outer_ustar, &seek_name) == OPKG_OPK_ERROR) - { + if (opkg_opk_ustar_seek_one(opk->outer_ustar, member) != OPKG_OPK_OK) { fprintf(stderr, "Error: Failed to find \"%s\" in archive\n", member); return OPKG_OPK_ERROR; diff --git a/src/ustar.c b/src/ustar.c index 9d95052..47e0dfa 100644 --- a/src/ustar.c +++ b/src/ustar.c @@ -53,6 +53,12 @@ struct opkg_opk_ustar { char read_record[OPKG_OPK_USTAR_RECORD_SIZE]; }; +struct opkg_opk_ustar_seek_name { + const char *name; + int found; + struct opkg_opk_ustar_seek_name *next; +}; + struct opkg_opk_ustar * opkg_opk_ustar_init(struct opkg_opk_gzip *gzip) { @@ -226,8 +232,8 @@ opkg_opk_ustar_list(struct opkg_opk_ustar *ustar, } int -opkg_opk_ustar_add_seek_name(struct opkg_opk_ustar_seek_name **head, - struct opkg_opk_ustar_seek_name **tail, const char *name) +opkg_opk_ustar_add_seek_name(struct opkg_opk_ustar_seek_name **names, + const char *name) { struct opkg_opk_ustar_seek_name *seek_name; @@ -237,18 +243,24 @@ opkg_opk_ustar_add_seek_name(struct opkg_opk_ustar_seek_name **head, } seek_name->name = name; seek_name->found = 0; - seek_name->next = NULL; - - if (*head == NULL) { - *head = seek_name; - } else { - (*tail)->next = seek_name; - } - *tail = seek_name; + seek_name->next = *names; + *names = seek_name; return OPKG_OPK_OK; } +void +opkg_opk_ustar_free_seek_names(struct opkg_opk_ustar_seek_name *names) +{ + struct opkg_opk_ustar_seek_name *name; + + while (names != NULL) { + name = names; + names = names->next; + free(name); + } +} + int opkg_opk_ustar_seek(struct opkg_opk_ustar *ustar, struct opkg_opk_ustar_seek_name *names) @@ -321,6 +333,22 @@ opkg_opk_ustar_seek(struct opkg_opk_ustar *ustar, } int +opkg_opk_ustar_seek_one(struct opkg_opk_ustar *ustar, const char *name) +{ + struct opkg_opk_ustar_seek_name seek_name; + + seek_name.name = name; + seek_name.found = 0; + seek_name.next = NULL; + + if (opkg_opk_ustar_seek(ustar, &seek_name) == OPKG_OPK_END) { + return OPKG_OPK_OK; + } else { + return OPKG_OPK_ERROR; + } +} + +int opkg_opk_ustar_read(struct opkg_opk_ustar *ustar, char **buffer, size_t *size) { if (ustar->data_size_remaining == 0) { diff --git a/src/ustar.h b/src/ustar.h index a5bb461..3495d38 100644 --- a/src/ustar.h +++ b/src/ustar.h @@ -41,11 +41,7 @@ struct opkg_opk_ustar_member { struct opkg_opk_ustar_member *next; }; -struct opkg_opk_ustar_seek_name { - const char *name; - int found; - struct opkg_opk_ustar_seek_name *next; -}; +struct opkg_opk_ustar_seek_name; /* * Allocates and initializes an archive structure. @@ -76,26 +72,32 @@ opkg_opk_ustar_list(struct opkg_opk_ustar *ustar, /* * Adds a name to a list of names to find with opkg_opk_ustar_seek(). List is - * dynamically allocated; free with free(). + * dynamically allocated; free with opkg_opk_ustar_free_seek_names(). * Parameters: - * - head: Address in which to store address of list head. - * - tail: Address in which to store address of list tail. - * - name: Name of member file to find. + * - names: Address in which to store address of list. + * - name: Name of member file to find. * Returns: * - OPKG_OPK_OK if the name was added to the list. * - OPKG_OPK_ERROR on memory exhaustion. */ int -opkg_opk_ustar_add_seek_name(struct opkg_opk_ustar_seek_name **head, - struct opkg_opk_ustar_seek_name **tail, const char *name); +opkg_opk_ustar_add_seek_name(struct opkg_opk_ustar_seek_name **names, + const char *name); + +/* + * Frees a list of names to find with opkg_opk_ustar_seek(). + * Parameters: + * - names: List of names. + */ +void +opkg_opk_ustar_free_seek_names(struct opkg_opk_ustar_seek_name *names); /* * Advances to a named member file. May be called multiple times until all * requested members are found. * Parameters: * - ustar: Archive structure. - * - names: Name(s) to find. Member "found" will be set to "1" on the first - * name found. + * - names: Name(s) to find. * Returns: * - OPKG_OPK_OK if a member matching one of the requested names is found but * more names remain to be found. @@ -109,6 +111,19 @@ opkg_opk_ustar_seek(struct opkg_opk_ustar *ustar, struct opkg_opk_ustar_seek_name *names); /* + * Advances to a named member file. + * Parameters: + * - ustar: Archive structure. + * - name: Name to find. + * Returns: + * - OPKG_OPK_OK if a member matching the requested name is found. + * - OPKG_OPK_ERROR if no matching member is found or on decompression error, an + * invalid header, or unsupported file type. + */ +int +opkg_opk_ustar_seek_one(struct opkg_opk_ustar *ustar, const char *name); + +/* * Reads up to a record (512 octets) of member file data at a time. * Parameters: * - ustar: Archive structure. -- cgit v0.9.1