# #
#############################################################################*/
-#include <errno.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
+#include <argp.h>
-#include <pakfire/pakfire.h>
-
-#include "lib/assert.h"
#include "lib/clean.h"
#include "lib/command.h"
#include "lib/info.h"
#include "lib/install.h"
-#include "lib/progressbar.h"
+#include "lib/pakfire.h"
#include "lib/provides.h"
#include "lib/remove.h"
#include "lib/repolist.h"
#include "lib/requires.h"
#include "lib/search.h"
#include "lib/sync.h"
-#include "lib/terminal.h"
#include "lib/update.h"
#include "lib/version.h"
#define MAX_REPOS 16
-struct config {
- char* file;
- char* arch;
- char* root;
- int flags;
- int yes;
-
- // Repos
- const char* enable_repos[MAX_REPOS];
- unsigned int num_enable_repos;
- const char* disable_repos[MAX_REPOS];
- unsigned int num_disable_repos;
+const char* argp_program_version = PACKAGE_VERSION;
+
+static const char* args_doc =
+ "install PACKAGES...\n"
+ "remove PACKAGES...\n"
+ "update [PACKAGES...]\n"
+ "sync\n"
+ "search PATTERNS...\n"
+ "provides PATTERNS...\n"
+ "requires PATTERNS...\n"
+ "repolist\n"
+ "clean";
+
+enum {
+ OPT_CONFIG = 1,
+ OPT_DEBUG = 2,
+ OPT_OFFLINE = 3,
+ OPT_ROOT = 4,
+
+ OPT_ENABLE_REPO = 5,
+ OPT_DISABLE_REPO = 6,
};
-static int cli_main(struct pakfire* pakfire, int argc, char* argv[]) {
- static const struct command commands[] = {
-#if 0
- { "clean", 0, cli_clean },
- { "info", 0, cli_info },
- { "install", 0, cli_install },
- { "provides", 0, cli_provides },
- { "remove", 0, cli_remove },
- { "repolist", 0, cli_repolist },
- { "requires", 0, cli_requires },
- { "search", 0, cli_search },
- { "sync", 0, cli_sync },
- { "update", 0, cli_update },
-#endif
- { NULL },
- };
-
-#if 0
- return command_dispatch(pakfire, commands, argc, argv);
-#endif
- return 0;
-}
-
-static void help(void) {
- printf(
- "%s [OPTIONS...] COMMAND\n\n"
- "Options:\n"
- " -a --arch Run in different architecture\n"
- " --config Configuration File\n"
- " --debug Run in debug mode\n"
- " -h --help Show help\n"
- " --offline Run in offline mode\n"
- " --root The path to operate in\n"
- " --version Show version\n"
- " -y --yes Assume yes for all questions\n"
- "\n"
- "Commands:\n"
- " install Install packages\n"
- " remove Removes packages\n"
- " update Updates all installed packages\n"
- " sync Synchronises the system with upstream\n"
- " search Search for packages\n"
- " provides Shows which package provides a dependency\n"
- " requires Shows which package requries a dependency\n"
- " repolist Show all configured repositories\n"
- " clean Cleans up no longer needed resources\n",
- program_invocation_short_name
- );
-
- exit(0);
-}
-
-static int parse_argv(struct config* config, int argc, char* argv[]) {
- enum {
- ARG_CONFIG,
- ARG_DEBUG,
- ARG_OFFLINE,
- ARG_ROOT,
- ARG_VERSION,
-
- // Repos
- ARG_ENABLE_REPO,
- ARG_DISABLE_REPO,
- };
+static struct argp_option options[] = {
+ { "config", OPT_CONFIG, "FILE", 0, "Use this configuration file", 0 },
+ { "debug", OPT_DEBUG, NULL, 0, "Run in debug mode", 0 },
+ { "offline", OPT_OFFLINE, NULL, 0, "Run in offline mode", 0 },
+ { "root", OPT_ROOT, "PATH", 0, "The path to operate in", 0 },
+ { "enable-repo", OPT_ENABLE_REPO, "REPO", 0, "Enable a repository", 0 },
+ { "disable-repo", OPT_DISABLE_REPO, "REPO", 0, "Disable a repository", 0 },
+ { NULL },
+};
- static const struct option options[] = {
- { "arch", required_argument, NULL, 'a' },
- { "config", required_argument, NULL, ARG_CONFIG },
- { "debug", no_argument, NULL, ARG_DEBUG },
- { "help", no_argument, NULL, 'h' },
- { "offline", no_argument, NULL, ARG_OFFLINE },
- { "root", required_argument, NULL, ARG_ROOT },
- { "version", no_argument, NULL, ARG_VERSION },
- { "yes", no_argument, NULL, 'y' },
+static const struct command commands[] = {
+ { "clean", cli_clean, 0, 0, 0 },
+ { "info", cli_info, 1, -1, 0 },
+ //{ "install", cli_install, 1, -1, 0 },
+ { "provides", cli_provides, 1, -1, 0 },
+ //{ "remove", cli_remove, 1, -1, 0 },
+ { "repolist", cli_repolist, 0, 0, 0 },
+ { "requires", cli_requires, 1, -1, 0 },
+ { "search", cli_search, 1, -1, 0 },
+ //{ "sync", cli_sync, 0, 0, 0 },
+ //{ "update", cli_update, 0, -1, 0 },
+ { NULL },
+};
- // Repos
- { "enable-repo", required_argument, NULL, ARG_ENABLE_REPO },
- { "disable-repo", required_argument, NULL, ARG_DISABLE_REPO },
- { NULL },
- };
- int c;
+static error_t parse(int key, char* arg, void* data) {
+ struct cli_config* config = data;
- for (;;) {
- c = getopt_long(argc, argv, "ahy", options, NULL);
- if (c < 0)
+ switch (key) {
+ case OPT_CONFIG:
+ config->config = arg;
break;
- switch (c) {
- case 'a':
- config->arch = optarg;
- break;
-
- case 'h':
- help();
-
- case 'y':
- config->yes = 1;
- break;
-
- case ARG_CONFIG:
- config->file = optarg;
- break;
-
- case ARG_DEBUG:
- config->flags |= PAKFIRE_FLAGS_DEBUG;
- break;
-
- case ARG_OFFLINE:
- config->flags |= PAKFIRE_FLAGS_OFFLINE;
- break;
-
- case ARG_ROOT:
- config->root = optarg;
- break;
-
- case ARG_VERSION:
- cli_version();
- exit(0);
-
- case ARG_ENABLE_REPO:
- if (config->num_enable_repos >= MAX_REPOS)
- return -ENOBUFS;
+ case OPT_DEBUG:
+ config->flags |= PAKFIRE_FLAGS_DEBUG;
+ break;
- config->enable_repos[config->num_enable_repos++] = optarg;
- break;
+ case OPT_OFFLINE:
+ config->flags |= PAKFIRE_FLAGS_OFFLINE;
+ break;
- case ARG_DISABLE_REPO:
- if (config->num_disable_repos >= MAX_REPOS)
- return -ENOBUFS;
+ case OPT_ROOT:
+ config->root = arg;
+ break;
- config->disable_repos[config->num_disable_repos++] = optarg;
- break;
+ // Enable/Disable Repositories
- case '?':
- break;
+ case OPT_ENABLE_REPO:
+ if (config->num_enable_repos >= MAX_REPOS)
+ return -ENOBUFS;
- default:
- assert_unreachable();
- }
- }
+ config->enable_repos[config->num_enable_repos++] = arg;
+ break;
- return 0;
-}
+ case OPT_DISABLE_REPO:
+ if (config->num_disable_repos >= MAX_REPOS)
+ return -ENOBUFS;
-static int configure_callbacks(const struct config* config, struct pakfire* pakfire) {
- // If the user wants to answer yes to everything we only configure that
- if (config->yes) {
- pakfire_set_confirm_callback(pakfire, cli_term_confirm_yes, NULL);
+ config->disable_repos[config->num_disable_repos++] = arg;
+ break;
- return 0;
+ default:
+ return ARGP_ERR_UNKNOWN;
}
- // Configure confirm callback
- pakfire_set_confirm_callback(pakfire, cli_term_confirm, NULL);
-
- // Configure pick solution callback
- pakfire_set_pick_solution_callback(pakfire, cli_term_pick_solution, NULL);
-
- // Configure setup progress callback
- pakfire_set_setup_progress_callback(pakfire, cli_setup_progressbar, NULL);
-
return 0;
}
-static void cli_set_repo_enabled(struct pakfire* pakfire, const char* name, int enabled) {
- struct pakfire_repo* repo = NULL;
-
- // Find the repository
- repo = pakfire_get_repo(pakfire, name);
-
- // Ignore if the repository could not be found
- if (!repo)
- return;
-
- // Set status
- pakfire_repo_set_enabled(repo, enabled);
- pakfire_repo_unref(repo);
-}
int main(int argc, char* argv[]) {
- struct pakfire* pakfire = NULL;
- FILE* f = NULL;
- int r;
-
- struct config config = {
+ struct cli_config config = {
// XXX hard-coded path
- .file = "/etc/pakfire/general.conf",
+ .config = "/etc/pakfire/general.conf",
.arch = NULL,
.root = "/",
.flags = 0,
.yes = 0,
};
- // Parse command line arguments
- r = parse_argv(&config, argc, argv);
- if (r)
- goto ERROR;
-
- // Open the configuration file
- f = fopen(config.file, "r");
- if (!f) {
- fprintf(stderr, "Could not open configuration file %s: %m\n", config.file);
- r = 1;
- goto ERROR;
- }
-
- // Initialize Pakfire
- r = pakfire_create(&pakfire, config.root, config.arch, f,
- config.flags, NULL, NULL);
- if (r)
- goto ERROR;
-
- // Configure callbacks
- r = configure_callbacks(&config, pakfire);
- if (r)
- goto ERROR;
-
- // Enable repositories
- for (unsigned int i = 0; i < config.num_enable_repos; i++)
- cli_set_repo_enabled(pakfire, config.enable_repos[i], 1);
-
- // Disable repositories
- for (unsigned int i = 0; i < config.num_disable_repos; i++)
- cli_set_repo_enabled(pakfire, config.disable_repos[i], 0);
-
- // Run a command
- r = cli_main(pakfire, argc, argv);
-
-ERROR:
- if (f)
- fclose(f);
- if (pakfire)
- pakfire_unref(pakfire);
-
- return r;
+ // Parse the command line and run any commands
+ return cli_parse(options, commands, args_doc, NULL, parse, argc, argv, &config);
}