* added embedding of license texts that need approval into repository
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40491 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -43,6 +43,7 @@ public:
|
||||
uint32 uncompressedSize) = 0;
|
||||
virtual void OnRepositoryDone(uint32 headerSize,
|
||||
uint32 repositoryInfoLength,
|
||||
uint32 licenseCount,
|
||||
uint32 packageCount,
|
||||
uint32 packageAttributesSize,
|
||||
uint64 totalSize) = 0;
|
||||
@@ -54,7 +55,7 @@ public:
|
||||
public:
|
||||
BRepositoryWriter(
|
||||
BRepositoryWriterListener* listener,
|
||||
const BRepositoryInfo* repositoryInfo);
|
||||
BRepositoryInfo* repositoryInfo);
|
||||
~BRepositoryWriter();
|
||||
|
||||
status_t Init(const char* fileName);
|
||||
|
||||
@@ -30,34 +30,19 @@ namespace BPrivate {
|
||||
|
||||
struct hpkg_header;
|
||||
|
||||
class RepositoryWriterImpl
|
||||
: public WriterImplBase, private BPackageContentHandler {
|
||||
class RepositoryWriterImpl : public WriterImplBase {
|
||||
typedef WriterImplBase inherited;
|
||||
|
||||
public:
|
||||
RepositoryWriterImpl(
|
||||
BRepositoryWriterListener* listener,
|
||||
const BRepositoryInfo* repositoryInfo);
|
||||
BRepositoryInfo* repositoryInfo);
|
||||
~RepositoryWriterImpl();
|
||||
|
||||
status_t Init(const char* fileName);
|
||||
status_t AddPackage(const BEntry& packageEntry);
|
||||
status_t Finish();
|
||||
|
||||
private:
|
||||
// BPackageContentHandler
|
||||
virtual status_t HandleEntry(BPackageEntry* entry);
|
||||
virtual status_t HandleEntryAttribute(BPackageEntry* entry,
|
||||
BPackageEntryAttribute* attribute);
|
||||
virtual status_t HandleEntryDone(BPackageEntry* entry);
|
||||
|
||||
virtual status_t HandlePackageAttribute(
|
||||
const BPackageInfoAttributeValue& value
|
||||
);
|
||||
virtual status_t HandlePackageAttributesDone();
|
||||
|
||||
virtual void HandleErrorOccurred();
|
||||
|
||||
private:
|
||||
status_t _Init(const char* fileName);
|
||||
status_t _AddPackage(const BEntry& packageEntry);
|
||||
@@ -75,7 +60,7 @@ private:
|
||||
private:
|
||||
BRepositoryWriterListener* fListener;
|
||||
|
||||
const BRepositoryInfo* fRepositoryInfo;
|
||||
BRepositoryInfo* fRepositoryInfo;
|
||||
|
||||
BPackageInfo fPackageInfo;
|
||||
uint32 fPackageCount;
|
||||
|
||||
@@ -85,12 +85,15 @@ public:
|
||||
}
|
||||
|
||||
virtual void OnRepositoryDone(uint32 headerSize, uint32 repositoryInfoSize,
|
||||
uint32 packageCount, uint32 packageAttributesSize, uint64 totalSize)
|
||||
uint32 licenseCount, uint32 packageCount, uint32 packageAttributesSize,
|
||||
uint64 totalSize)
|
||||
{
|
||||
if (fQuiet)
|
||||
return;
|
||||
|
||||
printf("----- Package Repository Info -----\n");
|
||||
if (fVerbose)
|
||||
printf("embedded license count %10lu\n", licenseCount);
|
||||
printf("package count %10lu\n", packageCount);
|
||||
printf("-----------------------------------\n");
|
||||
printf("header size: %10lu\n", headerSize);
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace BHPKG {
|
||||
|
||||
|
||||
BRepositoryWriter::BRepositoryWriter(BRepositoryWriterListener* listener,
|
||||
const BRepositoryInfo* repositoryInfo)
|
||||
BRepositoryInfo* repositoryInfo)
|
||||
:
|
||||
fImpl(new (std::nothrow) RepositoryWriterImpl(listener, repositoryInfo))
|
||||
{
|
||||
|
||||
@@ -14,9 +14,14 @@
|
||||
#include <Message.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
#include <package/hpkg/HPKGDefsPrivate.h>
|
||||
#include <package/hpkg/PackageDataReader.h>
|
||||
#include <package/hpkg/PackageEntry.h>
|
||||
#include <package/hpkg/PackageInfoAttributeValue.h>
|
||||
#include <package/hpkg/PackageReader.h>
|
||||
#include <package/BlockBufferCacheNoLock.h>
|
||||
#include <package/ChecksumAccessors.h>
|
||||
#include <package/RepositoryInfo.h>
|
||||
|
||||
@@ -31,12 +36,230 @@ namespace BPrivate {
|
||||
using BPackageKit::BPrivate::GeneralFileChecksumAccessor;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
struct PackageEntryDataFetcher {
|
||||
PackageEntryDataFetcher(BErrorOutput* errorOutput,
|
||||
BPackageData& packageData)
|
||||
:
|
||||
fErrorOutput(errorOutput),
|
||||
fBufferCache(B_HPKG_DEFAULT_DATA_CHUNK_SIZE_ZLIB, 2),
|
||||
fPackageData(packageData)
|
||||
{
|
||||
}
|
||||
|
||||
status_t ReadIntoString(BDataReader* dataReader, BString& _contents)
|
||||
{
|
||||
// create a BPackageDataReader
|
||||
BPackageDataReader* reader;
|
||||
status_t result = BPackageDataReaderFactory(&fBufferCache)
|
||||
.CreatePackageDataReader(dataReader, fPackageData, reader);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
ObjectDeleter<BPackageDataReader> readerDeleter(reader);
|
||||
|
||||
// copy data into the given string
|
||||
int32 bufferSize = fPackageData.UncompressedSize();
|
||||
char* buffer = _contents.LockBuffer(bufferSize);
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
result = reader->ReadData(0, buffer, bufferSize);
|
||||
if (result != B_OK) {
|
||||
fErrorOutput->PrintError("Error: Failed to read data: %s\n",
|
||||
strerror(result));
|
||||
_contents.UnlockBuffer(0);
|
||||
} else
|
||||
_contents.UnlockBuffer(bufferSize);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
BErrorOutput* fErrorOutput;
|
||||
BBlockBufferCacheNoLock fBufferCache;
|
||||
BPackageData& fPackageData;
|
||||
};
|
||||
|
||||
|
||||
struct PackageContentHandler : public BPackageContentHandler {
|
||||
PackageContentHandler(BErrorOutput* errorOutput, BPackageInfo* packageInfo,
|
||||
int packageFileFD, BRepositoryInfo* repositoryInfo)
|
||||
:
|
||||
fErrorOutput(errorOutput),
|
||||
fPackageInfo(packageInfo),
|
||||
fPackageFileReader(packageFileFD),
|
||||
fRepositoryInfo(repositoryInfo)
|
||||
{
|
||||
}
|
||||
|
||||
virtual status_t HandleEntry(BPackageEntry* entry)
|
||||
{
|
||||
// if license must be approved, read any license files from package such
|
||||
// that those can be stored in the repository later
|
||||
if ((fPackageInfo->Flags() & B_PACKAGE_FLAG_APPROVE_LICENSE) == 0
|
||||
|| entry == NULL)
|
||||
return B_OK;
|
||||
|
||||
// return if not in ./data/licenses folder
|
||||
const BPackageEntry* parent = entry->Parent();
|
||||
BString licenseFolderName("licenses");
|
||||
if (parent == NULL || licenseFolderName != parent->Name())
|
||||
return B_OK;
|
||||
|
||||
parent = parent->Parent();
|
||||
BString dataFolderName("data");
|
||||
if (parent == NULL || dataFolderName != parent->Name())
|
||||
return B_OK;
|
||||
|
||||
if (parent->Parent() != NULL)
|
||||
return B_OK;
|
||||
|
||||
// check if license already is in repository
|
||||
const BObjectList<BString>& licenseNames
|
||||
= fRepositoryInfo->LicenseNames();
|
||||
for (int i = 0; i < licenseNames.CountItems(); ++i) {
|
||||
if (licenseNames.ItemAt(i)->ICompare(entry->Name()) == 0) {
|
||||
// license already exists
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// fetch contents of license file
|
||||
BPackageData& packageData = entry->Data();
|
||||
PackageEntryDataFetcher dataFetcher(fErrorOutput, packageData);
|
||||
|
||||
BString licenseText;
|
||||
status_t result;
|
||||
if (packageData.IsEncodedInline()) {
|
||||
BBufferDataReader dataReader(packageData.InlineData(),
|
||||
packageData.CompressedSize());
|
||||
result = dataFetcher.ReadIntoString(&dataReader, licenseText);
|
||||
} else {
|
||||
result
|
||||
= dataFetcher.ReadIntoString(&fPackageFileReader, licenseText);
|
||||
}
|
||||
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
// add license to repository
|
||||
return fRepositoryInfo->AddLicense(entry->Name(), licenseText);
|
||||
}
|
||||
|
||||
virtual status_t HandleEntryAttribute(BPackageEntry* entry,
|
||||
BPackageEntryAttribute* attribute)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandleEntryDone(BPackageEntry* entry)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t HandlePackageAttribute(
|
||||
const BPackageInfoAttributeValue& value)
|
||||
{
|
||||
switch (value.attributeID) {
|
||||
case B_PACKAGE_INFO_NAME:
|
||||
fPackageInfo->SetName(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_SUMMARY:
|
||||
fPackageInfo->SetSummary(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_DESCRIPTION:
|
||||
fPackageInfo->SetDescription(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_VENDOR:
|
||||
fPackageInfo->SetVendor(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_PACKAGER:
|
||||
fPackageInfo->SetPackager(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_FLAGS:
|
||||
fPackageInfo->SetFlags(value.unsignedInt);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_ARCHITECTURE:
|
||||
fPackageInfo->SetArchitecture(
|
||||
(BPackageArchitecture)value.unsignedInt);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_VERSION:
|
||||
fPackageInfo->SetVersion(value.version);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_COPYRIGHTS:
|
||||
fPackageInfo->AddCopyright(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_LICENSES:
|
||||
fPackageInfo->AddLicense(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_PROVIDES:
|
||||
fPackageInfo->AddProvides(value.resolvable);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_REQUIRES:
|
||||
fPackageInfo->AddRequires(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_SUPPLEMENTS:
|
||||
fPackageInfo->AddSupplements(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_CONFLICTS:
|
||||
fPackageInfo->AddConflicts(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_FRESHENS:
|
||||
fPackageInfo->AddFreshens(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_REPLACES:
|
||||
fPackageInfo->AddReplaces(value.string);
|
||||
break;
|
||||
|
||||
default:
|
||||
fErrorOutput->PrintError(
|
||||
"Invalid package attribute section: unexpected package "
|
||||
"attribute id %d encountered\n", value.attributeID);
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual void HandleErrorOccurred()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
BErrorOutput* fErrorOutput;
|
||||
BPackageInfo* fPackageInfo;
|
||||
BPackageReader* fPackageReader;
|
||||
BFDDataReader fPackageFileReader;
|
||||
BRepositoryInfo* fRepositoryInfo;
|
||||
};
|
||||
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
struct RepositoryWriterImpl::PackageNameSet : public std::set<BString> {
|
||||
};
|
||||
|
||||
|
||||
RepositoryWriterImpl::RepositoryWriterImpl(BRepositoryWriterListener* listener,
|
||||
const BRepositoryInfo* repositoryInfo)
|
||||
BRepositoryInfo* repositoryInfo)
|
||||
:
|
||||
inherited(listener),
|
||||
fListener(listener),
|
||||
@@ -96,125 +319,6 @@ RepositoryWriterImpl::Finish()
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::HandleEntry(BPackageEntry* entry)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::HandleEntryAttribute(BPackageEntry* entry,
|
||||
BPackageEntryAttribute* attribute)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::HandleEntryDone(BPackageEntry* entry)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::HandlePackageAttribute(
|
||||
const BPackageInfoAttributeValue& value)
|
||||
{
|
||||
switch (value.attributeID) {
|
||||
case B_PACKAGE_INFO_NAME:
|
||||
fPackageInfo.SetName(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_SUMMARY:
|
||||
fPackageInfo.SetSummary(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_DESCRIPTION:
|
||||
fPackageInfo.SetDescription(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_VENDOR:
|
||||
fPackageInfo.SetVendor(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_PACKAGER:
|
||||
fPackageInfo.SetPackager(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_FLAGS:
|
||||
fPackageInfo.SetFlags(value.unsignedInt);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_ARCHITECTURE:
|
||||
fPackageInfo.SetArchitecture(
|
||||
(BPackageArchitecture)value.unsignedInt);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_VERSION:
|
||||
fPackageInfo.SetVersion(value.version);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_COPYRIGHTS:
|
||||
fPackageInfo.AddCopyright(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_LICENSES:
|
||||
fPackageInfo.AddLicense(value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_PROVIDES:
|
||||
fPackageInfo.AddProvides(value.resolvable);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_REQUIRES:
|
||||
fPackageInfo.AddRequires(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_SUPPLEMENTS:
|
||||
fPackageInfo.AddSupplements(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_CONFLICTS:
|
||||
fPackageInfo.AddConflicts(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_FRESHENS:
|
||||
fPackageInfo.AddFreshens(value.resolvableExpression);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_REPLACES:
|
||||
fPackageInfo.AddReplaces(value.string);
|
||||
break;
|
||||
|
||||
default:
|
||||
fListener->PrintError(
|
||||
"Invalid package attribute section: unexpected package "
|
||||
"attribute id %d encountered\n", value.attributeID);
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::HandlePackageAttributesDone()
|
||||
{
|
||||
status_t result = _RegisterCurrentPackageInfo();
|
||||
fPackageInfo.Clear();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RepositoryWriterImpl::HandleErrorOccurred()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
RepositoryWriterImpl::_Init(const char* fileName)
|
||||
{
|
||||
@@ -239,7 +343,8 @@ RepositoryWriterImpl::_Finish()
|
||||
sizeof(header) + infoLengthCompressed, packagesLengthCompressed);
|
||||
|
||||
fListener->OnRepositoryDone(sizeof(header), infoLengthCompressed,
|
||||
fPackageCount, packagesLengthCompressed, totalSize);
|
||||
fRepositoryInfo->LicenseNames().CountItems(), fPackageCount,
|
||||
packagesLengthCompressed, totalSize);
|
||||
|
||||
// general
|
||||
header.magic = B_HOST_TO_BENDIAN_INT32(B_HPKG_REPO_MAGIC);
|
||||
@@ -278,6 +383,13 @@ RepositoryWriterImpl::_AddPackage(const BEntry& packageEntry)
|
||||
|
||||
fPackageInfo.Clear();
|
||||
|
||||
// parse package
|
||||
PackageContentHandler contentHandler(fListener, &fPackageInfo,
|
||||
packageReader.PackageFileFD(), fRepositoryInfo);
|
||||
if ((result = packageReader.ParseContent(&contentHandler)) != B_OK)
|
||||
return result;
|
||||
|
||||
// determine package's checksum
|
||||
GeneralFileChecksumAccessor checksumAccessor(packageEntry);
|
||||
BString checksum;
|
||||
if ((result = checksumAccessor.GetChecksum(checksum)) != B_OK) {
|
||||
@@ -286,9 +398,11 @@ RepositoryWriterImpl::_AddPackage(const BEntry& packageEntry)
|
||||
}
|
||||
fPackageInfo.SetChecksum(checksum);
|
||||
|
||||
// register package's attributes
|
||||
if ((result = _RegisterCurrentPackageInfo()) != B_OK)
|
||||
return result;
|
||||
|
||||
|
||||
return packageReader.ParseContent(this);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user