summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/opk.c165
-rw-r--r--src/ustar.c117
-rw-r--r--src/ustar.h53
3 files changed, 126 insertions, 209 deletions
diff --git a/src/opk.c b/src/opk.c
index a6cafce..7bf5870 100644
--- a/src/opk.c
+++ b/src/opk.c
@@ -28,18 +28,24 @@
#include "opk.h"
#include "ustar.h"
+struct _opkg_opk_opk_seek_name {
+ const char *name;
+ int found;
+ struct _opkg_opk_opk_seek_name *next;
+};
+
struct opkg_opk_opk {
- struct opkg_opk_ustar_seek_name *print_control;
- int list_data;
- FILE *file;
- char file_buffer[8192];
- struct opkg_opk_gzip *outer_gzip;
- struct opkg_opk_ustar *outer_ustar;
- char *version_buffer;
- size_t version_size;
- struct opkg_opk_gzip *inner_gzip;
- struct opkg_opk_ustar *inner_ustar;
- int previously_printed;
+ struct _opkg_opk_opk_seek_name *print_control;
+ int list_data;
+ FILE *file;
+ char file_buffer[8192];
+ struct opkg_opk_gzip *outer_gzip;
+ struct opkg_opk_ustar *outer_ustar;
+ char *version_buffer;
+ size_t version_size;
+ struct opkg_opk_gzip *inner_gzip;
+ struct opkg_opk_ustar *inner_ustar;
+ int previously_printed;
};
struct opkg_opk_opk *
@@ -59,10 +65,28 @@ opkg_opk_opk_init(void)
return opk;
}
+static int
+_opkg_opk_opk_add_seek_name(struct _opkg_opk_opk_seek_name **names,
+ const char *name)
+{
+ struct _opkg_opk_opk_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 = *names;
+
+ *names = seek_name;
+ return OPKG_OPK_OK;
+}
+
int
opkg_opk_opk_print_control(struct opkg_opk_opk *opk, const char *name)
{
- return opkg_opk_ustar_add_seek_name(&opk->print_control, name);
+ return _opkg_opk_opk_add_seek_name(&opk->print_control, name);
}
int
@@ -90,25 +114,8 @@ _opkg_opk_opk_file_read(void *user_data, char **buffer, size_t *size)
}
static int
-_opkg_opk_opk_init_inner(struct opkg_opk_opk *opk, const char *member)
+_opkg_opk_opk_init_inner(struct opkg_opk_opk *opk)
{
- int ret;
-
- /* Finish reading previous inner archive, if any. */
- while ((ret = opkg_opk_ustar_read(opk->outer_ustar, NULL, NULL)) ==
- OPKG_OPK_OK);
- if (ret == OPKG_OPK_ERROR) {
- fputs(_("Error: Failed to read archive\n"), stderr);
- return OPKG_OPK_ERROR;
- }
-
- /* Find requested inner archive. */
- 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;
- }
-
/* Initialize inner gzip decompressor. */
opk->inner_gzip = opkg_opk_gzip_init_read(
(opkg_opk_gzip_read_func *) &opkg_opk_ustar_read,
@@ -137,6 +144,61 @@ _opkg_opk_opk_free_inner(struct opkg_opk_opk *opk)
}
static int
+_opkg_opk_opk_seek(struct opkg_opk_ustar *ustar,
+ struct _opkg_opk_opk_seek_name *names)
+{
+ struct opkg_opk_ustar_member *member;
+ int found;
+ int found_all;
+ struct _opkg_opk_opk_seek_name *seek_name;
+
+ for (;;) {
+ /* Get next header record. */
+ if (opkg_opk_ustar_list(ustar, &member) != OPKG_OPK_OK) {
+ return OPKG_OPK_ERROR; /* Error or end (not found) */
+ }
+
+ /* Check each requested name. */
+ 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(member->name, seek_name->name) == 0) {
+ if (found == 0) {
+ seek_name->found = 1;
+ found = 1;
+ continue;
+ }
+ }
+ if (member->name[0] == '.' && member->name[1] == '/' &&
+ strcmp(member->name + 2,
+ seek_name->name) == 0)
+ {
+ if (found == 0) {
+ seek_name->found = 1;
+ found = 1;
+ continue;
+ }
+ }
+ found_all = 0;
+ }
+ free(member);
+ if (found == 1) {
+ if (found_all == 1) {
+ /* All requested members found */
+ return OPKG_OPK_END;
+ }
+ return OPKG_OPK_OK; /* Member found, but more remain */
+ }
+ }
+
+ return OPKG_OPK_ERROR; /* Member not found */
+}
+
+static int
_opkg_opk_opk_read_control(struct opkg_opk_opk *opk)
{
char *buffer;
@@ -149,11 +211,11 @@ _opkg_opk_opk_read_control(struct opkg_opk_opk *opk)
return OPKG_OPK_OK;
}
- if (_opkg_opk_opk_init_inner(opk, "control.tar.gz") != OPKG_OPK_OK) {
+ if (_opkg_opk_opk_init_inner(opk) != OPKG_OPK_OK) {
return OPKG_OPK_ERROR;
}
- while ((ret_seek = opkg_opk_ustar_seek(opk->inner_ustar,
+ while ((ret_seek = _opkg_opk_opk_seek(opk->inner_ustar,
opk->print_control)) != OPKG_OPK_ERROR)
{
if (opk->previously_printed == 1) {
@@ -219,7 +281,7 @@ _opkg_opk_opk_list_members(struct opkg_opk_opk *opk)
puts("");
}
- if (_opkg_opk_opk_init_inner(opk, "data.tar.gz") != OPKG_OPK_OK) {
+ if (_opkg_opk_opk_init_inner(opk) != OPKG_OPK_OK) {
return OPKG_OPK_ERROR;
}
@@ -311,7 +373,8 @@ _opkg_opk_opk_list_members(struct opkg_opk_opk *opk)
int
opkg_opk_opk_read(struct opkg_opk_opk *opk, const char *file_name)
{
- int ret;
+ int ret;
+ struct opkg_opk_ustar_member *member;
ret = OPKG_OPK_OK;
@@ -342,13 +405,15 @@ opkg_opk_opk_read(struct opkg_opk_opk *opk, const char *file_name)
}
/* Check package version. */
- if (opkg_opk_ustar_seek_one(opk->outer_ustar, "debian-binary") !=
- OPKG_OPK_OK) {
+ if (opkg_opk_ustar_list(opk->outer_ustar, &member) != OPKG_OPK_OK ||
+ strcmp(member->name, "debian-binary") != 0) {
+ free(member);
fputs(_("Error: Failed to find \"debian-binary\" in archive\n"),
stderr);
ret = OPKG_OPK_ERROR;
goto out3;
}
+ free(member);
if (opkg_opk_ustar_read(opk->outer_ustar,
&opk->version_buffer, &opk->version_size) !=
OPKG_OPK_OK) {
@@ -364,11 +429,29 @@ opkg_opk_opk_read(struct opkg_opk_opk *opk, const char *file_name)
goto out3;
}
- /* Perform the configured read actions. */
+ /* Read control archive. */
+ if (opkg_opk_ustar_list(opk->outer_ustar, &member) != OPKG_OPK_OK ||
+ strcmp(member->name, "control.tar.gz") != 0) {
+ free(member);
+ fputs(_("Error: Failed to find \"control.tar.gz\" in archive\n")
+ , stderr);
+ return OPKG_OPK_ERROR;
+ }
+ free(member);
if (_opkg_opk_opk_read_control(opk) != OPKG_OPK_OK) {
ret = OPKG_OPK_ERROR;
goto out3;
}
+
+ /* Read data archive. */
+ if (opkg_opk_ustar_list(opk->outer_ustar, &member) != OPKG_OPK_OK ||
+ strcmp(member->name, "data.tar.gz") != 0) {
+ free(member);
+ fputs(_("Error: Failed to find \"data.tar.gz\" in archive\n"),
+ stderr);
+ return OPKG_OPK_ERROR;
+ }
+ free(member);
if (_opkg_opk_opk_list_members(opk) != OPKG_OPK_OK) {
ret = OPKG_OPK_ERROR;
goto out3;
@@ -387,8 +470,12 @@ opkg_opk_opk_read(struct opkg_opk_opk *opk, const char *file_name)
void
opkg_opk_opk_free(struct opkg_opk_opk *opk)
{
- if (opk->print_control != NULL) {
- opkg_opk_ustar_free_seek_names(opk->print_control);
+ struct _opkg_opk_opk_seek_name *name;
+
+ while (opk->print_control != NULL) {
+ name = opk->print_control;
+ opk->print_control = opk->print_control->next;
+ free(name);
}
free(opk);
}
diff --git a/src/ustar.c b/src/ustar.c
index 1bc8261..1a2858b 100644
--- a/src/ustar.c
+++ b/src/ustar.c
@@ -54,12 +54,6 @@ 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)
{
@@ -236,117 +230,6 @@ opkg_opk_ustar_list(struct opkg_opk_ustar *ustar,
}
int
-opkg_opk_ustar_add_seek_name(struct opkg_opk_ustar_seek_name **names,
- const char *name)
-{
- 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 = *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)
-{
- char name[OPKG_OPK_USTAR_NAME_SIZE];
- int found;
- int found_all;
- struct opkg_opk_ustar_seek_name *seek_name;
-
- for (;;) {
- /* Get next header record. */
- if (_opkg_opk_ustar_next(ustar) != OPKG_OPK_OK) {
- return OPKG_OPK_ERROR; /* Error or end (not found) */
- }
-
- /* Prepare name (with prefix if any) for check. */
- if (ustar->header.prefix[0] != '\0') {
- sprintf(name, "%s/%s", ustar->header.prefix,
- ustar->header.name);
- } else {
- /* Use memcpy() because ustar->header.name may not be
- * NUL-terminated. */
- memcpy(name, ustar->header.name,
- sizeof(ustar->header.name));
- name[sizeof(ustar->header.name)] = '\0';
- }
-
- /* Check each requested name. */
- 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 */
- }
- }
-
- return OPKG_OPK_ERROR; /* Member not found */
-}
-
-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 220603a..802412a 100644
--- a/src/ustar.h
+++ b/src/ustar.h
@@ -71,59 +71,6 @@ opkg_opk_ustar_list(struct opkg_opk_ustar *ustar,
struct opkg_opk_ustar_member **member);
/*
- * Adds a name to a list of names to find with opkg_opk_ustar_seek(). List is
- * dynamically allocated; free with opkg_opk_ustar_free_seek_names().
- * Parameters:
- * - 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 **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.
- * Returns:
- * - OPKG_OPK_OK if a member matching one of the requested names is found but
- * more names remain to be found.
- * - OPKG_OPK_END if a member matching one of the requested names is found and
- * no more names remain to be 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(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.