Beispiel #1
0
/**
 * pk_task_list_item_create:
 **/
static PkTaskListItem *
pk_task_list_item_create (PkTaskList *tlist, const gchar *tid)
{
	gboolean ret;
	GError *error = NULL;
	PkTaskListItem *item;

	g_return_val_if_fail (PK_IS_TASK_LIST (tlist), NULL);
	g_return_val_if_fail (tid != NULL, NULL);

	item = g_new0 (PkTaskListItem, 1);
	item->tid = g_strdup (tid);
	item->monitor = pk_client_new ();
	g_signal_connect (item->monitor, "status-changed",
			  G_CALLBACK (pk_task_list_status_changed_cb), tlist);
	g_signal_connect (item->monitor, "finished",
			  G_CALLBACK (gpk_task_list_finished_cb), tlist);
	g_signal_connect (item->monitor, "error-code",
			  G_CALLBACK (gpk_task_list_error_code_cb), tlist);
	g_signal_connect (item->monitor, "message",
			  G_CALLBACK (gpk_task_list_message_cb), tlist);
	ret = pk_client_set_tid (item->monitor, tid, &error);
	if (!ret) {
		egg_error ("could not set tid: %s", error->message);
		g_error_free (error);
		pk_task_list_item_free (item);
		return NULL;
	}
	pk_client_set_use_buffer (item->monitor, TRUE, NULL);
	pk_client_get_role (item->monitor, &item->role, &item->text, NULL);
	pk_client_get_status (item->monitor, &item->status, NULL);

	return item;
}
Beispiel #2
0
/**
 * pk_package_sack_init:
 **/
static void
pk_package_sack_init (PkPackageSack *sack)
{
	PkPackageSackPrivate *priv;
	sack->priv = PK_PACKAGE_SACK_GET_PRIVATE (sack);
	priv = sack->priv;

	priv->array = g_ptr_array_new_with_free_func (g_object_unref);
	priv->client = pk_client_new ();
}
void
gs_plugin_initialize (GsPlugin *plugin)
{
	GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));

	g_mutex_init (&priv->client_mutex);
	priv->client = pk_client_new ();

	pk_client_set_background (priv->client, FALSE);
	pk_client_set_cache_age (priv->client, G_MAXUINT);
}
Beispiel #4
0
void
pk_task_list_test (EggTest *test)
{
	PkConnection *connection;
	PkTaskList *tlist;
	PkClient *client;
	gboolean ret;
	GError *error = NULL;

	if (!egg_test_start (test, "PkTaskList"))
		return;

	/* check to see if there is a daemon running */
	connection = pk_connection_new ();
	ret = pk_connection_valid (connection);
	g_object_unref (connection);
	if (!ret) {
		egg_warning ("daemon is not running, skipping tests");
		goto out;
	}

	/************************************************************/
	egg_test_title (test, "get client");
	tlist = pk_task_list_new ();
	egg_test_assert (test, tlist != NULL);
	g_signal_connect (tlist, "finished",
			  G_CALLBACK (pk_task_list_test_finished_cb), test);

	/************************************************************/
	egg_test_title (test, "search for power");
	client = pk_client_new ();
	ret = pk_client_search_name (client, PK_FILTER_ENUM_NONE, "power", &error);
	if (!ret) {
		egg_test_failed (test, "failed: %s", error->message);
		g_error_free (error);
	}
	egg_test_loop_wait (test, 5000);
	egg_test_success (test, NULL);

	/************************************************************/
	egg_test_title (test, "we finished?");
	if (finished)
		egg_test_success (test, NULL);
	else
		egg_test_failed (test, "not finished");

	g_object_unref (tlist);
	g_object_unref (client);
out:
	egg_test_end (test);
}
/**
 * main:
 **/
int
main (int argc, char *argv[])
{
	GOptionContext *context;
	GConfClient *gconf_client;
	GtkWidget *widget;
	GtkTreeSelection *selection;
	GtkEntryCompletion *completion;
	UniqueApp *unique_app;
	gboolean ret;
	guint retval;
	guint xid = 0;
	GError *error = NULL;

	const GOptionEntry options[] = {
		{ "filter", 'f', 0, G_OPTION_ARG_STRING, &filter,
		  /* TRANSLATORS: preset the GtktextBox with this filter text */
		  N_("Set the filter to this value"), NULL },
		{ "parent-window", 'p', 0, G_OPTION_ARG_INT, &xid,
		  /* TRANSLATORS: we can make this modal (stay on top of) another window */
		  _("Set the parent window to make this modal"), NULL },
		{ NULL}
	};

	setlocale (LC_ALL, "");

	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	if (! g_thread_supported ())
		g_thread_init (NULL);
	g_type_init ();
	gtk_init (&argc, &argv);

	context = g_option_context_new (NULL);
	g_option_context_set_summary (context, _("Software Log Viewer"));
	g_option_context_add_main_entries (context, options, NULL);
	g_option_context_add_group (context, egg_debug_get_option_group ());
	g_option_context_add_group (context, gtk_get_option_group (TRUE));
	g_option_context_parse (context, &argc, &argv, NULL);
	g_option_context_free (context);

	/* are we running privileged */
	ret = gpk_check_privileged_user (_("Log viewer"), TRUE);
	if (!ret)
		return 1;

	/* are we already activated? */
	unique_app = unique_app_new ("org.freedesktop.PackageKit.LogViewer", NULL);
	if (unique_app_is_running (unique_app)) {
		egg_debug ("You have another instance running. This program will now close");
		unique_app_send_message (unique_app, UNIQUE_ACTIVATE, NULL);
		goto unique_out;
	}
	g_signal_connect (unique_app, "message-received",
			  G_CALLBACK (gpk_log_message_received_cb), NULL);

	/* add application specific icons to search path */
	gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
					   GPK_DATA G_DIR_SEPARATOR_S "icons");

	client = pk_client_new ();
	g_object_set (client,
		      "background", FALSE,
		      NULL);

	/* get UI */
	builder = gtk_builder_new ();
	retval = gtk_builder_add_from_file (builder, GPK_DATA "/gpk-log.ui", &error);
	if (retval == 0) {
		egg_warning ("failed to load ui: %s", error->message);
		g_error_free (error);
		goto out_build;
	}

	widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_simple"));
	gtk_window_set_icon_name (GTK_WINDOW (widget), GPK_ICON_SOFTWARE_LOG);

	/* set a size, if the screen allows */
	gpk_window_set_size_request (GTK_WINDOW (widget), 900, 300);

	/* if command line arguments are set, then setup UI */
	if (filter != NULL) {
		widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry_package"));
		gtk_entry_set_text (GTK_ENTRY(widget), filter);
	}

	/* Get the main window quit */
	g_signal_connect_swapped (widget, "delete_event", G_CALLBACK (gtk_main_quit), NULL);

	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_close"));
	g_signal_connect_swapped (widget, "clicked", G_CALLBACK (gtk_main_quit), NULL);
	gtk_widget_grab_default (widget);

	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_help"));
	g_signal_connect (widget, "clicked", G_CALLBACK (gpk_log_button_help_cb), NULL);
	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_refresh"));
	g_signal_connect (widget, "clicked", G_CALLBACK (gpk_log_button_refresh_cb), NULL);
	gtk_widget_hide (widget);
	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_filter"));
	g_signal_connect (widget, "clicked", G_CALLBACK (gpk_log_button_filter_cb), NULL);

	/* hit enter in the search box for filter */
	widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry_package"));
	g_signal_connect (widget, "activate", G_CALLBACK (gpk_log_button_filter_cb), NULL);

	/* autocompletion can be turned off as it's slow */
	gconf_client = gconf_client_get_default ();
	ret = gconf_client_get_bool (gconf_client, GPK_CONF_AUTOCOMPLETE, NULL);
	if (ret) {
		/* create the completion object */
		completion = gpk_package_entry_completion_new ();
		widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry_package"));
		gtk_entry_set_completion (GTK_ENTRY (widget), completion);
		g_object_unref (completion);
	} else {
		/* use search as you type */
		g_signal_connect (widget, "key-release-event", G_CALLBACK (gpk_log_entry_filter_cb), NULL);
	}
	g_object_unref (gconf_client);

	/* create list stores */
	list_store = gtk_list_store_new (GPK_LOG_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING,
					 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
					 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);

	/* create transaction_id tree view */
	widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_simple"));
	gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
				 GTK_TREE_MODEL (list_store));

	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
	g_signal_connect (selection, "changed",
			  G_CALLBACK (gpk_log_treeview_clicked_cb), NULL);

	/* add columns to the tree view */
	pk_treeview_add_general_columns (GTK_TREE_VIEW (widget));
	gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget));

	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store),
					      GPK_LOG_COLUMN_TIMESPEC, GTK_SORT_DESCENDING);

	/* show */
	widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_simple"));
	gtk_widget_show (widget);

	/* set the parent window if it is specified */
	if (xid != 0) {
		egg_debug ("Setting xid %i", xid);
		gpk_window_set_parent_xid (GTK_WINDOW (widget), xid);
	}

	/* get the update list */
	gpk_log_refresh ();

	gtk_main ();

out_build:
	g_object_unref (builder);
	g_object_unref (list_store);
	g_object_unref (client);
	g_free (transaction_id);
	g_free (filter);
	if (transactions != NULL)
		g_ptr_array_unref (transactions);
unique_out:
	g_object_unref (unique_app);
	return 0;
}
Beispiel #6
0
/**
 * gpk_log_startup_cb:
 **/
static void
gpk_log_startup_cb (GtkApplication *application, gpointer user_data)
{
	gboolean ret;
	GError *error = NULL;
	GSettings *settings;
	GtkEntryCompletion *completion;
	GtkTreeSelection *selection;
	GtkWidget *widget;
	GtkWindow *window;
	guint retval;

	client = pk_client_new ();
	g_object_set (client,
		      "background", FALSE,
		      NULL);

	/* get UI */
	builder = gtk_builder_new ();
	retval = gtk_builder_add_from_file (builder, GPK_DATA "/pi-gpk-log.ui", &error);
	if (retval == 0) {
		g_warning ("failed to load ui: %s", error->message);
		g_error_free (error);
		goto out;
	}

	window = GTK_WINDOW (gtk_builder_get_object (builder, "dialog_simple"));
	gtk_window_set_icon_name (window, GPK_ICON_SOFTWARE_LOG);
	gtk_window_set_application (window, application);

	/* set a size, as the screen allows */
	gpk_window_set_size_request (window, 1200, 1200);

	/* if command line arguments are set, then setup UI */
	if (filter != NULL) {
		widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry_package"));
		gtk_entry_set_text (GTK_ENTRY(widget), filter);
	}

	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_close"));
	g_signal_connect (widget, "clicked",
			  G_CALLBACK (gpk_log_button_close_cb), application);
	gtk_widget_grab_default (widget);

	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_refresh"));
	g_signal_connect (widget, "clicked", G_CALLBACK (gpk_log_button_refresh_cb), NULL);
	gtk_widget_hide (widget);
	widget = GTK_WIDGET (gtk_builder_get_object (builder, "button_filter"));
	g_signal_connect (widget, "clicked", G_CALLBACK (gpk_log_button_filter_cb), NULL);

	/* hit enter in the search box for filter */
	widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry_package"));
	g_signal_connect (widget, "activate", G_CALLBACK (gpk_log_button_filter_cb), NULL);

	/* autocompletion can be turned off as it's slow */
	settings = g_settings_new (GPK_SETTINGS_SCHEMA);
	ret = g_settings_get_boolean (settings, GPK_SETTINGS_AUTOCOMPLETE);
	if (ret) {
		/* create the completion object */
		completion = gpk_package_entry_completion_new ();
		widget = GTK_WIDGET (gtk_builder_get_object (builder, "entry_package"));
		gtk_entry_set_completion (GTK_ENTRY (widget), completion);
		g_object_unref (completion);
	} else {
		/* use search as you type */
		g_signal_connect (widget, "key-release-event", G_CALLBACK (gpk_log_entry_filter_cb), NULL);
	}
	g_object_unref (settings);

	/* create list stores */
	list_store = gtk_list_store_new (GPK_LOG_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING,
					 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
					 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);

	/* create transaction_id tree view */
	widget = GTK_WIDGET (gtk_builder_get_object (builder, "treeview_simple"));
	gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
				 GTK_TREE_MODEL (list_store));

	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
	g_signal_connect (selection, "changed",
			  G_CALLBACK (gpk_log_treeview_clicked_cb), NULL);

	/* add columns to the tree view */
	pk_treeview_add_general_columns (GTK_TREE_VIEW (widget));
	gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget));

	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store),
					      GPK_LOG_COLUMN_TIMESPEC, GTK_SORT_DESCENDING);

	/* show */
	widget = GTK_WIDGET (gtk_builder_get_object (builder, "dialog_simple"));
	gtk_widget_show (widget);

	/* set the parent window if it is specified */
	if (xid != 0) {
		g_debug ("Setting xid %i", xid);
		gpk_window_set_parent_xid (GTK_WINDOW (widget), xid);
	}

	/* get the update list */
	gpk_log_refresh ();
out:
	g_object_unref (list_store);
	g_object_unref (client);
	g_free (transaction_id);
	g_free (filter);
	if (transactions != NULL)
		g_ptr_array_unref (transactions);
}
Beispiel #7
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;
}