diff options
-rw-r--r-- | src/main.c | 280 |
1 files changed, 58 insertions, 222 deletions
@@ -19,243 +19,79 @@ #include "config.h" -#ifdef ENABLE_NLS -#include <locale.h> -#endif #include <stdio.h> #include <stdlib.h> #include "defs.h" -#include "i18n.h" -#include "opk.h" -#include "ustar.h" +#include "gzip.h" -#ifdef HAVE_GETOPT_LONG -#include <getopt.h> -#else -#include <unistd.h> -#endif +FILE *_out_fp; +char _out_buffer[8192]; -extern const char *PACKAGE_VERSION_GIT; - -const char *_optstring = "I:fchV"; -#ifdef HAVE_GETOPT_LONG -struct option _longopts[] = { - { - .name = "info", - .has_arg = 1, - .flag = NULL, - .val = 'I', - }, - { - .name = "control", - .has_arg = 0, - .flag = NULL, - .val = 'f', - }, - { - .name = "contents", - .has_arg = 0, - .flag = NULL, - .val = 'c', - }, - { - .name = "help", - .has_arg = 0, - .flag = NULL, - .val = 'h', - }, - { - .name = "version", - .has_arg = 0, - .flag = NULL, - .val = 'V', - }, -}; -#endif - -static void -_help(const char *program_name) -{ - printf(_("Usage: %s OPTION... PACKAGE\n"), program_name); -#ifdef HAVE_GETOPT_LONG - puts(_("Options:\n" -" -I, --info=CONTROL-FILE Print the named control file. If this option is\n" -" given multiple times, the named control files will " - "be\n" -" printed in the order they appear in the package.\n" -" -f, --control Print the control file.\n" -" -c, --contents List the contents of the filesystem tree archive\n" -" portion of the package. It is currently produced " - "in\n" -" a format similar to that generated by GNU and " - "BusyBox\n" -" tar's verbose listing. User and group IDs and " - "names\n" -" are not checked against those on the host system,\n" -" since they may differ.\n" -" -h, --help Show this help information and exit.\n" -" -V, --version Show version information and exit.")); -#else - puts(_("Options:\n" -" -I Print the named control file. If this option is given multiple times, " - "the\n" -" named control files will be printed in the order they appear in the\n" -" package.\n" -" -f Print the control file.\n" -" -c List the contents of the filesystem tree archive portion of the " - "package.\n" -" It is currently produced in a format similar to that generated by GNU " - "and\n" -" BusyBox tar's verbose listing. User and group IDs and names are not\n" -" checked against those on the host system, since they may differ.\n" -" -h Show this help information and exit.\n" -" -V Show version information and exit.")); -#endif -} - -static void -_version(void) +static int +_write(void *user_data, size_t size) { - printf("%s %s%s\n", PACKAGE_NAME, PACKAGE_VERSION, PACKAGE_VERSION_GIT); - /* TRANSLATORS: The "%s" conversion specifications are the copyright - * year(s) and copyright holder(s), respectively. */ - printf(_("Copyright (C) %s %s\n"), "2023", "Patrick McDermott"); - puts(_("License GPLv3+: GNU GPL version 3 or later " - "<http://gnu.org/licenses/gpl.html>.\n" - "This is free software: you are free to change and " - "redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by " - "law.\n")); - printf(_("Please report bugs to <%s>.\n"), PACKAGE_BUGREPORT); -} - -static void -_help_tip(const char *program_name) -{ - /* TRANSLATORS: The "%s" conversion specifications are the program name - * and help option, respectively. */ - fprintf(stderr, _("Try \"%s %s\" for more information\n"), program_name, -#ifdef HAVE_GETOPT_LONG - "--help" -#else - "-h" -#endif - ); + if (fwrite(_out_buffer, 1, size, _out_fp) == size) { + return OPKG_OPK_OK; + } else { + return OPKG_OPK_ERROR; + } } 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; - -#ifdef ENABLE_NLS - bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); -#ifdef HAVE_BIND_TEXTDOMAIN_CODESET - bind_textdomain_codeset(PACKAGE, "UTF-8"); -#endif - textdomain(PACKAGE); - setlocale(LC_ALL, ""); -#endif - - program_name = argv[0]; - control_files = NULL; - list_members = 0; - opterr = 0; -#ifdef HAVE_GETOPT_LONG - while ((opt = getopt_long(argc, argv, _optstring, _longopts, NULL)) - != -1) { -#else - while ((opt = getopt(argc, argv, _optstring)) != -1) { -#endif - switch(opt) { - case 'I': - if (opkg_opk_ustar_add_seek_name(&control_files, - optarg) != - OPKG_OPK_OK) { - goto error0; - } - break; - case 'f': - if (opkg_opk_ustar_add_seek_name(&control_files, - "control") != - OPKG_OPK_OK) { - goto error0; - } - break; - case 'c': - list_members = 1; - break; - case 'h': - _help(program_name); - return EXIT_SUCCESS; - case 'V': - _version(); - return EXIT_SUCCESS; - default: - fprintf(stderr, _("%s: Invalid option: " - "\"%c\"\n"), - program_name, optopt); - _help_tip(program_name); - return EXIT_FAILURE; - } - } - argc -= optind; - argv += optind; - - if (argc < 1) { - fprintf(stderr, _("%s: Missing package file operand\n"), - program_name); - _help_tip(program_name); - return EXIT_FAILURE; - } else if (argc > 1) { - fprintf(stderr, _("%s: Too many package file operands\n"), - program_name); - _help_tip(program_name); - return EXIT_FAILURE; + int ret; + FILE *in_fp; + char in_buffer[512]; + struct opkg_opk_gzip *gzip; + size_t in_size; + + ret = EXIT_SUCCESS; + in_fp = fopen(argv[1], "rb"); + if (in_fp == NULL) { + puts("Error opening input"); + ret = EXIT_FAILURE; + goto out0; } - 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; + _out_fp = fopen("out.gz", "wb"); + if (_out_fp == NULL) { + puts("Error opening output"); + ret = EXIT_FAILURE; + goto out1; } - - /* Initialize outer archive. */ - opk = opkg_opk_opk_init(argv[0]); - if (opk == NULL) { - goto error0; + gzip = opkg_opk_gzip_init_write(_out_buffer, sizeof(_out_buffer), + _write, NULL); + if (gzip == NULL) { + puts("Error initializing compressor"); + ret = EXIT_FAILURE; + goto out2; } - - /* Read control file. */ - if (control_files != NULL) { - if (opkg_opk_opk_read_control(opk, control_files) != - OPKG_OPK_OK) { - goto error1; + while ((in_size = fread(in_buffer, 1, sizeof(in_buffer), in_fp)) > 0) { + if (feof(in_fp)) { + if (opkg_opk_gzip_write(gzip, in_buffer, in_size, 1) != + OPKG_OPK_END) { + puts("Error finishing compression"); + ret = EXIT_FAILURE; + goto out3; + } + } else { + if (opkg_opk_gzip_write(gzip, in_buffer, in_size, 0) != + OPKG_OPK_OK) { + puts("Error compressing"); + ret = EXIT_FAILURE; + goto out3; + } } } - - /* List data files. */ - if (list_members == 1) { - if (opkg_opk_opk_list_members(opk) != OPKG_OPK_OK) { - goto error1; - } - } - - 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); + out3: + if (opkg_opk_gzip_free(gzip) != OPKG_OPK_OK) { + puts("Error freeing compressor"); + ret = EXIT_FAILURE; } - return EXIT_FAILURE; + out2: + fclose(_out_fp); + out1: + fclose(in_fp); + out0: + return ret; } |