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