gboolean pk_backend_spawn_set_filter_stderr (PkBackendSpawn *backend_spawn, PkBackendSpawnFilterFunc func) { g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); backend_spawn->priv->stderr_func = func; return TRUE; }
gboolean pk_backend_spawn_exit (PkBackendSpawn *backend_spawn) { g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); pk_spawn_exit (backend_spawn->priv->spawn); return TRUE; }
gboolean pk_backend_spawn_helper (PkBackendSpawn *backend_spawn, PkBackendJob *job, const gchar *first_element, ...) { gboolean ret = TRUE; va_list args; g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); g_return_val_if_fail (first_element != NULL, FALSE); g_return_val_if_fail (backend_spawn->priv->name != NULL, FALSE); /* save this */ backend_spawn->priv->is_busy = TRUE; backend_spawn->priv->job = job; backend_spawn->priv->backend = g_object_ref (pk_backend_job_get_backend (job)); /* don't auto-kill this */ if (backend_spawn->priv->kill_id > 0) { g_source_remove (backend_spawn->priv->kill_id); backend_spawn->priv->kill_id = 0; } /* get the argument list */ va_start (args, first_element); ret = pk_backend_spawn_helper_va_list (backend_spawn, job, first_element, &args); va_end (args); return ret; }
static void pk_backend_spawn_exit_cb (PkSpawn *spawn, PkSpawnExitType exit_enum, PkBackendSpawn *backend_spawn) { gboolean ret; g_return_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn)); /* reset the busy flag */ backend_spawn->priv->is_busy = FALSE; /* if we force killed the process, set an error */ if (exit_enum == PK_SPAWN_EXIT_TYPE_SIGKILL) { /* we just call this failed, and set an error */ pk_backend_job_error_code (backend_spawn->priv->job, PK_ERROR_ENUM_PROCESS_KILL, "Process had to be killed to be cancelled"); } if (exit_enum == PK_SPAWN_EXIT_TYPE_DISPATCHER_EXIT || exit_enum == PK_SPAWN_EXIT_TYPE_DISPATCHER_CHANGED) { g_debug ("dispatcher exited, nothing to see here"); return; } /* only emit if not finished */ if (!backend_spawn->priv->finished) { g_debug ("script exited without doing finished, tidying up"); ret = pk_backend_job_has_set_error_code (backend_spawn->priv->job); if (!ret) { pk_backend_job_error_code (backend_spawn->priv->job, PK_ERROR_ENUM_INTERNAL_ERROR, "The backend exited unexpectedly. " "This is a serious error as the spawned backend did not complete the pending transaction."); } pk_backend_job_finished (backend_spawn->priv->job); } }
void pk_backend_spawn_set_allow_sigkill (PkBackendSpawn *backend_spawn, gboolean allow_sigkill) { g_return_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn)); g_object_set (backend_spawn->priv->spawn, "allow-sigkill", allow_sigkill, NULL); }
gboolean pk_backend_spawn_set_name (PkBackendSpawn *backend_spawn, const gchar *name) { g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); g_return_val_if_fail (name != NULL, FALSE); g_free (backend_spawn->priv->name); backend_spawn->priv->name = g_strdup (name); return TRUE; }
gboolean pk_backend_spawn_kill (PkBackendSpawn *backend_spawn) { g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); /* set an error as the script will just exit without doing finished */ pk_backend_job_error_code (backend_spawn->priv->job, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "the script was killed as the action was cancelled"); pk_spawn_kill (backend_spawn->priv->spawn); return TRUE; }
static gboolean pk_backend_spawn_exit_timeout_cb (PkBackendSpawn *backend_spawn) { g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); /* only try to close if running */ if (pk_spawn_is_running (backend_spawn->priv->spawn)) { g_debug ("closing dispatcher as running and is idle"); pk_spawn_exit (backend_spawn->priv->spawn); } backend_spawn->priv->kill_id = 0; return FALSE; }
static void pk_backend_spawn_stderr_cb (PkBackendSpawn *spawn, const gchar *line, PkBackendSpawn *backend_spawn) { gboolean ret; g_return_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn)); /* do we ignore with a filter func ? */ if (backend_spawn->priv->stderr_func != NULL) { ret = backend_spawn->priv->stderr_func (backend_spawn->priv->job, line); if (!ret) return; } g_warning ("STDERR: %s", line); }
/** * pk_backend_spawn_inject_data: **/ gboolean pk_backend_spawn_inject_data (PkBackendSpawn *backend_spawn, const gchar *line, GError **error) { gboolean ret; g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); /* do we ignore with a filter func ? */ if (backend_spawn->priv->stdout_func != NULL) { ret = backend_spawn->priv->stdout_func (backend_spawn->priv->backend, line); if (!ret) return TRUE; } return pk_backend_spawn_parse_stdout (backend_spawn, line, error); }
/** * pk_backend_spawn_stderr_cb: **/ static void pk_backend_spawn_stderr_cb (PkBackendSpawn *spawn, const gchar *line, PkBackendSpawn *backend_spawn) { gboolean ret; g_return_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn)); /* do we ignore with a filter func ? */ if (backend_spawn->priv->stderr_func != NULL) { ret = backend_spawn->priv->stderr_func (backend_spawn->priv->job, line); if (!ret) return; } /* send warning up to session, this is never going to be pretty... */ g_warning ("STDERR: %s", line); pk_backend_job_message (backend_spawn->priv->job, PK_MESSAGE_ENUM_BACKEND_ERROR, "%s", line); }
/** * pk_backend_spawn_finalize: **/ static void pk_backend_spawn_finalize (GObject *object) { PkBackendSpawn *backend_spawn; g_return_if_fail (PK_IS_BACKEND_SPAWN (object)); backend_spawn = PK_BACKEND_SPAWN (object); if (backend_spawn->priv->kill_id > 0) g_source_remove (backend_spawn->priv->kill_id); g_free (backend_spawn->priv->name); g_object_unref (backend_spawn->priv->conf); g_object_unref (backend_spawn->priv->spawn); g_object_unref (backend_spawn->priv->backend); G_OBJECT_CLASS (pk_backend_spawn_parent_class)->finalize (object); }
/** * pk_backend_spawn_set_allow_sigkill: **/ gboolean pk_backend_spawn_set_allow_sigkill (PkBackendSpawn *backend_spawn, gboolean allow_sigkill) { gboolean ret = TRUE; g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); /* have we banned this in the config ile */ if (!backend_spawn->priv->allow_sigkill && allow_sigkill) { g_warning ("cannot set allow_cancel TRUE as BackendSpawnAllowSIGKILL is set to FALSE in PackageKit.conf"); ret = FALSE; goto out; } /* set this property */ g_object_set (backend_spawn->priv->spawn, "allow-sigkill", allow_sigkill, NULL); out: return ret; }
/** * pk_backend_spawn_helper: **/ gboolean pk_backend_spawn_helper (PkBackendSpawn *backend_spawn, const gchar *first_element, ...) { gboolean ret; va_list args; g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); g_return_val_if_fail (first_element != NULL, FALSE); g_return_val_if_fail (backend_spawn->priv->name != NULL, FALSE); /* don't auto-kill this */ if (backend_spawn->priv->kill_id > 0) { g_source_remove (backend_spawn->priv->kill_id); backend_spawn->priv->kill_id = 0; } /* get the argument list */ va_start (args, first_element); ret = pk_backend_spawn_helper_va_list (backend_spawn, first_element, &args); va_end (args); return ret; }
/** * pk_backend_spawn_parse_stdout: **/ static gboolean pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line, GError **error) { gchar **sections; guint size; gchar *command; gchar *text; gboolean ret = TRUE; guint64 speed; PkInfoEnum info; PkRestartEnum restart; PkGroupEnum group; gulong package_size; gint percentage; PkErrorEnum error_enum; PkStatusEnum status_enum; PkMessageEnum message_enum; PkRestartEnum restart_enum; PkSigTypeEnum sig_type; PkUpdateStateEnum update_state_enum; PkMediaTypeEnum media_type_enum; PkDistroUpgradeEnum distro_upgrade_enum; PkBackendSpawnPrivate *priv = backend_spawn->priv; g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); /* check if output line */ if (line == NULL) return FALSE; /* split by tab */ sections = g_strsplit (line, "\t", 0); command = sections[0]; /* get size */ size = g_strv_length (sections); if (g_strcmp0 (command, "package") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (pk_package_id_check (sections[2]) == FALSE) { g_set_error_literal (error, 1, 0, "invalid package_id"); ret = FALSE; goto out; } info = pk_info_enum_from_string (sections[1]); if (info == PK_INFO_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Info enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } pk_backend_package (priv->backend, info, sections[2], sections[3]); } else if (g_strcmp0 (command, "details") == 0) { if (size != 7) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } group = pk_group_enum_from_string (sections[3]); /* ITS4: ignore, checked for overflow */ package_size = atol (sections[6]); if (package_size > 1073741824) { g_set_error_literal (error, 1, 0, "package size cannot be larger than one Gb"); ret = FALSE; goto out; } text = g_strdup (sections[4]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); pk_backend_details (priv->backend, sections[1], sections[2], group, text, sections[5], package_size); g_free (text); } else if (g_strcmp0 (command, "finished") == 0) { if (size != 1) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } pk_backend_finished (priv->backend); /* from this point on, we can start the kill timer */ pk_backend_spawn_start_kill_timer (backend_spawn); } else if (g_strcmp0 (command, "files") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } pk_backend_files (priv->backend, sections[1], sections[2]); } else if (g_strcmp0 (command, "repo-detail") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (g_strcmp0 (sections[3], "true") == 0) { pk_backend_repo_detail (priv->backend, sections[1], sections[2], TRUE); } else if (g_strcmp0 (sections[3], "false") == 0) { pk_backend_repo_detail (priv->backend, sections[1], sections[2], FALSE); } else { g_set_error (error, 1, 0, "invalid qualifier '%s'", sections[3]); ret = FALSE; goto out; } } else if (g_strcmp0 (command, "updatedetail") == 0) { if (size != 13) { g_set_error (error, 1, 0, "invalid command '%s', size %i", command, size); ret = FALSE; goto out; } restart = pk_restart_enum_from_string (sections[7]); if (restart == PK_RESTART_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[7]); ret = FALSE; goto out; } update_state_enum = pk_update_state_enum_from_string (sections[10]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (sections[8], ";", '\n'); g_strdelimit (sections[9], ";", '\n'); pk_backend_update_detail (priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5], sections[6], restart, sections[8], sections[9], update_state_enum, sections[11], sections[12]); } else if (g_strcmp0 (command, "percentage") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } ret = pk_strtoint (sections[1], &percentage); if (!ret) { g_set_error (error, 1, 0, "invalid percentage value %s", sections[1]); ret = FALSE; } else if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid percentage value %i", percentage); ret = FALSE; } else { pk_backend_set_percentage (priv->backend, percentage); } } else if (g_strcmp0 (command, "subpercentage") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } ret = pk_strtoint (sections[1], &percentage); if (!ret) { g_set_error (error, 1, 0, "invalid subpercentage value %s", sections[1]); ret = FALSE; } else if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid subpercentage value %i", percentage); ret = FALSE; } else { pk_backend_set_sub_percentage (priv->backend, percentage); } } else if (g_strcmp0 (command, "item-percentage") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (!pk_package_id_check (sections[1])) { g_set_error (error, 1, 0, "invalid package_id"); ret = FALSE; goto out; } ret = pk_strtoint (sections[2], &percentage); if (!ret) { g_set_error (error, 1, 0, "invalid item-percentage value %s", sections[1]); ret = FALSE; } else if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid item-percentage value %i", percentage); ret = FALSE; } else { pk_backend_set_item_progress (priv->backend, sections[1], percentage); } } else if (g_strcmp0 (command, "error") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } error_enum = pk_error_enum_from_string (sections[1]); if (error_enum == PK_ERROR_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Error enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } /* convert back all the ;'s to newlines */ text = g_strdup (sections[2]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); /* convert % else we try to format them */ g_strdelimit (text, "%", '$'); pk_backend_error_code (priv->backend, error_enum, text); g_free (text); } else if (g_strcmp0 (command, "requirerestart") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } restart_enum = pk_restart_enum_from_string (sections[1]); if (restart_enum == PK_RESTART_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } if (!pk_package_id_check (sections[2])) { g_set_error (error, 1, 0, "invalid package_id"); ret = FALSE; goto out; } pk_backend_require_restart (priv->backend, restart_enum, sections[2]); } else if (g_strcmp0 (command, "message") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } message_enum = pk_message_enum_from_string (sections[1]); if (message_enum == PK_MESSAGE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Message enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } text = g_strdup (sections[2]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); pk_backend_message (priv->backend, message_enum, text); g_free (text); } else if (g_strcmp0 (command, "change-transaction-data") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } pk_backend_set_transaction_data (priv->backend, sections[1]); } else if (g_strcmp0 (command, "status") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } status_enum = pk_status_enum_from_string (sections[1]); if (status_enum == PK_STATUS_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Status enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } pk_backend_set_status (priv->backend, status_enum); } else if (g_strcmp0 (command, "speed") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } ret = pk_strtouint64 (sections[1], &speed); if (!ret) { g_set_error (error, 1, 0, "failed to parse speed: '%s'", sections[1]); ret = FALSE; goto out; } pk_backend_set_speed (priv->backend, speed); } else if (g_strcmp0 (command, "allow-cancel") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (g_strcmp0 (sections[1], "true") == 0) { pk_backend_set_allow_cancel (priv->backend, TRUE); } else if (g_strcmp0 (sections[1], "false") == 0) { pk_backend_set_allow_cancel (priv->backend, FALSE); } else { g_set_error (error, 1, 0, "invalid section '%s'", sections[1]); ret = FALSE; goto out; } } else if (g_strcmp0 (command, "no-percentage-updates") == 0) { if (size != 1) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } pk_backend_set_percentage (priv->backend, PK_BACKEND_PERCENTAGE_INVALID); } else if (g_strcmp0 (command, "repo-signature-required") == 0) { if (size != 9) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } sig_type = pk_sig_type_enum_from_string (sections[8]); if (sig_type == PK_SIGTYPE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Sig enum not recognised, and hence ignored: '%s'", sections[8]); ret = FALSE; goto out; } if (pk_strzero (sections[1])) { g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } if (pk_strzero (sections[2])) { g_set_error (error, 1, 0, "repository name blank, and hence ignored: '%s'", sections[2]); ret = FALSE; goto out; } /* pass _all_ of the data */ ret = pk_backend_repo_signature_required (priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5], sections[6], sections[7], sig_type); goto out; } else if (g_strcmp0 (command, "eula-required") == 0) { if (size != 5) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (pk_strzero (sections[1])) { g_set_error (error, 1, 0, "eula_id blank, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } if (pk_strzero (sections[2])) { g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[2]); ret = FALSE; goto out; } if (pk_strzero (sections[4])) { g_set_error (error, 1, 0, "agreement name blank, and hence ignored: '%s'", sections[4]); ret = FALSE; goto out; } ret = pk_backend_eula_required (priv->backend, sections[1], sections[2], sections[3], sections[4]); goto out; } else if (g_strcmp0 (command, "media-change-required") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } media_type_enum = pk_media_type_enum_from_string (sections[1]); if (media_type_enum == PK_MEDIA_TYPE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "media type enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } ret = pk_backend_media_change_required (priv->backend, media_type_enum, sections[2], sections[3]); goto out; } else if (g_strcmp0 (command, "distro-upgrade") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } distro_upgrade_enum = pk_distro_upgrade_enum_from_string (sections[1]); if (distro_upgrade_enum == PK_DISTRO_UPGRADE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "distro upgrade enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } ret = pk_backend_distro_upgrade (priv->backend, distro_upgrade_enum, sections[2], sections[3]); goto out; } else if (g_strcmp0 (command, "category") == 0) { if (size != 6) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (g_strcmp0 (sections[1], sections[2]) == 0) { g_set_error_literal (error, 1, 0, "cat_id cannot be the same as parent_id"); ret = FALSE; goto out; } if (pk_strzero (sections[2])) { g_set_error_literal (error, 1, 0, "cat_id cannot not blank"); ret = FALSE; goto out; } if (pk_strzero (sections[3])) { g_set_error_literal (error, 1, 0, "name cannot not blank"); ret = FALSE; goto out; } if (pk_strzero (sections[5])) { g_set_error_literal (error, 1, 0, "icon cannot not blank"); ret = FALSE; goto out; } if (g_str_has_prefix (sections[5], "/")) { g_set_error (error, 1, 0, "icon '%s' should be a named icon, not a path", sections[5]); ret = FALSE; goto out; } ret = pk_backend_category (priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5]); goto out; } else { ret = FALSE; g_set_error (error, 1, 0, "invalid command '%s'", command); } out: g_strfreev (sections); return ret; }
gboolean pk_backend_spawn_is_busy (PkBackendSpawn *backend_spawn) { g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); return backend_spawn->priv->is_busy; }
const gchar * pk_backend_spawn_get_name (PkBackendSpawn *backend_spawn) { g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), NULL); return backend_spawn->priv->name; }
/** * pk_backend_spawn_helper_va_list: **/ static gboolean pk_backend_spawn_helper_va_list (PkBackendSpawn *backend_spawn, PkBackendJob *job, const gchar *executable, va_list *args) { gboolean ret; gchar *filename; gchar **argv; gchar **envp; PkHintEnum background; GError *error = NULL; PkBackendSpawnPrivate *priv = backend_spawn->priv; #if PK_BUILD_LOCAL const gchar *directory; #endif g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); /* convert to a argv */ argv = pk_backend_spawn_va_list_to_argv (executable, args); if (argv == NULL) { g_warning ("argv NULL"); return FALSE; } #if PK_BUILD_LOCAL /* prefer the local version */ directory = priv->name; if (g_str_has_prefix (directory, "test_")) directory = "test"; filename = g_build_filename ("..", "backends", directory, "helpers", argv[0], NULL); if (g_file_test (filename, G_FILE_TEST_EXISTS) == FALSE) { g_debug ("local helper not found '%s'", filename); g_free (filename); filename = g_build_filename ("..", "backends", directory, argv[0], NULL); } if (g_file_test (filename, G_FILE_TEST_EXISTS) == FALSE) { g_debug ("local helper not found '%s'", filename); g_free (filename); filename = g_build_filename (DATADIR, "PackageKit", "helpers", priv->name, argv[0], NULL); } #else filename = g_build_filename (DATADIR, "PackageKit", "helpers", priv->name, argv[0], NULL); #endif g_debug ("using spawn filename %s", filename); /* replace the filename with the full path */ g_free (argv[0]); argv[0] = g_strdup (filename); /* copy idle setting from backend to PkSpawn instance */ background = pk_backend_job_get_background (job); g_object_set (priv->spawn, "background", (background == PK_HINT_ENUM_TRUE), NULL); priv->finished = FALSE; envp = pk_backend_spawn_get_envp (backend_spawn); ret = pk_spawn_argv (priv->spawn, argv, envp, &error); if (!ret) { pk_backend_job_error_code (priv->job, PK_ERROR_ENUM_INTERNAL_ERROR, "Spawn of helper '%s' failed", argv[0], error->message); g_error_free (error); pk_backend_job_finished (priv->job); } g_free (filename); g_strfreev (argv); g_strfreev (envp); return ret; }
static gboolean pk_backend_spawn_helper_va_list (PkBackendSpawn *backend_spawn, PkBackendJob *job, const gchar *executable, va_list *args) { gboolean background; PkBackendSpawnPrivate *priv = backend_spawn->priv; PkSpawnArgvFlags flags = PK_SPAWN_ARGV_FLAGS_NONE; #if PK_BUILD_LOCAL const gchar *directory; #endif g_autoptr(GError) error = NULL; g_autofree gchar *filename = NULL; g_auto(GStrv) argv = NULL; g_auto(GStrv) envp = NULL; g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); /* convert to a argv */ argv = pk_backend_spawn_va_list_to_argv (executable, args); if (argv == NULL) { g_warning ("argv NULL"); return FALSE; } #if PK_BUILD_LOCAL /* prefer the local version */ directory = priv->name; if (g_str_has_prefix (directory, "test_")) directory = "test"; filename = g_build_filename ("..", "backends", directory, "helpers", argv[PK_BACKEND_SPAWN_ARGV0], NULL); if (g_file_test (filename, G_FILE_TEST_EXISTS) == FALSE) { g_debug ("local helper not found '%s'", filename); g_free (filename); filename = g_build_filename ("..", "backends", directory, argv[PK_BACKEND_SPAWN_ARGV0], NULL); } if (g_file_test (filename, G_FILE_TEST_EXISTS) == FALSE) { g_debug ("local helper not found '%s'", filename); g_free (filename); filename = g_build_filename (DATADIR, "PackageKit", "helpers", priv->name, argv[PK_BACKEND_SPAWN_ARGV0], NULL); } #else filename = g_build_filename (DATADIR, "PackageKit", "helpers", priv->name, argv[PK_BACKEND_SPAWN_ARGV0], NULL); #endif g_debug ("using spawn filename %s", filename); /* replace the filename with the full path */ g_free (argv[PK_BACKEND_SPAWN_ARGV0]); argv[PK_BACKEND_SPAWN_ARGV0] = g_strdup (filename); /* copy idle setting from backend to PkSpawn instance */ background = pk_backend_job_get_background (job); g_object_set (priv->spawn, "background", (background == TRUE), NULL); #ifdef ENABLE_STRACE /* we can't reuse when using strace */ flags |= PK_SPAWN_ARGV_FLAGS_NEVER_REUSE; #endif priv->finished = FALSE; envp = pk_backend_spawn_get_envp (backend_spawn); if (!pk_spawn_argv (priv->spawn, argv, envp, flags, &error)) { pk_backend_job_error_code (priv->job, PK_ERROR_ENUM_INTERNAL_ERROR, "Spawn of helper '%s' failed: %s", argv[PK_BACKEND_SPAWN_ARGV0], error->message); pk_backend_job_finished (priv->job); return FALSE; } return TRUE; }
/** * pk_backend_spawn_parse_stdout: **/ static gboolean pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, PkBackendJob *job, const gchar *line, GError **error) { gchar **sections; guint size; gchar *command; gchar *text; gboolean ret = TRUE; guint64 speed; guint64 download_size_remaining; PkInfoEnum info; PkRestartEnum restart; PkGroupEnum group; gulong package_size; gint percentage; PkErrorEnum error_enum; PkStatusEnum status_enum; PkMessageEnum message_enum; PkRestartEnum restart_enum; PkSigTypeEnum sig_type; PkUpdateStateEnum update_state_enum; PkMediaTypeEnum media_type_enum; PkDistroUpgradeEnum distro_upgrade_enum; PkBackendSpawnPrivate *priv = backend_spawn->priv; g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); /* check if output line */ if (line == NULL) return FALSE; /* split by tab */ sections = g_strsplit (line, "\t", 0); command = sections[0]; /* get size */ size = g_strv_length (sections); if (g_strcmp0 (command, "package") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (pk_package_id_check (sections[2]) == FALSE) { g_set_error_literal (error, 1, 0, "invalid package_id"); ret = FALSE; goto out; } info = pk_info_enum_from_string (sections[1]); if (info == PK_INFO_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Info enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } g_strdelimit (sections[3], PK_UNSAFE_DELIMITERS, ' '); ret = g_utf8_validate (sections[3], -1, NULL); if (!ret) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[3]); ret = FALSE; goto out; } pk_backend_job_package (job, info, sections[2], sections[3]); } else if (g_strcmp0 (command, "details") == 0) { if (size != 7) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } group = pk_group_enum_from_string (sections[3]); /* ITS4: ignore, checked for overflow */ package_size = atol (sections[6]); if (package_size > 1073741824) { g_set_error_literal (error, 1, 0, "package size cannot be larger than one Gb"); ret = FALSE; goto out; } g_strdelimit (sections[4], PK_UNSAFE_DELIMITERS, ' '); ret = g_utf8_validate (sections[4], -1, NULL); if (!ret) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[4]); ret = FALSE; goto out; } text = g_strdup (sections[4]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); pk_backend_job_details (job, sections[1], sections[2], group, text, sections[5], package_size); g_free (text); } else if (g_strcmp0 (command, "finished") == 0) { if (size != 1) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } pk_backend_job_finished (job); priv->is_busy = FALSE; /* from this point on, we can start the kill timer */ pk_backend_spawn_start_kill_timer (backend_spawn); } else if (g_strcmp0 (command, "files") == 0) { gchar **tmp; if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } tmp = g_strsplit (sections[2], ";", -1); pk_backend_job_files (job, sections[1], tmp); g_strfreev (tmp); } else if (g_strcmp0 (command, "repo-detail") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } g_strdelimit (sections[2], PK_UNSAFE_DELIMITERS, ' '); ret = g_utf8_validate (sections[2], -1, NULL); if (!ret) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[2]); ret = FALSE; goto out; } if (g_strcmp0 (sections[3], "true") == 0) { pk_backend_job_repo_detail (job, sections[1], sections[2], TRUE); } else if (g_strcmp0 (sections[3], "false") == 0) { pk_backend_job_repo_detail (job, sections[1], sections[2], FALSE); } else { g_set_error (error, 1, 0, "invalid qualifier '%s'", sections[3]); ret = FALSE; goto out; } } else if (g_strcmp0 (command, "updatedetail") == 0) { gchar **updates; gchar **obsoletes; gchar **vendor_urls; gchar **bugzilla_urls; gchar **cve_urls; if (size != 13) { g_set_error (error, 1, 0, "invalid command '%s', size %i", command, size); ret = FALSE; goto out; } restart = pk_restart_enum_from_string (sections[7]); if (restart == PK_RESTART_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[7]); ret = FALSE; goto out; } g_strdelimit (sections[12], PK_UNSAFE_DELIMITERS, ' '); ret = g_utf8_validate (sections[12], -1, NULL); if (!ret) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[12]); ret = FALSE; goto out; } update_state_enum = pk_update_state_enum_from_string (sections[10]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (sections[8], ";", '\n'); g_strdelimit (sections[9], ";", '\n'); updates = g_strsplit (sections[2], "&", -1); obsoletes = g_strsplit (sections[3], "&", -1); vendor_urls = g_strsplit (sections[4], ";", -1); bugzilla_urls = g_strsplit (sections[5], ";", -1); cve_urls = g_strsplit (sections[6], ";", -1); pk_backend_job_update_detail (job, sections[1], updates, obsoletes, vendor_urls, bugzilla_urls, cve_urls, restart, sections[8], sections[9], update_state_enum, sections[11], sections[12]); g_strfreev (updates); g_strfreev (obsoletes); g_strfreev (vendor_urls); g_strfreev (bugzilla_urls); g_strfreev (cve_urls); } else if (g_strcmp0 (command, "percentage") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } ret = pk_strtoint (sections[1], &percentage); if (!ret) { g_set_error (error, 1, 0, "invalid percentage value %s", sections[1]); ret = FALSE; } else if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid percentage value %i", percentage); ret = FALSE; } else { pk_backend_job_set_percentage (job, percentage); } } else if (g_strcmp0 (command, "item-progress") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } if (!pk_package_id_check (sections[1])) { g_set_error (error, 1, 0, "invalid package_id"); ret = FALSE; goto out; } status_enum = pk_status_enum_from_string (sections[2]); if (status_enum == PK_STATUS_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Status enum not recognised, and hence ignored: '%s'", sections[2]); ret = FALSE; goto out; } ret = pk_strtoint (sections[3], &percentage); if (!ret) { g_set_error (error, 1, 0, "invalid item-progress value %s", sections[3]); ret = FALSE; goto out; } if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid item-progress value %i", percentage); ret = FALSE; goto out; } pk_backend_job_set_item_progress (job, sections[1], status_enum, percentage); } else if (g_strcmp0 (command, "error") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } error_enum = pk_error_enum_from_string (sections[1]); if (error_enum == PK_ERROR_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Error enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } /* convert back all the ;'s to newlines */ text = g_strdup (sections[2]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); /* convert % else we try to format them */ g_strdelimit (text, "%", '$'); pk_backend_job_error_code (job, error_enum, "%s", text); g_free (text); } else if (g_strcmp0 (command, "requirerestart") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } restart_enum = pk_restart_enum_from_string (sections[1]); if (restart_enum == PK_RESTART_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } if (!pk_package_id_check (sections[2])) { g_set_error (error, 1, 0, "invalid package_id"); ret = FALSE; goto out; } pk_backend_job_require_restart (job, restart_enum, sections[2]); } else if (g_strcmp0 (command, "message") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); ret = FALSE; goto out; } G_GNUC_BEGIN_IGNORE_DEPRECATIONS message_enum = pk_message_enum_from_string (sections[1]); G_GNUC_END_IGNORE_DEPRECATIONS if (message_enum == PK_MESSAGE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Message enum not recognised, and hence ignored: '%s'", sections[1]); ret = FALSE; goto out; } text = g_strdup (sections[2]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); G_GNUC_BEGIN_IGNORE_DEPRECATIONS pk_backend_job_message (job, message_enum, "%s", text); G_GNUC_END_IGNORE_DEPRECATIONS g_free (text); } else if (g_strcmp0 (command, "status") == 0) {
/** * pk_backend_spawn_get_backend: **/ PkBackend * pk_backend_spawn_get_backend (PkBackendSpawn *backend_spawn) { g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), NULL); return backend_spawn->priv->backend; }
static gboolean pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, PkBackendJob *job, const gchar *line, GError **error) { guint size; gchar *command; gchar *text; guint64 speed; guint64 download_size_remaining; PkInfoEnum info; PkRestartEnum restart; PkGroupEnum group; gulong package_size; gint percentage; PkErrorEnum error_enum; PkStatusEnum status_enum; PkRestartEnum restart_enum; PkSigTypeEnum sig_type; PkUpdateStateEnum update_state_enum; PkMediaTypeEnum media_type_enum; PkDistroUpgradeEnum distro_upgrade_enum; PkBackendSpawnPrivate *priv = backend_spawn->priv; g_auto(GStrv) sections = NULL; g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); /* check if output line */ if (line == NULL) return FALSE; /* split by tab */ sections = g_strsplit (line, "\t", 0); command = sections[0]; /* get size */ size = g_strv_length (sections); if (g_strcmp0 (command, "package") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (pk_package_id_check (sections[2]) == FALSE) { g_set_error_literal (error, 1, 0, "invalid package_id"); return FALSE; } info = pk_info_enum_from_string (sections[1]); if (info == PK_INFO_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Info enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } g_strdelimit (sections[3], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[3], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[3]); return FALSE; } pk_backend_job_package (job, info, sections[2], sections[3]); } else if (g_strcmp0 (command, "details") == 0) { if (size != 8) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } group = pk_group_enum_from_string (sections[4]); /* ITS4: ignore, checked for overflow */ package_size = atol (sections[7]); if (package_size > 1073741824) { g_set_error_literal (error, 1, 0, "package size cannot be that large"); return FALSE; } g_strdelimit (sections[5], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[4], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[5]); return FALSE; } text = g_strdup (sections[5]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); pk_backend_job_details (job, sections[1], sections[2], sections[3], group, text, sections[6], package_size); g_free (text); } else if (g_strcmp0 (command, "finished") == 0) { if (size != 1) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } pk_backend_job_finished (job); priv->is_busy = FALSE; /* from this point on, we can start the kill timer */ pk_backend_spawn_start_kill_timer (backend_spawn); } else if (g_strcmp0 (command, "files") == 0) { g_auto(GStrv) tmp = NULL; if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } tmp = g_strsplit (sections[2], ";", -1); pk_backend_job_files (job, sections[1], tmp); } else if (g_strcmp0 (command, "repo-detail") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } g_strdelimit (sections[2], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[2], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[2]); return FALSE; } if (g_strcmp0 (sections[3], "true") == 0) { pk_backend_job_repo_detail (job, sections[1], sections[2], TRUE); } else if (g_strcmp0 (sections[3], "false") == 0) { pk_backend_job_repo_detail (job, sections[1], sections[2], FALSE); } else { g_set_error (error, 1, 0, "invalid qualifier '%s'", sections[3]); return FALSE; } } else if (g_strcmp0 (command, "updatedetail") == 0) { g_auto(GStrv) updates = NULL; g_auto(GStrv) obsoletes = NULL; g_auto(GStrv) vendor_urls = NULL; g_auto(GStrv) bugzilla_urls = NULL; g_auto(GStrv) cve_urls = NULL; if (size != 13) { g_set_error (error, 1, 0, "invalid command '%s', size %i", command, size); return FALSE; } restart = pk_restart_enum_from_string (sections[7]); if (restart == PK_RESTART_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[7]); return FALSE; } g_strdelimit (sections[12], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[12], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[12]); return FALSE; } update_state_enum = pk_update_state_enum_from_string (sections[10]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (sections[8], ";", '\n'); g_strdelimit (sections[9], ";", '\n'); updates = g_strsplit (sections[2], "&", -1); obsoletes = g_strsplit (sections[3], "&", -1); vendor_urls = g_strsplit (sections[4], ";", -1); bugzilla_urls = g_strsplit (sections[5], ";", -1); cve_urls = g_strsplit (sections[6], ";", -1); pk_backend_job_update_detail (job, sections[1], updates, obsoletes, vendor_urls, bugzilla_urls, cve_urls, restart, sections[8], sections[9], update_state_enum, sections[11], sections[12]); } else if (g_strcmp0 (command, "percentage") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (!pk_strtoint (sections[1], &percentage)) { g_set_error (error, 1, 0, "invalid percentage value %s", sections[1]); return FALSE; } else if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid percentage value %i", percentage); return FALSE; } else { pk_backend_job_set_percentage (job, percentage); } } else if (g_strcmp0 (command, "item-progress") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (!pk_package_id_check (sections[1])) { g_set_error (error, 1, 0, "invalid package_id"); return FALSE; } status_enum = pk_status_enum_from_string (sections[2]); if (status_enum == PK_STATUS_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Status enum not recognised, and hence ignored: '%s'", sections[2]); return FALSE; } if (!pk_strtoint (sections[3], &percentage)) { g_set_error (error, 1, 0, "invalid item-progress value %s", sections[3]); return FALSE; } if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid item-progress value %i", percentage); return FALSE; } pk_backend_job_set_item_progress (job, sections[1], status_enum, percentage); } else if (g_strcmp0 (command, "error") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } error_enum = pk_error_enum_from_string (sections[1]); if (error_enum == PK_ERROR_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Error enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } /* convert back all the ;'s to newlines */ text = g_strdup (sections[2]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); /* convert % else we try to format them */ g_strdelimit (text, "%", '$'); pk_backend_job_error_code (job, error_enum, "%s", text); g_free (text); } else if (g_strcmp0 (command, "requirerestart") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } restart_enum = pk_restart_enum_from_string (sections[1]); if (restart_enum == PK_RESTART_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } if (!pk_package_id_check (sections[2])) { g_set_error (error, 1, 0, "invalid package_id"); return FALSE; } pk_backend_job_require_restart (job, restart_enum, sections[2]); } else if (g_strcmp0 (command, "status") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } status_enum = pk_status_enum_from_string (sections[1]); if (status_enum == PK_STATUS_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Status enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } pk_backend_job_set_status (job, status_enum); } else if (g_strcmp0 (command, "speed") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (!pk_strtouint64 (sections[1], &speed)) { g_set_error (error, 1, 0, "failed to parse speed: '%s'", sections[1]); return FALSE; } pk_backend_job_set_speed (job, speed); } else if (g_strcmp0 (command, "download-size-remaining") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (!pk_strtouint64 (sections[1], &download_size_remaining)) { g_set_error (error, 1, 0, "failed to parse download_size_remaining: '%s'", sections[1]); return FALSE; } pk_backend_job_set_download_size_remaining (job, download_size_remaining); } else if (g_strcmp0 (command, "allow-cancel") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (g_strcmp0 (sections[1], "true") == 0) { pk_backend_job_set_allow_cancel (job, TRUE); } else if (g_strcmp0 (sections[1], "false") == 0) { pk_backend_job_set_allow_cancel (job, FALSE); } else { g_set_error (error, 1, 0, "invalid section '%s'", sections[1]); return FALSE; } } else if (g_strcmp0 (command, "no-percentage-updates") == 0) { if (size != 1) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } pk_backend_job_set_percentage (job, PK_BACKEND_PERCENTAGE_INVALID); } else if (g_strcmp0 (command, "repo-signature-required") == 0) { if (size != 9) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } sig_type = pk_sig_type_enum_from_string (sections[8]); if (sig_type == PK_SIGTYPE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Sig enum not recognised, and hence ignored: '%s'", sections[8]); return FALSE; } if (pk_strzero (sections[1])) { g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[1]); return FALSE; } if (pk_strzero (sections[2])) { g_set_error (error, 1, 0, "repository name blank, and hence ignored: '%s'", sections[2]); return FALSE; } /* pass _all_ of the data */ pk_backend_job_repo_signature_required (job, sections[1], sections[2], sections[3], sections[4], sections[5], sections[6], sections[7], sig_type); } else if (g_strcmp0 (command, "eula-required") == 0) { if (size != 5) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (pk_strzero (sections[1])) { g_set_error (error, 1, 0, "eula_id blank, and hence ignored: '%s'", sections[1]); return FALSE; } if (pk_strzero (sections[2])) { g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[2]); return FALSE; } if (pk_strzero (sections[4])) { g_set_error (error, 1, 0, "agreement name blank, and hence ignored: '%s'", sections[4]); return FALSE; } pk_backend_job_eula_required (job, sections[1], sections[2], sections[3], sections[4]); } else if (g_strcmp0 (command, "media-change-required") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } media_type_enum = pk_media_type_enum_from_string (sections[1]); if (media_type_enum == PK_MEDIA_TYPE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "media type enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } pk_backend_job_media_change_required (job, media_type_enum, sections[2], sections[3]); } else if (g_strcmp0 (command, "distro-upgrade") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } distro_upgrade_enum = pk_distro_upgrade_enum_from_string (sections[1]); if (distro_upgrade_enum == PK_DISTRO_UPGRADE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "distro upgrade enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } g_strdelimit (sections[3], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[3], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[3]); return FALSE; } pk_backend_job_distro_upgrade (job, distro_upgrade_enum, sections[2], sections[3]); } else if (g_strcmp0 (command, "category") == 0) { if (size != 6) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (g_strcmp0 (sections[1], sections[2]) == 0) { g_set_error_literal (error, 1, 0, "cat_id cannot be the same as parent_id"); return FALSE; } if (pk_strzero (sections[2])) { g_set_error_literal (error, 1, 0, "cat_id cannot not blank"); return FALSE; } if (pk_strzero (sections[3])) { g_set_error_literal (error, 1, 0, "name cannot not blank"); return FALSE; } g_strdelimit (sections[4], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[4], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[4]); return FALSE; } if (pk_strzero (sections[5])) { g_set_error_literal (error, 1, 0, "icon cannot not blank"); return FALSE; } if (g_str_has_prefix (sections[5], "/")) { g_set_error (error, 1, 0, "icon '%s' should be a named icon, not a path", sections[5]); return FALSE; } pk_backend_job_category (job, sections[1], sections[2], sections[3], sections[4], sections[5]); } else { g_set_error (error, 1, 0, "invalid command '%s'", command); return FALSE; } return TRUE; }