From f6a6b1c9dae1538b9fed7ab52b5ffd31cc411326 Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Fri, 28 Apr 2023 18:33:32 -0400 Subject: opk: Manage control file list and listing flag Instead of main() doing so. --- 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 @@ -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. -- cgit v0.9.1