/*
* 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;
#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;
}
/* 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;
}