From 79327b8967e3323b0b12a74a907c726b7ef8bddd Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Fri, 12 Aug 2022 12:07:56 +0000 Subject: [PATCH] add bomtool skeleton --- Makefile.am | 8 +- cli/bomtool/main.c | 200 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 cli/bomtool/main.c diff --git a/Makefile.am b/Makefile.am index d4916ae..c9504c8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,7 @@ nodist_pkgconfig_DATA = libpkgconf.pc AM_CFLAGS = -DPERSONALITY_PATH=\"$(personality_dir)\" -DPKG_DEFAULT_PATH=\"$(pkg_default_dir)\" -DSYSTEM_INCLUDEDIR=\"$(system_includedir)\" -DSYSTEM_LIBDIR=\"$(system_libdir)\" -bin_PROGRAMS = pkgconf +bin_PROGRAMS = pkgconf bomtool lib_LTLIBRARIES = libpkgconf.la EXTRA_DIST = pkg.m4 \ @@ -172,6 +172,12 @@ noinst_HEADERS = \ cli/getopt_long.h \ cli/renderer-msvc.h +bomtool_LDADD = libpkgconf.la +bomtool_SOURCES = \ + cli/bomtool/main.c \ + cli/getopt_long.c +bomtool_CPPFLAGS = -Ilibpkgconf -Icli -Icli/bomtool + dist_doc_DATA = README.md AUTHORS m4datadir = $(datadir)/aclocal diff --git a/cli/bomtool/main.c b/cli/bomtool/main.c new file mode 100644 index 0000000..ae0b48d --- /dev/null +++ b/cli/bomtool/main.c @@ -0,0 +1,200 @@ +/* + * bomtool/main.c + * main() routine, printer functions + * + * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + * pkgconf authors (see AUTHORS). + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +#include "libpkgconf/config.h" +#include +#include +#include "getopt_long.h" + +#define PKG_VERSION (((uint64_t) 1) << 1) +#define PKG_ABOUT (((uint64_t) 1) << 2) +#define PKG_HELP (((uint64_t) 1) << 3) + +static pkgconf_client_t pkg_client; +static uint64_t want_flags; +static size_t maximum_package_count = 0; +static int maximum_traverse_depth = 2000; +FILE *error_msgout = NULL; + +static bool +error_handler(const char *msg, const pkgconf_client_t *client, void *data) +{ + (void) client; + (void) data; + fprintf(error_msgout, "%s", msg); + return true; +} + +static bool +generate_sbom_from_world(pkgconf_client_t *client, pkgconf_pkg_t *world) +{ + return true; +} + +static int +version(void) +{ + printf("bomtool %s\n", PACKAGE_VERSION); + return EXIT_SUCCESS; +} + +static int +about(void) +{ + printf("bomtool (%s %s)\n", PACKAGE_NAME, PACKAGE_VERSION); + printf("Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021\n"); + printf(" pkgconf authors (see AUTHORS in documentation directory).\n\n"); + printf("Permission to use, copy, modify, and/or distribute this software for any\n"); + printf("purpose with or without fee is hereby granted, provided that the above\n"); + printf("copyright notice and this permission notice appear in all copies.\n\n"); + printf("This software is provided 'as is' and without any warranty, express or\n"); + printf("implied. In no event shall the authors be liable for any damages arising\n"); + printf("from the use of this software.\n\n"); + printf("Report bugs at <%s>.\n", PACKAGE_BUGREPORT); + return EXIT_SUCCESS; +} + +static int +usage(void) +{ + printf("usage: bomtool [--flags] [modules]\n"); + + printf("\nbasic options:\n\n"); + + printf(" --help this message\n"); + printf(" --about print bomtool version and license to stdout\n"); + printf(" --version print bomtool version to stdout\n"); + + return EXIT_SUCCESS; +} + +int +main(int argc, char *argv[]) +{ + int ret = EXIT_SUCCESS; + pkgconf_list_t pkgq = PKGCONF_LIST_INITIALIZER; + pkgconf_list_t dir_list = PKGCONF_LIST_INITIALIZER; + unsigned int want_client_flags = PKGCONF_PKG_PKGF_NONE; + pkgconf_cross_personality_t *personality = pkgconf_cross_personality_default(); + pkgconf_pkg_t world = { + .id = "virtual:world", + .realname = "virtual world package", + .flags = PKGCONF_PKG_PROPF_STATIC | PKGCONF_PKG_PROPF_VIRTUAL, + }; + + error_msgout = stderr; + + struct pkg_option options[] = { + { "version", no_argument, &want_flags, PKG_VERSION, }, + { "about", no_argument, &want_flags, PKG_ABOUT, }, + { "help", no_argument, &want_flags, PKG_HELP, }, + { NULL, 0, NULL, 0 } + }; + + while ((ret = pkg_getopt_long_only(argc, argv, "", options, NULL)) != -1) + { + switch (ret) + { + case '?': + case ':': + return EXIT_FAILURE; + default: + break; + } + } + + pkgconf_client_init(&pkg_client, error_handler, NULL, personality); + + /* we have determined what features we want most likely. in some cases, we override later. */ + pkgconf_client_set_flags(&pkg_client, want_client_flags); + + /* at this point, want_client_flags should be set, so build the dir list */ + pkgconf_client_dir_list_build(&pkg_client, personality); + + if ((want_flags & PKG_ABOUT) == PKG_ABOUT) + return about(); + + if ((want_flags & PKG_VERSION) == PKG_VERSION) + return version(); + + if ((want_flags & PKG_HELP) == PKG_HELP) + return usage(); + + while (1) + { + const char *package = argv[pkg_optind]; + + if (package == NULL) + break; + + /* check if there is a limit to the number of packages allowed to be included, if so and we have hit + * the limit, stop adding packages to the queue. + */ + if (maximum_package_count > 0 && pkgq.length > maximum_package_count) + break; + + while (isspace((unsigned int)package[0])) + package++; + + /* skip empty packages */ + if (package[0] == '\0') { + pkg_optind++; + continue; + } + + if (argv[pkg_optind + 1] == NULL || !PKGCONF_IS_OPERATOR_CHAR(*(argv[pkg_optind + 1]))) + { + pkgconf_queue_push(&pkgq, package); + pkg_optind++; + } + else + { + char packagebuf[PKGCONF_BUFSIZE]; + + snprintf(packagebuf, sizeof packagebuf, "%s %s %s", package, argv[pkg_optind + 1], argv[pkg_optind + 2]); + pkg_optind += 3; + + pkgconf_queue_push(&pkgq, packagebuf); + } + } + + if (pkgq.head == NULL) + { + fprintf(stderr, "Please specify at least one package name on the command line.\n"); + ret = EXIT_FAILURE; + } + + ret = EXIT_SUCCESS; + + if (!pkgconf_queue_solve(&pkg_client, &pkgq, &world, maximum_traverse_depth)) + { + ret = EXIT_FAILURE; + goto out; + } + + if (!generate_sbom_from_world(&pkg_client, &world)) + { + ret = EXIT_FAILURE; + goto out; + } + +out: + pkgconf_queue_free(&pkgq); + pkgconf_cross_personality_deinit(personality); + pkgconf_client_deinit(&pkg_client); + + return ret; +}