コード例 #1
0
/**
 * backend_refresh_cache:
 */
static void
backend_refresh_cache (PkBackend *backend, gboolean force)
{
	pk_backend_set_allow_cancel (backend, TRUE);
	pk_backend_set_status (backend, PK_STATUS_ENUM_REFRESH_CACHE);
	slapt_update_pkg_cache(_config);
	pk_backend_finished (backend);
}
コード例 #2
0
/**
 * backend_refresh_cache_thread:
 */
static gboolean
backend_refresh_cache_thread (PkBackend *backend)
{
	pk_backend_set_allow_cancel (backend, true);

	aptcc *m_apt = new aptcc(backend, _cancel);
	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
	if (m_apt->init()) {
		egg_debug ("Failed to create apt cache");
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	pk_backend_set_status (backend, PK_STATUS_ENUM_REFRESH_CACHE);
	// Lock the list directory
	FileFd Lock;
	if (_config->FindB("Debug::NoLocking", false) == false)
	{
		Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock"));
		if (_error->PendingError() == true) {
			pk_backend_error_code (backend, PK_ERROR_ENUM_CANNOT_GET_LOCK, "Unable to lock the list directory");
			delete m_apt;
			pk_backend_finished (backend);
			return false;
	// 	 return _error->Error(_("Unable to lock the list directory"));
		}
	}
	// Create the progress
	AcqPackageKitStatus Stat(m_apt, backend, _cancel);

	// do the work
	if (_config->FindB("APT::Get::Download",true) == true) {
		ListUpdate(Stat, *m_apt->packageSourceList);
	}

	// Rebuild the cache.
	pkgCacheFile Cache;
	OpTextProgress Prog(*_config);
	if (Cache.BuildCaches(Prog, true) == false) {
		if (_error->PendingError() == true) {
			show_errors(backend, PK_ERROR_ENUM_CANNOT_GET_LOCK);
		}
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	// missing gpg signature would appear here
	// TODO we need a better enum
	if (_error->PendingError() == false && _error->empty() == false) {
		show_warnings(backend, PK_MESSAGE_ENUM_UNTRUSTED_PACKAGE);
	}

	pk_backend_finished (backend);
	delete m_apt;
	return true;
}
コード例 #3
0
gboolean
pk_backend_transaction_commit (PkBackend *self, GError **error)
{
	alpm_list_t *data = NULL;
	gchar *prefix;

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

	if (pk_backend_cancelled (self)) {
		return TRUE;
	}

	pk_backend_set_allow_cancel (self, FALSE);
	pk_backend_set_status (self, PK_STATUS_ENUM_RUNNING);

	if (alpm_trans_commit (alpm, &data) >= 0) {
		return TRUE;
	}

	switch (alpm_errno (alpm)) {
		case ALPM_ERR_FILE_CONFLICTS:
			prefix = alpm_fileconflict_build_list (data);
			alpm_list_free_inner (data, alpm_fileconflict_free);
			alpm_list_free (data);
			break;

		case ALPM_ERR_PKG_INVALID:
		case ALPM_ERR_DLT_INVALID:
			prefix = alpm_string_build_list (data);
			alpm_list_free (data);
			break;

		default:
			prefix = NULL;
			if (data != NULL) {
				g_warning ("unhandled error %d",
					   alpm_errno (alpm));
			}
			break;
	}

	if (prefix != NULL) {
		alpm_errno_t errno = alpm_errno (alpm);
		g_set_error (error, ALPM_ERROR, errno, "%s: %s", prefix,
			     alpm_strerror (errno));
		g_free (prefix);
	} else {
		alpm_errno_t errno = alpm_errno (alpm);
		g_set_error_literal (error, ALPM_ERROR, errno,
				     alpm_strerror (errno));
	}

	return FALSE;
}
コード例 #4
0
static gboolean
backend_search_file_thread (PkBackend *backend)
{
	const gchar *search;
	PkBitfield filters;

	search = pk_backend_get_string (backend, "search");
	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");

	pk_backend_set_allow_cancel (backend, true);

	// as we can only search for installed files lets avoid the opposite
	if (!pk_bitfield_contain (filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
		aptcc *m_apt = new aptcc(backend, _cancel);
		pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
		if (m_apt->init()) {
			egg_debug ("Failed to create apt cache");
			delete m_apt;
			pk_backend_finished (backend);
			return false;
		}

		pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
		vector<string> packages = search_file (backend, search, _cancel);
		vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
		for(vector<string>::iterator i = packages.begin();
		    i != packages.end(); ++i)
		{
			if (_cancel) {
			    break;
			}
			pkgCache::PkgIterator pkg = m_apt->packageCache->FindPkg(i->c_str());
			pkgCache::VerIterator ver = m_apt->find_ver(pkg);
			if (ver.end() == true)
			{
				continue;
			}
			output.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, ver));
		}
		// It's faster to emmit the packages here rather than in the matching part
		m_apt->emit_packages(output, filters);

		delete m_apt;
	}

	pk_backend_finished (backend);
	return true;
}
コード例 #5
0
static gboolean
backend_get_packages_thread (PkBackend *backend)
{
	PkBitfield filters;
	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
	pk_backend_set_allow_cancel (backend, true);

	aptcc *m_apt = new aptcc(backend, _cancel);
	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
	if (m_apt->init()) {
		egg_debug ("Failed to create apt cache");
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
	output.reserve(m_apt->packageCache->HeaderP->PackageCount);
	for(pkgCache::PkgIterator pkg = m_apt->packageCache->PkgBegin();
	    !pkg.end(); ++pkg)
	{
		if (_cancel) {
			break;
		}
		// Ignore packages that exist only due to dependencies.
		if(pkg.VersionList().end() && pkg.ProvidesList().end())
			continue;

		// Don't insert virtual packages as they don't have all kinds of info
		pkgCache::VerIterator ver = m_apt->find_ver(pkg);
		if (ver.end() == false) {
			output.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, ver));
		}
	}

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

	delete m_apt;

	pk_backend_finished (backend);
	return true;
}
コード例 #6
0
static gboolean
backend_search_package_thread (PkBackend *backend)
{
	const gchar *search;
	PkBitfield filters;

	search = pk_backend_get_string (backend, "search");
	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");

	pk_backend_set_percentage (backend, PK_BACKEND_PERCENTAGE_INVALID);
	pk_backend_set_allow_cancel (backend, true);

	matcher *m_matcher = new matcher(string(search));
	if (m_matcher->hasError()) {
		egg_debug("Regex compilation error");
		delete m_matcher;
		pk_backend_finished (backend);
		return false;
	}

	aptcc *m_apt = new aptcc(backend, _cancel);
	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
	if (m_apt->init()) {
		egg_debug ("Failed to create apt cache");
		delete m_matcher;
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	if (_error->PendingError() == true)
	{
		delete m_matcher;
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
	pkgDepCache::Policy Plcy;
	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
	if (pk_backend_get_bool (backend, "search_details")) {
		for (pkgCache::PkgIterator pkg = m_apt->packageCache->PkgBegin(); !pkg.end(); ++pkg) {
			if (_cancel) {
				break;
			}
			// Ignore packages that exist only due to dependencies.
			if (pkg.VersionList().end() && pkg.ProvidesList().end()) {
				continue;
			}

			if (m_matcher->matches(pkg.Name())) {
				// Don't insert virtual packages instead add what it provides
				pkgCache::VerIterator ver = m_apt->find_ver(pkg);
				if (ver.end() == false) {
					output.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, ver));
				} else {
					// iterate over the provides list
					for (pkgCache::PrvIterator Prv = pkg.ProvidesList(); Prv.end() == false; Prv++) {
						ver = m_apt->find_ver(Prv.OwnerPkg());

						// check to see if the provided package isn't virtual too
						if (ver.end() == false)
						{
							// we add the package now because we will need to
							// remove duplicates later anyway
							output.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(Prv.OwnerPkg(), ver));
						}
					}
				}
			} else {
				// Don't insert virtual packages instead add what it provides
				pkgCache::VerIterator ver = m_apt->find_ver(pkg);
				if (ver.end() == false) {
					if (m_matcher->matches(get_default_short_description(ver, m_apt->packageRecords))
					    || m_matcher->matches(get_default_long_description(ver, m_apt->packageRecords))
					    || m_matcher->matches(get_short_description(ver, m_apt->packageRecords))
					    || m_matcher->matches(get_long_description(ver, m_apt->packageRecords)))
					{
						output.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, ver));
					}
				} else {
					// iterate over the provides list
					for (pkgCache::PrvIterator Prv = pkg.ProvidesList(); Prv.end() == false; Prv++) {
						ver = m_apt->find_ver(Prv.OwnerPkg());

						// check to see if the provided package isn't virtual too
						if (ver.end() == false)
						{
							// we add the package now because we will need to
							// remove duplicates later anyway
							if (m_matcher->matches(Prv.OwnerPkg().Name())
							    || m_matcher->matches(get_default_short_description(ver, m_apt->packageRecords))
							    || m_matcher->matches(get_default_long_description(ver, m_apt->packageRecords))
							    || m_matcher->matches(get_short_description(ver, m_apt->packageRecords))
							    || m_matcher->matches(get_long_description(ver, m_apt->packageRecords)))
							{
								output.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(Prv.OwnerPkg(), ver));
							}
						}
					}
				}
			}
		}
	} else {
		for (pkgCache::PkgIterator pkg = m_apt->packageCache->PkgBegin(); !pkg.end(); ++pkg) {
			if (_cancel) {
				break;
			}
			// Ignore packages that exist only due to dependencies.
			if (pkg.VersionList().end() && pkg.ProvidesList().end()) {
				continue;
			}

			if (m_matcher->matches(pkg.Name())) {
				// Don't insert virtual packages instead add what it provides
				pkgCache::VerIterator ver = m_apt->find_ver(pkg);
				if (ver.end() == false) {
					output.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, ver));
				} else {
					// iterate over the provides list
					for (pkgCache::PrvIterator Prv = pkg.ProvidesList(); Prv.end() == false; Prv++) {
						ver = m_apt->find_ver(Prv.OwnerPkg());

						// check to see if the provided package isn't virtual too
						if (ver.end() == false)
						{
							// we add the package now because we will need to
							// remove duplicates later anyway
							output.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(Prv.OwnerPkg(), ver));
						}
					}
				}
			}
		}
	}

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

	delete m_matcher;
	delete m_apt;

	pk_backend_set_percentage (backend, 100);
	pk_backend_finished (backend);
	return true;
}
コード例 #7
0
static gboolean
backend_search_group_thread (PkBackend *backend)
{
	const gchar *group;
	PkBitfield filters;

	group = pk_backend_get_string (backend, "search");
	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
	pk_backend_set_allow_cancel (backend, true);

	if (group == NULL) {
		pk_backend_error_code (backend,
				       PK_ERROR_ENUM_GROUP_NOT_FOUND,
				       group);
		pk_backend_finished (backend);
		return false;
	}

	pk_backend_set_percentage (backend, 0);

	PkGroupEnum pkGroup = pk_group_enum_from_text (group);

	aptcc *m_apt = new aptcc(backend, _cancel);
	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
	if (m_apt->init()) {
		egg_debug ("Failed to create apt cache");
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
	for (pkgCache::PkgIterator pkg = m_apt->packageCache->PkgBegin(); !pkg.end(); ++pkg) {
		if (_cancel) {
			break;
		}
		// Ignore packages that exist only due to dependencies.
		if (pkg.VersionList().end() && pkg.ProvidesList().end()) {
			continue;
		}

		// Ignore virtual packages
		pkgCache::VerIterator ver = m_apt->find_ver(pkg);
		if (ver.end() == false) {
			string section = pkg.VersionList().Section();

			size_t found;
			found = section.find_last_of("/");
			section = section.substr(found + 1);

			// Don't insert virtual packages instead add what it provides
			if (pkGroup == get_enum_group(section)) {
				output.push_back(pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, ver));
			}
		}
	}

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

	delete m_apt;

	pk_backend_set_percentage (backend, 100);
	pk_backend_finished (backend);
	return true;
}
コード例 #8
0
static gboolean
backend_resolve_thread (PkBackend *backend)
{
	gchar **package_ids;
	PkBitfield filters;

	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
	package_ids = pk_backend_get_strv (backend, "package_ids");
	pk_backend_set_allow_cancel (backend, true);

	aptcc *m_apt = new aptcc(backend, _cancel);
	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
	if (m_apt->init()) {
		egg_debug ("Failed to create apt cache");
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
	gchar *pi;
	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
	for (uint i = 0; i < g_strv_length(package_ids); i++) {
		if (_cancel) {
			break;
		}

		pair<pkgCache::PkgIterator, pkgCache::VerIterator> pkg_ver;
		pi = package_ids[i];
		if (pk_package_id_check(pi) == false) {
			pkg_ver.first = m_apt->packageCache->FindPkg(pi);
			// Ignore packages that could not be found or that exist only due to dependencies.
			if (pkg_ver.first.end() == true ||
			    (pkg_ver.first.VersionList().end() && pkg_ver.first.ProvidesList().end()))
			{
				continue;
			}

			pkg_ver.second = m_apt->find_ver(pkg_ver.first);
			// check to see if the provided package isn't virtual too
			if (pkg_ver.second.end() == false)
			{
				output.push_back(pkg_ver);
			}

			pkg_ver.second = m_apt->find_candidate_ver(pkg_ver.first);
			// check to see if the provided package isn't virtual too
			if (pkg_ver.second.end() == false)
			{
				output.push_back(pkg_ver);
			}
		} else {
			pkg_ver = m_apt->find_package_id(pi);
			// check to see if we found the package
			if (pkg_ver.second.end() == false)
			{
				output.push_back(pkg_ver);
			}
		}
	}
	// It's faster to emmit the packages here rather than in the matching part
	m_apt->emit_packages(output, filters);

	delete m_apt;

	pk_backend_finished (backend);
	return true;
}
コード例 #9
0
/**
 * backend_download_packages_thread:
 */
static gboolean
backend_download_packages_thread (PkBackend *backend)
{
	gchar **package_ids;
	string directory;

	package_ids = pk_backend_get_strv(backend, "package_ids");
	directory = _config->FindDir("Dir::Cache::archives") + "partial/";
	pk_backend_set_allow_cancel (backend, true);

	aptcc *m_apt = new aptcc(backend, _cancel);
	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
	if (m_apt->init()) {
		egg_debug ("Failed to create apt cache");
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
	// Create the progress
	AcqPackageKitStatus Stat(m_apt, backend, _cancel);

	// get a fetcher
	pkgAcquire fetcher(&Stat);
	string filelist;
	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_error_code (backend,
					       PK_ERROR_ENUM_PACKAGE_ID_INVALID,
					       pi);
			delete m_apt;
			pk_backend_finished (backend);
			return false;
		}

		if (_cancel) {
			break;
		}

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

			string storeFileName;
			if (get_archive(&fetcher,
					m_apt->packageSourceList,
					m_apt->packageRecords,
					pkg_ver.second,
					directory,
					storeFileName))
			{
				Stat.addPackagePair(pkg_ver);
			}
			string destFile = directory + "/" + flNotDir(storeFileName);
			if (filelist.empty()) {
				filelist = destFile;
			} else {
				filelist.append(";" + destFile);
			}
		}
	}

	if (fetcher.Run() != pkgAcquire::Continue
	    && _cancel == false)
	// We failed and we did not cancel
	{
		show_errors(backend, PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED);
		delete m_apt;
		pk_backend_finished (backend);
		return _cancel;
	}

	// send the filelist
	pk_backend_files(backend, NULL, filelist.c_str());

	delete m_apt;
	pk_backend_finished (backend);
	return true;
}
コード例 #10
0
static gboolean
backend_get_or_update_system_thread (PkBackend *backend)
{
	PkBitfield filters;
	bool getUpdates;
	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
	getUpdates = pk_backend_get_bool(backend, "getUpdates");
	pk_backend_set_allow_cancel (backend, true);

	aptcc *m_apt = new aptcc(backend, _cancel);
	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
	if (m_apt->init()) {
		egg_debug ("Failed to create apt cache");
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);

	pkgCacheFile Cache;
	OpTextProgress Prog(*_config);
	int timeout = 10;
	// TODO test this
	while (Cache.Open(Prog, !getUpdates) == false) {
		// failed to open cache, try checkDeps then..
		// || Cache.CheckDeps(CmdL.FileSize() != 1) == false
		if (getUpdates == true || (timeout <= 0)) {
			pk_backend_error_code(backend,
					      PK_ERROR_ENUM_NO_CACHE,
					      "Could not open package cache.");
			return false;
		} else {
			pk_backend_set_status (backend, PK_STATUS_ENUM_WAITING_FOR_LOCK);
			sleep(1);
			timeout--;
		}
	}
	pk_backend_set_status (backend, PK_STATUS_ENUM_RUNNING);

	if (pkgDistUpgrade(*Cache) == false)
	{
		show_broken(backend, Cache, false);
		egg_debug ("Internal error, DistUpgrade broke stuff");
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	bool res = true;
	if (getUpdates) {
		vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > update,
									    kept;

		for(pkgCache::PkgIterator pkg=m_apt->packageCache->PkgBegin();
		    !pkg.end();
		    ++pkg)
		{
			if((*Cache)[pkg].Upgrade()    == true &&
			(*Cache)[pkg].NewInstall() == false) {
				update.push_back(
					pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, m_apt->find_candidate_ver(pkg)));
			} else if ((*Cache)[pkg].Upgradable() == true &&
				pkg->CurrentVer != 0 &&
				(*Cache)[pkg].Delete() == false) {
				kept.push_back(
					pair<pkgCache::PkgIterator, pkgCache::VerIterator>(pkg, m_apt->find_candidate_ver(pkg)));
			}
		}

		m_apt->emitUpdates(update, filters);
		m_apt->emit_packages(kept, filters, PK_INFO_ENUM_BLOCKED);
	} else {
		res = m_apt->installPackages(Cache);
	}

	delete m_apt;
	pk_backend_finished (backend);
	return res;
}
コード例 #11
0
static gboolean
backend_get_depends_or_requires_thread (PkBackend *backend)
{
	gchar **package_ids;
	PkBitfield filters;
	gchar *pi;
	bool recursive;

	package_ids = pk_backend_get_strv (backend, "package_ids");
	filters = (PkBitfield) pk_backend_get_uint (backend, "filters");
	recursive = pk_backend_get_bool (backend, "recursive");

	pk_backend_set_allow_cancel (backend, true);

	aptcc *m_apt = new aptcc(backend, _cancel);
	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
	if (m_apt->init()) {
		egg_debug ("Failed to create apt cache");
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	bool depends = pk_backend_get_bool(backend, "get_depends");

	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > output;
	for (uint i = 0; i < g_strv_length(package_ids); i++) {
		if (_cancel) {
			break;
		}
		pi = package_ids[i];
		if (pk_package_id_check(pi) == false) {
			pk_backend_error_code (backend,
					       PK_ERROR_ENUM_PACKAGE_ID_INVALID,
					       pi);
			delete m_apt;
			pk_backend_finished (backend);
			return false;
		}

		pair<pkgCache::PkgIterator, pkgCache::VerIterator> pkg_ver;
		pkg_ver = m_apt->find_package_id(pi);
		if (pkg_ver.second.end() == true)
		{
			pk_backend_error_code (backend,
					       PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
					       "Couldn't find package");
			delete m_apt;
			pk_backend_finished (backend);
			return false;
		}

		if (depends) {
			m_apt->get_depends(output, pkg_ver.first, recursive);
		} else {
			m_apt->get_requires(output, pkg_ver.first, recursive);
		}
	}

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

	delete m_apt;
	pk_backend_finished (backend);
	return true;
}
コード例 #12
0
static gboolean
backend_manage_packages_thread (PkBackend *backend)
{
	gchar **package_ids;
	gchar *pi;
	bool simulate;
	bool remove;

	package_ids = pk_backend_get_strv (backend, "package_ids");
	simulate = pk_backend_get_bool (backend, "simulate");
	remove = pk_backend_get_bool (backend, "remove");

	pk_backend_set_allow_cancel (backend, true);

	aptcc *m_apt = new aptcc(backend, _cancel);
	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
	if (m_apt->init()) {
		egg_debug ("Failed to create apt cache");
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
	vector<pair<pkgCache::PkgIterator, pkgCache::VerIterator> > pkgs;
	for (uint i = 0; i < g_strv_length(package_ids); i++) {
		if (_cancel) {
			break;
		}

		pi = package_ids[i];
		if (pk_package_id_check(pi) == false) {
			pk_backend_error_code (backend,
					       PK_ERROR_ENUM_PACKAGE_ID_INVALID,
					       pi);
			delete m_apt;
			pk_backend_finished (backend);
			return false;
		}

		pair<pkgCache::PkgIterator, pkgCache::VerIterator> pkg_ver;
		pkg_ver = m_apt->find_package_id(pi);
		// Ignore packages that could not be found or that exist only due to dependencies.
		if (pkg_ver.second.end() == true)
		{
			pk_backend_error_code (backend,
					       PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
					       "couldn't find package");

			delete m_apt;
			pk_backend_finished (backend);
			return false;
		} else {
			pkgs.push_back(pkg_ver);
		}
	}

	if (!m_apt->runTransaction(pkgs, simulate, remove)) {
		// Print transaction errors
		cout << "runTransaction failed" << endl;
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	delete m_apt;
	pk_backend_finished (backend);
	return true;
}
コード例 #13
0
/**
 * pk_backend_spawn_parse_stdout:
 **/
static gboolean
pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, const gchar *line, GError **error)
{
	gchar **sections;
	guint size;
	gchar *command;
	gchar *text;
	gboolean ret = TRUE;
	guint64 speed;
	PkInfoEnum info;
	PkRestartEnum restart;
	PkGroupEnum group;
	gulong package_size;
	gint percentage;
	PkErrorEnum error_enum;
	PkStatusEnum status_enum;
	PkMessageEnum message_enum;
	PkRestartEnum restart_enum;
	PkSigTypeEnum sig_type;
	PkUpdateStateEnum update_state_enum;
	PkMediaTypeEnum media_type_enum;
	PkDistroUpgradeEnum distro_upgrade_enum;
	PkBackendSpawnPrivate *priv = backend_spawn->priv;

	g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE);

	/* check if output line */
	if (line == NULL)
		return FALSE;

	/* split by tab */
	sections = g_strsplit (line, "\t", 0);
	command = sections[0];

	/* get size */
	size = g_strv_length (sections);

	if (g_strcmp0 (command, "package") == 0) {
		if (size != 4) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		if (pk_package_id_check (sections[2]) == FALSE) {
			g_set_error_literal (error, 1, 0, "invalid package_id");
			ret = FALSE;
			goto out;
		}
		info = pk_info_enum_from_string (sections[1]);
		if (info == PK_INFO_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Info enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		pk_backend_package (priv->backend, info, sections[2], sections[3]);
	} else if (g_strcmp0 (command, "details") == 0) {
		if (size != 7) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		group = pk_group_enum_from_string (sections[3]);

		/* ITS4: ignore, checked for overflow */
		package_size = atol (sections[6]);
		if (package_size > 1073741824) {
			g_set_error_literal (error, 1, 0, "package size cannot be larger than one Gb");
			ret = FALSE;
			goto out;
		}
		text = g_strdup (sections[4]);
		/* convert ; to \n as we can't emit them on stdout */
		g_strdelimit (text, ";", '\n');
		pk_backend_details (priv->backend, sections[1], sections[2],
					group, text, sections[5], package_size);
		g_free (text);
	} else if (g_strcmp0 (command, "finished") == 0) {
		if (size != 1) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		pk_backend_finished (priv->backend);

		/* from this point on, we can start the kill timer */
		pk_backend_spawn_start_kill_timer (backend_spawn);

	} else if (g_strcmp0 (command, "files") == 0) {
		if (size != 3) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		pk_backend_files (priv->backend, sections[1], sections[2]);
	} else if (g_strcmp0 (command, "repo-detail") == 0) {
		if (size != 4) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		if (g_strcmp0 (sections[3], "true") == 0) {
			pk_backend_repo_detail (priv->backend, sections[1], sections[2], TRUE);
		} else if (g_strcmp0 (sections[3], "false") == 0) {
			pk_backend_repo_detail (priv->backend, sections[1], sections[2], FALSE);
		} else {
			g_set_error (error, 1, 0, "invalid qualifier '%s'", sections[3]);
			ret = FALSE;
			goto out;
		}
	} else if (g_strcmp0 (command, "updatedetail") == 0) {
		if (size != 13) {
			g_set_error (error, 1, 0, "invalid command '%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		restart = pk_restart_enum_from_string (sections[7]);
		if (restart == PK_RESTART_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[7]);
			ret = FALSE;
			goto out;
		}
		update_state_enum = pk_update_state_enum_from_string (sections[10]);
		/* convert ; to \n as we can't emit them on stdout */
		g_strdelimit (sections[8], ";", '\n');
		g_strdelimit (sections[9], ";", '\n');
		pk_backend_update_detail (priv->backend, sections[1],
					  sections[2], sections[3], sections[4],
					  sections[5], sections[6], restart, sections[8],
					  sections[9], update_state_enum,
					  sections[11], sections[12]);
	} else if (g_strcmp0 (command, "percentage") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		ret = pk_strtoint (sections[1], &percentage);
		if (!ret) {
			g_set_error (error, 1, 0, "invalid percentage value %s", sections[1]);
			ret = FALSE;
		} else if (percentage < 0 || percentage > 100) {
			g_set_error (error, 1, 0, "invalid percentage value %i", percentage);
			ret = FALSE;
		} else {
			pk_backend_set_percentage (priv->backend, percentage);
		}
	} else if (g_strcmp0 (command, "subpercentage") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		ret = pk_strtoint (sections[1], &percentage);
		if (!ret) {
			g_set_error (error, 1, 0, "invalid subpercentage value %s", sections[1]);
			ret = FALSE;
		} else if (percentage < 0 || percentage > 100) {
			g_set_error (error, 1, 0, "invalid subpercentage value %i", percentage);
			ret = FALSE;
		} else {
			pk_backend_set_sub_percentage (priv->backend, percentage);
		}
	} else if (g_strcmp0 (command, "item-percentage") == 0) {
		if (size != 3) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		if (!pk_package_id_check (sections[1])) {
			g_set_error (error, 1, 0, "invalid package_id");
			ret = FALSE;
			goto out;
		}
		ret = pk_strtoint (sections[2], &percentage);
		if (!ret) {
			g_set_error (error, 1, 0, "invalid item-percentage value %s", sections[1]);
			ret = FALSE;
		} else if (percentage < 0 || percentage > 100) {
			g_set_error (error, 1, 0, "invalid item-percentage value %i", percentage);
			ret = FALSE;
		} else {
			pk_backend_set_item_progress (priv->backend,
							sections[1],
							percentage);
		}
	} else if (g_strcmp0 (command, "error") == 0) {
		if (size != 3) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		error_enum = pk_error_enum_from_string (sections[1]);
		if (error_enum == PK_ERROR_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Error enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		/* convert back all the ;'s to newlines */
		text = g_strdup (sections[2]);

		/* convert ; to \n as we can't emit them on stdout */
		g_strdelimit (text, ";", '\n');

		/* convert % else we try to format them */
		g_strdelimit (text, "%", '$');

		pk_backend_error_code (priv->backend, error_enum, text);
		g_free (text);
	} else if (g_strcmp0 (command, "requirerestart") == 0) {
		if (size != 3) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		restart_enum = pk_restart_enum_from_string (sections[1]);
		if (restart_enum == PK_RESTART_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		if (!pk_package_id_check (sections[2])) {
			g_set_error (error, 1, 0, "invalid package_id");
			ret = FALSE;
			goto out;
		}
		pk_backend_require_restart (priv->backend, restart_enum, sections[2]);
	} else if (g_strcmp0 (command, "message") == 0) {
		if (size != 3) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		message_enum = pk_message_enum_from_string (sections[1]);
		if (message_enum == PK_MESSAGE_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Message enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		text = g_strdup (sections[2]);
		/* convert ; to \n as we can't emit them on stdout */
		g_strdelimit (text, ";", '\n');
		pk_backend_message (priv->backend, message_enum, text);
		g_free (text);
	} else if (g_strcmp0 (command, "change-transaction-data") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		pk_backend_set_transaction_data (priv->backend, sections[1]);
	} else if (g_strcmp0 (command, "status") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		status_enum = pk_status_enum_from_string (sections[1]);
		if (status_enum == PK_STATUS_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Status enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		pk_backend_set_status (priv->backend, status_enum);
	} else if (g_strcmp0 (command, "speed") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		ret = pk_strtouint64 (sections[1], &speed);
		if (!ret) {
			g_set_error (error, 1, 0,
				     "failed to parse speed: '%s'",
				     sections[1]);
			ret = FALSE;
			goto out;
		}
		pk_backend_set_speed (priv->backend, speed);
	} else if (g_strcmp0 (command, "allow-cancel") == 0) {
		if (size != 2) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		if (g_strcmp0 (sections[1], "true") == 0) {
			pk_backend_set_allow_cancel (priv->backend, TRUE);
		} else if (g_strcmp0 (sections[1], "false") == 0) {
			pk_backend_set_allow_cancel (priv->backend, FALSE);
		} else {
			g_set_error (error, 1, 0, "invalid section '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
	} else if (g_strcmp0 (command, "no-percentage-updates") == 0) {
		if (size != 1) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		pk_backend_set_percentage (priv->backend, PK_BACKEND_PERCENTAGE_INVALID);
	} else if (g_strcmp0 (command, "repo-signature-required") == 0) {

		if (size != 9) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}

		sig_type = pk_sig_type_enum_from_string (sections[8]);
		if (sig_type == PK_SIGTYPE_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "Sig enum not recognised, and hence ignored: '%s'", sections[8]);
			ret = FALSE;
			goto out;
		}
		if (pk_strzero (sections[1])) {
			g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}
		if (pk_strzero (sections[2])) {
			g_set_error (error, 1, 0, "repository name blank, and hence ignored: '%s'", sections[2]);
			ret = FALSE;
			goto out;
		}

		/* pass _all_ of the data */
		ret = pk_backend_repo_signature_required (priv->backend, sections[1],
							  sections[2], sections[3], sections[4],
							  sections[5], sections[6], sections[7], sig_type);
		goto out;

	} else if (g_strcmp0 (command, "eula-required") == 0) {

		if (size != 5) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}

		if (pk_strzero (sections[1])) {
			g_set_error (error, 1, 0, "eula_id blank, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}

		if (pk_strzero (sections[2])) {
			g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[2]);
			ret = FALSE;
			goto out;
		}

		if (pk_strzero (sections[4])) {
			g_set_error (error, 1, 0, "agreement name blank, and hence ignored: '%s'", sections[4]);
			ret = FALSE;
			goto out;
		}

		ret = pk_backend_eula_required (priv->backend, sections[1], sections[2], sections[3], sections[4]);
		goto out;

	} else if (g_strcmp0 (command, "media-change-required") == 0) {

		if (size != 4) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}

		media_type_enum = pk_media_type_enum_from_string (sections[1]);
		if (media_type_enum == PK_MEDIA_TYPE_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "media type enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}

		ret = pk_backend_media_change_required (priv->backend, media_type_enum, sections[2], sections[3]);
		goto out;
	} else if (g_strcmp0 (command, "distro-upgrade") == 0) {

		if (size != 4) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}

		distro_upgrade_enum = pk_distro_upgrade_enum_from_string (sections[1]);
		if (distro_upgrade_enum == PK_DISTRO_UPGRADE_ENUM_UNKNOWN) {
			g_set_error (error, 1, 0, "distro upgrade enum not recognised, and hence ignored: '%s'", sections[1]);
			ret = FALSE;
			goto out;
		}

		ret = pk_backend_distro_upgrade (priv->backend, distro_upgrade_enum, sections[2], sections[3]);
		goto out;
	} else if (g_strcmp0 (command, "category") == 0) {

		if (size != 6) {
			g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size);
			ret = FALSE;
			goto out;
		}
		if (g_strcmp0 (sections[1], sections[2]) == 0) {
			g_set_error_literal (error, 1, 0, "cat_id cannot be the same as parent_id");
			ret = FALSE;
			goto out;
		}
		if (pk_strzero (sections[2])) {
			g_set_error_literal (error, 1, 0, "cat_id cannot not blank");
			ret = FALSE;
			goto out;
		}
		if (pk_strzero (sections[3])) {
			g_set_error_literal (error, 1, 0, "name cannot not blank");
			ret = FALSE;
			goto out;
		}
		if (pk_strzero (sections[5])) {
			g_set_error_literal (error, 1, 0, "icon cannot not blank");
			ret = FALSE;
			goto out;
		}
		if (g_str_has_prefix (sections[5], "/")) {
			g_set_error (error, 1, 0, "icon '%s' should be a named icon, not a path", sections[5]);
			ret = FALSE;
			goto out;
		}
		ret = pk_backend_category (priv->backend, sections[1], sections[2], sections[3], sections[4], sections[5]);
		goto out;
	} else {
		ret = FALSE;
		g_set_error (error, 1, 0, "invalid command '%s'", command);
	}
out:
	g_strfreev (sections);
	return ret;
}