/* * Copyright (C) 2023 Patrick McDermott * * This file is part of opkg-opk. * * opkg-opk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * opkg-opk is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with opkg-opk. If not, see . */ #include #include #include "defs.h" #include "opk.h" #include "ustar.h" #include "config.h" #ifdef HAVE_GETOPT_LONG #include #else #include #endif 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); puts("Options:"); #ifdef HAVE_GETOPT_LONG puts(" -I, --info=CONTROL-FILE Print the named control file. If " "this option is"); puts(" given multiple times, the named " "control files will be"); puts(" printed in the order they appear in " "the package."); puts(" -f, --control Print the control file."); puts(" -c, --contents List the contents of the filesystem " "tree archive"); puts(" portion of the package. It is " "currently produced in"); puts(" a format similar to that generated by " "GNU and BusyBox"); puts(" tar's verbose listing. User and " "group IDs and names"); puts(" are not checked against those on the " "host system,"); puts(" since they may differ."); puts(" -h, --help Show this help information and exit."); puts(" -V, --version Show version information and exit."); #else puts(" -I Print the named control file. If this option is given " "multiple times, the"); puts(" named control files will be printed in the order they " "appear in the"); puts(" package."); puts(" -f Print the control file."); puts(" -c List the contents of the filesystem tree archive portion " "of the package."); puts(" It is currently produced in a format similar to that " "generated by GNU and"); puts(" BusyBox tar's verbose listing. User and group IDs and " "names are not"); puts(" checked against those on the host system, since they may " "differ."); puts(" -h Show this help information and exit."); puts(" -V Show version information and exit."); #endif } static void _version(void) { printf("%s %s%s\n", PACKAGE_NAME, PACKAGE_VERSION, PACKAGE_VERSION_GIT); printf("Copyright (C) %s %s\n", "2023", "Patrick McDermott"); puts("License GPLv3+: GNU GPL version 3 or later " ".\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) { fprintf(stderr, "Try \"%s %s\" for more information\n", program_name, #ifdef HAVE_GETOPT_LONG "--help" #else "-h" #endif ); } 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; 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; } 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; } } 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; }