Пример #1
0
static void backend_get_files_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **package_ids;
    gchar *pi;

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

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        return;
    }

    if (package_ids == NULL) {
        pk_backend_job_error_code(job,
                                  PK_ERROR_ENUM_PACKAGE_ID_INVALID,
                                  "Invalid package id");
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    for (uint i = 0; i < g_strv_length(package_ids); ++i) {
        pi = package_ids[i];
        if (pk_package_id_check(pi) == false) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_ID_INVALID,
                                      "%s",
                                      pi);
            return;
        }

        const pkgCache::VerIterator &ver = apt->aptCacheFile()->resolvePkgID(pi);
        if (ver.end()) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
                                      "Couldn't find package %s",
                                      pi);
            return;
        }

        apt->emitPackageFiles(pi);
    }
}
Пример #2
0
static void backend_search_package_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **values;
    PkBitfield filters;
    PkRoleEnum role;
    vector<string> queries;

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

    if (*values) {
        for (gint i = 0; values[i] != NULL; i++) {
            queries.push_back(values[i]);
        }
    }

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        return;
    }

    if (_error->PendingError() == true) {
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    pk_backend_job_set_percentage(job, PK_BACKEND_PERCENTAGE_INVALID);
    pk_backend_job_set_allow_cancel(job, true);

    PkgList output;
    role = pk_backend_job_get_role(job);
    if (role == PK_ROLE_ENUM_SEARCH_DETAILS) {
        output = apt->searchPackageDetails(queries);
    } else {
        output = apt->searchPackageName(queries);
    }

    // It's faster to emit the packages here than in the matching part
    apt->emitPackages(output, filters);

    pk_backend_job_set_percentage(job, 100);
}
Пример #3
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);
}
Пример #4
0
/**
 * pk_backend_get_repo_list:
 */
static void
pk_backend_get_repo_list (PkBackend *backend, PkBackendJob *job, PkBitfield filters)
{
	GList *list;
	GList *li;
	RepoInfo *repo;

	pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY);

	list = box_repos_list_get ();
	for (li = list; li != NULL; li=li->next)
	{
		repo = (RepoInfo*) li->data;
		pk_backend_job_repo_detail (job, repo->name, repo->description, repo->enabled);
	}
	box_repos_list_free (list);

	pk_backend_job_finished (job);
}
Пример #5
0
static void
backend_remove_packages_thread (PkBackendJob *job, GVariant *params, gpointer user_data)
{
	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]);

	pk_backend_job_set_status (job, PK_STATUS_ENUM_REMOVE);

	if (!box_package_uninstall (package_id_data[PK_PACKAGE_ID_NAME], ROOT_DIRECTORY, common_progress, backend, FALSE))
	{
		pk_backend_job_error_code (job, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, "Cannot uninstall");
	}

	pk_backend_finished (backend);
}
Пример #6
0
static void
backend_install_packages_thread (PkBackendJob *job, GVariant *params, gpointer user_data)
{
	gboolean result = TRUE;
	gchar **package_ids;
	size_t i;

	pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY);

	/* FIXME: support only_trusted */

	package_ids = pk_backend_get_strv (backend, "package_ids");
	for (i = 0; i < g_strv_length (package_ids); i++) {
		gchar **package_id_data = pk_package_id_split (package_ids[i]);
		result = box_package_install (package_id_data[PK_PACKAGE_ID_NAME], ROOT_DIRECTORY, common_progress, backend, FALSE);
	}

	pk_backend_job_finished (job);
}
Пример #7
0
static void
pk_backend_remove_packages (PkBackend *backend, PkBackendJob *job, gchar **package_ids, gboolean allow_deps, gboolean autoremove)
{
	gpointer *params;

	pk_backend_job_set_status (job, PK_STATUS_ENUM_REMOVE);
	pk_backend_job_set_percentage (job, PK_BACKEND_PERCENTAGE_INVALID);

	/* params is a small array we can pack our thread parameters into */
	params = g_new0 (gpointer, 2);

	params[0] = g_strdupv (package_ids);
	params[1] = GINT_TO_POINTER (allow_deps);
	params[2] = GINT_TO_POINTER (autoremove);

	pk_backend_set_pointer (backend, "remove-params", params);

	pk_backend_job_thread_create (job, backend_remove_packages_thread, NULL, NULL);
}
/**
 * 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);
}
Пример #9
0
void
pk_backend_run (PkBackend *self, PkStatusEnum status, PkBackendThreadFunc func)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (func != NULL);

	g_static_mutex_lock (&mutex);

	if (cancellable != NULL) {
		g_warning ("cancellable was not NULL");
		g_object_unref (cancellable);
	}
	cancellable = g_cancellable_new ();

	g_static_mutex_unlock (&mutex);

	pk_backend_job_set_allow_cancel (self, TRUE);

	pk_backend_job_set_status (self, status);
	pk_backend_job_thread_create (self, func);
}
Пример #10
0
/**
 * pk_backend_thread_start:
 **/
void
pk_backend_thread_start (PkBackend *backend, PkBackendJob *job, gpointer func)
{
	GMutex *mutex;
	gboolean ret;

	g_mutex_lock (&backend->priv->thread_hash_mutex);
	mutex = g_hash_table_lookup (backend->priv->thread_hash, func);
	if (mutex == NULL) {
		mutex = g_new0 (GMutex, 1);
		g_mutex_init (mutex);
		g_hash_table_insert (backend->priv->thread_hash, func, mutex);
	}
	g_mutex_unlock (&backend->priv->thread_hash_mutex);

	ret = g_mutex_trylock (mutex);
	if (!ret) {
		pk_backend_job_set_status (job,
					   PK_STATUS_ENUM_WAITING_FOR_LOCK);
		g_mutex_lock (mutex);
	}
}
Пример #11
0
static void backend_get_updates_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    PkBitfield filters;
    g_variant_get(params, "(t)", &filters);

    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);

    PkgList updates;
    PkgList blocked;
    updates = apt->getUpdates(blocked);

    apt->emitUpdates(updates, filters);
    apt->emitPackages(blocked, filters, PK_INFO_ENUM_BLOCKED);
}
Пример #12
0
static void
backend_get_files_thread (PkBackendJob *job, GVariant *params, gpointer user_data)
{
	gchar *files;
	sqlite3 *db;
	gchar **package_ids;
	gchar **package_id_data;

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

	pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY);

	files = box_db_repos_get_files_string (db, package_id_data[PK_PACKAGE_ID_NAME], package_id_data[PK_PACKAGE_ID_VERSION]);
	pk_backend_job_files (job, package_ids[0], files);

	db_close (db);
	g_free (files);

	pk_backend_finished (backend);
}
Пример #13
0
static void backend_get_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    PkBitfield filters;
    g_variant_get(params, "(t)",
                  &filters);
    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        apt->emitFinished();
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    PkgList output;
    output = apt->getPackages();

    // It's faster to emmit the packages rather here than in the matching part
    apt->emitPackages(output, filters);

    apt->emitFinished();
}
static void
pk_backend_transaction_dlcb (const gchar *basename, off_t complete, off_t total)
{
	guint percentage = 100, sub_percentage = 100;

	g_return_if_fail (basename != NULL);
	g_return_if_fail (complete <= total);
	g_return_if_fail (backend != NULL);

	if (total > 0) {
		sub_percentage = complete * 100 / total;
	}

	if (dtotal > 0) {
		percentage = (dcomplete + complete) * 100 / dtotal;
	} else if (dtotal < 0) {
		/* database files */
		percentage = (dcomplete * 100 + sub_percentage) / -dtotal;

		if (complete == total) {
			complete = total = 1;
		} else {
			complete = total + 1;
		}
	}

	if (complete == 0) {
		g_debug ("downloading file %s", basename);
		pk_backend_job_set_status (job, PK_STATUS_ENUM_DOWNLOAD);
		pk_backend_transaction_download_start (backend, basename);
	} else if (complete == total) {
		dcomplete += complete;
	}

	pk_backend_set_sub_percentage (backend, sub_percentage);
	pk_backend_job_set_percentage (job, percentage);
}
Пример #15
0
static void pk_backend_get_update_detail_thread(PkBackendJob *job, GVariant *params, gpointer user_data) {
	guint i;
	gchar **pkg_ids;

	pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);

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

	for (i = 0; pkg_ids[i] != NULL; i++) {
		pk_backend_job_update_detail (job,
									  pkg_ids[i],
									  NULL,
									  NULL,
									  NULL,
									  NULL,
									  NULL,
									  PK_RESTART_ENUM_NONE,
									  NULL,
									  NULL,
									  PK_UPDATE_STATE_ENUM_STABLE,
									  NULL,
									  NULL);
	}
}
Пример #16
0
void pk_backend_start_job(PkBackend *backend, PkBackendJob *job) {
	gchar *db_filename = NULL;
	PkBackendKatjaJobData *job_data = g_new0(PkBackendKatjaJobData, 1);

	pk_backend_job_set_allow_cancel(job, TRUE);
	pk_backend_job_set_allow_cancel(job, FALSE);

	db_filename = g_build_filename(LOCALSTATEDIR, "cache", "PackageKit", "metadata", "metadata.db", NULL);
	if (sqlite3_open(db_filename, &job_data->db) == SQLITE_OK) { /* Some SQLite settings */
		sqlite3_exec(job_data->db, "PRAGMA foreign_keys = ON", NULL, NULL, NULL);
	} else {
		pk_backend_job_error_code(job, PK_ERROR_ENUM_NO_CACHE,
								  "%s: %s",
								  db_filename,
								  sqlite3_errmsg(job_data->db));
		goto out;
	}

	pk_backend_job_set_user_data(job, job_data);
	pk_backend_job_set_status(job, PK_STATUS_ENUM_RUNNING);

out:
	g_free(db_filename);
}
Пример #17
0
static void backend_get_details_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **package_ids;
    PkRoleEnum role;
    role = pk_backend_job_get_role(job);

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

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug ("Failed to create apt cache");
        apt->emitFinished();
        return;
    }

    if (package_ids == NULL) {
        pk_backend_job_error_code(job,
                                  PK_ERROR_ENUM_PACKAGE_ID_INVALID,
                                  "Invalid package id");
        pk_backend_job_finished(job);
        apt->emitFinished();
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    PkgList pkgs = apt->resolvePackageIds(package_ids);

    if (role == PK_ROLE_ENUM_GET_UPDATE_DETAIL) {
        apt->emitUpdateDetails(pkgs);
    } else {
        apt->emitDetails(pkgs);
    }

    apt->emitFinished();
}
Пример #18
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);
}
Пример #19
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_plugin_transaction_finished_results:
 */
void
pk_plugin_transaction_finished_results (PkPlugin *plugin,
					PkTransaction *transaction)
{
	gchar **package_ids = NULL;
	gchar *package_id_tmp;
	GPtrArray *array = NULL;
	GPtrArray *list = NULL;
	guint i;
	PkInfoEnum info;
	PkPackage *item;
	PkResults *results;
	PkRoleEnum role;

	/* skip simulate actions */
	if (pk_bitfield_contain (pk_transaction_get_transaction_flags (transaction),
				 PK_TRANSACTION_FLAG_ENUM_SIMULATE)) {
		goto out;
	}

	/* skip only-download */
	if (pk_bitfield_contain (pk_transaction_get_transaction_flags (transaction),
				 PK_TRANSACTION_FLAG_ENUM_ONLY_DOWNLOAD)) {
		goto out;
	}

	/* load */
	if (plugin->priv->db == NULL)
		pk_transaction_plugin_load_db (plugin, transaction);

	/* no database */
	if (plugin->priv->db == NULL)
		goto out;

	/* check the role */
	role = pk_transaction_get_role (transaction);
	if (role != PK_ROLE_ENUM_INSTALL_PACKAGES)
		goto out;

	/* connect to backend */
	if (!pk_backend_is_implemented (plugin->backend,
					PK_ROLE_ENUM_GET_FILES)) {
		g_debug ("cannot get files");
		goto out;
	}

	/* get results */
	results = pk_transaction_get_results (transaction);
	array = pk_results_get_package_array (results);

	/* filter on INSTALLING | UPDATING */
	list = g_ptr_array_new_with_free_func (g_free);
	for (i=0; i<array->len; i++) {
		item = g_ptr_array_index (array, i);
		info = pk_package_get_info (item);
		if (info == PK_INFO_ENUM_INSTALLING ||
		    info == PK_INFO_ENUM_UPDATING) {
			/* we convert the package_id data to be 'installed' */
			package_id_tmp = pk_package_id_build (pk_package_get_name (item),
							      pk_package_get_version (item),
							      pk_package_get_arch (item),
							      "installed");
			g_ptr_array_add (list, package_id_tmp);
		}
	}

	/* process file lists on these packages */
	g_debug ("processing %i packags for desktop files", list->len);
	if (list->len == 0)
		goto out;

	/* get all the files touched in the packages we just installed */
	pk_backend_reset_job (plugin->backend, plugin->job);
	pk_backend_job_set_vfunc (plugin->job,
				  PK_BACKEND_SIGNAL_FINISHED,
				  (PkBackendJobVFunc) pk_plugin_finished_cb,
				  plugin);
	pk_backend_job_set_vfunc (plugin->job,
				  PK_BACKEND_SIGNAL_FILES,
				  (PkBackendJobVFunc) pk_plugin_files_cb,
				  plugin);
	pk_backend_job_set_status (plugin->job, PK_STATUS_ENUM_SCAN_APPLICATIONS);
	pk_backend_job_set_percentage (plugin->job, 101);
	package_ids = pk_ptr_array_to_strv (list);
	pk_backend_get_files (plugin->backend, plugin->job, package_ids);

	/* wait for finished */
	g_main_loop_run (plugin->priv->loop);

	pk_backend_job_set_percentage (plugin->job, 100);
out:
	if (array != NULL)
		g_ptr_array_unref (array);
	if (list != NULL)
		g_ptr_array_unref (list);
	g_strfreev (package_ids);
}
/**
 * pk_plugin_transaction_finished_end:
 */
void
pk_plugin_transaction_finished_end (PkPlugin *plugin,
				    PkTransaction *transaction)
{
	gchar *error_msg = NULL;
	gchar *path;
	gchar *statement;
	gfloat step;
	gint rc;
	GPtrArray *array = NULL;
	guint i;
	PkRoleEnum role;

	/* skip simulate actions */
	if (pk_bitfield_contain (pk_transaction_get_transaction_flags (transaction),
				 PK_TRANSACTION_FLAG_ENUM_SIMULATE)) {
		goto out;
	}

	/* skip only-download */
	if (pk_bitfield_contain (pk_transaction_get_transaction_flags (transaction),
				 PK_TRANSACTION_FLAG_ENUM_ONLY_DOWNLOAD)) {
		goto out;
	}

	/* load */
	if (plugin->priv->db == NULL)
		pk_transaction_plugin_load_db (plugin, transaction);

	/* no database */
	if (plugin->priv->db == NULL)
		goto out;

	/* check the role */
	role = pk_transaction_get_role (transaction);
	if (role != PK_ROLE_ENUM_REFRESH_CACHE)
		goto out;

	/* connect to backend */
	if (!pk_backend_is_implemented (plugin->backend,
					PK_ROLE_ENUM_SEARCH_FILE)) {
		g_debug ("cannot search files");
		goto out;
	}

	/* use a local backend instance */
	pk_backend_reset_job (plugin->backend, plugin->job);
	pk_backend_job_set_vfunc (plugin->job,
				  PK_BACKEND_SIGNAL_FINISHED,
				  (PkBackendJobVFunc) pk_plugin_finished_cb,
				  plugin);
	pk_backend_job_set_vfunc (plugin->job,
				  PK_BACKEND_SIGNAL_PACKAGE,
				  (PkBackendJobVFunc) pk_plugin_package_cb,
				  plugin);
	pk_backend_job_set_status (plugin->job,
				   PK_STATUS_ENUM_SCAN_APPLICATIONS);

	/* reset hash */
	g_hash_table_remove_all (plugin->priv->hash);
	pk_backend_job_set_percentage (plugin->job, 101);

	/* first go through the existing data, and look for
	 * modifications and removals */
	statement = g_strdup ("SELECT filename, md5 FROM cache");
	rc = sqlite3_exec (plugin->priv->db,
			   statement,
			   pk_plugin_sqlite_cache_rescan_cb,
			   plugin,
			   &error_msg);
	g_free (statement);
	if (rc != SQLITE_OK) {
		g_warning ("SQL error: %s\n", error_msg);
		sqlite3_free (error_msg);
		goto out;
	}

	array = g_ptr_array_new_with_free_func (g_free);
	pk_plugin_get_desktop_files (plugin,
				     PK_DESKTOP_DEFAULT_APPLICATION_DIR,
				     array);

	if (array->len) {
		step = 100.0f / array->len;
		pk_backend_job_set_status (plugin->job,
				       PK_STATUS_ENUM_GENERATE_PACKAGE_LIST);

		/* process files in an array */
		for (i=0; i<array->len; i++) {
			pk_backend_job_set_percentage (plugin->job, i * step);
			path = g_ptr_array_index (array, i);
			pk_plugin_sqlite_add_filename (plugin,
						       path,
						       NULL);
		}
	}

	pk_backend_job_set_percentage (plugin->job, 100);
	pk_backend_job_set_status (plugin->job, PK_STATUS_ENUM_FINISHED);
out:
	if (array != NULL)
		g_ptr_array_unref (array);
}
Пример #22
0
static void backend_manage_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    // Transaction flags
    PkBitfield transaction_flags = 0;
    gboolean allow_deps = false;
    gboolean autoremove = false;
    bool fileInstall = false;
    gchar **full_paths = NULL;
    gchar **package_ids = NULL;

    // Get the transaction role since this method is called by install/remove/update/repair
    PkRoleEnum role = pk_backend_job_get_role(job);
    if (role == PK_ROLE_ENUM_INSTALL_FILES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &full_paths);
        fileInstall = true;
    } else if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
        g_variant_get(params, "(t^a&sbb)",
                      &transaction_flags,
                      &package_ids,
                      &allow_deps,
                      &autoremove);
    } else if (role == PK_ROLE_ENUM_INSTALL_PACKAGES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &package_ids);
    } else if (role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &package_ids);
    }

    // Check if we should only simulate the install (calculate dependencies)
    bool simulate;
    simulate = pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE);

    // Check if we should only download all the required packages for this transaction
    bool downloadOnly;
    downloadOnly = pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_ONLY_DOWNLOAD);

    // Check if we should fix broken packages
    bool fixBroken = false;
    if (role == PK_ROLE_ENUM_REPAIR_SYSTEM) {
        // On fix broken mode no package to remove/install is allowed
        fixBroken = true;
    }

    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init(full_paths)) {
        g_debug("Failed to create apt cache");
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    PkgList installPkgs, removePkgs, updatePkgs;

    if (!fixBroken) {
        // Resolve the given packages
        if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
            removePkgs = apt->resolvePackageIds(package_ids);
        } else if (role == PK_ROLE_ENUM_INSTALL_PACKAGES) {
            installPkgs = apt->resolvePackageIds(package_ids);
        } else if (role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
            updatePkgs = apt->resolvePackageIds(package_ids);
        } else if (role == PK_ROLE_ENUM_INSTALL_FILES) {
            installPkgs = apt->resolveLocalFiles(full_paths);
        } else {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
                                      "Could not figure out what to do to apply the change.");
            return;
        }

        if (removePkgs.size() == 0 && installPkgs.size() == 0 && updatePkgs.size() == 0) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
                                      "Could not find package(s)");
            return;
        }
    }

    // Install/Update/Remove packages, or just simulate
    bool ret = apt->runTransaction(installPkgs,
                                   removePkgs,
                                   updatePkgs,
                                   fixBroken,
                                   transaction_flags,
                                   autoremove);
    if (!ret) {
        // Print transaction errors
        g_debug("AptIntf::runTransaction() failed: %i", _error->PendingError());
        return;
    }
}
Пример #23
0
static void backend_repo_manager_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    // list
    PkBitfield filters;
    // enable
    const gchar *repo_id;
    gboolean enabled;
    bool found = false;
    // generic
    PkRoleEnum role;
    const char *const salt = "$1$/iSaq7rB$EoUw5jJPPvAPECNaaWzMK/";
    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));

    role = pk_backend_job_get_role(job);
    if (role == PK_ROLE_ENUM_GET_REPO_LIST) {
        pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
        g_variant_get(params, "(t)",
                      &filters);
    } else {
        pk_backend_job_set_status(job, PK_STATUS_ENUM_REQUEST);
        g_variant_get (params, "(&sb)",
                       &repo_id,
                       &enabled);
    }

    SourcesList _lst;
    if (_lst.ReadSources() == false) {
        _error->
                Warning("Ignoring invalid record(s) in sources.list file!");
        //return false;
    }

    if (_lst.ReadVendors() == false) {
        _error->Error("Cannot read vendors.list file");
        show_errors(job, PK_ERROR_ENUM_FAILED_CONFIG_PARSING);
        apt->emitFinished();
        return;
    }

    for (SourcesListIter it = _lst.SourceRecords.begin();
         it != _lst.SourceRecords.end(); ++it) {
        if ((*it)->Type & SourcesList::Comment) {
            continue;
        }

        string Sections;
        for (unsigned int j = 0; j < (*it)->NumSections; ++j) {
            Sections += (*it)->Sections[j];
            Sections += " ";
        }

        if (pk_bitfield_contain(filters, PK_FILTER_ENUM_NOT_DEVELOPMENT) &&
                ((*it)->Type & SourcesList::DebSrc ||
                 (*it)->Type & SourcesList::RpmSrc ||
                 (*it)->Type & SourcesList::RpmSrcDir ||
                 (*it)->Type & SourcesList::RepomdSrc)) {
            continue;
        }

        string repo;
        repo = (*it)->GetType();
        repo += " " + (*it)->VendorID;
        repo += " " + (*it)->URI;
        repo += " " + (*it)->Dist;
        repo += " " + Sections;
        gchar *hash;
        const gchar allowedChars[] =
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        hash = crypt(repo.c_str(), salt);
        g_strcanon(hash, allowedChars, 'D');
        string repoId(hash);

        if (role == PK_ROLE_ENUM_GET_REPO_LIST) {
            pk_backend_job_repo_detail(job,
                                       repoId.c_str(),
                                       repo.c_str(),
                                       !((*it)->Type & SourcesList::Disabled));
        } else {
            if (repoId.compare(repo_id) == 0) {
                if (enabled) {
                    (*it)->Type = (*it)->Type & ~SourcesList::Disabled;
                } else {
                    (*it)->Type |= SourcesList::Disabled;
                }
                found = true;
                break;
            }
        }
    }

    if (role == PK_ROLE_ENUM_REPO_ENABLE) {
        if (!found) {
            _error->Error("Could not found the repositorie");
            show_errors(job, PK_ERROR_ENUM_REPO_NOT_AVAILABLE);
        } else if (!_lst.UpdateSources()) {
            _error->Error("Could not update sources file");
            show_errors(job, PK_ERROR_ENUM_CANNOT_WRITE_REPO_CONFIG);
        }
    }

    apt->emitFinished();
}
Пример #24
0
static void pk_backend_refresh_cache_thread(PkBackendJob *job, GVariant *params, gpointer user_data) {
	gchar *tmp_dir_name, *db_err, *path = NULL;
	gint ret;
	gboolean force;
	GSList *file_list = NULL, *l;
	GFile *db_file = NULL;
	GFileInfo *file_info = NULL;
	GError *err = NULL;
	sqlite3_stmt *stmt = NULL;
	PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job);

	pk_backend_job_set_status(job, PK_STATUS_ENUM_DOWNLOAD_CHANGELOG);

	/* Create temporary directory */
	tmp_dir_name = g_dir_make_tmp("PackageKit.XXXXXX", &err);
	if (!tmp_dir_name) {
		pk_backend_job_error_code(job, PK_ERROR_ENUM_INTERNAL_ERROR, "%s", err->message);
		g_error_free(err);
		pk_backend_job_finished(job);
		return;
	}

	g_variant_get(params, "(b)", &force);

	/* Force the complete cache refresh if the read configuration file is newer than the metadata cache */
	if (!force) {
		path = g_build_filename(LOCALSTATEDIR, "cache", "PackageKit", "metadata", "metadata.db", NULL);
		db_file = g_file_new_for_path(path);
		file_info = g_file_query_info(db_file, "time::modified-usec", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &err);
		if (err) {
			pk_backend_job_error_code(job, PK_ERROR_ENUM_NO_CACHE, "%s: %s", path, err->message);
			g_error_free(err);
			goto out;
		}
		ret = sqlite3_prepare_v2(job_data->db,
								 "SELECT value FROM cache_info WHERE key LIKE 'last_modification'",
								 -1,
								 &stmt,
								 NULL);
		if ((ret != SQLITE_OK) || ((ret = sqlite3_step(stmt)) != SQLITE_ROW)) {
			pk_backend_job_error_code(job, PK_ERROR_ENUM_NO_CACHE, "%s: %s", path, sqlite3_errstr(ret));
			goto out;
		}
		if ((guint32) sqlite3_column_int(stmt, 0) > g_file_info_get_attribute_uint32(file_info, "time::modified-usec"))
			force = TRUE;
	}

	if (force) { /* It should empty all tables */
		if (sqlite3_exec(job_data->db, "DELETE FROM repos", NULL, 0, &db_err) != SQLITE_OK) {
			pk_backend_job_error_code(job, PK_ERROR_ENUM_INTERNAL_ERROR, "%s", db_err);
			sqlite3_free(db_err);
			goto out;
		}
	}

	for (l = repos; l; l = g_slist_next(l))	/* Get list of files that should be downloaded */
		file_list = g_slist_concat(file_list, katja_pkgtools_collect_cache_info(l->data, tmp_dir_name));

	/* Download repository */
	pk_backend_job_set_status(job, PK_STATUS_ENUM_DOWNLOAD_REPOSITORY);

	for (l = file_list; l; l = g_slist_next(l))
		katja_get_file(&job_data->curl, ((gchar **)l->data)[0], ((gchar **)l->data)[1]);
	g_slist_free_full(file_list, (GDestroyNotify)g_strfreev);

	/* Refresh cache */
	pk_backend_job_set_status(job, PK_STATUS_ENUM_REFRESH_CACHE);

	for (l = repos; l; l = g_slist_next(l))
		katja_pkgtools_generate_cache(l->data, job, tmp_dir_name);

out:
	sqlite3_finalize(stmt);
	if (file_info)
		g_object_unref(file_info);
	if (db_file)
		g_object_unref(db_file);
	g_free(path);

	pk_directory_remove_contents(tmp_dir_name);
	g_rmdir(tmp_dir_name);
	g_free(tmp_dir_name);
	pk_backend_job_finished(job);
}
Пример #25
0
static void backend_manage_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    // Transaction flags
    PkBitfield transaction_flags = 0;
    gboolean allow_deps = false;
    gboolean autoremove = false;
    bool fileInstall = false;
    gchar **full_paths = NULL;
    gchar **package_ids = NULL;

    // Get the transaction role since this method is called by install/remove/update/repair
    PkRoleEnum role = pk_backend_job_get_role(job);
    if (role == PK_ROLE_ENUM_INSTALL_FILES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &full_paths);
        fileInstall = true;
    } else if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
        g_variant_get(params, "(t^a&sbb)",
                      &transaction_flags,
                      &package_ids,
                      &allow_deps,
                      &autoremove);
    } else if (role == PK_ROLE_ENUM_INSTALL_PACKAGES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &package_ids);
    } else if (role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &package_ids);
    }

    // Check if we should only simulate the install (calculate dependencies)
    bool simulate;
    simulate = pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE);

    // Check if we should only download all the required packages for this transaction
    bool downloadOnly;
    downloadOnly = pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_ONLY_DOWNLOAD);

    // Check if we should fix broken packages
    bool fixBroken = false;
    if (role == PK_ROLE_ENUM_REPAIR_SYSTEM) {
        // On fix broken mode no package to remove/install is allowed
        fixBroken = true;
    }

    g_debug("FILE INSTALL: %i", fileInstall);
    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    PkgList installPkgs, removePkgs;

    if (fileInstall) {
        // File installation EXPERIMENTAL

        // GDebi can not install more than one package at time
        if (g_strv_length(full_paths) > 1) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_NOT_SUPPORTED,
                                      "The backend can only process one file at time.");
            return;
        }

        // get the list of packages to install
        if (!apt->markFileForInstall(full_paths[0], installPkgs, removePkgs)) {
            return;
        }

        cout << "installPkgs.size: " << installPkgs.size() << endl;
        cout << "removePkgs.size: " << removePkgs.size() << endl;

    } else if (!fixBroken) {
        // Resolve the given packages
        if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
            removePkgs = apt->resolvePackageIds(package_ids);
        } else {
            installPkgs = apt->resolvePackageIds(package_ids);
        }

        if (removePkgs.size() == 0 && installPkgs.size() == 0) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
                                      "Could not find package(s)");
            return;
        }
    }

    // Install/Update/Remove packages, or just simulate
    bool ret;
    ret = apt->runTransaction(installPkgs,
                              removePkgs,
                              fileInstall, // Mark newly installed packages as auto-installed
                              // (they're dependencies of the new local package)
                              fixBroken,
                              transaction_flags,
                              autoremove);
    if (!ret) {
        // Print transaction errors
        g_debug("AptIntf::runTransaction() failed: %i", _error->PendingError());
        return;
    }

    if (fileInstall) {
        // Now perform the installation!
        gchar *path;
        for (uint i = 0; i < g_strv_length(full_paths); ++i) {
            if (apt->cancelled()) {
                break;
            }

            path = full_paths[i];
            if (!apt->installFile(path, simulate)) {
                cout << "Installation of DEB file " << path << " failed." << endl;
                return;
            }
        }
    }
}
Пример #26
0
static void backend_get_depends_or_requires_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    PkRoleEnum role;
    PkBitfield filters;
    gchar **package_ids;
    gboolean recursive;
    gchar *pi;

    g_variant_get(params, "(t^a&sb)",
                  &filters,
                  &package_ids,
                  &recursive);
    role = pk_backend_job_get_role(job);

    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        apt->emitFinished();
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    PkgList output;
    for (uint i = 0; i < g_strv_length(package_ids); ++i) {
        if (apt->cancelled()) {
            break;
        }
        pi = package_ids[i];
        if (pk_package_id_check(pi) == false) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_ID_INVALID,
                                      "%s",
                                      pi);
            apt->emitFinished();
            return;
        }

        const pkgCache::VerIterator &ver = apt->aptCacheFile()->resolvePkgID(pi);
        if (ver.end()) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
                                      "Couldn't find package %s",
                                      pi);
            apt->emitFinished();
            return;
        }

        if (role == PK_ROLE_ENUM_GET_DEPENDS) {
            apt->getDepends(output, ver, recursive);
        } else {
            apt->getRequires(output, ver, recursive);
        }
    }

    // It's faster to emmit the packages here than in the matching part
    apt->emitPackages(output, filters);

    apt->emitFinished();
}
Пример #27
0
/**
 * pk_backend_download_packages_thread:
 */
static void pk_backend_download_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **package_ids;
    const gchar *tmpDir;
    string directory;

    g_variant_get(params, "(^a&ss)",
                  &package_ids,
                  &tmpDir);
    directory = _config->FindDir("Dir::Cache::archives");
    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        return;
    }

    PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job));
    if (pk_backend_is_online(backend)) {
        pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
        // Create the progress
        AcqPackageKitStatus Stat(apt, job);

        // get a fetcher
        pkgAcquire fetcher(&Stat);
        gchar *pi;

        // TODO this might be useful when the item is in the cache
        // 	for (pkgAcquire::ItemIterator I = fetcher.ItemsBegin(); I < fetcher.ItemsEnd();)
        // 	{
        // 		if ((*I)->Local == true)
        // 		{
        // 			I++;
        // 			continue;
        // 		}
        //
        // 		// Close the item and check if it was found in cache
        // 		(*I)->Finished();
        // 		if ((*I)->Complete == false) {
        // 			Transient = true;
        // 		}
        //
        // 		// Clear it out of the fetch list
        // 		delete *I;
        // 		I = fetcher.ItemsBegin();
        // 	}

        for (uint i = 0; i < g_strv_length(package_ids); ++i) {
            pi = package_ids[i];
            if (pk_package_id_check(pi) == false) {
                pk_backend_job_error_code(job,
                                          PK_ERROR_ENUM_PACKAGE_ID_INVALID,
                                          "%s",
                                          pi);
                return;
            }

            if (apt->cancelled()) {
                break;
            }

            const pkgCache::VerIterator &ver = apt->aptCacheFile()->resolvePkgID(pi);
            // Ignore packages that could not be found or that exist only due to dependencies.
            if (ver.end()) {
                _error->Error("Can't find this package id \"%s\".", pi);
                continue;
            } else {
                if(!ver.Downloadable()) {
                    _error->Error("No downloadable files for %s,"
                                  "perhaps it is a local or obsolete" "package?",
                                  pi);
                    continue;
                }

                string storeFileName;
                if (!apt->getArchive(&fetcher,
                                     ver,
                                     directory,
                                     storeFileName)) {
                    return;
                }

                gchar **files = (gchar **) g_malloc(2 * sizeof(gchar *));
                files[0] = g_strdup_printf("%s/%s", directory.c_str(), flNotDir(storeFileName).c_str());
                files[1] = NULL;
                pk_backend_job_files(job, pi, files);
                g_strfreev(files);
            }
        }

        if (fetcher.Run() != pkgAcquire::Continue
                && apt->cancelled() == false) {
            // We failed and we did not cancel
            show_errors(job, PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED);
            return;
        }

    } else {
        pk_backend_job_error_code(job,
                                  PK_ERROR_ENUM_NO_NETWORK,
                                  "Cannot download packages whilst offline");
    }
}
Пример #28
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);
}
Пример #29
0
static void backend_repo_manager_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    // list
    PkBitfield filters;
    PkBitfield transaction_flags = 0;
    // enable
    const gchar *repo_id;
    gboolean enabled;
    gboolean autoremove;
    bool found = false;
    // generic
    PkRoleEnum role;
    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));

    role = pk_backend_job_get_role(job);
    if (role == PK_ROLE_ENUM_GET_REPO_LIST) {
        pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
        g_variant_get(params, "(t)",
                      &filters);
    } else if (role == PK_ROLE_ENUM_REPO_REMOVE) {
        g_variant_get(params, "(t&sb)",
                      &transaction_flags,
                      &repo_id,
                      &autoremove);
    } else {
        pk_backend_job_set_status(job, PK_STATUS_ENUM_REQUEST);
        g_variant_get (params, "(&sb)",
                       &repo_id,
                       &enabled);
    }

    SourcesList _lst;
    if (_lst.ReadSources() == false) {
        _error->
        Warning("Ignoring invalid record(s) in sources.list file!");
        //return false;
    }

    if (_lst.ReadVendors() == false) {
        _error->Error("Cannot read vendors.list file");
        show_errors(job, PK_ERROR_ENUM_FAILED_CONFIG_PARSING);
        return;
    }

    for (SourcesListIter it = _lst.SourceRecords.begin();
            it != _lst.SourceRecords.end(); ++it) {
        if ((*it)->Type & SourcesList::Comment) {
            continue;
        }

        string sections = (*it)->joinedSections();

        string repoId = (*it)->repoId();

        if (role == PK_ROLE_ENUM_GET_REPO_LIST) {
            if (pk_bitfield_contain(filters, PK_FILTER_ENUM_NOT_DEVELOPMENT) &&
                    ((*it)->Type & SourcesList::DebSrc ||
                     (*it)->Type & SourcesList::RpmSrc ||
                     (*it)->Type & SourcesList::RpmSrcDir ||
                     (*it)->Type & SourcesList::RepomdSrc)) {
                continue;
            }

            pk_backend_job_repo_detail(job,
                                       repoId.c_str(),
                                       (*it)->niceName().c_str(),
                                       !((*it)->Type & SourcesList::Disabled));
        } else if (repoId.compare(repo_id) == 0) {
            // Found the repo to enable/disable
            found = true;

            if (role == PK_ROLE_ENUM_REPO_ENABLE) {
                if (enabled) {
                    (*it)->Type = (*it)->Type & ~SourcesList::Disabled;
                } else {
                    (*it)->Type |= SourcesList::Disabled;
                }

                // Commit changes
                if (!_lst.UpdateSources()) {
                    _error->Error("Could not update sources file");
                    show_errors(job, PK_ERROR_ENUM_CANNOT_WRITE_REPO_CONFIG);
                }
            } else if (role == PK_ROLE_ENUM_REPO_REMOVE) {
                if (autoremove) {
                    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
                    if (!apt->init()) {
                        g_debug("Failed to create apt cache");
                        return;
                    }

                    PkgList removePkgs = apt->getPackagesFromRepo(*it);
                    if (removePkgs.size() > 0) {
                        // Install/Update/Remove packages, or just simulate
                        bool ret;
                        ret = apt->runTransaction(PkgList(),
                                                  removePkgs,
                                                  false,
                                                  false,
                                                  transaction_flags,
                                                  false);
                        if (!ret) {
                            // Print transaction errors
                            g_debug("AptIntf::runTransaction() failed: %i", _error->PendingError());
                            return;
                        }
                    }
                }

                // Now if we are not simulating remove the repository
                if (!pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) {
                    _lst.RemoveSource(*it);

                    // Commit changes
                    if (!_lst.UpdateSources()) {
                        _error->Error("Could not update sources file");
                        show_errors(job, PK_ERROR_ENUM_CANNOT_WRITE_REPO_CONFIG);
                    }
                }
            }

            // Leave the search loop
            break;
        }
    }

    if ((role == PK_ROLE_ENUM_REPO_ENABLE || role == PK_ROLE_ENUM_REPO_REMOVE) &&
            !found) {
        _error->Error("Could not found the repository");
        show_errors(job, PK_ERROR_ENUM_REPO_NOT_AVAILABLE);
    }
}
Пример #30
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);
}