/** * pk_backend_start_job: * * This is called just before the threaded transaction method, and in * the newly created thread context. e.g. * * >>> desc->job_start(backend) * (locked backend) * >>> desc->backend_method_we_want_to_run(backend) * <<< ::Package(PK_INFO_ENUM_INSTALLING,"hal;0.1.1;i386;fedora","Hardware Stuff") * >>> desc->job_stop(backend) * (unlocked backend) * <<< ::Finished() * * or in the case of backend_method_we_want_to_run() failure: * >>> desc->job_start(backend) * (locked backend) * >>> desc->backend_method_we_want_to_run(backend) * <<< ::ErrorCode(PK_ERROR_ENUM_FAILED_TO_FIND,"no package") * >>> desc->job_stop(backend) * (unlocked backend) * <<< ::Finished() * * or in the case of job_start() failure: * >>> desc->job_start(backend) * (failed to lock backend) * <<< ::ErrorCode(PK_ERROR_ENUM_FAILED_TO_LOCK,"no pid file") * >>> desc->job_stop(backend) * <<< ::Finished() * * It is *not* called for non-threaded backends, as multiple processes * would be inherently racy. */ void pk_backend_start_job (PkBackend *backend, PkBackendJob *job) { g_return_if_fail (PK_IS_BACKEND (backend)); /* common stuff */ pk_backend_job_set_backend (job, backend); if (pk_backend_job_get_started (job)) { g_warning ("trying to start an already started job again"); return; } pk_backend_job_set_started (job, TRUE); /* optional */ if (backend->priv->desc->job_start != NULL) backend->priv->desc->job_start (backend, job); }
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; }