/** * main: **/ int main (int argc, char *argv[]) { gboolean ret; GError *error = NULL; GPtrArray *added_repos = NULL; GPtrArray *package_ids_recognised = NULL; GPtrArray *package_ids_to_install = NULL; guint i; guint retval = 0; gchar *package_id; gchar *name; gchar *name_debuginfo; gboolean simulate = FALSE; gboolean no_depends = FALSE; gboolean quiet = FALSE; gboolean noninteractive = FALSE; GOptionContext *context; const gchar *repo_id; gchar *repo_id_debuginfo; PkDebuginfoInstallPrivate *priv = NULL; guint step = 1; const GOptionEntry options[] = { { "simulate", 's', 0, G_OPTION_ARG_NONE, &simulate, /* command line argument, simulate what would be done, but don't actually do it */ _("Don't actually install any packages, only simulate what would be installed"), NULL }, { "no-depends", 'n', 0, G_OPTION_ARG_NONE, &no_depends, /* command line argument, do we skip packages that depend on the ones specified */ _("Do not install dependencies of the core packages"), NULL }, { "quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, /* command line argument, do we operate quietly */ _("Do not display information or progress"), NULL }, { "noninteractive", 'y', 0, G_OPTION_ARG_NONE, &noninteractive, /* command line argument, do we ask questions */ _("Install the packages without asking for confirmation"), NULL }, { NULL} }; setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); #if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 31) if (! g_thread_supported ()) g_thread_init (NULL); #endif #if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 35) g_type_init (); #endif context = g_option_context_new (NULL); /* TRANSLATORS: tool that gets called when the command is not found */ g_option_context_set_summary (context, _("PackageKit Debuginfo Installer")); g_option_context_add_main_entries (context, options, NULL); g_option_context_add_group (context, pk_debug_get_option_group ()); g_option_context_parse (context, &argc, &argv, NULL); g_option_context_free (context); /* new private struct */ priv = g_new0 (PkDebuginfoInstallPrivate, 1); /* no input */ if (argv[1] == NULL) { /* should be vocal? */ if (!quiet) { /* TRANSLATORS: the use needs to specify a list of package names on the command line */ g_print (_("ERROR: Specify package names to install.")); g_print ("\n"); } /* return correct failure retval */ retval = PK_DEBUGINFO_EXIT_CODE_FAILED; goto out; } /* store as strings */ priv->enabled = g_ptr_array_new (); priv->disabled = g_ptr_array_new (); added_repos = g_ptr_array_new (); package_ids_to_install = g_ptr_array_new (); package_ids_recognised = g_ptr_array_new (); /* create #PkClient */ priv->client = PK_CLIENT(pk_task_text_new ()); /* we are not asking questions, so it's pointless simulating */ if (noninteractive) { g_object_set (priv->client, "simulate", FALSE, NULL); } /* use text progressbar */ priv->progress_bar = pk_progress_bar_new (); pk_progress_bar_set_size (priv->progress_bar, 25); pk_progress_bar_set_padding (priv->progress_bar, 60); /* should be vocal? */ if (!quiet) { /* starting this section */ g_print ("%i. ", step++); /* TRANSLATORS: we are getting the list of repositories */ g_print (_("Getting sources list")); g_print ("..."); } /* get all enabled repos */ ret = pk_debuginfo_install_get_repo_list (priv, &error); if (!ret) { /* should be vocal? */ if (!quiet) { /* TRANSLATORS: operation was not successful */ g_print ("%s ", _("FAILED.")); } /* TRANSLATORS: we're failed to enable the sources, detailed error follows */ g_print ("Failed to enable sources list: %s", error->message); g_print ("\n"); g_error_free (error); /* return correct failure retval */ retval = PK_DEBUGINFO_EXIT_CODE_FAILED_TO_ENABLE; goto out; } /* should be vocal? */ if (!quiet) { /* TRANSLATORS: all completed 100% */ g_print ("%s ", _("OK.")); /* TRANSLATORS: tell the user what we found */ g_print (_("Found %i enabled and %i disabled sources."), priv->enabled->len, priv->disabled->len); g_print ("\n"); /* starting this section */ g_print ("%i. ", step++); /* TRANSLATORS: we're finding repositories that match out pattern */ g_print (_("Finding debugging sources")); g_print ("..."); } /* find all debuginfo repos for repos that are enabled */ for (i=0; i<priv->enabled->len; i++) { /* is already a -debuginfo */ repo_id = g_ptr_array_index (priv->enabled, i); if (g_str_has_suffix (repo_id, "-debuginfo")) { g_debug ("already enabled: %s", repo_id); continue; } /* has a debuginfo repo */ repo_id_debuginfo = g_strjoin ("-", repo_id, "debuginfo", NULL); ret = pk_debuginfo_install_in_array (priv->disabled, repo_id_debuginfo); if (ret) { /* add to list to change back at the end */ g_ptr_array_add (added_repos, g_strdup (repo_id_debuginfo)); } else { g_debug ("no debuginfo repo for %s", repo_id_debuginfo); } g_free (repo_id_debuginfo); } /* should be vocal? */ if (!quiet) { /* TRANSLATORS: all completed 100% */ g_print ("%s ", _("OK.")); /* TRANSLATORS: tell the user what we found */ g_print (_("Found %i disabled debuginfo repos."), added_repos->len); g_print ("\n"); /* starting this section */ g_print ("%i. ", step++); /* TRANSLATORS: we're now enabling all the debug sources we found */ g_print (_("Enabling debugging sources")); g_print ("..."); } /* enable all debuginfo repos we found */ ret = pk_debuginfo_install_enable_repos (priv, added_repos, TRUE, &error); if (!ret) { /* should be vocal? */ if (!quiet) { /* TRANSLATORS: operation was not successful */ g_print ("%s ", _("FAILED.")); } /* TRANSLATORS: we're failed to enable the sources, detailed error follows */ g_print ("Failed to enable debugging sources: %s", error->message); g_print ("\n"); g_error_free (error); /* return correct failure retval */ retval = PK_DEBUGINFO_EXIT_CODE_FAILED_TO_ENABLE; goto out; } /* should be vocal? */ if (!quiet) { /* TRANSLATORS: all completed 100% */ g_print ("%s ", _("OK.")); /* TRANSLATORS: tell the user how many we enabled */ g_print (_("Enabled %i debugging sources."), added_repos->len); g_print ("\n"); /* starting this section */ g_print ("%i. ", step++); /* TRANSLATORS: we're now finding packages that match in all the repos */ g_print (_("Finding debugging packages")); g_print ("..."); } /* parse arguments and resolve to packages */ for (i=1; argv[i] != NULL; i++) { name = pk_get_package_name_from_nevra (argv[i]); /* resolve name */ package_id = pk_debuginfo_install_resolve_name_to_id (priv, name, &error); if (package_id == NULL) { /* TRANSLATORS: we couldn't find the package name, non-fatal */ g_print (_("Failed to find the package %s: %s"), name, error->message); g_print ("\n"); g_error_free (error); /* don't quit, this is non-fatal */ error = NULL; } /* add to array to install */ if (package_id != NULL) { g_debug ("going to try to install: %s", package_id); g_ptr_array_add (package_ids_recognised, package_id); } else { goto not_found; } /* convert into basename */ name_debuginfo = pk_debuginfo_install_name_to_debuginfo (name); g_debug ("install %s [%s]", argv[i], name_debuginfo); /* resolve name */ package_id = pk_debuginfo_install_resolve_name_to_id (priv, name_debuginfo, &error); if (package_id == NULL) { /* TRANSLATORS: we couldn't find the debuginfo package name, non-fatal */ g_print (_("Failed to find the debuginfo package %s: %s"), name_debuginfo, error->message); g_print ("\n"); g_error_free (error); /* don't quit, this is non-fatal */ error = NULL; } /* add to array to install */ if (package_id != NULL && !g_str_has_suffix (package_id, "installed")) { g_debug ("going to try to install: %s", package_id); g_ptr_array_add (package_ids_to_install, g_strdup (package_id)); } g_free (name_debuginfo); not_found: g_free (package_id); g_free (name); } /* no packages? */ if (package_ids_to_install->len == 0) { /* should be vocal? */ if (!quiet) { /* TRANSLATORS: operation was not successful */ g_print ("%s ", _("FAILED.")); } /* TRANSLATORS: no debuginfo packages could be found to be installed */ g_print (_("Found no packages to install.")); g_print ("\n"); /* return correct failure retval */ retval = PK_DEBUGINFO_EXIT_CODE_NOTHING_TO_DO; goto out; } /* should be vocal? */ if (!quiet) { /* TRANSLATORS: all completed 100% */ g_print ("%s ", _("OK.")); /* TRANSLATORS: tell the user we found some packages, and then list them */ g_print (_("Found %i packages:"), package_ids_to_install->len); g_print ("\n"); } /* optional */ if (!no_depends) { /* save for later logic */ i = package_ids_to_install->len; /* should be vocal? */ if (!quiet) { /* starting this section */ g_print ("%i. ", step++); /* TRANSLATORS: tell the user we are searching for deps */ g_print (_("Finding packages that depend on these packages")); g_print ("..."); } ret = pk_debuginfo_install_add_deps (priv, package_ids_recognised, package_ids_to_install, &error); if (!ret) { /* should be vocal? */ if (!quiet) { /* TRANSLATORS: operation was not successful */ g_print ("%s ", _("FAILED.")); } /* TRANSLATORS: could not install, detailed error follows */ g_print (_("Could not find dependent packages: %s"), error->message); g_print ("\n"); g_error_free (error); /* return correct failure retval */ retval = PK_DEBUGINFO_EXIT_CODE_FAILED_TO_FIND_DEPS; goto out; } /* should be vocal? */ if (!quiet) { /* TRANSLATORS: all completed 100% */ g_print ("%s ", _("OK.")); if (i < package_ids_to_install->len) { /* TRANSLATORS: tell the user we found some more packages */ g_print (_("Found %i extra packages."), package_ids_to_install->len - i); g_print ("\n"); } else { /* TRANSLATORS: tell the user we found some more packages */ g_print (_("No extra packages required.")); g_print ("\n"); } } } /* should be vocal? */ if (!quiet) { /* TRANSLATORS: tell the user we found some packages (and deps), and then list them */ g_print (_("Found %i packages to install:"), package_ids_to_install->len); g_print ("\n"); } /* print list */ if (!quiet) pk_debuginfo_install_print_array (package_ids_to_install); /* simulate mode for testing */ if (simulate) { /* should be vocal? */ if (!quiet) { /* TRANSLATORS: simulate mode is a testing mode where we quit before the action */ g_print (_("Not installing packages in simulate mode")); g_print ("\n"); } goto out; } /* should be vocal? */ if (!quiet) { /* starting this section */ g_print ("%i. ", step++); /* TRANSLATORS: we are now installing the debuginfo packages we found earlier */ g_print (_("Installing packages")); g_print ("...\n"); } /* install */ ret = pk_debuginfo_install_packages_install (priv, package_ids_to_install, &error); if (!ret) { /* should be vocal? */ if (!quiet) { /* TRANSLATORS: operation was not successful */ g_print ("%s ", _("FAILED.")); } /* TRANSLATORS: could not install, detailed error follows */ g_print (_("Could not install packages: %s"), error->message); g_print ("\n"); g_error_free (error); /* return correct failure retval */ retval = PK_DEBUGINFO_EXIT_CODE_FAILED_TO_INSTALL; goto out; } /* should be vocal? */ if (!quiet) { /* TRANSLATORS: all completed 100% */ g_print (_("OK.")); g_print ("\n"); } out: if (package_ids_to_install != NULL) { g_ptr_array_foreach (package_ids_to_install, (GFunc) g_free, NULL); g_ptr_array_free (package_ids_to_install, TRUE); } if (package_ids_recognised != NULL) { g_ptr_array_foreach (package_ids_recognised, (GFunc) g_free, NULL); g_ptr_array_free (package_ids_recognised, TRUE); } if (added_repos != NULL) { /* should be vocal? */ if (!quiet) { /* starting this section */ g_print ("%i. ", step); /* TRANSLATORS: we are now disabling all debuginfo repos we previously enabled */ g_print (_("Disabling sources previously enabled")); g_print ("..."); } /* disable all debuginfo repos we previously enabled */ ret = pk_debuginfo_install_enable_repos (priv, added_repos, FALSE, &error); if (!ret) { /* should be vocal? */ if (!quiet) { /* TRANSLATORS: operation was not successful */ g_print ("%s ", _("FAILED.")); } /* TRANSLATORS: no debuginfo packages could be found to be installed, detailed error follows */ g_print (_("Could not disable the debugging sources: %s"), error->message); g_print ("\n"); g_error_free (error); /* return correct failure retval */ retval = PK_DEBUGINFO_EXIT_CODE_FAILED_TO_DISABLE; } else { /* should be vocal? */ if (!quiet) { /* TRANSLATORS: all completed 100% */ g_print ("%s ", _("OK.")); /* TRANSLATORS: we disabled all the debugging repos that we enabled before */ g_print (_("Disabled %i debugging sources."), added_repos->len); g_print ("\n"); } } g_ptr_array_foreach (added_repos, (GFunc) g_free, NULL); g_ptr_array_free (added_repos, TRUE); } if (priv->enabled != NULL) { g_ptr_array_foreach (priv->enabled, (GFunc) g_free, NULL); g_ptr_array_free (priv->enabled, TRUE); } if (priv->disabled != NULL) { g_ptr_array_foreach (priv->disabled, (GFunc) g_free, NULL); g_ptr_array_free (priv->disabled, TRUE); } if (priv->client != NULL) g_object_unref (priv->client); if (priv->progress_bar != NULL) g_object_unref (priv->progress_bar); g_free (priv); return retval; }
/** * main: **/ int main (int argc, char *argv[]) { gboolean ret; PkCnfPolicyConfig *config = NULL; guint i; guint len; gchar *text; const gchar *possible; gchar **parts; guint retval = EXIT_COMMAND_NOT_FOUND; _cleanup_ptrarray_unref_ GPtrArray *array = NULL; _cleanup_strv_free_ gchar **package_ids = NULL; setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); #if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 31) if (! g_thread_supported ()) g_thread_init (NULL); #endif #if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 35) g_type_init (); #endif /* don't show debugging, unless VERBOSE is specified */ pk_debug_add_log_domain (G_LOG_DOMAIN); /* no input */ if (argv[1] == NULL) goto out; /* do stuff on ctrl-c */ signal (SIGINT, pk_cnf_sigint_handler); /* get policy config */ config = pk_cnf_get_config (); task = PK_TASK(pk_task_text_new ()); g_object_set (task, "cache-age", G_MAXUINT, "interactive", FALSE, "background", FALSE, NULL); cancellable = g_cancellable_new (); /* get length */ len = strlen (argv[1]); if (len < 1) goto out; if (argv[1][0] == '.') goto out; /* TRANSLATORS: the prefix of all the output telling the user * why it's not executing. NOTE: this is lowercase to mimic * the style of bash itself -- apologies */ g_printerr ("bash: %s: %s...\n", argv[1], _("command not found")); /* user is not allowing CNF to do anything useful */ if (!config->software_source_search && !config->similar_name_search) { goto out; } /* generate swizzles */ if (config->similar_name_search) array = pk_cnf_find_alternatives (argv[1], len); /* one exact possibility */ if (array != NULL && array->len == 1) { possible = g_ptr_array_index (array, 0); if (config->single_match == PK_CNF_POLICY_WARN) { /* TRANSLATORS: tell the user what we think the command is */ g_printerr ("%s '%s'\n", _("Similar command is:"), possible); goto out; } /* run */ if (config->single_match == PK_CNF_POLICY_RUN) { retval = pk_cnf_spawn_command (possible, &argv[2]); goto out; } /* ask */ if (config->single_match == PK_CNF_POLICY_ASK) { /* TRANSLATORS: Ask the user if we should run the similar command */ text = g_strdup_printf ("%s %s", _("Run similar command:"), possible); ret = pk_console_get_prompt (text, TRUE); if (ret) retval = pk_cnf_spawn_command (possible, &argv[2]); g_free (text); } goto out; /* multiple choice */ } else if (array != NULL && array->len > 1) { if (config->multiple_match == PK_CNF_POLICY_WARN) { /* TRANSLATORS: show the user a list of commands that they could have meant */ g_printerr ("%s:\n", _("Similar commands are:")); for (i = 0; i < array->len; i++) { possible = g_ptr_array_index (array, i); g_printerr ("'%s'\n", possible); } /* ask */ } else if (config->multiple_match == PK_CNF_POLICY_ASK) { /* TRANSLATORS: show the user a list of commands we could run */ g_printerr ("%s:\n", _("Similar commands are:")); for (i = 0; i < array->len; i++) { possible = g_ptr_array_index (array, i); g_printerr ("%i\t'%s'\n", i+1, possible); } /* TRANSLATORS: ask the user to choose a file to run */ i = pk_console_get_number (_("Please choose a command to run"), array->len); /* run command */ possible = g_ptr_array_index (array, i); retval = pk_cnf_spawn_command (possible, &argv[2]); } goto out; /* only search using PackageKit if configured to do so */ } else if (config->software_source_search) { package_ids = pk_cnf_find_available (argv[1], config->max_search_time); if (package_ids == NULL) goto out; len = g_strv_length (package_ids); if (len == 1) { parts = pk_package_id_split (package_ids[0]); if (config->single_install == PK_CNF_POLICY_WARN) { /* TRANSLATORS: tell the user what package provides the command */ g_printerr ("%s '%s'\n", _("The package providing this file is:"), parts[PK_PACKAGE_ID_NAME]); goto out; } /* ask */ if (config->single_install == PK_CNF_POLICY_ASK) { /* TRANSLATORS: as the user if we want to install a package to provide the command */ text = g_strdup_printf (_("Install package '%s' to provide command '%s'?"), parts[PK_PACKAGE_ID_NAME], argv[1]); ret = pk_console_get_prompt (text, FALSE); g_free (text); if (ret) { ret = pk_cnf_install_package_id (package_ids[0]); if (ret) retval = pk_cnf_spawn_command (argv[1], &argv[2]); } g_print ("\n"); goto out; } /* install */ if (config->single_install == PK_CNF_POLICY_INSTALL) { ret = pk_cnf_install_package_id (package_ids[0]); if (ret) retval = pk_cnf_spawn_command (argv[1], &argv[2]); } g_strfreev (parts); goto out; } else if (len > 1) { if (config->multiple_install == PK_CNF_POLICY_WARN) { /* TRANSLATORS: Show the user a list of packages that provide this command */ g_printerr ("%s\n", _("Packages providing this file are:")); for (i = 0; package_ids[i] != NULL; i++) { parts = pk_package_id_split (package_ids[i]); g_printerr ("'%s'\n", parts[PK_PACKAGE_ID_NAME]); g_strfreev (parts); } /* ask */ } else if (config->multiple_install == PK_CNF_POLICY_ASK) { /* TRANSLATORS: Show the user a list of packages that they can install to provide this command */ g_printerr ("%s:\n", _("Suitable packages are:")); for (i = 0; package_ids[i] != NULL; i++) { parts = pk_package_id_split (package_ids[i]); g_printerr ("%i\t'%s'\n", i+1, parts[PK_PACKAGE_ID_NAME]); g_strfreev (parts); } /* TRANSLATORS: ask the user to choose a file to install */ i = pk_console_get_number (_("Please choose a package to install"), len); if (i == 0) { g_printerr ("%s\n", _("User aborted selection")); goto out; } /* run command */ ret = pk_cnf_install_package_id (package_ids[i - 1]); if (ret) retval = pk_cnf_spawn_command (argv[1], &argv[2]); } goto out; } } out: if (task != NULL) g_object_unref (task); if (cancellable != NULL) g_object_unref (cancellable); if (config != NULL) { g_strfreev (config->locations); g_free (config); } return retval; }