示例#1
0
/**
 * pk_backend_spawn_init:
 **/
static void
pk_backend_spawn_init (PkBackendSpawn *backend_spawn)
{
	backend_spawn->priv = PK_BACKEND_SPAWN_GET_PRIVATE (backend_spawn);
	backend_spawn->priv->kill_id = 0;
	backend_spawn->priv->name = NULL;
	backend_spawn->priv->stdout_func = NULL;
	backend_spawn->priv->stderr_func = NULL;
	backend_spawn->priv->finished = FALSE;
	backend_spawn->priv->conf = pk_conf_new ();
	backend_spawn->priv->backend = pk_backend_new ();
	backend_spawn->priv->spawn = pk_spawn_new ();
	g_signal_connect (backend_spawn->priv->spawn, "exit",
			  G_CALLBACK (pk_backend_spawn_exit_cb), backend_spawn);
	g_signal_connect (backend_spawn->priv->spawn, "stdout",
			  G_CALLBACK (pk_backend_spawn_stdout_cb), backend_spawn);
	g_signal_connect (backend_spawn->priv->spawn, "stderr",
			  G_CALLBACK (pk_backend_spawn_stderr_cb), backend_spawn);

	/* set if SIGKILL is allowed */
	backend_spawn->priv->allow_sigkill = pk_conf_get_bool (backend_spawn->priv->conf, "BackendSpawnAllowSIGKILL");
	g_object_set (backend_spawn->priv->spawn,
		      "allow-sigkill", backend_spawn->priv->allow_sigkill,
		      NULL);
}
示例#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;
}
示例#3
0
/**
 * main:
 **/
int
main (int argc, char *argv[])
{
	DBusGConnection *system_connection;
	EggDbusMonitor *monitor;
	gboolean ret;
	gboolean disable_timer = FALSE;
	gboolean version = FALSE;
	gboolean use_daemon = FALSE;
	gboolean timed_exit = FALSE;
	gboolean immediate_exit = FALSE;
	gboolean do_logging = FALSE;
	gchar *backend_name = NULL;
	PkEngine *engine = NULL;
	PkBackend *backend = NULL;
	PkConf *conf = NULL;
	PkSyslog *syslog = NULL;
	GError *error = NULL;
	GOptionContext *context;

	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 },
		{ NULL}
	};

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

	if (! g_thread_supported ())
		g_thread_init (NULL);
	dbus_g_thread_init ();
	g_type_init ();

	/* 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, egg_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;
	}

	/* check if an instance is already running */
	monitor = egg_dbus_monitor_new ();
	egg_dbus_monitor_assign (monitor, EGG_DBUS_MONITOR_SYSTEM, PK_DBUS_SERVICE);
	ret = egg_dbus_monitor_is_connected (monitor);
	g_object_unref (monitor);
	if (ret) {
		g_print ("Already running service which provides %s\n", PK_DBUS_SERVICE);
		goto exit_program;
	}

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

	/* 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);

	/* check dbus connections, exit if not valid */
	system_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
	if (error) {
		/* TRANSLATORS: fatal error, dbus is not running */
		g_print ("%s: %s\n", _("Cannot connect to the system bus"), error->message);
		g_error_free (error);
		goto exit_program;
	}

	/* 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
	clearenv ();
#endif

	/* get values from the config file */
	conf = pk_conf_new ();

	/* 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");
	egg_debug ("Log all transactions: %i", do_logging);
	if (do_logging)
		egg_debug_set_log_filename ("/var/log/PackageKit");

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

	if (backend_name == NULL) {
		backend_name = pk_conf_get_string (conf, "DefaultBackend");
		egg_debug ("using default backend %s", backend_name);
	}

	/* load our chosen backend */
	backend = pk_backend_new ();
	ret = pk_backend_set_name (backend, backend_name);
	g_free (backend_name);

	/* all okay? */
	if (!ret)
		egg_error ("cannot continue, backend invalid");

	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);

	if (!pk_object_register (system_connection, G_OBJECT (engine), &error)) {
		/* TRANSLATORS: cannot register on system bus, unknown reason -- geeky error follows */
		g_print ("%s %s\n", _("Error trying to start:"), 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 every 10 seconds when we are alive */
	if (exit_idle_time != 0 && !disable_timer)
		g_timeout_add_seconds (5, (GSourceFunc) pk_main_timeout_check_cb, engine);

	/* 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");

	g_main_loop_unref (loop);
	g_object_unref (syslog);
	g_object_unref (conf);
	g_object_unref (engine);
	g_object_unref (backend);

exit_program:
	return 0;
}