diff options
Diffstat (limited to 'src/ustar.c')
-rw-r--r-- | src/ustar.c | 74 |
1 files changed, 61 insertions, 13 deletions
diff --git a/src/ustar.c b/src/ustar.c index cf1134a..2a386f0 100644 --- a/src/ustar.c +++ b/src/ustar.c @@ -17,7 +17,6 @@ * along with opkg-opk. If not, see <http://www.gnu.org/licenses/>. */ -#include <stdarg.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -227,13 +226,38 @@ opkg_opk_ustar_list(struct opkg_opk_ustar *ustar, } int -opkg_opk_ustar_seek(struct opkg_opk_ustar *ustar, int num_keys, ...) +opkg_opk_ustar_add_seek_name(struct opkg_opk_ustar_seek_name **head, + struct opkg_opk_ustar_seek_name **tail, const char *name) { - static struct _opkg_opk_ustar_header header; - static char name[OPKG_OPK_USTAR_NAME_MAX_LEN]; - va_list ap; - int key; - const char *member; + struct opkg_opk_ustar_seek_name *seek_name; + + seek_name = malloc(sizeof(*seek_name)); + if (seek_name == NULL) { + return OPKG_OPK_ERROR; + } + 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; + + return OPKG_OPK_OK; +} + +int +opkg_opk_ustar_seek(struct opkg_opk_ustar *ustar, + struct opkg_opk_ustar_seek_name *names) +{ + static struct _opkg_opk_ustar_header header; + static char name[OPKG_OPK_USTAR_NAME_MAX_LEN]; + int found; + int found_all; + struct opkg_opk_ustar_seek_name *seek_name; for (;;) { /* Get next header record. */ @@ -251,14 +275,38 @@ opkg_opk_ustar_seek(struct opkg_opk_ustar *ustar, int num_keys, ...) } /* Check each requested name. */ - va_start(ap, num_keys); - for (key = 0; key < num_keys; ++key) { - member = va_arg(ap, const char *); - if (strcmp(name, member) == 0) { - return OPKG_OPK_OK; /* Member found */ + found = 0; + found_all = 1; + for (seek_name = names; seek_name != NULL; + seek_name = seek_name->next) { + if (seek_name->found == 1) { + continue; /* Previously found this member */ + } + if (strcmp(name, seek_name->name) == 0) { + if (found == 0) { + seek_name->found = 1; + found = 1; + continue; + } + } + if (name[0] == '.' && name[1] == '/' && + strcmp(name + 2, seek_name->name) == 0) + { + if (found == 0) { + seek_name->found = 1; + found = 1; + continue; + } + } + found_all = 0; + } + if (found == 1) { + if (found_all == 1) { + /* All requested members found */ + return OPKG_OPK_END; } + return OPKG_OPK_OK; /* Member found, but more remain */ } - va_end(ap); /* Seek through data records until next header record. */ while (ustar->data_size_remaining > 0) { |