* implemented checking of licenses, such that it is no longer possible
to create a package that refers to a license that is not a system license or contained in the package * added package-info flags (currently only approve_license and system_package) * adjusted package-reader/writer and pkgman accordingly git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40393 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1b4f0abf9d
commit
d77c6cd26a
23
headers/os/package/PackageFlags.h
Normal file
23
headers/os/package/PackageFlags.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PACKAGE__PACKAGE_FLAGS_H_
|
||||
#define _PACKAGE__PACKAGE_FLAGS_H_
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
enum {
|
||||
B_PACKAGE_FLAG_APPROVE_LICENSE = 1ul << 0,
|
||||
// will trigger display and approval of license before installation
|
||||
B_PACKAGE_FLAG_SYSTEM_PACKAGE = 1ul << 1,
|
||||
// marks package as system package (i.e. belonging into /boot/system)
|
||||
};
|
||||
|
||||
|
||||
} // namespace BPackageKit
|
||||
|
||||
|
||||
#endif // _PACKAGE__PACKAGE_FLAGS_H_
|
@ -10,6 +10,7 @@
|
||||
#include <String.h>
|
||||
|
||||
#include <package/PackageArchitecture.h>
|
||||
#include <package/PackageFlags.h>
|
||||
#include <package/PackageInfoAttributes.h>
|
||||
#include <package/PackageResolvable.h>
|
||||
#include <package/PackageResolvableExpression.h>
|
||||
@ -55,6 +56,8 @@ public:
|
||||
const BString& Vendor() const;
|
||||
const BString& Packager() const;
|
||||
|
||||
uint32 Flags() const;
|
||||
|
||||
BPackageArchitecture Architecture() const;
|
||||
|
||||
const BPackageVersion& Version() const;
|
||||
@ -79,6 +82,8 @@ public:
|
||||
void SetVendor(const BString& vendor);
|
||||
void SetPackager(const BString& packager);
|
||||
|
||||
void SetFlags(uint32 flags);
|
||||
|
||||
void SetArchitecture(
|
||||
BPackageArchitecture architecture);
|
||||
|
||||
@ -128,6 +133,8 @@ private:
|
||||
BString fVendor;
|
||||
BString fPackager;
|
||||
|
||||
uint32 fFlags;
|
||||
|
||||
BPackageArchitecture fArchitecture;
|
||||
|
||||
BPackageVersion fVersion;
|
||||
|
@ -33,6 +33,7 @@ enum BPackageInfoAttributeIndex {
|
||||
// contains a patch for
|
||||
B_PACKAGE_INFO_REPLACES, // list of resolvables that this package
|
||||
// will replace (upon update)
|
||||
B_PACKAGE_INFO_FLAGS,
|
||||
//
|
||||
B_PACKAGE_INFO_ENUM_COUNT,
|
||||
};
|
||||
|
@ -34,8 +34,7 @@ public:
|
||||
uint64 uncompressedStringsSize,
|
||||
uint64 uncompressedMainSize,
|
||||
uint64 uncompressedTOCSize) = 0;
|
||||
virtual void OnPackageAttributesSizeInfo(
|
||||
uint32 stringCount,
|
||||
virtual void OnPackageAttributesSizeInfo(uint32 stringCount,
|
||||
uint32 uncompressedSize) = 0;
|
||||
virtual void OnPackageSizeInfo(uint32 headerSize,
|
||||
uint64 heapSize, uint64 tocSize,
|
||||
|
@ -61,6 +61,8 @@ private:
|
||||
const char* name, size_t nameLength,
|
||||
bool isImplicit);
|
||||
|
||||
status_t _CheckLicenses();
|
||||
|
||||
void _WriteTOC(hpkg_header& header);
|
||||
int32 _WriteTOCSections(uint64& _attributeTypesSize,
|
||||
uint64& _stringsSize, uint64& _mainSize);
|
||||
@ -114,6 +116,8 @@ private:
|
||||
|
||||
StringCache fStringCache;
|
||||
AttributeTypeTable* fAttributeTypes;
|
||||
|
||||
BPackageInfo fPackageInfo;
|
||||
};
|
||||
|
||||
|
||||
|
@ -129,6 +129,7 @@ enum HPKGPackageAttributeID {
|
||||
HPKG_PACKAGE_ATTRIBUTE_DESCRIPTION,
|
||||
HPKG_PACKAGE_ATTRIBUTE_VENDOR,
|
||||
HPKG_PACKAGE_ATTRIBUTE_PACKAGER,
|
||||
HPKG_PACKAGE_ATTRIBUTE_FLAGS,
|
||||
HPKG_PACKAGE_ATTRIBUTE_ARCHITECTURE,
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_MAJOR,
|
||||
HPKG_PACKAGE_ATTRIBUTE_VERSION_MINOR,
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -52,7 +53,7 @@ public:
|
||||
if (fQuiet || !fVerbose)
|
||||
return;
|
||||
|
||||
printf("----- TOC Info -----\n");
|
||||
printf("----- TOC Info -----------------------------------\n");
|
||||
printf("attribute types size: %10llu (uncompressed)\n",
|
||||
uncompressedAttributeTypesSize);
|
||||
printf("cached strings size: %10llu (uncompressed)\n",
|
||||
@ -69,9 +70,9 @@ public:
|
||||
if (fQuiet || !fVerbose)
|
||||
return;
|
||||
|
||||
printf("----- Package Attribute Info -----\n");
|
||||
printf("string count: %10ld\n", stringCount);
|
||||
printf("package attributes size: %10ld (uncompressed)\n",
|
||||
printf("----- Package Attribute Info ---------------------\n");
|
||||
printf("string count: %10lu\n", stringCount);
|
||||
printf("package attributes size: %10lu (uncompressed)\n",
|
||||
uncompressedSize);
|
||||
}
|
||||
|
||||
@ -81,12 +82,12 @@ public:
|
||||
if (fQuiet)
|
||||
return;
|
||||
|
||||
printf("----- Package Info -----\n");
|
||||
printf("----- Package Info ----------------\n");
|
||||
printf("header size: %10lu\n", headerSize);
|
||||
printf("heap size: %10lld\n", heapSize);
|
||||
printf("TOC size: %10lld\n", tocSize);
|
||||
printf("package attributes size: %10ld\n", packageAttributesSize);
|
||||
printf("total size: %10lld\n", totalSize);
|
||||
printf("heap size: %10llu\n", heapSize);
|
||||
printf("TOC size: %10llu\n", tocSize);
|
||||
printf("package attributes size: %10lu\n", packageAttributesSize);
|
||||
printf("total size: %10llu\n", totalSize);
|
||||
|
||||
}
|
||||
|
||||
@ -139,14 +140,11 @@ command_create(int argc, const char* const* argv)
|
||||
}
|
||||
}
|
||||
|
||||
// The remaining arguments are the package file and the list of files to
|
||||
// include, i.e. at least two more arguments.
|
||||
if (optind + 2 > argc)
|
||||
// The remaining arguments is the package file, i.e. one more argument.
|
||||
if (optind + 1 != argc)
|
||||
print_usage_and_exit(true);
|
||||
|
||||
const char* packageFileName = argv[optind++];
|
||||
const char* const* fileNames = argv + optind;
|
||||
int fileNameCount = argc - optind;
|
||||
|
||||
// create package
|
||||
PackageWriterListener listener(verbose, quiet);
|
||||
@ -164,32 +162,22 @@ command_create(int argc, const char* const* argv)
|
||||
}
|
||||
}
|
||||
|
||||
// add files
|
||||
for (int i = 0; i < fileNameCount; i++) {
|
||||
if (strcmp(fileNames[i], ".") == 0) {
|
||||
DIR* dir = opendir(".");
|
||||
if (dir == NULL) {
|
||||
listener.PrintError("Error: Failed to opendir '.': %s\n",
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
while (dirent* entry = readdir(dir)) {
|
||||
if (strcmp(entry->d_name, ".") == 0
|
||||
|| strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
result = packageWriter.AddEntry(entry->d_name);
|
||||
if (result != B_OK)
|
||||
return 1;
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
} else {
|
||||
result = packageWriter.AddEntry(fileNames[i]);
|
||||
if (result != B_OK)
|
||||
return 1;
|
||||
}
|
||||
// add all files of current directory
|
||||
DIR* dir = opendir(".");
|
||||
if (dir == NULL) {
|
||||
listener.PrintError("Error: Failed to opendir '.': %s\n",
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
while (dirent* entry = readdir(dir)) {
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
result = packageWriter.AddEntry(entry->d_name);
|
||||
if (result != B_OK)
|
||||
return 1;
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
// write the package
|
||||
result = packageWriter.Finish();
|
||||
|
@ -133,6 +133,16 @@ struct PackageContentListHandler : BPackageContentHandler {
|
||||
printf("\tpackager: %s\n", value.string);
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_FLAGS:
|
||||
if (value.unsignedInt == 0)
|
||||
break;
|
||||
printf("\tflags:\n");
|
||||
if ((value.unsignedInt & B_PACKAGE_FLAG_APPROVE_LICENSE) != 0)
|
||||
printf("\t\tapprove_license\n");
|
||||
if ((value.unsignedInt & B_PACKAGE_FLAG_SYSTEM_PACKAGE) != 0)
|
||||
printf("\t\tsystem_package\n");
|
||||
break;
|
||||
|
||||
case B_PACKAGE_INFO_ARCHITECTURE:
|
||||
printf("\tarchitecure: %s\n",
|
||||
BPackageInfo::kArchitectureNames[value.unsignedInt]);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -24,11 +25,10 @@ static const char* kUsage =
|
||||
"Creates, inspects, or extracts a Haiku package.\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
" create [ <options> ] <package> <file> ...\n"
|
||||
" Creates package file <package> from a list of files.\n"
|
||||
" create [ <options> ] <package>\n"
|
||||
" Creates package file <package> from contents of current directory.\n"
|
||||
"\n"
|
||||
" -C <dir> - Change to directory <dir> before interpreting the file\n"
|
||||
" names <file>.\n"
|
||||
" -C <dir> - Change to directory <dir> before starting.\n"
|
||||
"\n"
|
||||
" dump [ <options> ] <package>\n"
|
||||
" Dumps the TOC section of package file <package>. For debugging only.\n"
|
||||
|
@ -72,6 +72,7 @@ private:
|
||||
void _RewindTo(const Token& token);
|
||||
|
||||
void _ParseStringValue(BString* value);
|
||||
uint32 _ParseFlags();
|
||||
void _ParseArchitectureValue(
|
||||
BPackageArchitecture* value);
|
||||
void _ParseVersionValue(BPackageVersion* value,
|
||||
@ -416,6 +417,45 @@ BPackageInfo::Parser::_ParseStringList(BObjectList<BString>* value, bool
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
BPackageInfo::Parser::_ParseFlags()
|
||||
{
|
||||
uint32 flags = 0;
|
||||
|
||||
Token openBracket = _NextToken();
|
||||
if (openBracket.type != TOKEN_OPEN_BRACKET)
|
||||
throw ParseError("expected start of list ('[')", openBracket.pos);
|
||||
|
||||
bool needComma = false;
|
||||
while (true) {
|
||||
Token token = _NextToken();
|
||||
if (token.type == TOKEN_CLOSE_BRACKET)
|
||||
break;
|
||||
|
||||
if (needComma) {
|
||||
if (token.type != TOKEN_COMMA)
|
||||
throw ParseError("expected comma", token.pos);
|
||||
token = _NextToken();
|
||||
} else
|
||||
needComma = true;
|
||||
|
||||
if (token.type != TOKEN_WORD)
|
||||
throw ParseError("expected word (a flag)", token.pos);
|
||||
|
||||
if (token.text.ICompare("approve_license") == 0)
|
||||
flags |= B_PACKAGE_FLAG_APPROVE_LICENSE;
|
||||
else if (token.text.ICompare("system_package") == 0)
|
||||
flags |= B_PACKAGE_FLAG_SYSTEM_PACKAGE;
|
||||
else {
|
||||
throw ParseError("expected 'approve_license' or 'system_package'",
|
||||
token.pos);
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BPackageInfo::Parser::_ParseResolvableList(
|
||||
BObjectList<BPackageResolvable>* value)
|
||||
@ -729,6 +769,16 @@ BPackageInfo::Parser::_Parse(BPackageInfo* packageInfo)
|
||||
for (int i = 0; i < count; ++i)
|
||||
packageInfo->AddReplaces(*(replacesList.ItemAt(i)));
|
||||
seen[B_PACKAGE_INFO_REPLACES] = true;
|
||||
} else if (t.text.ICompare(names[B_PACKAGE_INFO_FLAGS])
|
||||
== 0) {
|
||||
if (seen[B_PACKAGE_INFO_FLAGS]) {
|
||||
BString error = BString(names[B_PACKAGE_INFO_FLAGS])
|
||||
<< " already seen!";
|
||||
throw ParseError(error, t.pos);
|
||||
}
|
||||
|
||||
packageInfo->SetFlags(_ParseFlags());
|
||||
seen[B_PACKAGE_INFO_FLAGS] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -758,6 +808,7 @@ const char* BPackageInfo::kElementNames[B_PACKAGE_INFO_ENUM_COUNT] = {
|
||||
"conflicts",
|
||||
"freshens",
|
||||
"replaces",
|
||||
"flags",
|
||||
};
|
||||
|
||||
|
||||
@ -771,6 +822,7 @@ BPackageInfo::kArchitectureNames[B_PACKAGE_ARCHITECTURE_ENUM_COUNT] = {
|
||||
|
||||
BPackageInfo::BPackageInfo()
|
||||
:
|
||||
fFlags(0),
|
||||
fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT),
|
||||
fCopyrightList(5, true),
|
||||
fLicenseList(5, true),
|
||||
@ -884,6 +936,13 @@ BPackageInfo::Packager() const
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
BPackageInfo::Flags() const
|
||||
{
|
||||
return fFlags;
|
||||
}
|
||||
|
||||
|
||||
BPackageArchitecture
|
||||
BPackageInfo::Architecture() const
|
||||
{
|
||||
@ -996,6 +1055,13 @@ BPackageInfo::SetVersion(const BPackageVersion& version)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BPackageInfo::SetFlags(uint32 flags)
|
||||
{
|
||||
fFlags = flags;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BPackageInfo::SetArchitecture(BPackageArchitecture architecture)
|
||||
{
|
||||
|
@ -1162,6 +1162,11 @@ PackageReaderImpl::_ParsePackageAttributes(AttributeHandlerContext* context)
|
||||
attributeValue.string);
|
||||
break;
|
||||
|
||||
case HPKG_PACKAGE_ATTRIBUTE_FLAGS:
|
||||
handlerValue.SetTo(B_PACKAGE_INFO_FLAGS,
|
||||
(uint32)attributeValue.unsignedInt);
|
||||
break;
|
||||
|
||||
case HPKG_PACKAGE_ATTRIBUTE_ARCHITECTURE:
|
||||
if (attributeValue.unsignedInt
|
||||
>= B_PACKAGE_ARCHITECTURE_ENUM_COUNT) {
|
||||
|
@ -20,8 +20,11 @@
|
||||
#include <new>
|
||||
|
||||
#include <ByteOrder.h>
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <fs_attr.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
@ -350,12 +353,11 @@ PackageWriterImpl::AddEntry(const char* fileName)
|
||||
BPackageWriterListener* listener;
|
||||
} errorListener(fListener);
|
||||
BEntry packageInfoEntry(fileName);
|
||||
BPackageInfo packageInfo;
|
||||
status_t result = packageInfo.ReadFromConfigFile(packageInfoEntry,
|
||||
status_t result = fPackageInfo.ReadFromConfigFile(packageInfoEntry,
|
||||
&errorListener);
|
||||
if (result != B_OK || (result = packageInfo.InitCheck()) != B_OK)
|
||||
if (result != B_OK || (result = fPackageInfo.InitCheck()) != B_OK)
|
||||
return result;
|
||||
RegisterPackageInfo(PackageAttributes(), packageInfo);
|
||||
RegisterPackageInfo(PackageAttributes(), fPackageInfo);
|
||||
}
|
||||
|
||||
return _RegisterEntry(fileName);
|
||||
@ -372,11 +374,16 @@ status_t
|
||||
PackageWriterImpl::Finish()
|
||||
{
|
||||
try {
|
||||
if (PackageAttributes().IsEmpty()) {
|
||||
if (fPackageInfo.InitCheck() != B_OK) {
|
||||
fListener->PrintError("No package-info file found (%s)!\n",
|
||||
B_HPKG_PACKAGE_INFO_FILE_NAME);
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
status_t result = _CheckLicenses();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
return _Finish();
|
||||
} catch (status_t error) {
|
||||
return error;
|
||||
@ -418,6 +425,44 @@ PackageWriterImpl::_Init(const char* fileName)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PackageWriterImpl::_CheckLicenses()
|
||||
{
|
||||
BPath systemLicensePath;
|
||||
status_t result
|
||||
= find_directory(B_SYSTEM_DATA_DIRECTORY, &systemLicensePath);
|
||||
if (result != B_OK) {
|
||||
fListener->PrintError("unable to find system data path!\n");
|
||||
return result;
|
||||
}
|
||||
if ((result = systemLicensePath.Append("licenses")) != B_OK) {
|
||||
fListener->PrintError("unable to append to system data path!\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
BDirectory systemLicenseDir(systemLicensePath.Path());
|
||||
BDirectory packageLicenseDir("./data/licenses");
|
||||
|
||||
const BObjectList<BString>& licenseList = fPackageInfo.LicenseList();
|
||||
for (int i = 0; i < licenseList.CountItems(); ++i) {
|
||||
const BString& licenseName = *licenseList.ItemAt(i);
|
||||
BEntry license;
|
||||
if (systemLicenseDir.FindEntry(licenseName.String(), &license) == B_OK)
|
||||
continue;
|
||||
|
||||
// license is not a system license, so it must be contained in package
|
||||
if (packageLicenseDir.FindEntry(licenseName.String(),
|
||||
&license) != B_OK) {
|
||||
fListener->PrintError("License '%s' isn't contained in package!\n",
|
||||
licenseName.String());
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
PackageWriterImpl::_Finish()
|
||||
{
|
||||
|
@ -391,12 +391,19 @@ WriterImplBase::RegisterPackageInfo(PackageAttributeList& attributeList,
|
||||
packager->string = fPackageStringCache.Get(packageInfo.Packager().String());
|
||||
attributeList.Add(packager);
|
||||
|
||||
// flags
|
||||
PackageAttribute* flags = new PackageAttribute(
|
||||
HPKG_PACKAGE_ATTRIBUTE_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(
|
||||
HPKG_PACKAGE_ATTRIBUTE_ARCHITECTURE, B_HPKG_ATTRIBUTE_TYPE_UINT,
|
||||
B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT);
|
||||
architecture->unsignedInt = packageInfo.Architecture();
|
||||
attributeList.Add(packager);
|
||||
attributeList.Add(architecture);
|
||||
|
||||
// version
|
||||
RegisterPackageVersion(attributeList, packageInfo.Version());
|
||||
|
Loading…
Reference in New Issue
Block a user