int main (int argc, char **argv) { GError *error = NULL; GCancellable *cancellable = g_cancellable_new (); RpmOstreeCommand *command; int in, out; const char *command_name = NULL; gs_free char *prgname = NULL; /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */ g_setenv ("GIO_USE_VFS", "local", TRUE); g_set_prgname (argv[0]); setlocale (LC_ALL, ""); /* * Parse the global options. We rearrange the options as * necessary, in order to pass relevant options through * to the commands, but also have them take effect globally. */ for (in = 1, out = 1; in < argc; in++, out++) { /* The non-option is the command, take it out of the arguments */ if (argv[in][0] != '-') { if (command_name == NULL) { command_name = argv[in]; out--; continue; } } else if (g_str_equal (argv[in], "--")) { break; } argv[out] = argv[in]; } argc = out; g_unix_signal_add (SIGINT, on_sigint, cancellable); g_unix_signal_add (SIGTERM, on_sigint, cancellable); g_unix_signal_add (SIGHUP, on_sigint, cancellable); /* Keep the "rpm" command working for backward-compatibility. */ if (g_strcmp0 (command_name, "rpm") == 0) command_name = "db"; command = commands; while (command->name) { if (g_strcmp0 (command_name, command->name) == 0) break; command++; } if (!command->fn) { GOptionContext *context; gs_free char *help; context = option_context_new_with_commands (); /* This will not return for some options (e.g. --version). */ if (rpmostree_option_context_parse (context, NULL, &argc, &argv, RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD, NULL, NULL, &error)) { if (command_name == NULL) { g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "No command specified"); } else { g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown command '%s'", command_name); } } help = g_option_context_get_help (context, FALSE, NULL); g_printerr ("%s", help); g_option_context_free (context); goto out; } prgname = g_strdup_printf ("%s %s", g_get_prgname (), command_name); g_set_prgname (prgname); if (!command->fn (argc, argv, cancellable, &error)) goto out; out: if (error != NULL) { int is_tty = isatty (1); const char *prefix = ""; const char *suffix = ""; if (is_tty) { prefix = "\x1b[31m\x1b[1m"; /* red, bold */ suffix = "\x1b[22m\x1b[0m"; /* bold off, color reset */ } g_dbus_error_strip_remote_error (error); g_printerr ("%serror: %s%s\n", prefix, suffix, error->message); g_error_free (error); return 1; } return 0; }
int main (int argc, char **argv) { GCancellable *cancellable = g_cancellable_new (); RpmOstreeCommand *command; int exit_status = EXIT_SUCCESS; int in, out; const char *command_name = NULL; g_autofree char *prgname = NULL; GError *local_error = NULL; /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */ g_setenv ("GIO_USE_VFS", "local", TRUE); g_set_prgname (argv[0]); setlocale (LC_ALL, ""); /* * Parse the global options. We rearrange the options as * necessary, in order to pass relevant options through * to the commands, but also have them take effect globally. */ for (in = 1, out = 1; in < argc; in++, out++) { /* The non-option is the command, take it out of the arguments */ if (argv[in][0] != '-') { if (command_name == NULL) { command_name = argv[in]; out--; continue; } } else if (g_str_equal (argv[in], "--")) { break; } argv[out] = argv[in]; } argc = out; g_unix_signal_add (SIGINT, on_sigint, cancellable); g_unix_signal_add (SIGTERM, on_sigint, cancellable); g_unix_signal_add (SIGHUP, on_sigint, cancellable); /* Keep the "rpm" command working for backward-compatibility. */ if (g_strcmp0 (command_name, "rpm") == 0) command_name = "db"; command = lookup_command_of_type (supported_commands, command_name, NULL); if (!command) command = lookup_command_of_type (legacy_alias_commands, command_name, NULL); if (!command) command = lookup_command_of_type (preview_commands, command_name, "a preview"); if (!command) command = lookup_command_of_type (experimental_commands, command_name, "an experimental"); if (!command) { g_autoptr(GOptionContext) context = option_context_new_with_commands (); g_autofree char *help = NULL; /* This will not return for some options (e.g. --version). */ (void) rpmostree_option_context_parse (context, NULL, &argc, &argv, RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD, NULL, NULL, NULL); if (command_name == NULL) { local_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED, "No command specified"); } else { local_error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, "Unknown command '%s'", command_name); } help = g_option_context_get_help (context, FALSE, NULL); g_printerr ("%s", help); exit_status = EXIT_FAILURE; goto out; } prgname = g_strdup_printf ("%s %s", g_get_prgname (), command_name); g_set_prgname (prgname); exit_status = command->fn (argc, argv, cancellable, &local_error); out: if (local_error != NULL) { int is_tty = isatty (1); const char *prefix = ""; const char *suffix = ""; if (is_tty) { prefix = "\x1b[31m\x1b[1m"; /* red, bold */ suffix = "\x1b[22m\x1b[0m"; /* bold off, color reset */ } g_dbus_error_strip_remote_error (local_error); g_printerr ("%serror: %s%s\n", prefix, suffix, local_error->message); g_error_free (local_error); /* Print a warning if the exit status indicates success when we * actually had an error, so it gets reported and fixed quickly. */ g_warn_if_fail (exit_status != EXIT_SUCCESS); } return exit_status; }