Пример #1
0
Id repo_add_haiku_package(Repo *repo, const char *hpkgPath, int flags)
{
  BPackageInfo packageInfo;
  if (packageInfo.ReadFromPackageFile(hpkgPath) != B_OK)
    return 0;

  return repo_add_haiku_package_info(repo, packageInfo, flags);
}
Пример #2
0
	virtual void OnPackageAdded(const BPackageInfo& packageInfo)
	{
		if (fQuiet)
			return;

		printf("%s (%s)\n", packageInfo.Name().String(),
			packageInfo.Version().ToString().String());
		if (fVerbose) {
			printf("\tsummary:  %s\n", packageInfo.Summary().String());
			printf("\tvendor:   %s\n", packageInfo.Vendor().String());
			printf("\tpackager: %s\n", packageInfo.Packager().String());
			printf("\tchecksum: %s\n", packageInfo.Checksum().String());
			if (uint32 flags = packageInfo.Flags()) {
				printf("\tflags:\n");
				if ((flags & B_PACKAGE_FLAG_APPROVE_LICENSE) != 0)
					printf("\t\tapprove_license\n");
				if ((flags & B_PACKAGE_FLAG_SYSTEM_PACKAGE) != 0)
					printf("\t\tsystem_package\n");
			}
		} else
			printf("\tchecksum: %s\n", packageInfo.Checksum().String());
	}
Пример #3
0
int32
BPackageManager::_FindBasePackage(const PackageList& packages,
	const BPackageInfo& info)
{
	if (info.BasePackage().IsEmpty())
		return -1;

	// find the requirement matching the base package
	BPackageResolvableExpression* basePackage = NULL;
	int32 count = info.RequiresList().CountItems();
	for (int32 i = 0; i < count; i++) {
		BPackageResolvableExpression* requires = info.RequiresList().ItemAt(i);
		if (requires->Name() == info.BasePackage()) {
			basePackage = requires;
			break;
		}
	}

	if (basePackage == NULL) {
		fUserInteractionHandler->Warn(B_OK, "package %s-%s doesn't have a "
			"matching requires for its base package \"%s\"",
			info.Name().String(), info.Version().ToString().String(),
			info.BasePackage().String());
		return -1;
	}

	// find the first package matching the base package requires
	count = packages.CountItems();
	for (int32 i = 0; i < count; i++) {
		BSolverPackage* package = packages.ItemAt(i);
		if (package->Name() == basePackage->Name()
			&& package->Info().Matches(*basePackage)) {
			return i;
		}
	}

	return -1;
}
Пример #4
0
static Id add_package_info_to_repo(Repo *repo, Repodata *repoData,
  const BPackageInfo &packageInfo)
{
  Pool *pool = repo->pool;

  Id solvableId = repo_add_solvable(repo);
  Solvable *solvable = pool_id2solvable(pool, solvableId);
  // Prepend "pkg:" to package name, so "provides" don't match unless explicitly
  // specified this way.
  BString name("pkg:");
  name << packageInfo.Name();
  solvable->name = pool_str2id(pool, name, 1);
  if (packageInfo.Architecture() == B_PACKAGE_ARCHITECTURE_ANY)
    solvable->arch = ARCH_ANY;
  else if (packageInfo.Architecture() == B_PACKAGE_ARCHITECTURE_SOURCE)
    solvable->arch = ARCH_SRC;
  else
    solvable->arch = pool_str2id(pool,
      BPackageInfo::kArchitectureNames[packageInfo.Architecture()], 1);
  solvable->evr = pool_str2id(pool, packageInfo.Version().ToString(), 1);
  solvable->vendor = pool_str2id(pool, packageInfo.Vendor(), 1);
  repodata_set_str(repoData, solvable - pool->solvables, SOLVABLE_SUMMARY,
    packageInfo.Summary());
  repodata_set_str(repoData, solvable - pool->solvables, SOLVABLE_DESCRIPTION,
    packageInfo.Description());
  repodata_set_str(repoData, solvable - pool->solvables, SOLVABLE_PACKAGER,
    packageInfo.Packager());

  if (!packageInfo.Checksum().IsEmpty())
    repodata_set_checksum(repoData, solvable - pool->solvables,
      SOLVABLE_CHECKSUM, REPOKEY_TYPE_SHA256, packageInfo.Checksum());

  solvable->provides = repo_addid_dep(repo, solvable->provides,
    pool_rel2id(pool, solvable->name, solvable->evr, REL_EQ, 1), 0);

  add_resolvables(repo, solvable->provides, packageInfo.ProvidesList());
  add_resolvable_expressions(repo, solvable->requires,
    packageInfo.RequiresList());
  add_resolvable_expressions(repo, solvable->supplements,
    packageInfo.SupplementsList());
  add_resolvable_expressions(repo, solvable->conflicts,
    packageInfo.ConflictsList());
  add_resolvable_expressions(repo, solvable->enhances,
    packageInfo.FreshensList());
  add_replaces_list(repo, solvable->obsoletes, packageInfo.ReplacesList());
  // TODO: Check whether freshens and replaces does indeed work as intended
  // here.

  // TODO: copyrights, licenses, URLs, source URLs

  return solvableId;
}
Пример #5
0
void
WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList,
	const BPackageInfo& packageInfo)
{
	// name
	AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_NAME, packageInfo.Name(),
		attributeList);

	// summary
	AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_SUMMARY,
		packageInfo.Summary(), attributeList);

	// description
	AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_DESCRIPTION,
		packageInfo.Description(), attributeList);

	// vendor
	AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_VENDOR,
		packageInfo.Vendor(), attributeList);

	// packager
	AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_PACKAGER,
		packageInfo.Packager(), attributeList);

	// base package (optional)
	_AddStringAttributeIfNotEmpty(B_HPKG_ATTRIBUTE_ID_PACKAGE_BASE_PACKAGE,
		packageInfo.BasePackage(), attributeList);

	// flags
	PackageAttribute* flags = new PackageAttribute(
		B_HPKG_ATTRIBUTE_ID_PACKAGE_FLAGS, B_HPKG_ATTRIBUTE_TYPE_UINT,
		B_HPKG_ATTRIBUTE_ENCODING_INT_32_BIT);
	flags->unsignedInt = packageInfo.Flags();
	attributeList.Add(flags);

	// architecture
	PackageAttribute* architecture = new PackageAttribute(
		B_HPKG_ATTRIBUTE_ID_PACKAGE_ARCHITECTURE, B_HPKG_ATTRIBUTE_TYPE_UINT,
		B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
	architecture->unsignedInt = packageInfo.Architecture();
	attributeList.Add(architecture);

	// version
	RegisterPackageVersion(attributeList, packageInfo.Version());

	// copyright list
	_AddStringAttributeList(B_HPKG_ATTRIBUTE_ID_PACKAGE_COPYRIGHT,
			packageInfo.CopyrightList(), attributeList);

	// license list
	_AddStringAttributeList(B_HPKG_ATTRIBUTE_ID_PACKAGE_LICENSE,
		packageInfo.LicenseList(), attributeList);

	// URL list
	_AddStringAttributeList(B_HPKG_ATTRIBUTE_ID_PACKAGE_URL,
		packageInfo.URLList(), attributeList);

	// source URL list
	_AddStringAttributeList(B_HPKG_ATTRIBUTE_ID_PACKAGE_SOURCE_URL,
		packageInfo.SourceURLList(), attributeList);

	// provides list
	const BObjectList<BPackageResolvable>& providesList
		= packageInfo.ProvidesList();
	for (int i = 0; i < providesList.CountItems(); ++i) {
		BPackageResolvable* resolvable = providesList.ItemAt(i);
		bool hasVersion = resolvable->Version().InitCheck() == B_OK;
		bool hasCompatibleVersion
			= resolvable->CompatibleVersion().InitCheck() == B_OK;

		PackageAttribute* provides = AddStringAttribute(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_PROVIDES, resolvable->Name(),
			attributeList);

		if (hasVersion)
			RegisterPackageVersion(provides->children, resolvable->Version());

		if (hasCompatibleVersion) {
			RegisterPackageVersion(provides->children,
				resolvable->CompatibleVersion(),
				B_HPKG_ATTRIBUTE_ID_PACKAGE_PROVIDES_COMPATIBLE);
		}
	}

	// requires list
	RegisterPackageResolvableExpressionList(attributeList,
		packageInfo.RequiresList(), B_HPKG_ATTRIBUTE_ID_PACKAGE_REQUIRES);

	// supplements list
	RegisterPackageResolvableExpressionList(attributeList,
		packageInfo.SupplementsList(), B_HPKG_ATTRIBUTE_ID_PACKAGE_SUPPLEMENTS);

	// conflicts list
	RegisterPackageResolvableExpressionList(attributeList,
		packageInfo.ConflictsList(), B_HPKG_ATTRIBUTE_ID_PACKAGE_CONFLICTS);

	// freshens list
	RegisterPackageResolvableExpressionList(attributeList,
		packageInfo.FreshensList(), B_HPKG_ATTRIBUTE_ID_PACKAGE_FRESHENS);

	// replaces list
	_AddStringAttributeList(B_HPKG_ATTRIBUTE_ID_PACKAGE_REPLACES,
		packageInfo.ReplacesList(), attributeList);

	// global writable file info list
	const BObjectList<BGlobalWritableFileInfo>& globalWritableFileInfos
		= packageInfo.GlobalWritableFileInfos();
	for (int32 i = 0; i < globalWritableFileInfos.CountItems(); ++i) {
		BGlobalWritableFileInfo* info = globalWritableFileInfos.ItemAt(i);
		PackageAttribute* attribute = AddStringAttribute(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_GLOBAL_WRITABLE_FILE, info->Path(),
			attributeList);

		if (info->IsDirectory()) {
			PackageAttribute* isDirectoryAttribute = new PackageAttribute(
				B_HPKG_ATTRIBUTE_ID_PACKAGE_IS_WRITABLE_DIRECTORY,
				B_HPKG_ATTRIBUTE_TYPE_UINT,
				B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
			isDirectoryAttribute->unsignedInt = 1;
			attribute->children.Add(isDirectoryAttribute);
		}

		if (info->IsIncluded()) {
			PackageAttribute* updateTypeAttribute = new PackageAttribute(
				B_HPKG_ATTRIBUTE_ID_PACKAGE_WRITABLE_FILE_UPDATE_TYPE,
				B_HPKG_ATTRIBUTE_TYPE_UINT,
				B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
			updateTypeAttribute->unsignedInt = info->UpdateType();
			attribute->children.Add(updateTypeAttribute);
		}
	}

	// user settings file info list
	const BObjectList<BUserSettingsFileInfo>& userSettingsFileInfos
		= packageInfo.UserSettingsFileInfos();
	for (int32 i = 0; i < userSettingsFileInfos.CountItems(); ++i) {
		BUserSettingsFileInfo* info = userSettingsFileInfos.ItemAt(i);
		PackageAttribute* attribute = AddStringAttribute(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_SETTINGS_FILE, info->Path(),
			attributeList);

		if (info->IsDirectory()) {
			PackageAttribute* isDirectoryAttribute = new PackageAttribute(
				B_HPKG_ATTRIBUTE_ID_PACKAGE_IS_WRITABLE_DIRECTORY,
				B_HPKG_ATTRIBUTE_TYPE_UINT,
				B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
			isDirectoryAttribute->unsignedInt = 1;
			attribute->children.Add(isDirectoryAttribute);
		} else {
			_AddStringAttributeIfNotEmpty(
				B_HPKG_ATTRIBUTE_ID_PACKAGE_SETTINGS_FILE_TEMPLATE,
				info->TemplatePath(), attribute->children);
		}
	}

	// user list
	const BObjectList<BUser>& users = packageInfo.Users();
	for (int32 i = 0; i < users.CountItems(); ++i) {
		const BUser* user = users.ItemAt(i);
		PackageAttribute* attribute = AddStringAttribute(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_USER, user->Name(), attributeList);

		_AddStringAttributeIfNotEmpty(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_REAL_NAME, user->RealName(),
			attribute->children);
		_AddStringAttributeIfNotEmpty(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_HOME, user->Home(),
			attribute->children);
		_AddStringAttributeIfNotEmpty(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_SHELL, user->Shell(),
			attribute->children);

		for (int32 k = 0; k < user->Groups().CountStrings(); k++) {
			AddStringAttribute(B_HPKG_ATTRIBUTE_ID_PACKAGE_USER_GROUP,
				user->Groups().StringAt(k), attribute->children);
		}
	}

	// group list
	_AddStringAttributeList(B_HPKG_ATTRIBUTE_ID_PACKAGE_GROUP,
		packageInfo.Groups(), attributeList);

	// post install script list
	_AddStringAttributeList(B_HPKG_ATTRIBUTE_ID_PACKAGE_POST_INSTALL_SCRIPT,
		packageInfo.PostInstallScripts(), attributeList);

	// checksum (optional, only exists in repositories)
	_AddStringAttributeIfNotEmpty(B_HPKG_ATTRIBUTE_ID_PACKAGE_CHECKSUM,
		packageInfo.Checksum(), attributeList);

	// install path (optional)
	_AddStringAttributeIfNotEmpty(B_HPKG_ATTRIBUTE_ID_PACKAGE_INSTALL_PATH,
		packageInfo.InstallPath(), attributeList);
}
status_t
BPackageRoster::GetActivePackages(BPackageInstallationLocation location,
	BPackageInfoSet& packageInfos)
{
// This method makes sense only on an installed Haiku, but not for the build
// tools.
#if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU)
	// check the given location
	directory_which packagesDirectory;
	switch (location) {
		case B_PACKAGE_INSTALLATION_LOCATION_SYSTEM:
			packagesDirectory = B_SYSTEM_PACKAGES_DIRECTORY;
			break;
		case B_PACKAGE_INSTALLATION_LOCATION_COMMON:
			packagesDirectory = B_COMMON_PACKAGES_DIRECTORY;
			break;
		case B_PACKAGE_INSTALLATION_LOCATION_HOME:
			packagesDirectory = B_USER_PACKAGES_DIRECTORY;
			break;
		default:
			return B_BAD_VALUE;
	}

	// find the package links directory
	BPath packageLinksPath;
	status_t error = find_directory(B_PACKAGE_LINKS_DIRECTORY,
		&packageLinksPath);
	if (error != B_OK)
		return error;

	// find and open the packages directory
	BPath packagesDirPath;
	error = find_directory(packagesDirectory, &packagesDirPath);
	if (error != B_OK)
		return error;

	BDirectory directory;
	error = directory.SetTo(packagesDirPath.Path());
	if (error != B_OK)
		return error;

	// TODO: Implement that correctly be reading the activation files/directory!

	// iterate through the packages
	char buffer[sizeof(dirent) + B_FILE_NAME_LENGTH];
	dirent* entry = (dirent*)&buffer;
	while (directory.GetNextDirents(entry, sizeof(buffer), 1) == 1) {
		if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
			continue;

		// get the full package file path
		BPath packagePath;
		error = packagePath.SetTo(packagesDirPath.Path(), entry->d_name);
		if (error != B_OK)
			continue;

		// read the package info from the file
		BPackageReader packageReader(NULL);
		error = packageReader.Init(packagePath.Path());
		if (error != B_OK)
			continue;

		BPackageInfo info;
		BPackageInfoContentHandler handler(info);
		error = packageReader.ParseContent(&handler);
		if (error != B_OK || info.InitCheck() != B_OK)
			continue;

		// check whether the package is really active by verifying that a
		// package link exists for it
		BString packageLinkName(info.Name());
		packageLinkName << '-' << info.Version().ToString();
		BPath packageLinkPath;
		struct stat st;
		if (packageLinkPath.SetTo(packageLinksPath.Path(), packageLinkName)
				!= B_OK
			|| lstat(packageLinkPath.Path(), &st) != 0) {
			continue;
		}

		// add the info
		error = packageInfos.AddInfo(info);
		if (error != B_OK)
			return error;
	}

	return B_OK;
#else
	return B_NOT_SUPPORTED;
#endif
}
Пример #7
0
int
main(int argc, const char* const* argv)
{
	if (argc != 3)
		print_usage_and_exit(true);

	if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
		print_usage_and_exit(false);

	const char* const packageInfoPath = argv[1];
	const char* const repositoryCachePath = argv[2];

	// read the repository cache
	BRepositoryCache repositoryCache;
	status_t error = repositoryCache.SetTo(repositoryCachePath);
	if (error != B_OK) {
		DIE(error, "failed to read repository cache file \"%s\"",
			repositoryCachePath);
	}

	// create a map for all provides (name -> resolvable list)
	typedef std::map<BString, ProvidesList> ProvidesMap;

	ProvidesMap providesMap;

	for (BRepositoryCache::Iterator it = repositoryCache.GetIterator();
		const BPackageInfo* info = it.Next();) {
		const BObjectList<BPackageResolvable>& provides = info->ProvidesList();
		int32 count = provides.CountItems();
		for (int32 i = 0; i < count; i++) {
			BPackageResolvable* resolvable = provides.ItemAt(i);
			ProvidesList& providesList = providesMap[resolvable->Name()];
			providesList.push_back(resolvable);
		}
	}

	// load the package info
	BPackageInfo packageInfo;
	error = packageInfo.ReadFromConfigFile(packageInfoPath);
	if (error != B_OK)
		DIE(error, "failed to read package info file \"%s\"", packageInfoPath);

	// clone the package info's requires list
	typedef std::list<BPackageResolvableExpression> RequiresList;
	RequiresList requiresList;
	int32 requiresCount = packageInfo.RequiresList().CountItems();
	for (int32 i = 0; i < requiresCount; i++)
		requiresList.push_back(*packageInfo.RequiresList().ItemAt(i));

	// rebuild the requires list with updated versions
	packageInfo.ClearRequiresList();
	for (RequiresList::iterator it = requiresList.begin();
		it != requiresList.end(); ++it) {
		BPackageResolvableExpression expression = *it;
		ProvidesMap::iterator foundIt = providesMap.find(expression.Name());
		if (foundIt != providesMap.end())
			update_requires_expression(expression, foundIt->second);

		error = packageInfo.AddRequires(expression);
		if (error != B_OK)
			DIE(error, "failed to add requires item to package info");
	}

	// write updated package info
	BString configString;
	error = packageInfo.GetConfigString(configString);
	if (error != B_OK)
		DIE(error, "failed to get updated package info string");

	FILE* file = fopen(packageInfoPath, "w");
	if (file == NULL) {
		DIE(errno, "failed to open package info file \"%s\" for writing",
			packageInfoPath);
	}

	if (fwrite(configString.String(), configString.Length(), 1, file) != 1) {
		DIE(errno, "failed to write updated package info file \"%s\"",
			packageInfoPath);
	}

	fclose(file);

	return 0;
}
Пример #8
0
void
WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList,
	const BPackageInfo& packageInfo)
{
	// name
	PackageAttribute* name = new PackageAttribute(
		B_HPKG_ATTRIBUTE_ID_PACKAGE_NAME, B_HPKG_ATTRIBUTE_TYPE_STRING,
		B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
	name->string = fPackageStringCache.Get(packageInfo.Name().String());
	attributeList.Add(name);

	// summary
	PackageAttribute* summary = new PackageAttribute(
		B_HPKG_ATTRIBUTE_ID_PACKAGE_SUMMARY, B_HPKG_ATTRIBUTE_TYPE_STRING,
		B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
	summary->string = fPackageStringCache.Get(packageInfo.Summary().String());
	attributeList.Add(summary);

	// description
	PackageAttribute* description = new PackageAttribute(
		B_HPKG_ATTRIBUTE_ID_PACKAGE_DESCRIPTION, B_HPKG_ATTRIBUTE_TYPE_STRING,
		B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
	description->string
		= fPackageStringCache.Get(packageInfo.Description().String());
	attributeList.Add(description);

	// vendor
	PackageAttribute* vendor = new PackageAttribute(
		B_HPKG_ATTRIBUTE_ID_PACKAGE_VENDOR, B_HPKG_ATTRIBUTE_TYPE_STRING,
		B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
	vendor->string = fPackageStringCache.Get(packageInfo.Vendor().String());
	attributeList.Add(vendor);

	// packager
	PackageAttribute* packager = new PackageAttribute(
		B_HPKG_ATTRIBUTE_ID_PACKAGE_PACKAGER, B_HPKG_ATTRIBUTE_TYPE_STRING,
		B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
	packager->string = fPackageStringCache.Get(packageInfo.Packager().String());
	attributeList.Add(packager);

	// flags
	PackageAttribute* flags = new PackageAttribute(
		B_HPKG_ATTRIBUTE_ID_PACKAGE_FLAGS, B_HPKG_ATTRIBUTE_TYPE_UINT,
		B_HPKG_ATTRIBUTE_ENCODING_INT_32_BIT);
	flags->unsignedInt = packageInfo.Flags();
	attributeList.Add(flags);

	// architecture
	PackageAttribute* architecture = new PackageAttribute(
		B_HPKG_ATTRIBUTE_ID_PACKAGE_ARCHITECTURE, B_HPKG_ATTRIBUTE_TYPE_UINT,
		B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
	architecture->unsignedInt = packageInfo.Architecture();
	attributeList.Add(architecture);

	// version
	RegisterPackageVersion(attributeList, packageInfo.Version());

	// copyright list
	const BObjectList<BString>& copyrightList = packageInfo.CopyrightList();
	for (int i = 0; i < copyrightList.CountItems(); ++i) {
		PackageAttribute* copyright = new PackageAttribute(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_COPYRIGHT, B_HPKG_ATTRIBUTE_TYPE_STRING,
			B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
		copyright->string
			= fPackageStringCache.Get(copyrightList.ItemAt(i)->String());
		attributeList.Add(copyright);
	}

	// license list
	const BObjectList<BString>& licenseList = packageInfo.LicenseList();
	for (int i = 0; i < licenseList.CountItems(); ++i) {
		PackageAttribute* license = new PackageAttribute(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_LICENSE, B_HPKG_ATTRIBUTE_TYPE_STRING,
			B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
		license->string
			= fPackageStringCache.Get(licenseList.ItemAt(i)->String());
		attributeList.Add(license);
	}

	// provides list
	const BObjectList<BPackageResolvable>& providesList
		= packageInfo.ProvidesList();
	for (int i = 0; i < providesList.CountItems(); ++i) {
		BPackageResolvable* resolvable = providesList.ItemAt(i);
		bool hasVersion = resolvable->Version().InitCheck() == B_OK;

		PackageAttribute* provides = new PackageAttribute(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_PROVIDES, B_HPKG_ATTRIBUTE_TYPE_STRING,
			B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
		provides->string = fPackageStringCache.Get(resolvable->Name().String());
		attributeList.Add(provides);

		PackageAttribute* providesType = new PackageAttribute(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_PROVIDES_TYPE,
			B_HPKG_ATTRIBUTE_TYPE_UINT, B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
		providesType->unsignedInt = resolvable->Type();
		provides->children.Add(providesType);

		if (hasVersion)
			RegisterPackageVersion(provides->children, resolvable->Version());
	}

	// requires list
	RegisterPackageResolvableExpressionList(attributeList,
		packageInfo.RequiresList(), B_HPKG_ATTRIBUTE_ID_PACKAGE_REQUIRES);

	// supplements list
	RegisterPackageResolvableExpressionList(attributeList,
		packageInfo.SupplementsList(), B_HPKG_ATTRIBUTE_ID_PACKAGE_SUPPLEMENTS);

	// conflicts list
	RegisterPackageResolvableExpressionList(attributeList,
		packageInfo.ConflictsList(), B_HPKG_ATTRIBUTE_ID_PACKAGE_CONFLICTS);

	// freshens list
	RegisterPackageResolvableExpressionList(attributeList,
		packageInfo.FreshensList(), B_HPKG_ATTRIBUTE_ID_PACKAGE_FRESHENS);

	// replaces list
	const BObjectList<BString>& replacesList = packageInfo.ReplacesList();
	for (int i = 0; i < replacesList.CountItems(); ++i) {
		PackageAttribute* replaces = new PackageAttribute(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_REPLACES, B_HPKG_ATTRIBUTE_TYPE_STRING,
			B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
		replaces->string
			= fPackageStringCache.Get(replacesList.ItemAt(i)->String());
		attributeList.Add(replaces);
	}

	// checksum (optional, only exists in repositories)
	if (packageInfo.Checksum().Length() > 0) {
		PackageAttribute* checksum = new PackageAttribute(
			B_HPKG_ATTRIBUTE_ID_PACKAGE_CHECKSUM, B_HPKG_ATTRIBUTE_TYPE_STRING,
			B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE);
		checksum->string
			= fPackageStringCache.Get(packageInfo.Checksum().String());
		attributeList.Add(checksum);
	}
}