Example #1
0
static void
backend_get_details_thread (PkBackendJob *job, GVariant *params, gpointer user_data)
{
	PackageSearch *ps;
	GList *list;
	sqlite3 *db;
	gchar **package_ids;
	gchar **package_id_data;

	package_ids = pk_backend_get_strv (backend, "package_ids");
	/* FIXME: support multiple packages */
	package_id_data = pk_package_id_split (package_ids[0]);

	db = db_open ();

	pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY);

	/* only one element is returned */
	list = box_db_repos_packages_search_by_data (db, package_id_data[PK_PACKAGE_ID_NAME], package_id_data[PK_PACKAGE_ID_VERSION]);

	if (list == NULL) {
		pk_backend_job_error_code (job, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "cannot find package by id");
		db_close (db);
		return;
	}
	ps = (PackageSearch*) list->data;

	pk_backend_job_details (job, package_ids[0], "unknown", PK_GROUP_ENUM_OTHER, ps->description, "", 0);

	box_db_repos_package_list_free (list);

	db_close (db);
	pk_backend_finished (backend);
}
Example #2
0
/**
 * pk_backend_get_details:
 */
static void
backend_get_details_thread (PkBackendJob *job, GVariant *params, gpointer user_data)
{
	gchar **package_ids;
	gchar **parts;
	int group_index;
	PkGroupEnum group = 0;
	pkg_t *pkg;
	gchar *newid;

	package_ids = pk_backend_get_strv(backend, "package_ids");
	parts = pk_package_id_split (package_ids[0]);

	if (!parts)
	{
		pk_backend_job_error_code (job, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
		pk_backend_job_finished (job);
		return;
	}

	pkg = opkg_find_package (parts[PK_PACKAGE_ID_NAME], parts[PK_PACKAGE_ID_VERSION], parts[PK_PACKAGE_ID_ARCH], parts[PK_PACKAGE_ID_DATA]);
	g_strfreev (parts);

	if (!pkg)
	{
		pk_backend_job_error_code (job, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL);
		pk_backend_job_finished (job);
		return;
	}

	newid = g_strdup_printf ("%s;%s;%s;%s", pkg->name, pkg->version, pkg->architecture, pkg->src->name);

	if (pkg->tags) {
		for (group_index = 0; group < PK_GROUP_ENUM_LAST; group_index++) {
			group = 1 << group_index;
			if (!(group & pk_backend_get_groups(backend))) continue;
			if (opkg_check_tag(pkg, (const gchar *)pk_group_enum_to_string(group))) 
				break;
		}
	}

	pk_backend_job_details (job, newid, NULL, NULL, group, pkg->description, NULL, pkg->size);
	g_free (newid);
	pk_backend_job_finished (job);
}
Example #3
0
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;
}
/**
 * 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) {
Example #5
0
static void pk_backend_get_details_thread(PkBackendJob *job, GVariant *params, gpointer user_data) {
	gchar **pkg_ids, **pkg_tokens, *homepage = NULL;
	gsize i;
	GString *desc;
	GRegex *expr;
	GMatchInfo *match_info;
	GError *err = NULL;
	sqlite3_stmt *stmt;
	PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job);

	pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);

	g_variant_get(params, "(^a&s)", &pkg_ids);

	if ((sqlite3_prepare_v2(job_data->db,
							"SELECT p.desc, p.cat, p.uncompressed FROM pkglist AS p NATURAL JOIN repos AS r "
							"WHERE name LIKE @name AND r.repo LIKE @repo AND ext NOT LIKE 'obsolete'",
							-1,
							&stmt,
							NULL) != SQLITE_OK)) {
		pk_backend_job_error_code(job, PK_ERROR_ENUM_CANNOT_GET_FILELIST, "%s", sqlite3_errmsg(job_data->db));
		goto out;
	}

	pkg_tokens = pk_package_id_split(pkg_ids[0]);
	sqlite3_bind_text(stmt, 1, pkg_tokens[PK_PACKAGE_ID_NAME], -1, SQLITE_TRANSIENT);
	sqlite3_bind_text(stmt, 2, pkg_tokens[PK_PACKAGE_ID_DATA], -1, SQLITE_TRANSIENT);
	g_strfreev(pkg_tokens);

	if (sqlite3_step(stmt) != SQLITE_ROW)
		goto out;

	desc = g_string_new((gchar *) sqlite3_column_text(stmt, 0));

	/* Regular expression for searching a homepage */
	expr = g_regex_new("(?:http|ftp):\\/\\/[[:word:]\\/\\-\\.]+[[:word:]\\/](?=\\.?$)",
			G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES,
			0,
			&err);
	if (err) {
		pk_backend_job_error_code(job, PK_ERROR_ENUM_UNKNOWN, "%s", err->message);
		g_error_free(err);
		goto out;
	}
	if (g_regex_match(expr, desc->str, 0, &match_info)) {
		homepage = g_match_info_fetch(match_info, 0); /* URL */
		/* Remove the last sentence with the copied URL */
		for (i = desc->len - 1; i > 0; i--) {
			if ((desc->str[i - 1] == '.') && (desc->str[i] == ' ')) {
				g_string_truncate(desc, i);
				break;
			}
		}
		g_match_info_free(match_info);
	}
	g_regex_unref(expr);

	/* Ready */
	pk_backend_job_details(job, pkg_ids[0],
						   NULL,
						   NULL,
						   pk_group_enum_from_string((gchar *) sqlite3_column_text(stmt, 1)),
						   desc->str,
						   homepage,
						   sqlite3_column_int(stmt, 2));

	g_free(homepage);
	if (desc)
		g_string_free(desc, TRUE);

out:
	sqlite3_finalize(stmt);

	pk_backend_job_finished(job);
}
Example #6
0
static gboolean
pk_backend_get_details_thread (PkBackend *self)
{
	gchar **packages;
	GError *error = NULL;

	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (localdb != NULL, FALSE);

	packages = pk_backend_get_strv (self, "package_ids");

	g_return_val_if_fail (packages != NULL, FALSE);

	for (; *packages != NULL; ++packages) {
		alpm_pkg_t *pkg;
		const alpm_list_t *i;

		GString *licenses;
		PkGroupEnum group;
		const gchar *desc, *url;
		gulong size;

		if (pk_backend_cancelled (self)) {
			break;
		}

		pkg = pk_backend_find_pkg (self, *packages, &error);
		if (pkg == NULL) {
			break;
		}

		i = alpm_pkg_get_licenses (pkg);
		if (i == NULL) {
			licenses = g_string_new ("Unknown");
		} else {
			licenses = g_string_new ((const gchar *) i->data);
			while ((i = i->next) != NULL) {
				const gchar *license = (const gchar *) i->data;
				/* assume OR although it may not be correct */
				g_string_append_printf (licenses, " or %s",
							license);
			}
		}

		group = pk_group_enum_from_string (alpm_pkg_get_group (pkg));
		desc = alpm_pkg_get_desc (pkg);
		url = alpm_pkg_get_url (pkg);

		if (alpm_pkg_get_origin (pkg) == ALPM_PKG_FROM_LOCALDB) {
			size = alpm_pkg_get_isize (pkg);
		} else {
			size = alpm_pkg_download_size (pkg);
		}

		pk_backend_job_details (self, *packages, licenses->str, group,
					desc, url, size);
		g_string_free (licenses, TRUE);
	}

	return pk_backend_finish (self, error);
}