summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McDermott <patrick.mcdermott@libiquity.com>2023-04-28 18:33:32 (EDT)
committer Patrick McDermott <patrick.mcdermott@libiquity.com>2023-04-28 18:33:32 (EDT)
commitf6a6b1c9dae1538b9fed7ab52b5ffd31cc411326 (patch)
treea429da20c41ee73852bc282ff942c718b5ff2d37
parent88dd37d6cc8bf40fd8766b41add0ae17a9cd7065 (diff)
opk: Manage control file list and listing flag
Instead of main() doing so.
-rw-r--r--src/main.c81
-rw-r--r--src/opk.c223
-rw-r--r--src/opk.h41
3 files changed, 184 insertions, 161 deletions
diff --git a/src/main.c b/src/main.c
index 5a20236..3338fcc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -27,7 +27,6 @@
#include "defs.h"
#include "i18n.h"
#include "opk.h"
-#include "ustar.h"
#ifdef HAVE_GETOPT_LONG
#include <getopt.h>
@@ -146,11 +145,9 @@ _help_tip(const char *program_name)
int
main(int argc, char *argv[])
{
- const char *program_name;
- struct opkg_opk_ustar_seek_name *control_files;
- int list_members;
- int opt;
- struct opkg_opk_opk *opk;
+ const char *program_name;
+ struct opkg_opk_opk *opk;
+ int opt;
#ifdef ENABLE_NLS
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
@@ -161,9 +158,14 @@ main(int argc, char *argv[])
setlocale(LC_ALL, "");
#endif
- program_name = argv[0];
- control_files = NULL;
- list_members = 0;
+ program_name = argv[0];
+
+ /* Initialize package. */
+ opk = opkg_opk_opk_init();
+ if (opk == NULL) {
+ return EXIT_FAILURE;
+ }
+
opterr = 0;
#ifdef HAVE_GETOPT_LONG
while ((opt = getopt_long(argc, argv, _optstring, _longopts, NULL))
@@ -173,21 +175,21 @@ main(int argc, char *argv[])
#endif
switch(opt) {
case 'I':
- if (opkg_opk_ustar_add_seek_name(&control_files,
- optarg) !=
- OPKG_OPK_OK) {
- goto error0;
+ if (opkg_opk_opk_print_control(opk, optarg)
+ != OPKG_OPK_OK) {
+ opkg_opk_opk_free(opk);
+ return EXIT_FAILURE;
}
break;
case 'f':
- if (opkg_opk_ustar_add_seek_name(&control_files,
- "control") !=
- OPKG_OPK_OK) {
- goto error0;
+ if (opkg_opk_opk_print_control(opk, "control")
+ != OPKG_OPK_OK) {
+ opkg_opk_opk_free(opk);
+ return EXIT_FAILURE;
}
break;
case 'c':
- list_members = 1;
+ opkg_opk_opk_list_data(opk);
break;
case 'h':
_help(program_name);
@@ -200,6 +202,7 @@ main(int argc, char *argv[])
"\"%c\"\n"),
program_name, optopt);
_help_tip(program_name);
+ opkg_opk_opk_free(opk);
return EXIT_FAILURE;
}
}
@@ -210,52 +213,22 @@ main(int argc, char *argv[])
fprintf(stderr, _("%s: Missing package file operand\n"),
program_name);
_help_tip(program_name);
+ opkg_opk_opk_free(opk);
return EXIT_FAILURE;
} else if (argc > 1) {
fprintf(stderr, _("%s: Too many package file operands\n"),
program_name);
_help_tip(program_name);
+ opkg_opk_opk_free(opk);
return EXIT_FAILURE;
}
- if (control_files == NULL && list_members == 0) {
- fprintf(stderr, _("%s: At least one of -I, -f, or -c must be "
- "given\n"), program_name);
- _help_tip(program_name);
- return EXIT_FAILURE;
- }
-
- /* Initialize outer archive. */
- opk = opkg_opk_opk_init(argv[0]);
- if (opk == NULL) {
- goto error0;
- }
- /* Read control file. */
- if (control_files != NULL) {
- if (opkg_opk_opk_read_control(opk, control_files) !=
- OPKG_OPK_OK) {
- goto error1;
- }
- }
-
- /* List data files. */
- if (list_members == 1) {
- if (opkg_opk_opk_list_members(opk) != OPKG_OPK_OK) {
- goto error1;
- }
+ /* Read package. */
+ if (opkg_opk_opk_read(opk, argv[0]) != OPKG_OPK_OK) {
+ opkg_opk_opk_free(opk);
+ return EXIT_FAILURE;
}
opkg_opk_opk_free(opk);
- if (control_files != NULL) {
- opkg_opk_ustar_free_seek_names(control_files);
- }
return EXIT_SUCCESS;
-
- error1:
- opkg_opk_opk_free(opk);
- error0:
- if (control_files != NULL) {
- opkg_opk_ustar_free_seek_names(control_files);
- }
- return EXIT_FAILURE;
}
diff --git a/src/opk.c b/src/opk.c
index 982ad3f..a6cafce 100644
--- a/src/opk.c
+++ b/src/opk.c
@@ -29,17 +29,49 @@
#include "ustar.h"
struct opkg_opk_opk {
- 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_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 *
+opkg_opk_opk_init(void)
+{
+ struct opkg_opk_opk *opk;
+
+ opk = malloc(sizeof(*opk));
+ if (opk == NULL) {
+ return NULL;
+ }
+
+ opk->print_control = NULL;
+ opk->list_data = 0;
+ opk->previously_printed = 0;
+
+ return opk;
+}
+
+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);
+}
+
+int
+opkg_opk_opk_list_data(struct opkg_opk_opk *opk)
+{
+ opk->list_data = 1;
+ return OPKG_OPK_OK;
+}
+
static int
_opkg_opk_opk_file_read(void *user_data, char **buffer, size_t *size)
{
@@ -57,75 +89,6 @@ _opkg_opk_opk_file_read(void *user_data, char **buffer, size_t *size)
}
}
-struct opkg_opk_opk *
-opkg_opk_opk_init(const char *file_name)
-{
- struct opkg_opk_opk *opk;
-
- opk = malloc(sizeof(*opk));
- if (opk == NULL) {
- goto error0;
- }
-
- /* Open outer archive. */
- opk->file = fopen(file_name, "rb");
- if (opk->file == NULL) {
- fprintf(stderr, _("Error: Failed to open file \"%s\"\n"),
- file_name);
- goto error1;
- }
-
- /* Initialize outer gzip decompressor. */
- opk->outer_gzip = opkg_opk_gzip_init_read(&_opkg_opk_opk_file_read,
- opk);
- if (opk->outer_gzip == NULL) {
- fputs(_("Error: Failed to initialize\n"), stderr);
- goto error2;
- }
-
- /* Initialize outer ustar unarchiver. */
- opk->outer_ustar = opkg_opk_ustar_init(opk->outer_gzip);
- if (opk->outer_ustar == NULL) {
- fputs(_("Error: Failed to initialize\n"), stderr);
- goto error3;
- }
-
- /* Check package version. */
- 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 error4;
- }
- if (opkg_opk_ustar_read(opk->outer_ustar,
- &opk->version_buffer, &opk->version_size) !=
- OPKG_OPK_OK) {
- fputs(_("Error: Failed to read \"debian-binary\" in archive\n"),
- stderr);
- goto error4;
- }
- if (opk->version_size < 4 || strncmp(opk->version_buffer, "2.", 2) != 0)
- {
- fputs(_("Error: Unsupported package version\n"), stderr);
- goto error4;
- }
-
- opk->previously_printed = 0;
-
- return opk;
-
- error4:
- opkg_opk_ustar_free(opk->outer_ustar);
- error3:
- opkg_opk_gzip_free(opk->outer_gzip);
- error2:
- fclose(opk->file);
- error1:
- free(opk);
- error0:
- return NULL;
-}
-
static int
_opkg_opk_opk_init_inner(struct opkg_opk_opk *opk, const char *member)
{
@@ -173,21 +136,26 @@ _opkg_opk_opk_free_inner(struct opkg_opk_opk *opk)
opkg_opk_gzip_free(opk->inner_gzip);
}
-int
-opkg_opk_opk_read_control(struct opkg_opk_opk *opk,
- struct opkg_opk_ustar_seek_name *names)
+static int
+_opkg_opk_opk_read_control(struct opkg_opk_opk *opk)
{
char *buffer;
size_t size;
int ret_seek;
int ret_read;
+ if (opk->print_control == NULL) {
+ /* No control files requested. */
+ return OPKG_OPK_OK;
+ }
+
if (_opkg_opk_opk_init_inner(opk, "control.tar.gz") != OPKG_OPK_OK) {
return OPKG_OPK_ERROR;
}
- while ((ret_seek = opkg_opk_ustar_seek(opk->inner_ustar, names)) !=
- OPKG_OPK_ERROR) {
+ while ((ret_seek = opkg_opk_ustar_seek(opk->inner_ustar,
+ opk->print_control)) != OPKG_OPK_ERROR)
+ {
if (opk->previously_printed == 1) {
puts("");
}
@@ -223,8 +191,8 @@ opkg_opk_opk_read_control(struct opkg_opk_opk *opk,
return OPKG_OPK_OK;
}
-int
-opkg_opk_opk_list_members(struct opkg_opk_opk *opk)
+static int
+_opkg_opk_opk_list_members(struct opkg_opk_opk *opk)
{
struct opkg_opk_ustar_member *head;
struct opkg_opk_ustar_member *tail;
@@ -242,6 +210,11 @@ opkg_opk_opk_list_members(struct opkg_opk_opk *opk)
char mode[10];
char mtime[20];
+ if (opk->list_data == 0) {
+ /* Not listing data. */
+ return OPKG_OPK_OK;
+ }
+
if (opk->previously_printed == 1) {
puts("");
}
@@ -335,11 +308,87 @@ opkg_opk_opk_list_members(struct opkg_opk_opk *opk)
return ret;
}
-void
-opkg_opk_opk_free(struct opkg_opk_opk *opk)
+int
+opkg_opk_opk_read(struct opkg_opk_opk *opk, const char *file_name)
{
+ int ret;
+
+ ret = OPKG_OPK_OK;
+
+ /* Open outer archive. */
+ opk->file = fopen(file_name, "rb");
+ if (opk->file == NULL) {
+ fprintf(stderr, _("Error: Failed to open file \"%s\"\n"),
+ file_name);
+ ret = OPKG_OPK_ERROR;
+ goto out0;
+ }
+
+ /* Initialize outer gzip decompressor. */
+ opk->outer_gzip = opkg_opk_gzip_init_read(&_opkg_opk_opk_file_read,
+ opk);
+ if (opk->outer_gzip == NULL) {
+ fputs(_("Error: Failed to initialize\n"), stderr);
+ ret = OPKG_OPK_ERROR;
+ goto out1;
+ }
+
+ /* Initialize outer ustar unarchiver. */
+ opk->outer_ustar = opkg_opk_ustar_init(opk->outer_gzip);
+ if (opk->outer_ustar == NULL) {
+ fputs(_("Error: Failed to initialize\n"), stderr);
+ ret = OPKG_OPK_ERROR;
+ goto out2;
+ }
+
+ /* Check package version. */
+ 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);
+ ret = OPKG_OPK_ERROR;
+ goto out3;
+ }
+ if (opkg_opk_ustar_read(opk->outer_ustar,
+ &opk->version_buffer, &opk->version_size) !=
+ OPKG_OPK_OK) {
+ fputs(_("Error: Failed to read \"debian-binary\" in archive\n"),
+ stderr);
+ ret = OPKG_OPK_ERROR;
+ goto out3;
+ }
+ if (opk->version_size < 4 || strncmp(opk->version_buffer, "2.", 2) != 0)
+ {
+ fputs(_("Error: Unsupported package version\n"), stderr);
+ ret = OPKG_OPK_ERROR;
+ goto out3;
+ }
+
+ /* Perform the configured read actions. */
+ if (_opkg_opk_opk_read_control(opk) != OPKG_OPK_OK) {
+ ret = OPKG_OPK_ERROR;
+ goto out3;
+ }
+ if (_opkg_opk_opk_list_members(opk) != OPKG_OPK_OK) {
+ ret = OPKG_OPK_ERROR;
+ goto out3;
+ }
+
+ out3:
opkg_opk_ustar_free(opk->outer_ustar);
+ out2:
opkg_opk_gzip_free(opk->outer_gzip);
+ out1:
fclose(opk->file);
+ out0:
+ return ret;
+}
+
+void
+opkg_opk_opk_free(struct opkg_opk_opk *opk)
+{
+ if (opk->print_control != NULL) {
+ opkg_opk_ustar_free_seek_names(opk->print_control);
+ }
free(opk);
}
diff --git a/src/opk.h b/src/opk.h
index 0677071..bf60808 100644
--- a/src/opk.h
+++ b/src/opk.h
@@ -25,43 +25,44 @@
struct opkg_opk_opk;
/*
- * Allocates and initializes a package structure.
- * Parameters:
- * - file_name: Package's file name.
+ * Allocates a package structure. Free with opkg_opk_opk_free().
* Returns:
* - Allocated package structure on success. Free with opkg_opk_opk_free().
* - NULL on memory exhaustion.
*/
struct opkg_opk_opk *
-opkg_opk_opk_init(const char *file_name);
+opkg_opk_opk_init(void);
/*
- * Reads and prints all specified control files.
+ * Adds a name to a list of control files to print when opkg_opk_opk_read() is
+ * called.
* Parameters:
- * - opk: Package structure.
- * - names: List of control file names to read.
+ * - opk: Package structure.
+ * - name: Name of control file to print.
* Returns:
- * - OPKG_OPK_OK if all control files are found, read, and printed.
- * - OPKG_OPK_ERROR if any control file is not found or on decompression error,
- * premature end of gzip stream, an invalid header, unsupported file type, or
- * error writing to standard output.
+ * - OPKG_OPK_OK if the name was added to the list.
+ * - OPKG_OPK_ERROR on memory exhaustion.
*/
int
-opkg_opk_opk_read_control(struct opkg_opk_opk *opk,
- struct opkg_opk_ustar_seek_name *names);
+opkg_opk_opk_print_control(struct opkg_opk_opk *opk, const char *name);
/*
- * Lists and prints all data files.
+ * Lists data files when opkg_opk_opk_read() is called.
* Parameters:
- * - opk: Package structure.
+ * - opk: Package structure.
* Returns:
- * - OPKG_OPK_OK if all data files are listed and printed.
- * - OPKG_OPK_ERROR on decompression error, memory exhaustion, mode or mtime
- * integer conversion error, unsupported file type, or error writing to
- * standard output.
+ * - OPKG_OPK_OK.
+ */
+int
+opkg_opk_opk_list_data(struct opkg_opk_opk *opk);
+
+/*
+ * Performs the configured read actions.
+ * Parameters:
+ * - file_name: Package's file name.
*/
int
-opkg_opk_opk_list_members(struct opkg_opk_opk *opk);
+opkg_opk_opk_read(struct opkg_opk_opk *opk, const char *file_name);
/*
* Frees a package structure.