Esempio n. 1
0
/**
 * main:
 **/
int
main (int argc, char *argv[])
{
	GError *error = NULL;
	GOptionContext *context;
	gchar *options_help;
	gboolean ret;
	gchar *filename = NULL;
	PkClient *client = NULL;
	PkControl *control = NULL;
	PkBitfield roles;
	gchar *tempdir = NULL;
	gboolean exists;
	gboolean overwrite;
	gchar **excludes = NULL;
	gchar *package_id = NULL;
	PkServicePack *pack = NULL;
	gchar *directory = NULL;
	gchar *package_list = NULL;
	gchar *package = NULL;
	gboolean updates = FALSE;
	gint retval = 1;

	const GOptionEntry options[] = {
		{ "with-package-list", 'l', 0, G_OPTION_ARG_STRING, &package_list,
			/* TRANSLATORS: we can exclude certain packages (glibc) when we know they'll exist on the target */
			_("Set the file name of dependencies to be excluded"), NULL},
		{ "output", 'o', 0, G_OPTION_ARG_STRING, &directory,
			/* TRANSLATORS: the output location */
			_("The output file or directory (the current directory is used if omitted)"), NULL},
		{ "package", 'p', 0, G_OPTION_ARG_STRING, &package,
			/* TRANSLATORS: put a list of packages in the pack */
			_("The package to be put into the service pack"), NULL},
		{ "updates", 'u', 0, G_OPTION_ARG_NONE, &updates,
			/* TRANSLATORS: put all pending updates in the pack */
			_("Put all updates available in the service pack"), 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

	g_type_init ();

	/* do stuff on ctrl-c */
	signal (SIGINT, pk_generate_pack_sigint_cb);

	context = g_option_context_new ("PackageKit Pack Generator");
	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);
	/* Save the usage string in case command parsing fails. */
	options_help = g_option_context_get_help (context, TRUE, NULL);
	g_option_context_free (context);

	client = pk_client_new ();
	pack = pk_service_pack_new ();
	cancellable = g_cancellable_new ();
	progressbar = pk_progress_bar_new ();
	pk_progress_bar_set_size (progressbar, 25);
	pk_progress_bar_set_padding (progressbar, 20);

	/* neither options selected */
	if (package == NULL && !updates) {
		/* TRANSLATORS: This is when the user fails to supply the correct arguments */
		g_print ("%s\n", _("Neither --package or --updates option selected."));
		retval = 1;
		goto out;
	}

	/* both options selected */
	if (package != NULL && updates) {
		/* TRANSLATORS: This is when the user fails to supply just one argument */
		g_print ("%s\n", _("Both options selected."));
		retval = 1;
		goto out;
	}

	/* no argument given to --package */
	if (package != NULL && package[0] == '\0') {
		/* TRANSLATORS: This is when the user fails to supply the package name */
		g_print ("%s\n", _("A package name is required"));
		retval = 1;
		goto out;
	}

	/* no argument given to --output */
	if (directory != NULL && directory[0] == '\0') {
		/* TRANSLATORS: This is when the user fails to supply the output */
		g_print ("%s\n", _("A output directory or file name is required"));
		retval = 1;
		goto out;
	}

	/* fall back to the system copy */
	if (package_list == NULL)
		package_list = g_strdup (PK_SYSTEM_PACKAGE_LIST_FILENAME);

	/* fall back to CWD */
	if (directory == NULL)
		directory = g_get_current_dir ();

	/* are we dumb and can't do some actions */
	control = pk_control_new ();
	ret = pk_control_get_properties (control, NULL, &error);
	if (!ret) {
		/* TRANSLATORS: This is when the daemon is not-installed/broken and fails to startup */
		g_print ("%s: %s\n", _("The daemon failed to startup"), error->message);
		goto out;
	}

	/* get data */
	g_object_get (control,
		      "roles", &roles,
		      NULL);

	if (!pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DEPENDS)) {
		/* TRANSLATORS: This is when the backend doesn't have the capability to get-depends */
		g_print ("%s (GetDepends)\n", _("The package manager cannot perform this type of operation."));
		retval = 1;
		goto out;
	}
	if (!pk_bitfield_contain (roles, PK_ROLE_ENUM_DOWNLOAD_PACKAGES)) {
		/* TRANSLATORS: This is when the backend doesn't have the capability to download */
		g_print ("%s (DownloadPackage)\n", _("The package manager cannot perform this type of operation."));
		retval = 1;
		goto out;
	}

#ifndef HAVE_ARCHIVE_H
	/* TRANSLATORS: This is when the distro didn't include libarchive support into PK */
	g_print ("%s\n", _("Service packs cannot be created as PackageKit was not built with libarchive support."));
	goto out;
#endif

	/* the user can speciify a complete path */
	ret = g_file_test (directory, G_FILE_TEST_IS_DIR);
	if (ret) {
		filename = pk_generate_pack_get_filename (package, directory);
	} else {
		if (!g_str_has_suffix (directory, PK_SERVICE_PACK_FILE_EXTENSION)) {
			/* TRANSLATORS: the user specified an absolute path, but didn't get the extension correct */
			g_print ("%s .%s \n", _("If specifying a file, the service pack name must end with"), PK_SERVICE_PACK_FILE_EXTENSION);
			retval = 1;
			goto out;
		}
		filename = g_strdup (directory);
	}

	/* download packages to a temporary directory */
	tempdir = g_build_filename (g_get_tmp_dir (), "pack", NULL);

	/* check if file exists before we overwrite it */
	exists = g_file_test (filename, G_FILE_TEST_EXISTS);

	/*ask user input*/
	if (exists) {
		/* TRANSLATORS: This is when file already exists */
		overwrite = pk_console_get_prompt (_("A pack with the same name already exists, do you want to overwrite it?"), FALSE);
		if (!overwrite) {
			/* TRANSLATORS: This is when the pack was not overwritten */
			g_print ("%s\n", _("The pack was not overwritten."));
			retval = 1;
			goto out;
		}
	}

	/* get rid of temp directory if it already exists */
	g_rmdir (tempdir);

	/* make the temporary directory */
	retval = g_mkdir_with_parents (tempdir, 0777);
	if (retval != 0) {
		/* TRANSLATORS: This is when the temporary directory cannot be created, the directory name follows */
		g_print ("%s '%s'\n", _("Failed to create directory:"), tempdir);
		retval = 1;
		goto out;
	}
	pk_service_pack_set_temp_directory (pack, tempdir);

	/* get the exclude list */
	excludes = NULL;
#if 0
	ret = pk_obj_list_from_file (PK_OBJ_LIST(list), package_list);
	if (!ret) {
		/* TRANSLATORS: This is when the list of packages from the remote computer cannot be opened */
		g_print ("%s: '%s'\n", _("Failed to open package list."), package_list);
		retval = 1;
		goto out;
	}
#endif

	/* resolve package name to package_id */
	if (!updates) {
		/* TRANSLATORS: The package name is being matched up to available packages */
		g_print ("%s\n", _("Finding package name."));
		package_id = pk_console_resolve_package (client, pk_bitfield_value (PK_FILTER_ENUM_NONE), package, &error);
		if (package_id == NULL) {
			/* TRANSLATORS: This is when the package cannot be found in any software source. The detailed error follows */
			g_print (_("Failed to find package '%s': %s"), package, error->message);
			g_error_free (error);
			retval = 1;
			goto out;
		}
	}

	/* TRANSLATORS: This is telling the user we are in the process of making the pack */
	g_print ("%s\n", _("Creating service pack..."));
	if (updates)
		ret = pk_generate_pack_create_for_updates (pack, filename, excludes, &error);
	else {
		gchar **package_ids;
		package_ids = pk_package_ids_from_id (package_id);
		ret = pk_generate_pack_create_for_package_ids (pack, filename, package_ids, excludes, &error);
		g_strfreev (package_ids);
	}

	/* no more progress */
	pk_progress_bar_end (progressbar);

	if (ret) {
		/* TRANSLATORS: we succeeded in making the file */
		g_print (_("Service pack created '%s'"), filename);
		g_print ("\n");
		retval = 0;
	} else {
		/* TRANSLATORS: we failed to make te file */
		g_print (_("Failed to create '%s': %s"), filename, error->message);
		g_print ("\n");
		g_error_free (error);
	}

out:
	/* get rid of temp directory */
	g_rmdir (tempdir);

	g_object_unref (cancellable);
	if (progressbar != NULL)
		g_object_unref (progressbar);
	if (pack != NULL)
		g_object_unref (pack);
	if (client != NULL)
		g_object_unref (client);
	if (control != NULL)
		g_object_unref (control);
	g_free (tempdir);
	g_free (filename);
	g_free (package_id);
	g_free (directory);
	g_free (package_list);
	g_free (options_help);
	g_strfreev (excludes);
	return retval;
}
Esempio n. 2
0
int
main (int argc, char *argv[])
{
	PkDirectPrivate *priv = NULL;
	const gchar *destdir;
	gboolean ret = TRUE;
	gint retval = EXIT_SUCCESS;
	g_autoptr(GError) error = NULL;
	g_autofree gchar *backend_name = NULL;
	g_autofree gchar *cmd_descriptions = NULL;
	g_autofree gchar *conf_filename = NULL;
	g_autoptr(GKeyFile) conf = NULL;

	const GOptionEntry options[] = {
		{ "backend", '\0', 0, G_OPTION_ARG_STRING, &backend_name,
		  /* TRANSLATORS: a backend is the system package tool, e.g. dnf, apt */
		  _("Packaging backend to use, e.g. dummy"), NULL },
		{ NULL }
	};

	setlocale (LC_ALL, "");
	bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	/* create priv object */
	priv = g_new0 (PkDirectPrivate, 1);

	/* add commands */
	priv->cmd_array = g_ptr_array_new_with_free_func ((GDestroyNotify) pk_direct_item_free);
	pk_direct_add (priv->cmd_array, "refresh", NULL,
		       /* TRANSLATORS: command description */
		       _("Refresh the cache"),
		       pk_direct_refresh);
	pk_direct_add (priv->cmd_array, "refresh-force", NULL,
		       /* TRANSLATORS: command description */
		       _("Refresh the cache (forced)"),
		       pk_direct_refresh_force);
	pk_direct_add (priv->cmd_array, "search-name", "[SEARCH]",
		       /* TRANSLATORS: command description */
		       _("Search by names"),
		       pk_direct_search_names);
	pk_direct_add (priv->cmd_array, "search-detail", "[SEARCH]",
		       /* TRANSLATORS: command description */
		       _("Search by details"),
		       pk_direct_search_details);
	pk_direct_add (priv->cmd_array, "search-file", "[SEARCH]",
		       /* TRANSLATORS: command description */
		       _("Search by files"),
		       pk_direct_search_files);
	pk_direct_add (priv->cmd_array, "install", "[PKGID]",
		       /* TRANSLATORS: command description */
		       _("Install package"),
		       pk_direct_install);
	pk_direct_add (priv->cmd_array, "remove", "[PKGID]",
		       /* TRANSLATORS: command description */
		       _("Remove package"),
		       pk_direct_remove);
	pk_direct_add (priv->cmd_array, "repo-set-data", "[REPO] [KEY] [VALUE]",
		       /* TRANSLATORS: command description */
		       _("Set repository options"),
		       pk_direct_repo_set_data);

	/* sort by command name */
	g_ptr_array_sort (priv->cmd_array,
			  (GCompareFunc) pk_sort_command_name_cb);

	/* get a list of the commands */
	priv->context = g_option_context_new (NULL);
	cmd_descriptions = pk_direct_get_descriptions (priv->cmd_array);
	g_option_context_set_summary (priv->context, cmd_descriptions);

	/* TRANSLATORS: program name */
	g_set_application_name (_("PackageKit"));
	g_option_context_add_main_entries (priv->context, options, NULL);
	g_option_context_add_group (priv->context, pk_debug_get_option_group ());
	ret = g_option_context_parse (priv->context, &argc, &argv, &error);
	if (!ret) {
		/* TRANSLATORS: the user didn't read the man page */
		g_print ("%s: %s\n", _("Failed to parse arguments"), error->message);
		goto out;
	}

	/* get values from the config file */
	conf = g_key_file_new ();
	conf_filename = pk_util_get_config_filename ();
	ret = g_key_file_load_from_file (conf, conf_filename,
					 G_KEY_FILE_NONE, &error);
	if (!ret) {
		/* TRANSLATORS: probably not yet installed */
		g_print ("%s: %s\n", _("Failed to load the config file"), error->message);
		retval = EXIT_FAILURE;
		goto out;
	}

	/* support DESTDIR */
	destdir = g_getenv ("DESTDIR");
	if (destdir != NULL)
		g_key_file_set_string (conf, "Daemon", "DestDir", destdir);

	/* override the backend name */
	if (backend_name != NULL)
		g_key_file_set_string (conf, "Daemon", "DefaultBackend", backend_name);

	/* resolve 'auto' to an actual name */
	backend_name = g_key_file_get_string (conf, "Daemon", "DefaultBackend", NULL);
	if (backend_name == NULL || g_strcmp0 (backend_name, "auto") == 0) {
		if (!pk_util_set_auto_backend (conf, &error)) {
			g_print ("Failed to resolve auto: %s\n", error->message);
			retval = EXIT_FAILURE;
			goto out;
		}
	}

	/* do stuff on ctrl-c */
	priv->loop = g_main_loop_new (NULL, FALSE);
	g_unix_signal_add_full (G_PRIORITY_DEFAULT, SIGINT,
				pk_direct_sigint_cb, &priv, NULL);

	/* load the backend */
	priv->backend = pk_backend_new (conf);
	if (!pk_backend_load (priv->backend, &error)) {
		/* TRANSLATORS: cannot load the backend the user specified */
		g_print ("%s: %s\n", _("Failed to load the backend"), error->message);
		retval = EXIT_FAILURE;
		goto out;
	}

	/* set up the job */
	priv->job = pk_backend_job_new (conf);
	pk_backend_job_set_cache_age (priv->job, G_MAXUINT);
	pk_backend_job_set_backend (priv->job, priv->backend);
	pk_backend_job_set_vfunc (priv->job, PK_BACKEND_SIGNAL_FINISHED,
				  pk_direct_finished_cb, priv);
	pk_backend_job_set_vfunc (priv->job, PK_BACKEND_SIGNAL_PERCENTAGE,
				  pk_direct_percentage_cb, priv);
	pk_backend_job_set_vfunc (priv->job, PK_BACKEND_SIGNAL_STATUS_CHANGED,
				  pk_direct_status_changed_cb, priv);
	pk_backend_job_set_vfunc (priv->job, PK_BACKEND_SIGNAL_PACKAGE,
				  pk_direct_package_cb, priv);
	pk_backend_job_set_vfunc (priv->job, PK_BACKEND_SIGNAL_ERROR_CODE,
				  pk_direct_error_cb, priv);
	pk_backend_job_set_vfunc (priv->job, PK_BACKEND_SIGNAL_ITEM_PROGRESS,
				  pk_direct_item_progress_cb, priv);

	/* run the specified command */
	ret = pk_direct_run (priv, argv[1], (gchar**) &argv[2], &error);
	if (!ret) {
		if (g_error_matches (error, PK_ERROR, PK_ERROR_NO_SUCH_CMD)) {
			g_autofree gchar *tmp = NULL;
			tmp = g_option_context_get_help (priv->context, TRUE, NULL);
			g_print ("%s", tmp);
		} else {
			g_print ("%s\n", error->message);
		}
		goto out;
	}

	/* unload backend */
	if (!pk_backend_unload (priv->backend)) {
		/* TRANSLATORS: cannot unload the backend the user specified */
		g_print ("%s\n", _("Failed to unload the backend"));
		retval = EXIT_FAILURE;
		goto out;
	}
out:
	if (priv->cmd_array != NULL)
		g_ptr_array_unref (priv->cmd_array);
	if (priv->backend != NULL)
		g_object_unref (priv->backend);
	if (priv->job != NULL)
		g_object_unref (priv->job);
	if (priv->loop != NULL)
		g_main_loop_unref (priv->loop);
	g_option_context_free (priv->context);
	g_free (priv);
	return retval;
}
Esempio n. 3
0
/**
 * 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;
}
Esempio n. 4
0
/**
 * main:
 **/
int
main (int argc, char *argv[])
{
	gboolean ret = TRUE;
	gboolean disable_timer = FALSE;
	gboolean version = FALSE;
	gboolean use_daemon = FALSE;
	gboolean timed_exit = FALSE;
	gboolean immediate_exit = FALSE;
	gboolean keep_environment = FALSE;
	gboolean do_logging = FALSE;
	gchar *backend_name = NULL;
	PkEngine *engine = NULL;
	PkConf *conf = NULL;
	PkSyslog *syslog = NULL;
	GError *error = NULL;
	GOptionContext *context;
	guint timer_id = 0;

	const GOptionEntry options[] = {
		{ "backend", '\0', 0, G_OPTION_ARG_STRING, &backend_name,
		  /* TRANSLATORS: a backend is the system package tool, e.g. yum, apt */
		  _("Packaging backend to use, e.g. dummy"), NULL },
		{ "daemonize", '\0', 0, G_OPTION_ARG_NONE, &use_daemon,
		  /* TRANSLATORS: if we should run in the background */
		  _("Daemonize and detach from the terminal"), NULL },
		{ "disable-timer", '\0', 0, G_OPTION_ARG_NONE, &disable_timer,
		  /* TRANSLATORS: if we should not monitor how long we are inactive for */
		  _("Disable the idle timer"), NULL },
		{ "version", '\0', 0, G_OPTION_ARG_NONE, &version,
		  /* TRANSLATORS: show version */
		  _("Show version and exit"), NULL },
		{ "timed-exit", '\0', 0, G_OPTION_ARG_NONE, &timed_exit,
		  /* TRANSLATORS: exit after we've started up, used for user profiling */
		  _("Exit after a small delay"), NULL },
		{ "immediate-exit", '\0', 0, G_OPTION_ARG_NONE, &immediate_exit,
		  /* TRANSLATORS: exit straight away, used for automatic profiling */
		  _("Exit after the engine has loaded"), NULL },
		{ "keep-environment", '\0', 0, G_OPTION_ARG_NONE, &keep_environment,
		  /* TRANSLATORS: don't unset environment variables, used for debugging */
		  _("Don't clear environment on startup"), 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 < 35)
	g_type_init ();
#endif

	/* TRANSLATORS: describing the service that is running */
	context = g_option_context_new (_("PackageKit service"));
	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);

	if (version) {
		g_print ("Version %s\n", VERSION);
		goto exit_program;
	}

#if GLIB_CHECK_VERSION(2,29,19)
	/* do stuff on ctrl-c */
	g_unix_signal_add_full (G_PRIORITY_DEFAULT,
				SIGINT,
				pk_main_sigint_cb,
				loop,
				NULL);
#else
	signal (SIGINT, pk_main_sigint_handler);
#endif

	/* we need to daemonize before we get a system connection */
	if (use_daemon && daemon (0, 0)) {
		g_print ("Could not daemonize: %s\n", g_strerror (errno));
		goto exit_program;
	}

	/* don't let GIO start it's own session bus: http://bugzilla.gnome.org/show_bug.cgi?id=526454 */
	setenv ("GIO_USE_VFS", "local", 1);

	/* we don't actually need to do this, except it rules out the
	 * 'it works from the command line but not service activation' bugs */
#ifdef HAVE_CLEARENV
	g_debug ("keep_environment: %i\n", keep_environment);
	if (!keep_environment)
		clearenv ();
#endif

	/* get values from the config file */
	conf = pk_conf_new ();
	pk_conf_set_bool (conf, "KeepEnvironment", keep_environment);

	/* log the startup */
	syslog = pk_syslog_new ();
	pk_syslog_add (syslog, PK_SYSLOG_TYPE_INFO, "daemon start");

	/* do we log? */
	do_logging = pk_conf_get_bool (conf, "TransactionLogging");
	g_debug ("Log all transactions: %i", do_logging);

	/* after how long do we timeout? */
	exit_idle_time = pk_conf_get_int (conf, "ShutdownTimeout");
	g_debug ("daemon shutdown set to %i seconds", exit_idle_time);

	/* override the backend name */
	if (backend_name != NULL) {
		pk_conf_set_string (conf,
				    "DefaultBackend",
				    backend_name);
	}

	/* resolve 'auto' to an actual name */
	backend_name = pk_conf_get_string (conf, "DefaultBackend");
	if (g_strcmp0 (backend_name, "auto") == 0) {
		ret  = pk_main_set_auto_backend (conf, &error);
		if (!ret) {
			g_print ("Failed to resolve auto: %s",
				 error->message);
			g_error_free (error);
			goto out;
		}
	}

	loop = g_main_loop_new (NULL, FALSE);

	/* create a new engine object */
	engine = pk_engine_new ();
	g_signal_connect (engine, "quit",
			  G_CALLBACK (pk_main_quit_cb), loop);

	/* load the backend */
	ret = pk_engine_load_backend (engine, &error);
	if (!ret) {
		/* TRANSLATORS: cannot load the backend the user specified */
		g_print ("Failed to load the backend: %s",
			 error->message);
		g_error_free (error);
		goto out;
	}

	/* Only timeout and close the mainloop if we have specified it
	 * on the command line */
	if (timed_exit)
		g_timeout_add_seconds (20, (GSourceFunc) timed_exit_cb, loop);

	/* only poll when we are alive */
	if (exit_idle_time != 0 && !disable_timer) {
		timer_id = g_timeout_add_seconds (5, (GSourceFunc) pk_main_timeout_check_cb, engine);
		g_source_set_name_by_id (timer_id, "[PkMain] main poll");
	}

	/* immediatly exit */
	if (immediate_exit)
		g_timeout_add (50, (GSourceFunc) timed_exit_cb, loop);

	/* run until quit */
	g_main_loop_run (loop);
out:
	/* log the shutdown */
	pk_syslog_add (syslog, PK_SYSLOG_TYPE_INFO, "daemon quit");

	if (timer_id > 0)
		g_source_remove (timer_id);

	if (loop != NULL)
		g_main_loop_unref (loop);
	g_object_unref (syslog);
	g_object_unref (conf);
	if (engine != NULL)
		g_object_unref (engine);
	g_free (backend_name);

exit_program:
	return 0;
}