/**
 * pk_backend_search_groups_thread:
 */
static void
pk_backend_search_groups_thread (PkBackendJob *job, GVariant *params, gpointer user_data)
{
	pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY);

	/* emit */
	pk_backend_job_package (job, PK_INFO_ENUM_INSTALLED,
			    "glib2;2.14.0;i386;fedora", "The GLib library");
	pk_backend_job_package (job, PK_INFO_ENUM_INSTALLED,
			    "gtk2;gtk2-2.11.6-6.fc8;i386;fedora", "GTK+ Libraries for GIMP");
	pk_backend_job_finished (job);
}
예제 #2
0
static void
backend_install_packages_thread (PkBackendJob *job, GVariant *params, gpointer user_data)
{
	gint err, i;
	gchar **package_ids;
	gchar **parts;

	package_ids = pk_backend_get_strv (backend, "pkids");

	err = 0;

	for (i = 0; package_ids[i]; i++)
	{
		pk_backend_job_package (job, PK_INFO_ENUM_INSTALLING, package_ids[i], NULL);

		parts = pk_package_id_split (package_ids[i]);

		err = opkg_install_package (parts[PK_PACKAGE_ID_NAME], pk_opkg_progress_cb, backend);
		if (err)
			handle_install_error (backend, err);

		g_strfreev (parts);
		if (err != 0)
			break;
	}

	pk_backend_job_finished (job);
}
예제 #3
0
static void pk_backend_resolve_thread(PkBackendJob *job, GVariant *params, gpointer user_data) {
	gchar **vals, **val;
	sqlite3_stmt *stmt;
	PkInfoEnum ret;
	PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job);

	pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
	pk_backend_job_set_percentage(job, 0);

	g_variant_get(params, "(t^a&s)", NULL, &vals);

	if ((sqlite3_prepare_v2(job_data->db,
							"SELECT (p1.name || ';' || p1.ver || ';' || p1.arch || ';' || r.repo), p1.summary, "
						   	"p1.full_name FROM pkglist AS p1 NATURAL JOIN repos AS r "
							"WHERE p1.name LIKE @search AND p1.repo_order = "
							"(SELECT MIN(p2.repo_order) FROM pkglist AS p2 WHERE p2.name = p1.name GROUP BY p2.name)",
							-1,
							&stmt,
							NULL) == SQLITE_OK)) {
		/* Output packages matching each pattern */
		for (val = vals; *val; val++) {
			sqlite3_bind_text(stmt, 1, *val, -1, SQLITE_TRANSIENT);

			while (sqlite3_step(stmt) == SQLITE_ROW) {
				ret = katja_pkg_is_installed((gchar *) sqlite3_column_text(stmt, 2));
				if ((ret == PK_INFO_ENUM_INSTALLED) || (ret == PK_INFO_ENUM_UPDATING)) {
					pk_backend_job_package(job, PK_INFO_ENUM_INSTALLED,
											(gchar *) sqlite3_column_text(stmt, 0),
											(gchar *) sqlite3_column_text(stmt, 1));
				} else if (ret == PK_INFO_ENUM_INSTALLING) {
					pk_backend_job_package(job, PK_INFO_ENUM_AVAILABLE,
											(gchar *) sqlite3_column_text(stmt, 0),
											(gchar *) sqlite3_column_text(stmt, 1));
				}
			}

			sqlite3_clear_bindings(stmt);
			sqlite3_reset(stmt);
		}
		sqlite3_finalize(stmt);
	} else {
		pk_backend_job_error_code(job, PK_ERROR_ENUM_CANNOT_GET_FILELIST, "%s", sqlite3_errmsg(job_data->db));
	}

	pk_backend_job_set_percentage(job, 100);
	pk_backend_job_finished(job);
}
예제 #4
0
static void pk_backend_search_thread(PkBackendJob *job, GVariant *params, gpointer user_data) {
	gchar **vals, *search, *query;
	sqlite3_stmt *stmt;
	PkInfoEnum ret;
	PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job);

	pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
	pk_backend_job_set_percentage(job, 0);

	g_variant_get(params, "(t^a&s)", NULL, &vals);
	search = g_strjoinv("%", vals);

	query = sqlite3_mprintf("SELECT (p1.name || ';' || p1.ver || ';' || p1.arch || ';' || r.repo), p1.summary, "
							"p1.full_name FROM pkglist AS p1 NATURAL JOIN repos AS r "
							"WHERE p1.%s LIKE '%%%q%%' AND p1.ext NOT LIKE 'obsolete' AND p1.repo_order = "
							"(SELECT MIN(p2.repo_order) FROM pkglist AS p2 WHERE p2.name = p1.name GROUP BY p2.name)",
							(gchar *) user_data,
							search);

	if ((sqlite3_prepare_v2(job_data->db, query, -1, &stmt, NULL) == SQLITE_OK)) {
		/* Now we're ready to output all packages */
		while (sqlite3_step(stmt) == SQLITE_ROW) {
			ret = katja_pkg_is_installed((gchar *) sqlite3_column_text(stmt, 2));
			if ((ret == PK_INFO_ENUM_INSTALLED) || (ret == PK_INFO_ENUM_UPDATING)) {
				pk_backend_job_package(job, PK_INFO_ENUM_INSTALLED,
										(gchar *) sqlite3_column_text(stmt, 0),
										(gchar *) sqlite3_column_text(stmt, 1));
			} else if (ret == PK_INFO_ENUM_INSTALLING) {
				pk_backend_job_package(job, PK_INFO_ENUM_AVAILABLE,
										(gchar *) sqlite3_column_text(stmt, 0),
										(gchar *) sqlite3_column_text(stmt, 1));
			}
		}
		sqlite3_finalize(stmt);
	} else {
		pk_backend_job_error_code(job, PK_ERROR_ENUM_CANNOT_GET_FILELIST, "%s", sqlite3_errmsg(job_data->db));
	}

	sqlite3_free(query);
	g_free(search);

	pk_backend_job_set_percentage(job, 100);
	pk_backend_job_finished(job);
}
/**
 * pk_backend_search_names_thread:
 */
static void
pk_backend_search_names_thread (PkBackendJob *job, GVariant *params, gpointer user_data)
{
	GTimer *timer;
	guint percentage;
	PkBitfield filters;
	gchar *filters_text;
	gchar **search;

	g_variant_get (params, "(t^a&s)",
		       &filters,
		       &search);

	filters_text = pk_filter_bitfield_to_string (filters);
	g_debug ("started task (%p) search=%s filters=%s", job, search[0], filters_text);
	g_free (filters_text);
	pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY);
	timer = g_timer_new ();
	percentage = 0;
	do {
		/* now is a good time to see if we should cancel the thread */
		if (is_cancelled) {
			pk_backend_job_error_code (job, PK_ERROR_ENUM_TRANSACTION_CANCELLED,
					       "The thread was stopped successfully");
			pk_backend_job_finished (job);
			return;
		}
		pk_backend_job_set_percentage (job, percentage);
		percentage += 10;
		g_usleep (1000*100);
	} while (percentage < 100);
	g_timer_destroy (timer);
	pk_backend_job_set_percentage (job, 100);
	g_debug ("exited task (%p)", job);

	pk_backend_job_package (job, PK_INFO_ENUM_INSTALLED,
			    "glib2;2.14.0;i386;fedora", "The GLib library");
	pk_backend_job_package (job, PK_INFO_ENUM_INSTALLED,
			    "gtk2;gtk2-2.11.6-6.fc8;i386;fedora", "GTK+ Libraries for GIMP");
	pk_backend_job_finished (job);
}
예제 #6
0
void
pk_backend_pkg (PkBackend *self, alpm_pkg_t *pkg, PkInfoEnum info)
{
	gchar *package;

	g_return_if_fail (self != NULL);
	g_return_if_fail (pkg != NULL);

	package = alpm_pkg_build_id (pkg);
	pk_backend_job_package (self, info, package, alpm_pkg_get_desc (pkg));
	g_free (package);
}
예제 #7
0
/**
 * dnf_emit_package:
 */
void
dnf_emit_package (PkBackendJob *job, PkInfoEnum info, DnfPackage *pkg)
{
	/* detect */
	if (info == PK_INFO_ENUM_UNKNOWN)
		info = dnf_package_get_info (pkg);
	if (info == PK_INFO_ENUM_UNKNOWN)
		info = dnf_package_installed (pkg) ? PK_INFO_ENUM_INSTALLED : PK_INFO_ENUM_AVAILABLE;
	pk_backend_job_package (job,
				info,
				dnf_package_get_package_id (pkg),
				dnf_package_get_summary (pkg));
}
예제 #8
0
static void pk_backend_download_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data) {
	gchar *dir_path, *path, **pkg_ids, **pkg_tokens, *to_strv[] = {NULL, NULL};
	guint i;
	GSList *repo;
	sqlite3_stmt *stmt;
	PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job);

	g_variant_get(params, "(^a&ss)", &pkg_ids, &dir_path);
	pk_backend_job_set_status (job, PK_STATUS_ENUM_DOWNLOAD);

	if ((sqlite3_prepare_v2(job_data->db,
							"SELECT summary, (full_name || '.' || ext) FROM pkglist NATURAL JOIN repos "
							"WHERE name LIKE @name AND ver LIKE @ver AND arch LIKE @arch AND repo LIKE @repo",
							-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;
	}

	for (i = 0; pkg_ids[i]; i++) {
		pkg_tokens = pk_package_id_split(pkg_ids[i]);
		sqlite3_bind_text(stmt, 1, pkg_tokens[PK_PACKAGE_ID_NAME], -1, SQLITE_TRANSIENT);
		sqlite3_bind_text(stmt, 2, pkg_tokens[PK_PACKAGE_ID_VERSION], -1, SQLITE_TRANSIENT);
		sqlite3_bind_text(stmt, 3, pkg_tokens[PK_PACKAGE_ID_ARCH], -1, SQLITE_TRANSIENT);
		sqlite3_bind_text(stmt, 4, pkg_tokens[PK_PACKAGE_ID_DATA], -1, SQLITE_TRANSIENT);
		if (sqlite3_step(stmt) == SQLITE_ROW) {
			if ((repo = g_slist_find_custom(repos, pkg_tokens[PK_PACKAGE_ID_DATA], katja_cmp_repo))) {
				pk_backend_job_package(job, PK_INFO_ENUM_DOWNLOADING,
									   pkg_ids[i],
									   (gchar *) sqlite3_column_text(stmt, 0));
				katja_pkgtools_download(KATJA_PKGTOOLS(repo->data), job, dir_path, pkg_tokens[PK_PACKAGE_ID_NAME]);
				path = g_build_filename(dir_path, (gchar *) sqlite3_column_text(stmt, 1), NULL);
				to_strv[0] = path;
				pk_backend_job_files(job, NULL, to_strv);
				g_free(path);
			}
		}
		sqlite3_clear_bindings(stmt);
		sqlite3_reset(stmt);
		g_strfreev(pkg_tokens);
	}

out:
	sqlite3_finalize(stmt);

	pk_backend_job_finished (job);
}
예제 #9
0
static void
backend_remove_packages_thread (PkBackendJob *job, GVariant *params, gpointer user_data)
{
	gint err, i;
	gchar **package_ids;
	gchar **parts;
	gboolean allow_deps;
	gboolean autoremove;
	gpointer *data;

	data = pk_backend_get_pointer (backend, "remove-params");

	package_ids = (gchar**) data[0];
	allow_deps = GPOINTER_TO_INT (data[1]);
	autoremove = GPOINTER_TO_INT (data[2]);
	g_free (data);

	opkg_set_option ((char *)"autoremove", &autoremove);
	opkg_set_option ((char *)"force_removal_of_dependent_packages", &allow_deps);

	err = 0;

	for (i = 0; package_ids[i]; i++)
	{
		pk_backend_job_package (job, PK_INFO_ENUM_REMOVING, package_ids[i], NULL);

		parts = pk_package_id_split (package_ids[i]);

		err = opkg_remove_package (parts[PK_PACKAGE_ID_NAME], pk_opkg_progress_cb, backend);

		switch (err)
		{
		//case OPKG_NO_ERROR:
		//	break;
		//case OPKG_PACKAGE_NOT_INSTALLED:
		//	pk_backend_job_error_code (job, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL);
		//	break;
		default:
			opkg_unknown_error (backend, err, "Remove");
		}
		g_strfreev (parts);

		if (err != 0)
			break;
	}

	pk_backend_job_finished (job);
}
예제 #10
0
static void
pk_opkg_list_upgradable_cb (pkg_t *pkg, void *data)
{
	PkBackend *backend = (PkBackend*) data;
	gchar *uid;
	gint status;

	if (pkg->state_status == SS_INSTALLED)
		status = PK_INFO_ENUM_INSTALLED;
	else
		status = PK_INFO_ENUM_AVAILABLE;

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

	pk_backend_job_package (job, status, uid, pkg->description);
	g_free(uid);
}
예제 #11
0
static void
pk_opkg_progress_cb (const opkg_progress_data_t *pdata, void *data)
{
	PkBackend *backend = (PkBackend*) data;
	if (!backend)
		return;

	pk_backend_job_set_percentage (job, pdata->percentage);
	if (pdata->pkg)
	{
		gchar *uid;
		pkg_t *pkg = pdata->pkg;
		gint status = PK_INFO_ENUM_UNKNOWN;

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

		if (pdata->action == OPKG_DOWNLOAD)
			status = PK_INFO_ENUM_DOWNLOADING;
		else if (pdata->action == OPKG_INSTALL)
			status = PK_INFO_ENUM_INSTALLING;
		else if (pdata->action == OPKG_REMOVE)
			status = PK_INFO_ENUM_REMOVING;

		pk_backend_job_package (job, status, uid, pkg->description);
		g_free (uid);
	}

	switch (pdata->action)
	{
	case OPKG_DOWNLOAD:
		pk_backend_job_set_status (job, PK_STATUS_ENUM_DOWNLOAD);
		break;
	case OPKG_INSTALL:
		pk_backend_job_set_status (job, PK_STATUS_ENUM_INSTALL);
		break;
	case OPKG_REMOVE:
		pk_backend_job_set_status (job, PK_STATUS_ENUM_REMOVE);
		break;
	}
}
예제 #12
0
static void
add_packages_from_list (PkBackend *backend, GList *list, gboolean updates)
{
	PackageSearch *package = NULL;
	GList *li = NULL;
	gchar *pkg_string = NULL;
	PkInfoEnum info;

	for (li = list; li != NULL; li = li->next) {
		package = (PackageSearch*)li->data;
		pkg_string = pk_package_id_build (package->package, package->version, package->arch, package->reponame);
		if (updates == TRUE)
			info = PK_INFO_ENUM_NORMAL;
		else if (package->installed)
			info = PK_INFO_ENUM_INSTALLED;
		else
			info = PK_INFO_ENUM_AVAILABLE;
		pk_backend_job_package (job, info, pkg_string, package->description);
		g_free (pkg_string);
	}
}
예제 #13
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;
}
예제 #14
0
/**
 * 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) {
예제 #15
0
static void pk_backend_get_updates_thread(PkBackendJob *job, GVariant *params, gpointer user_data) {
	gchar *pkg_id, *full_name, *desc, **pkg_tokens;
	const gchar *pkg_metadata_filename;
	GFile *pkg_metadata_dir;
	GFileEnumerator *pkg_metadata_enumerator;
	GFileInfo *pkg_metadata_file_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);

	if ((sqlite3_prepare_v2(job_data->db,
							"SELECT p1.full_name, p1.name, p1.ver, p1.arch, r.repo, p1.summary, p1.ext "
							"FROM pkglist AS p1 NATURAL JOIN repos AS r "
							"WHERE p1.name LIKE @name AND p1.repo_order = "
							"(SELECT MIN(p2.repo_order) FROM pkglist AS p2 WHERE p2.name = p1.name GROUP BY p2.name)",
							-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;
	}

	/* Read the package metadata directory and comprare all installed packages with ones in the cache */
	pkg_metadata_dir = g_file_new_for_path("/var/log/packages");
	pkg_metadata_enumerator = g_file_enumerate_children(pkg_metadata_dir, "standard::name",
														 G_FILE_QUERY_INFO_NONE,
														 NULL,
														 &err);
	g_object_unref(pkg_metadata_dir);
	if (err) {
		pk_backend_job_error_code(job, PK_ERROR_ENUM_NO_CACHE, "/var/log/packages: %s", err->message);
		g_error_free(err);
		goto out;
	}

	while ((pkg_metadata_file_info = g_file_enumerator_next_file(pkg_metadata_enumerator, NULL, NULL))) {
		pkg_metadata_filename = g_file_info_get_name(pkg_metadata_file_info);
		pkg_tokens = katja_cut_pkg(pkg_metadata_filename);

		/* Select the package from the database */
		sqlite3_bind_text(stmt, 1, pkg_tokens[0], -1, SQLITE_TRANSIENT);

		/* If there are more packages with the same name, remember the one from the repository with the lowest order */
		if ((sqlite3_step(stmt) == SQLITE_ROW) ||
			g_slist_find_custom(repos, ((gchar *) sqlite3_column_text(stmt, 4)), katja_cmp_repo)) {

			full_name = g_strdup((gchar *) sqlite3_column_text(stmt, 0));

			if (!g_strcmp0((gchar *) sqlite3_column_text(stmt, 6), "obsolete")) { /* Remove if obsolete */
				pkg_id = pk_package_id_build(pkg_tokens[PK_PACKAGE_ID_NAME],
											 pkg_tokens[PK_PACKAGE_ID_VERSION],
											 pkg_tokens[PK_PACKAGE_ID_ARCH],
											 "obsolete");
				/* TODO:
				 * 1: Use the repository name instead of "obsolete" above and check in pk_backend_update_packages()
				      if the package is obsolete or not
				 * 2: Get description from /var/log/packages, not from the database */
				desc = g_strdup((gchar *) sqlite3_column_text(stmt, 5));

				pk_backend_job_package(job, PK_INFO_ENUM_REMOVING, pkg_id, desc);

				g_free(desc);
				g_free(pkg_id);
			} else if (g_strcmp0(pkg_metadata_filename, full_name)) { /* Update available */
				pkg_id = pk_package_id_build((gchar *) sqlite3_column_text(stmt, 1),
											 (gchar *) sqlite3_column_text(stmt, 2),
											 (gchar *) sqlite3_column_text(stmt, 3),
											 (gchar *) sqlite3_column_text(stmt, 4));
				desc = g_strdup((gchar *) sqlite3_column_text(stmt, 5));

				pk_backend_job_package(job, PK_INFO_ENUM_NORMAL, pkg_id, desc);

				g_free(desc);
				g_free(pkg_id);
			}
			g_free(full_name);
		}

		sqlite3_clear_bindings(stmt);
		sqlite3_reset(stmt);

		g_strfreev(pkg_tokens);
		g_object_unref(pkg_metadata_file_info);
	}
	g_object_unref(pkg_metadata_enumerator);

out:
	sqlite3_finalize(stmt);

	pk_backend_job_finished (job);
}
예제 #16
0
static void pk_backend_install_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data) {
	gchar *dest_dir_name, **pkg_tokens, **pkg_ids;
	guint i;
	gdouble percent_step;
	GSList *repo, *install_list = NULL, *l;
	sqlite3_stmt *pkglist_stmt = NULL, *collection_stmt = NULL;
    PkBitfield transaction_flags = 0;
	PkInfoEnum ret;
	PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job);

	g_variant_get(params, "(t^a&s)", &transaction_flags, &pkg_ids);
	pk_backend_job_set_status(job, PK_STATUS_ENUM_DEP_RESOLVE);

	if ((sqlite3_prepare_v2(job_data->db,
							"SELECT summary, cat FROM pkglist NATURAL JOIN repos "
							"WHERE name LIKE @name AND ver LIKE @ver AND arch LIKE @arch AND repo LIKE @repo",
							-1,
							&pkglist_stmt,
							NULL) != SQLITE_OK) ||
		(sqlite3_prepare_v2(job_data->db,
						   "SELECT (c.collection_pkg || ';' || p.ver || ';' || p.arch || ';' || r.repo), p.summary, "
						   "p.full_name, p.ext FROM collections AS c "
						   "JOIN pkglist AS p ON c.collection_pkg = p.name "
						   "JOIN repos AS r ON p.repo_order = r.repo_order "
						   "WHERE c.name LIKE @name AND r.repo LIKE @repo",
						   -1,
						   &collection_stmt,
						   NULL) != SQLITE_OK)) {
		pk_backend_job_error_code(job, PK_ERROR_ENUM_CANNOT_GET_FILELIST, "%s", sqlite3_errmsg(job_data->db));
		goto out;
	}

	for (i = 0; pkg_ids[i]; i++) {
		pkg_tokens = pk_package_id_split(pkg_ids[i]);
		sqlite3_bind_text(pkglist_stmt, 1, pkg_tokens[PK_PACKAGE_ID_NAME], -1, SQLITE_TRANSIENT);
		sqlite3_bind_text(pkglist_stmt, 2, pkg_tokens[PK_PACKAGE_ID_VERSION], -1, SQLITE_TRANSIENT);
		sqlite3_bind_text(pkglist_stmt, 3, pkg_tokens[PK_PACKAGE_ID_ARCH], -1, SQLITE_TRANSIENT);
		sqlite3_bind_text(pkglist_stmt, 4, pkg_tokens[PK_PACKAGE_ID_DATA], -1, SQLITE_TRANSIENT);

		if (sqlite3_step(pkglist_stmt) == SQLITE_ROW) {

			/* If it isn't a collection */
			if (g_strcmp0((gchar *) sqlite3_column_text(pkglist_stmt, 1), "collections")) {
				if (pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) {
					pk_backend_job_package(job, PK_INFO_ENUM_INSTALLING,
										   pkg_ids[i],
										   (gchar *) sqlite3_column_text(pkglist_stmt, 0));
				} else {
					install_list = g_slist_append(install_list, g_strdup(pkg_ids[i]));
				}
			} else {
				sqlite3_bind_text(collection_stmt, 1, pkg_tokens[PK_PACKAGE_ID_NAME], -1, SQLITE_TRANSIENT);
				sqlite3_bind_text(collection_stmt, 2, pkg_tokens[PK_PACKAGE_ID_DATA], -1, SQLITE_TRANSIENT);

				while (sqlite3_step(collection_stmt) == SQLITE_ROW) {
					ret = katja_pkg_is_installed((gchar *) sqlite3_column_text(collection_stmt, 2));
					if ((ret == PK_INFO_ENUM_INSTALLING) || (ret == PK_INFO_ENUM_UPDATING)) {
						if ((pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) &&
							!g_strcmp0((gchar *) sqlite3_column_text(collection_stmt, 3), "obsolete")) {
							/* TODO: Don't just skip obsolete packages but remove them */
						} else if (pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) {
							pk_backend_job_package(job, ret,
												   (gchar *) sqlite3_column_text(collection_stmt, 0),
												   (gchar *) sqlite3_column_text(collection_stmt, 1));
						} else {
							install_list = g_slist_append(install_list,
														  g_strdup((gchar *) sqlite3_column_text(collection_stmt, 0)));
						}
					}
				}

				sqlite3_clear_bindings(collection_stmt);
				sqlite3_reset(collection_stmt);
			}
		}

		sqlite3_clear_bindings(pkglist_stmt);
		sqlite3_reset(pkglist_stmt);
		g_strfreev(pkg_tokens);
	}

	if (install_list && !pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) {
		/* / 2 means total percentage for installing and for downloading */
		percent_step = 100.0 / g_slist_length(install_list) / 2;

		/* Download the packages */
		pk_backend_job_set_status(job, PK_STATUS_ENUM_DOWNLOAD);
		dest_dir_name = g_build_filename(LOCALSTATEDIR, "cache", "PackageKit", "downloads", NULL);
		for (l = install_list, i = 0; l; l = g_slist_next(l), i++) {
			pk_backend_job_set_percentage(job, percent_step * i);
			pkg_tokens = pk_package_id_split(l->data);
			repo = g_slist_find_custom(repos, pkg_tokens[PK_PACKAGE_ID_DATA], katja_cmp_repo);

			if (repo)
				katja_pkgtools_download(KATJA_PKGTOOLS(repo->data), job,
										dest_dir_name,
										pkg_tokens[PK_PACKAGE_ID_NAME]);
			g_strfreev(pkg_tokens);
		}
		g_free(dest_dir_name);

		/* Install the packages */
		pk_backend_job_set_status(job, PK_STATUS_ENUM_INSTALL);
		for (l = install_list; l; l = g_slist_next(l), i++) {
			pk_backend_job_set_percentage(job, percent_step * i);
			pkg_tokens = pk_package_id_split(l->data);
			repo = g_slist_find_custom(repos, pkg_tokens[PK_PACKAGE_ID_DATA], katja_cmp_repo);

			if (repo)
				katja_pkgtools_install(KATJA_PKGTOOLS(repo->data), job, pkg_tokens[PK_PACKAGE_ID_NAME]);
			g_strfreev(pkg_tokens);
		}
	}
	g_slist_free_full(install_list, g_free);

out:
	sqlite3_finalize(pkglist_stmt);
	sqlite3_finalize(collection_stmt);

	pk_backend_job_finished (job);
}
예제 #17
0
static void
pk_opkg_package_list_cb (pkg_t *pkg, void *data)
{
	SearchParams *params = (SearchParams*) data;
	gchar *uid;
	gchar *haystack;
	gint status, match;
	PkBitfield filters = params->filters;

	if (!pkg->name)
		return;

	switch (params->search_type)
	{
		case SEARCH_NAME:
			if (!pkg->name)
				return;
			haystack = g_utf8_strdown (pkg->name, -1);
			match = (g_strrstr (haystack, params->needle) != NULL);
			g_free (haystack);
			if (!match)
				return;
			break;
		case SEARCH_DESCRIPTION:
			if (!pkg->description)
				return;
			haystack = g_utf8_strdown (pkg->description, -1);
			match = (g_strrstr (haystack, params->needle) != NULL);
			g_free (haystack);
			if (!match)
				return;
			break;
		case SEARCH_TAG:
			if (!pkg->tags)
				return;
			if (!g_strrstr (pkg->tags, params->needle))
				return;
			break;
	}

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

	if (pkg->state_status == SS_INSTALLED)
		status = PK_INFO_ENUM_INSTALLED;
	else
		status = PK_INFO_ENUM_AVAILABLE;

	/* check filters */

	if (pk_bitfield_contain(filters, PK_FILTER_ENUM_DEVELOPMENT) && 
		!opkg_is_devel_pkg (pkg))
		goto end_handle;
	if (pk_bitfield_contain(filters, PK_FILTER_ENUM_NOT_DEVELOPMENT) && 
		opkg_is_devel_pkg (pkg))
		goto end_handle;
	if (pk_bitfield_contain(filters, PK_FILTER_ENUM_GUI) && 
		!opkg_is_gui_pkg (pkg))
		goto end_handle;
	if (pk_bitfield_contain(filters, PK_FILTER_ENUM_NOT_GUI) && 
		opkg_is_gui_pkg (pkg))
		goto end_handle;
	if (pk_bitfield_contain(filters, PK_FILTER_ENUM_INSTALLED) && 
		(pkg->state_status != SS_INSTALLED))
		goto end_handle;
	if (pk_bitfield_contain(filters, PK_FILTER_ENUM_NOT_INSTALLED) && 
		(pkg->state_status == SS_INSTALLED))
		goto end_handle;

	pk_backend_job_package (params->backend, status, uid, pkg->description);

end_handle:
	g_free(uid);

}