# #
#############################################################################*/
-#include <errno.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include <argp.h>
#include <pakfire/pakfire.h>
-#include <pakfire/transaction.h>
-#include "update.h"
+#include "command.h"
+#include "pakfire.h"
#include "transaction.h"
+#include "update.h"
+
+static const char* args_doc = "update [OPTIONS...] PACKAGES...";
-#define MAX_EXCLUDE 64
+static const char* doc = "Update packages";
+
+#define MAX_EXCLUDES 128
+#define MAX_PACKAGES 128
struct config {
int transaction_flags;
- char* exclude[MAX_EXCLUDE];
- unsigned int nexclude;
+
+ // Excludes
+ char* excludes[MAX_EXCLUDES];
+ unsigned int num_excludes;
+
+ // Packages
+ char* packages[MAX_PACKAGES];
+ unsigned int num_packages;
};
-static void help(void) {
- printf(
- "%s [OPTIONS...] update [OPTIONS...]\n\n"
- "Options:\n"
- " --allow-downgrade Allows downgrading packages\n"
- " --allow-uninstall Allows uninstalling packages\n"
- " -x --exclude Excludes a package from being updated\n"
- " -h --help Show help\n",
- program_invocation_short_name
- );
-
- exit(0);
-}
+enum {
+ OPT_ALLOW_DOWNGRADE = 1,
+ OPT_ALLOW_UNINSTALL = 2,
+};
-static int parse_argv(struct config* config, int argc, char* argv[]) {
- enum {
- ARG_ALLOW_DOWNGRADE,
- ARG_ALLOW_UNINSTALL,
- };
-
- static const struct option options[] = {
- { "allow-downgrade", no_argument, NULL, ARG_ALLOW_DOWNGRADE },
- { "allow-uninstall", no_argument, NULL, ARG_ALLOW_UNINSTALL },
- { "help", no_argument, NULL, 'h' },
- { "exclude", required_argument, NULL, 'x' },
- { NULL },
- };
- int c;
-
- for (;;) {
- c = getopt_long(argc, argv, "hx", 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 },
+ { "exclude", 'x', "PACKAGE", 0, "Exclude a package from being updated", 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;
- case ARG_ALLOW_DOWNGRADE:
- config->transaction_flags |= PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE;
- break;
+ switch (key) {
+ case OPT_ALLOW_DOWNGRADE:
+ config->transaction_flags |= PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE;
+ break;
- case ARG_ALLOW_UNINSTALL:
- config->transaction_flags |= PAKFIRE_TRANSACTION_ALLOW_UNINSTALL;
- break;
+ case OPT_ALLOW_UNINSTALL:
+ config->transaction_flags |= PAKFIRE_TRANSACTION_ALLOW_UNINSTALL;
+ break;
- case 'x':
- // Check if there is space
- if (config->nexclude >= MAX_EXCLUDE)
- return -ENOBUFS;
+ case 'x':
+ if (config->num_excludes >= MAX_EXCLUDES)
+ return -ENOBUFS;
- config->exclude[config->nexclude++] = optarg;
- break;
+ config->excludes[config->num_excludes++] = arg;
+ break;
- case '?':
- return -EINVAL;
+ case ARGP_KEY_ARG:
+ if (config->num_packages >= MAX_PACKAGES)
+ return -ENOBUFS;
- default:
- break;
- }
+ config->packages[config->num_packages++] = arg;
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
}
return 0;
int r;
// Exclude any packages
- for (unsigned int i = 0; i < config->nexclude; i++) {
- r = pakfire_transaction_request(transaction, PAKFIRE_JOB_LOCK, config->exclude[i], 0);
+ for (unsigned int i = 0; i < config->num_excludes; i++) {
+ r = pakfire_transaction_request(transaction, PAKFIRE_JOB_LOCK, config->excludes[i], 0);
if (r)
return r;
}
// Did the user pass any packages?
if (argc) {
// Add the remaining command line options as packages
- for (int i = 0; i < argc; i++) {
- r = pakfire_transaction_request(transaction, PAKFIRE_JOB_UPDATE, argv[i], 0);
+ for (unsigned int i = 0; i < config->num_packages; i++) {
+ r = pakfire_transaction_request(transaction,
+ PAKFIRE_JOB_UPDATE, config->packages[i], 0);
if (r) {
fprintf(stderr, "Could not find '%s': %m\n", argv[i]);
return r;
return 0;
}
-int cli_update(struct pakfire* pakfire, int argc, char* argv[]) {
- struct config config = {
- .transaction_flags = 0,
- .nexclude = 0,
- };
+int cli_update(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_update, &config);
+
+ERROR:
+ if (pakfire)
+ pakfire_unref(pakfire);
- return cli_transaction(pakfire, argc, argv, config.transaction_flags, __cli_update, &config);
+ return r;
}