# #
#############################################################################*/
+#include <argp.h>
#include <errno.h>
-#include <getopt.h>
#include <stdlib.h>
#include <pakfire/pakfire.h>
#include <pakfire/transaction.h>
+#include "command.h"
#include "install.h"
+#include "pakfire.h"
#include "transaction.h"
+static const char* args_doc = "install [OPTIONS...] PACKAGES...";
+
+static const char* doc = "Install packages";
+
+#define MAX_PACKAGES 128
+
struct config {
int transaction_flags;
int job_flags;
+
+ // Packages
+ char* packages[MAX_PACKAGES];
+ unsigned int num_packages;
};
-static void help(void) {
- printf(
- "%s [OPTIONS...] install [OPTIONS...] PACKAGE...\n\n"
- "Options:\n"
- " --allow-downgrade Allow downgrading packages\n"
- " --allow-uninstall Allow uninstalling packages\n"
- " --without-recommended Do not install recommended packages\n"
- " -h --help Show help\n",
- program_invocation_short_name
- );
-
- exit(0);
-}
+enum {
+ OPT_BEST = 1,
+ OPT_ALLOW_DOWNGRADE = 2,
+ OPT_ALLOW_UNINSTALL = 3,
+ OPT_WITHOUT_RECOMMENDED = 4,
+};
-static int parse_argv(struct config* config, int argc, char* argv[]) {
- enum {
- ARG_BEST,
- ARG_ALLOW_DOWNGRADE,
- ARG_ALLOW_UNINSTALL,
- ARG_WITHOUT_RECOMMENDED,
- };
-
- static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "allow-downgrade", no_argument, NULL, ARG_ALLOW_DOWNGRADE },
- { "allow-uninstall", no_argument, NULL, ARG_ALLOW_UNINSTALL },
- { "best", no_argument, NULL, ARG_BEST },
- { "without-recommended", no_argument, NULL, ARG_WITHOUT_RECOMMENDED },
- { NULL },
- };
- int c;
-
- for (;;) {
- c = getopt_long(argc, argv, "h", options, NULL);
- if (c < 0)
- break;
+static struct argp_option options[] = {
+ { "allow-downgrade", OPT_ALLOW_DOWNGRADE, NULL, 0, "Allow downgrading packages", 0 },
+ { "allow-uninstall", OPT_ALLOW_UNINSTALL, NULL, 0, "Allow uninstalling packages", 0 },
+ { "best", OPT_BEST, NULL, 0, "Only install the best package(s)", 0 },
+ { "without-recommended", OPT_ALLOW_DOWNGRADE, NULL, 0, "Do not install recommended packages", 0 },
+ { NULL },
+};
- switch (c) {
- case 'h':
- help();
+static error_t parse(int key, char* arg, struct argp_state* state, void* data) {
+ struct config* config = data;
+
+ switch (key) {
+ case OPT_BEST:
+ config->job_flags |= PAKFIRE_JOB_BEST;
+ break;
- case ARG_BEST:
- config->job_flags |= PAKFIRE_JOB_BEST;
- break;
+ case OPT_ALLOW_DOWNGRADE:
+ config->transaction_flags |= PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE;
+ break;
- case ARG_ALLOW_DOWNGRADE:
- config->transaction_flags |= PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE;
- break;
+ case OPT_ALLOW_UNINSTALL:
+ config->transaction_flags |= PAKFIRE_TRANSACTION_ALLOW_UNINSTALL;
+ break;
- case ARG_ALLOW_UNINSTALL:
- config->transaction_flags |= PAKFIRE_TRANSACTION_ALLOW_UNINSTALL;
- break;
+ case OPT_WITHOUT_RECOMMENDED:
+ config->transaction_flags |= PAKFIRE_TRANSACTION_WITHOUT_RECOMMENDED;
+ break;
- case ARG_WITHOUT_RECOMMENDED:
- config->transaction_flags |= PAKFIRE_TRANSACTION_WITHOUT_RECOMMENDED;
- break;
+ case ARGP_KEY_ARG:
+ if (config->num_packages >= MAX_PACKAGES)
+ return -ENOBUFS;
- case '?':
- return -EINVAL;
+ config->packages[config->num_packages++] = arg;
+ break;
- default:
- break;
- }
+ default:
+ return ARGP_ERR_UNKNOWN;
}
return 0;
int r;
// Add the remaining command line options as packages
- for (int i = 0; i < argc; i++) {
+ for (unsigned int i = 0; i < config->num_packages; i++) {
r = pakfire_transaction_request(transaction,
- PAKFIRE_JOB_INSTALL, argv[i], config->job_flags);
+ PAKFIRE_JOB_INSTALL, config->packages[i], config->job_flags);
if (r) {
fprintf(stderr, "Could not find '%s': %m\n", argv[i]);
return r;
return 0;
}
-int cli_install(struct pakfire* pakfire, int argc, char* argv[]) {
- struct config config = {
- .transaction_flags = 0,
- .job_flags = 0,
- };
+int cli_install(void* data, int argc, char* argv[]) {
+ struct pakfire* pakfire = NULL;
+ struct config config = {};
int r;
- // Parse CLI options
- r = parse_argv(&config, argc, argv);
+ struct cli_config* cli_config = data;
+
+ // Parse the command line
+ r = cli_parse(options, NULL, args_doc, doc, parse, argc, argv, &config);
+ if (r)
+ goto ERROR;
+
+ // Setup Pakfire
+ r = cli_setup_pakfire(&pakfire, cli_config);
if (r)
- return r;
+ goto ERROR;
+
+ r = cli_transaction(pakfire, argc, argv, config.transaction_flags, __cli_install, &config);
+
+ERROR:
+ if (pakfire)
+ pakfire_unref(pakfire);
- return cli_transaction(pakfire, argc, argv, config.transaction_flags, __cli_install, &config);
+ return r;
}